diff --git a/ChangeLog b/ChangeLog index e8a6f03ad3..0f744dbdbe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2007-08-07 Wim Taymans + + * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_caps_with_codecid): + Improve debugging of codec data. + realvideo caps are underspecified, use fields of alternative variant + before we settle this. + + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_open), + (gst_ffmpegdec_video_frame): + Add more debugging of used parsers. + Setup the realvideo slices correctly before calling the decoder, fixed + realvideo in matroska. + 2007-08-01 Stefan Kost * ext/ffmpeg/gstffmpegcfg.c: (gst_ffmpeg_cfg_install_property), diff --git a/ext/ffmpeg/gstffmpegcodecmap.c b/ext/ffmpeg/gstffmpegcodecmap.c index b399779b88..88d67bc03f 100644 --- a/ext/ffmpeg/gstffmpegcodecmap.c +++ b/ext/ffmpeg/gstffmpegcodecmap.c @@ -1523,12 +1523,14 @@ gst_ffmpeg_caps_with_codecid (enum CodecID codec_id, av_mallocz (GST_ROUND_UP_16 (size + FF_INPUT_BUFFER_PADDING_SIZE)); memcpy (context->extradata, GST_BUFFER_DATA (buf), size); context->extradata_size = size; + GST_DEBUG ("have codec data of size %d", size); } else if (context->extradata == NULL) { /* no extradata, alloc dummy with 0 sized, some codecs insist on reading * extradata anyway which makes then segfault. */ context->extradata = av_mallocz (GST_ROUND_UP_16 (FF_INPUT_BUFFER_PADDING_SIZE)); context->extradata_size = 0; + GST_DEBUG ("no codec data"); } switch (codec_id) { @@ -1600,11 +1602,15 @@ gst_ffmpeg_caps_with_codecid (enum CodecID codec_id, case CODEC_ID_RV40: { guint32 fourcc; + gint format; if (gst_structure_get_fourcc (str, "rmsubid", &fourcc)) context->sub_id = fourcc; - } + if (gst_structure_get_int (str, "format", &format)) + context->sub_id = format; + break; + } case CODEC_ID_COOK: case CODEC_ID_RA_288: case CODEC_ID_RA_144: diff --git a/ext/ffmpeg/gstffmpegdec.c b/ext/ffmpeg/gstffmpegdec.c index e25253f7f7..b3e48f55fe 100644 --- a/ext/ffmpeg/gstffmpegdec.c +++ b/ext/ffmpeg/gstffmpegdec.c @@ -93,6 +93,8 @@ struct _GstFFMpegDec gboolean outoforder; GstClockTime tstamp1, tstamp2; GstClockTime dur1, dur2; + + gboolean is_realvideo; }; typedef struct _GstFFMpegDecClass GstFFMpegDecClass; @@ -485,6 +487,7 @@ gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec) goto could_not_open; ffmpegdec->opened = TRUE; + ffmpegdec->is_realvideo = FALSE; GST_LOG_OBJECT (ffmpegdec, "Opened ffmpeg codec %s, id %d", oclass->in_plugin->name, oclass->in_plugin->id); @@ -509,9 +512,16 @@ gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec) ffmpegdec->pctx = NULL; } break; + case CODEC_ID_RV10: + case CODEC_ID_RV20: + ffmpegdec->is_realvideo = TRUE; + break; default: - GST_LOG_OBJECT (ffmpegdec, "Using parser"); ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id); + if (ffmpegdec->pctx) + GST_LOG_OBJECT (ffmpegdec, "Using parser %p", ffmpegdec->pctx); + else + GST_LOG_OBJECT (ffmpegdec, "No parser for codec"); break; } @@ -1315,6 +1325,24 @@ gst_ffmpegdec_video_frame (GstFFMpegDec * ffmpegdec, /* in case we skip frames */ ffmpegdec->picture->pict_type = -1; + if (ffmpegdec->is_realvideo && data != NULL) { + gint slice_count; + gint i; + + /* setup the slice table for realvideo */ + if (ffmpegdec->context->slice_offset == NULL) + ffmpegdec->context->slice_offset = g_malloc (sizeof (guint32) * 1000); + + slice_count = (*data++) + 1; + ffmpegdec->context->slice_count = slice_count; + + for (i = 0; i < slice_count; i++) { + data += 4; + ffmpegdec->context->slice_offset[i] = GST_READ_UINT32_LE (data); + data += 4; + } + } + /* now decode the frame */ len = avcodec_decode_video (ffmpegdec->context, ffmpegdec->picture, &have_data, data, size);