From 676721d2670c65224c895e196f121dceafc047d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Colin=20G=C3=BCnther?= Date: Sun, 10 Aug 2014 13:56:58 +0200 Subject: [PATCH] FFMPEG Plugin: Fix video start_time generation. - Ensure that start times are increased monotonically for video formats that contain B-frames, too, as expected by the BMediaDecoders. Previously start times were returned that seemed to go back in time for videos containing B-frames. Tested with resolutionchange.mpg (\see http://samples.ffmpeg.org/MPEG2) Note: Even though start times aren't going back in time anymore there are times where two consecutive start times are equal. This would need more research once this exposes a bug in a real application. Further more this might seem like a new bug, but before this commit the equal start times would have simply some different start time[s] in between. So at most this is the same bug just wearing new clothes :) - Documentation updated accordingly. --- .../media/plugins/ffmpeg/AVFormatReader.cpp | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp index 3cb21311f5..f88b936b09 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVFormatReader.cpp @@ -701,18 +701,22 @@ StreamBase::GetNextChunk(const void** chunkBuffer, mediaHeader->destination = -1; mediaHeader->time_source = -1; mediaHeader->size_used = fPacket.size; - if (fPacket.pts != kNoPTSValue) { -//TRACE(" PTS: %lld (time_base.num: %d, .den: %d), stream DTS: %lld\n", -//fPacket.pts, fStream->time_base.num, fStream->time_base.den, -//fStream->cur_dts); - mediaHeader->start_time = _ConvertFromStreamTimeBase(fPacket.pts); - } else { -//TRACE(" PTS (stream): %lld (time_base.num: %d, .den: %d), stream DTS: %lld\n", -//lastStreamDTS, fStream->time_base.num, fStream->time_base.den, -//fStream->cur_dts); - mediaHeader->start_time - = _ConvertFromStreamTimeBase(lastStreamDTS); - } + + // FFmpeg recommends to use the decoding time stamps as primary source + // for presentation time stamps, especially for video formats that are + // using frame reordering. More over this way it is ensured that the + // returned start times are ordered in a monotonically increasing time + // series (even for videos that contain B-frames). + // \see http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavformat/avformat.h;h=1e8a6294890d580cd9ebc684eaf4ce57c8413bd8;hb=9153b33a742c4e2a85ff6230aea0e75f5a8b26c2#l1623 + bigtime_t presentationTimeStamp; + if (fPacket.dts != kNoPTSValue) + presentationTimeStamp = fPacket.dts; + else if (fPacket.pts != kNoPTSValue) + presentationTimeStamp = fPacket.pts; + else + presentationTimeStamp = lastStreamDTS; + + mediaHeader->start_time = _ConvertFromStreamTimeBase(presentationTimeStamp); mediaHeader->file_pos = fPacket.pos; mediaHeader->data_offset = 0; switch (mediaHeader->type) {