ext/ffmpeg/gstffmpegcodecmap.c: Make type explicit.
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Fri, 22 Jul 2005 16:07:02 +0000 (16:07 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Fri, 22 Jul 2005 16:07:02 +0000 (16:07 +0000)
Original commit message from CVS:
* ext/ffmpeg/gstffmpegcodecmap.c:
Make type explicit.
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_release_buffer),
(gst_ffmpegdec_frame), (gst_ffmpegdec_chain),
(gst_ffmpegdec_change_state):
When we provide a buffer and get a valid return value (data was
read), but no output (have-data==0), then we need to reuse this
same output buffer, because it may be used for caching output
data. Fixes #307353.
* ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_loop):
Timestamp fix.

ChangeLog
common
ext/ffmpeg/gstffmpegcodecmap.c
ext/ffmpeg/gstffmpegdec.c
ext/ffmpeg/gstffmpegdemux.c

index 77a5d90..feb50a9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2005-07-22  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
+
+       * ext/ffmpeg/gstffmpegcodecmap.c:
+         Make type explicit.
+       * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_release_buffer),
+       (gst_ffmpegdec_frame), (gst_ffmpegdec_chain),
+       (gst_ffmpegdec_change_state):
+         When we provide a buffer and get a valid return value (data was
+         read), but no output (have-data==0), then we need to reuse this
+         same output buffer, because it may be used for caching output
+         data. Fixes #307353.
+       * ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_loop):
+         Timestamp fix.
+
 2005-07-20  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
 
        * ext/ffmpeg/gstffmpeg.h:
diff --git a/common b/common
index 6f9b691..694de4d 160000 (submodule)
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 6f9b691adc2a0300598311671dd7c4d9d2035afa
+Subproject commit 694de4dbf4827f372321f0634643a254d7edd986
index 09f1b83..7b1c201 100644 (file)
@@ -86,7 +86,7 @@ gst_ffmpeg_set_palette (GstCaps *caps, AVCodecContext *context)
     gst_caps_new_simple (mimetype,                             \
        "width",     G_TYPE_INT,   context->width,              \
        "height",    G_TYPE_INT,   context->height,             \
-       "framerate", G_TYPE_DOUBLE, 1. *                        \
+       "framerate", G_TYPE_DOUBLE, (double) 1. *               \
                                context->time_base.den /        \
                                        context->time_base.num, \
        __VA_ARGS__, NULL)                                      \
@@ -94,7 +94,8 @@ gst_ffmpeg_set_palette (GstCaps *caps, AVCodecContext *context)
     gst_caps_new_simple (mimetype,                             \
        "width",     GST_TYPE_INT_RANGE, 16, 4096,              \
        "height",    GST_TYPE_INT_RANGE, 16, 4096,              \
-       "framerate", GST_TYPE_DOUBLE_RANGE, 0., G_MAXDOUBLE,    \
+       "framerate", GST_TYPE_DOUBLE_RANGE, (double) 0.,        \
+                                               G_MAXDOUBLE,    \
        __VA_ARGS__, NULL)
 
 /* same for audio - now with channels/sample rate
index d3c1f77..031a1b2 100644 (file)
@@ -562,7 +562,8 @@ gst_ffmpegdec_release_buffer (AVCodecContext * context, AVFrame * picture)
   g_return_if_fail (buf != NULL);
   g_return_if_fail (picture->type == FF_BUFFER_TYPE_USER);
 
-  ffmpegdec->last_buffer = NULL;
+  if (buf == ffmpegdec->last_buffer)
+    ffmpegdec->last_buffer = NULL;
   gst_buffer_unref (buf);
 
   /* zero out the reference in ffmpeg */
@@ -665,7 +666,7 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec,
   GstFFMpegDecClass *oclass =
       (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
   GstBuffer *outbuf = NULL;
-  gint have_data, len = 0;
+  gint have_data = 0, len = 0;
   
   ffmpegdec->context->frame_number++;
 
@@ -690,6 +691,8 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec,
 
        if (ffmpegdec->picture->opaque != NULL) {
          outbuf = (GstBuffer *) ffmpegdec->picture->opaque;
+          if (outbuf == ffmpegdec->last_buffer)
+            ffmpegdec->last_buffer = NULL;
        } else {
          AVPicture pic;
          gint fsize = gst_ffmpeg_avpicture_get_size (ffmpegdec->context->pix_fmt,
@@ -778,14 +781,18 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec,
       break;
 
     case CODEC_TYPE_AUDIO:
-      outbuf = gst_buffer_new_and_alloc (AVCODEC_MAX_AUDIO_FRAME_SIZE);
+      if (!ffmpegdec->last_buffer)
+        outbuf = gst_buffer_new_and_alloc (AVCODEC_MAX_AUDIO_FRAME_SIZE);
+      else {
+        outbuf = ffmpegdec->last_buffer;
+        ffmpegdec->last_buffer = NULL;
+      }
       len = avcodec_decode_audio (ffmpegdec->context,
           (int16_t *) GST_BUFFER_DATA (outbuf), &have_data, data, size);
       GST_DEBUG_OBJECT (ffmpegdec,
           "Decode audio: len=%d, have_data=%d", len, have_data);
 
       if (len >= 0 && have_data > 0) {
-
        if (!gst_ffmpegdec_negotiate (ffmpegdec)) {
          gst_buffer_unref (outbuf);
          return -1;
@@ -801,6 +808,9 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec,
             ffmpegdec->context->sample_rate);
         ffmpegdec->next_ts += GST_BUFFER_DURATION (outbuf);
         *in_ts += GST_BUFFER_DURATION (outbuf);
+      } else if (len > 0 && have_data == 0) {
+        /* cache output, because it may be used for caching (in-place) */
+        ffmpegdec->last_buffer = outbuf;
       } else {
         gst_buffer_unref (outbuf);
       }
@@ -1006,6 +1016,8 @@ gst_ffmpegdec_chain (GstPad * pad, GstData * _data)
 
     ffmpegdec->pcache = gst_buffer_create_sub (inbuf,
         GST_BUFFER_SIZE (inbuf) - bsize, bsize);
+  } else if (bsize > 0) {
+    GST_DEBUG_OBJECT (ffmpegdec, "Dropping %d bytes of data", bsize);
   }
   gst_buffer_unref (inbuf);
 }
@@ -1021,6 +1033,7 @@ gst_ffmpegdec_change_state (GstElement * element)
       gst_ffmpegdec_close (ffmpegdec);
       if (ffmpegdec->last_buffer != NULL) {
        gst_buffer_unref (ffmpegdec->last_buffer);
+        ffmpegdec->last_buffer = NULL;
       }
       break;
   }
index 3cbdf2f..b7710b3 100644 (file)
@@ -656,8 +656,9 @@ gst_ffmpegdemux_loop (GstElement * element)
     GST_BUFFER_SIZE (outbuf) = pkt.size;
 
     if (pkt.pts != AV_NOPTS_VALUE) {
-      GST_BUFFER_TIMESTAMP (outbuf) = (GstClockTime) (pkt.pts +
-          stream->start_time) * GST_SECOND / AV_TIME_BASE;
+      AVRational bq = { 1, GST_SECOND };
+      GST_BUFFER_TIMESTAMP (outbuf) = av_rescale_q (pkt.pts,
+          demux->context->streams[pkt.stream_index]->time_base, bq);
       demux->last_ts[stream->index] = GST_BUFFER_TIMESTAMP (outbuf);
     }