Bug 1336947: P3. Only attempt to drain FFmpeg decoder when decoder. r?gerald draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 07 Feb 2017 23:33:27 +0100
changeset 480197 b26ddd056de19c382553c54b4ae2fe27c7b29228
parent 480184 a032157a8b98cbf423ede97fbc5c923d81c92439
child 480198 67dec7035d746fa676088726171b566ab265ea5a
push id44485
push userbmo:jyavenard@mozilla.com
push dateTue, 07 Feb 2017 23:15:33 +0000
reviewersgerald
bugs1336947
milestone54.0a1
Bug 1336947: P3. Only attempt to drain FFmpeg decoder when decoder. r?gerald The FFmpeg can't be drained if the decoder just got created or if it has already been drained. MozReview-Commit-ID: FEHxihTWNT
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
@@ -163,16 +163,17 @@ RefPtr<MediaDataDecoder::DecodePromise>
 FFmpegVideoDecoder<LIBAV_VER>::ProcessDecode(MediaRawData* aSample)
 {
   bool gotFrame = false;
   DecodedData results;
   MediaResult rv = DoDecode(aSample, &gotFrame, results);
   if (NS_FAILED(rv)) {
     return DecodePromise::CreateAndReject(rv, __func__);
   }
+  mDrained = false;
   return DecodePromise::CreateAndResolve(Move(results), __func__);
 }
 
 MediaResult
 FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample, bool* aGotFrame,
                                         MediaDataDecoder::DecodedData& aResults)
 {
   uint8_t* inputData = const_cast<uint8_t*>(aSample->Data());
@@ -347,30 +348,35 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
     *aGotFrame = true;
   }
   return NS_OK;
 }
 
 RefPtr<MediaDataDecoder::DecodePromise>
 FFmpegVideoDecoder<LIBAV_VER>::ProcessDrain()
 {
+  DecodedData results;
+  if (mDrained) {
+    return DecodePromise::CreateAndResolve(results, __func__);
+  }
   RefPtr<MediaRawData> empty(new MediaRawData());
   empty->mTimecode = mLastInputDts;
   bool gotFrame = false;
-  DecodedData results;
   while (NS_SUCCEEDED(DoDecode(empty, &gotFrame, results)) && gotFrame) {
   }
+  mDrained = true;
   return DecodePromise::CreateAndResolve(Move(results), __func__);
 }
 
 RefPtr<MediaDataDecoder::FlushPromise>
 FFmpegVideoDecoder<LIBAV_VER>::ProcessFlush()
 {
   mPtsContext.Reset();
   mDurationMap.Clear();
+  mDrained = true;
   return FFmpegDataDecoder::ProcessFlush();
 }
 
 FFmpegVideoDecoder<LIBAV_VER>::~FFmpegVideoDecoder()
 {
   MOZ_COUNT_DTOR(FFmpegVideoDecoder);
   if (mCodecParser) {
     mLib->av_parser_close(mCodecParser);
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
@@ -82,16 +82,19 @@ private:
     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;
 
+  // Set to false if the decoder has anything to drain.
+  bool mDrained = true;
+
   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)
     {