Bug 1270323: [ffmpeg] P3. Use the dts of the last sample input, not the dts of the last decoded sample. r?cpearce draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 23 May 2016 15:37:34 +1000
changeset 369996 f712770a2b455ab4b96d3ef74110219b368bebc4
parent 369995 f319d11d743d8fccd12c5d2c65478e5ce1b88269
child 369997 37e919ae75a0f3de655090df5c47bc96d1304a0a
push id18971
push userbmo:jyavenard@mozilla.com
push dateTue, 24 May 2016 03:18:45 +0000
reviewerscpearce
bugs1270323, 1244410
milestone49.0a1
Bug 1270323: [ffmpeg] P3. Use the dts of the last sample input, not the dts of the last decoded sample. r?cpearce Amendment to bug 1244410. If no frames had been output yet, last dts would have been INT64_MIN. MozReview-Commit-ID: LOdWLpyuLYm
dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -103,16 +103,17 @@ FFmpegVideoDecoder<LIBAV_VER>::PtsCorrec
 FFmpegVideoDecoder<LIBAV_VER>::FFmpegVideoDecoder(FFmpegLibWrapper* aLib,
   FlushableTaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback,
   const VideoInfo& aConfig,
   ImageContainer* aImageContainer)
   : FFmpegDataDecoder(aLib, aTaskQueue, aCallback, GetCodecId(aConfig.mMimeType))
   , mImageContainer(aImageContainer)
   , mInfo(aConfig)
   , mCodecParser(nullptr)
+  , mLastInputDts(INT64_MIN)
 {
   MOZ_COUNT_CTOR(FFmpegVideoDecoder);
   // Use a new MediaByteBuffer as the object will be modified during initialization.
   mExtraData = new MediaByteBuffer;
   mExtraData->AppendElements(*aConfig.mExtraData);
 }
 
 RefPtr<MediaDataDecoder::InitPromise>
@@ -205,17 +206,17 @@ FFmpegVideoDecoder<LIBAV_VER>::DecodeRes
 FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
                                         uint8_t* aData, int aSize)
 {
   AVPacket packet;
   mLib->av_init_packet(&packet);
 
   packet.data = aData;
   packet.size = aSize;
-  packet.dts = aSample->mTimecode;
+  packet.dts = mLastInputDts = aSample->mTimecode;
   packet.pts = aSample->mTime;
   packet.flags = aSample->mKeyframe ? AV_PKT_FLAG_KEY : 0;
   packet.pos = aSample->mOffset;
 
   // LibAV provides no API to retrieve the decoded sample's duration.
   // (FFmpeg >= 1.0 provides av_frame_get_pkt_duration)
   // As such we instead use a map using the dts as key that we will retrieve
   // later.
@@ -307,17 +308,17 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
   }
   return DecodeResult::DECODE_NO_FRAME;
 }
 
 void
 FFmpegVideoDecoder<LIBAV_VER>::ProcessDrain()
 {
   RefPtr<MediaRawData> empty(new MediaRawData());
-  empty->mTimecode = mPtsContext.LastDts();
+  empty->mTimecode = mLastInputDts;
   while (DoDecode(empty) == DecodeResult::DECODE_FRAME) {
   }
   mCallback->DrainComplete();
 }
 
 void
 FFmpegVideoDecoder<LIBAV_VER>::ProcessFlush()
 {
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
@@ -77,16 +77,17 @@ private:
   private:
     int64_t mNumFaultyPts; /// Number of incorrect PTS values so far
     int64_t mNumFaultyDts; /// Number of incorrect DTS values so far
     int64_t mLastPts;       /// PTS of the last frame
     int64_t mLastDts;       /// DTS of the last frame
   };
 
   PtsCorrectionContext mPtsContext;
+  int64_t mLastInputDts;
 
   class DurationMap {
   public:
     typedef Pair<int64_t, int64_t> DurationElement;
 
     // Insert Key and Duration pair at the end of our map.
     void Insert(int64_t aKey, int64_t aDuration)
     {