diff options
author | Edward Hervey <bilboed@bilboed.com> | 2005-12-07 12:14:34 +0000 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2005-12-07 12:14:34 +0000 |
commit | 3fe565fc1dd6706f5376957681f2ec54b63ffae0 (patch) | |
tree | 6c8f411094d08a10a9fc4966f707df8da75e9063 /ext | |
parent | 9783a9207a3e9ae40a70932dfdea0431ab2b5bb7 (diff) |
ext/ffmpeg/gstffmpegdec.c: So, stupid ffmpeg.... Not all [en|de]coders set AVFrame->type.
Original commit message from CVS:
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_frame):
So, stupid ffmpeg.... Not all [en|de]coders set AVFrame->type.
This should handle the case where AVFrame->reference is set to 1 (which
is the equivalent of a keyframe).
Also fixes #323286.
I tried a truckload of other files with this modification and it didn't seem
to break playback.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/ffmpeg/gstffmpegdec.c | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/ext/ffmpeg/gstffmpegdec.c b/ext/ffmpeg/gstffmpegdec.c index e805e4c..0ecb2f0 100644 --- a/ext/ffmpeg/gstffmpegdec.c +++ b/ext/ffmpeg/gstffmpegdec.c @@ -804,18 +804,23 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec, ffmpegdec->context->frame_number++; switch (oclass->in_plugin->type) { - case CODEC_TYPE_VIDEO: + case CODEC_TYPE_VIDEO: + { + gboolean iskeyframe = FALSE; + ffmpegdec->picture->pict_type = -1; /* in case we skip frames */ ffmpegdec->context->opaque = ffmpegdec; len = avcodec_decode_video (ffmpegdec->context, ffmpegdec->picture, &have_data, data, size); + iskeyframe = ((ffmpegdec->picture->pict_type == FF_I_TYPE) || (ffmpegdec->picture->reference)); GST_DEBUG_OBJECT (ffmpegdec, - "Decoded video: len=%d, have_data=%d", len, have_data); + "Decoded video: len=%d, have_data=%d, is_keyframe:%d", + len, have_data, iskeyframe); if (ffmpegdec->waiting_for_key) { - if (ffmpegdec->picture->pict_type == FF_I_TYPE) { + if (iskeyframe) { ffmpegdec->waiting_for_key = FALSE; } else { GST_WARNING_OBJECT (ffmpegdec, "Dropping non-keyframe (seek/init)"); @@ -823,21 +828,20 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec, break; } } - + /* note that ffmpeg sometimes gets the FPS wrong. * For B-frame containing movies, we get all pictures delayed * except for the I frames, so we synchronize only on I frames * and keep an internal counter based on FPS for the others. */ if (!(oclass->in_plugin->capabilities & CODEC_CAP_DELAY) || - ((ffmpegdec->picture->pict_type == FF_I_TYPE || - !GST_CLOCK_TIME_IS_VALID (ffmpegdec->next_ts)) && - GST_CLOCK_TIME_IS_VALID (*in_ts))) { - GST_DEBUG_OBJECT (ffmpegdec, "setting next_ts to %" GST_TIME_FORMAT, - GST_TIME_ARGS (*in_ts)); - ffmpegdec->next_ts = *in_ts; - *in_ts = GST_CLOCK_TIME_NONE; + ((iskeyframe || !GST_CLOCK_TIME_IS_VALID (ffmpegdec->next_ts)) && + GST_CLOCK_TIME_IS_VALID (*in_ts))) { + GST_DEBUG_OBJECT (ffmpegdec, "setting next_ts to %" GST_TIME_FORMAT, + GST_TIME_ARGS (*in_ts)); + ffmpegdec->next_ts = *in_ts; + *in_ts = GST_CLOCK_TIME_NONE; } - + /* precise seeking.... */ if (GST_CLOCK_TIME_IS_VALID (ffmpegdec->synctime)) { if (ffmpegdec->next_ts >= ffmpegdec->synctime) { @@ -859,8 +863,7 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec, } } - if (ffmpegdec->waiting_for_key && - ffmpegdec->picture->pict_type != FF_I_TYPE) { + if (ffmpegdec->waiting_for_key && !iskeyframe) { have_data = 0; } else if (len >= 0 && have_data > 0) { /* libavcodec constantly crashes on stupid buffer allocation @@ -904,7 +907,7 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec, ffmpegdec->waiting_for_key = FALSE; - if (!ffmpegdec->picture->key_frame) { + if (!iskeyframe) { GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); } @@ -935,9 +938,8 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec, } else if (ffmpegdec->picture->pict_type != -1 && oclass->in_plugin->capabilities & CODEC_CAP_DELAY) { /* update time for skip-frame */ - if ((!have_data) - || (ffmpegdec->picture->pict_type == FF_I_TYPE || - !GST_CLOCK_TIME_IS_VALID (ffmpegdec->next_ts)) + if ((!have_data) || + (iskeyframe || !GST_CLOCK_TIME_IS_VALID (ffmpegdec->next_ts)) && GST_CLOCK_TIME_IS_VALID (*in_ts)) { GST_DEBUG_OBJECT (ffmpegdec, "setting next_ts to *in_ts"); ffmpegdec->next_ts = *in_ts; @@ -961,7 +963,7 @@ gst_ffmpegdec_frame (GstFFMpegDec * ffmpegdec, } } break; - + } case CODEC_TYPE_AUDIO: if (!ffmpegdec->last_buffer) outbuf = gst_buffer_new_and_alloc (AVCODEC_MAX_AUDIO_FRAME_SIZE); |