+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:
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) \
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
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 */
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++;
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,
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;
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);
}
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);
}
gst_ffmpegdec_close (ffmpegdec);
if (ffmpegdec->last_buffer != NULL) {
gst_buffer_unref (ffmpegdec->last_buffer);
+ ffmpegdec->last_buffer = NULL;
}
break;
}