Bug 1406503 - P2. Use common draining mechanism for both audio and video decoder. r=jwwang
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 26 Oct 2017 22:56:32 +0200
changeset 389038 a1f28a42c07fb09a46ed6862749eb9a377e477f7
parent 389037 5017b988318884fbb07978d1ae512362f5fab3eb
child 389039 5f06da1362df0f9cb0587378d31e3785aeb40a5a
push id32777
push userarchaeopteryx@coole-files.de
push dateMon, 30 Oct 2017 22:44:45 +0000
treeherdermozilla-central@dd0f265a1300 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwwang
bugs1406503
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1406503 - P2. Use common draining mechanism for both audio and video decoder. r=jwwang MozReview-Commit-ID: AtDHOuDfpi5
dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
dom/media/platforms/ffmpeg/FFmpegAudioDecoder.h
dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
dom/media/platforms/ffmpeg/FFmpegDataDecoder.h
dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
--- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
@@ -210,23 +210,16 @@ FFmpegAudioDecoder<LIBAV_VER>::DoDecode(
     }
     packet.data += bytesConsumed;
     packet.size -= bytesConsumed;
     samplePosition += bytesConsumed;
   }
   return NS_OK;
 }
 
-RefPtr<MediaDataDecoder::DecodePromise>
-FFmpegAudioDecoder<LIBAV_VER>::ProcessDrain()
-{
-  ProcessFlush();
-  return DecodePromise::CreateAndResolve(DecodedData(), __func__);
-}
-
 AVCodecID
 FFmpegAudioDecoder<LIBAV_VER>::GetCodecId(const nsACString& aMimeType)
 {
   if (aMimeType.EqualsLiteral("audio/mpeg")) {
     return AV_CODEC_ID_MP3;
   } else if (aMimeType.EqualsLiteral("audio/flac")) {
     return AV_CODEC_ID_FLAC;
   } else if (aMimeType.EqualsLiteral("audio/mp4a-latm")) {
--- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.h
@@ -28,17 +28,16 @@ public:
   void InitCodecContext() override;
   static AVCodecID GetCodecId(const nsACString& aMimeType);
   nsCString GetDescriptionName() const override
   {
     return NS_LITERAL_CSTRING("ffmpeg audio decoder");
   }
 
 private:
-  RefPtr<DecodePromise> ProcessDrain() override;
   MediaResult DoDecode(MediaRawData* aSample,
                        uint8_t* aData,
                        int aSize,
                        bool* aGotFrame,
                        DecodedData& aResults) override;
 };
 
 } // namespace mozilla
--- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
@@ -24,16 +24,17 @@ FFmpegDataDecoder<LIBAV_VER>::FFmpegData
                                                 AVCodecID aCodecID)
   : mLib(aLib)
   , mCodecContext(nullptr)
   , mCodecParser(nullptr)
   , mFrame(NULL)
   , mExtraData(nullptr)
   , mCodecID(aCodecID)
   , mTaskQueue(aTaskQueue)
+  , mLastInputDts(media::TimeUnit::FromMicroseconds(INT64_MIN))
 {
   MOZ_ASSERT(aLib);
   MOZ_COUNT_CTOR(FFmpegDataDecoder);
 }
 
 FFmpegDataDecoder<LIBAV_VER>::~FFmpegDataDecoder()
 {
   MOZ_COUNT_DTOR(FFmpegDataDecoder);
@@ -132,16 +133,18 @@ FFmpegDataDecoder<LIBAV_VER>::ProcessDec
 
 MediaResult
 FFmpegDataDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample, bool* aGotFrame,
                                        MediaDataDecoder::DecodedData& aResults)
 {
   uint8_t* inputData = const_cast<uint8_t*>(aSample->Data());
   size_t inputSize = aSample->Size();
 
+  mLastInputDts = aSample->mTimecode;
+
   if (inputSize && mCodecParser) {
     while (inputSize) {
       uint8_t* data = inputData;
       int size = inputSize;
       int len = mLib->av_parser_parse2(
         mCodecParser, mCodecContext, &data, &size, inputData, inputSize,
         aSample->mTime.ToMicroseconds(), aSample->mTimecode.ToMicroseconds(),
         aSample->mOffset);
@@ -175,16 +178,29 @@ FFmpegDataDecoder<LIBAV_VER>::Flush()
 
 RefPtr<MediaDataDecoder::DecodePromise>
 FFmpegDataDecoder<LIBAV_VER>::Drain()
 {
   return InvokeAsync(mTaskQueue, this, __func__,
                      &FFmpegDataDecoder<LIBAV_VER>::ProcessDrain);
 }
 
+RefPtr<MediaDataDecoder::DecodePromise>
+FFmpegDataDecoder<LIBAV_VER>::ProcessDrain()
+{
+  RefPtr<MediaRawData> empty(new MediaRawData());
+  empty->mTimecode = mLastInputDts;
+  bool gotFrame = false;
+  DecodedData results;
+  while (NS_SUCCEEDED(DoDecode(empty, &gotFrame, results)) &&
+         gotFrame) {
+  }
+  return DecodePromise::CreateAndResolve(Move(results), __func__);
+}
+
 RefPtr<MediaDataDecoder::FlushPromise>
 FFmpegDataDecoder<LIBAV_VER>::ProcessFlush()
 {
   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
   if (mCodecContext) {
     mLib->avcodec_flush_buffers(mCodecContext);
   }
   return FlushPromise::CreateAndResolve(true, __func__);
--- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.h
@@ -53,25 +53,26 @@ protected:
   AVCodecContext* mCodecContext;
   AVCodecParserContext* mCodecParser;
   AVFrame* mFrame;
   RefPtr<MediaByteBuffer> mExtraData;
   AVCodecID mCodecID;
 
 private:
   RefPtr<DecodePromise> ProcessDecode(MediaRawData* aSample);
-  virtual RefPtr<DecodePromise> ProcessDrain() = 0;
+  RefPtr<DecodePromise> ProcessDrain();
   virtual MediaResult DoDecode(MediaRawData* aSample,
                                uint8_t* aData,
                                int aSize,
                                bool* aGotFrame,
                                MediaDataDecoder::DecodedData& aOutResults) = 0;
   virtual bool NeedParser() const { return false; }
   virtual int ParserFlags() const { return PARSER_FLAG_COMPLETE_FRAMES; }
 
   static StaticMutex sMonitor;
   const RefPtr<TaskQueue> mTaskQueue;
   MozPromiseHolder<DecodePromise> mPromise;
+  media::TimeUnit mLastInputDts;
 };
 
 } // namespace mozilla
 
 #endif // __FFmpegDataDecoder_h__
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -123,17 +123,16 @@ FFmpegVideoDecoder<LIBAV_VER>::PtsCorrec
 FFmpegVideoDecoder<LIBAV_VER>::FFmpegVideoDecoder(
   FFmpegLibWrapper* aLib, TaskQueue* aTaskQueue, const VideoInfo& aConfig,
   KnowsCompositor* aAllocator, ImageContainer* aImageContainer,
   bool aLowLatency)
   : FFmpegDataDecoder(aLib, aTaskQueue, GetCodecId(aConfig.mMimeType))
   , mImageAllocator(aAllocator)
   , mImageContainer(aImageContainer)
   , mInfo(aConfig)
-  , mLastInputDts(INT64_MIN)
   , mLowLatency(aLowLatency)
 {
   // Use a new MediaByteBuffer as the object will be modified during
   // initialization.
   mExtraData = new MediaByteBuffer;
   mExtraData->AppendElements(*aConfig.mExtraData);
 }
 
@@ -190,17 +189,17 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
                                         bool* aGotFrame,
                                         MediaDataDecoder::DecodedData& aResults)
 {
   AVPacket packet;
   mLib->av_init_packet(&packet);
 
   packet.data = aData;
   packet.size = aSize;
-  packet.dts = mLastInputDts = aSample->mTimecode.ToMicroseconds();
+  packet.dts = aSample->mTimecode.ToMicroseconds();
   packet.pts = aSample->mTime.ToMicroseconds();
   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.
@@ -353,29 +352,16 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
   }
   aResults.AppendElement(Move(v));
   if (aGotFrame) {
     *aGotFrame = true;
   }
   return NS_OK;
 }
 
-RefPtr<MediaDataDecoder::DecodePromise>
-FFmpegVideoDecoder<LIBAV_VER>::ProcessDrain()
-{
-  RefPtr<MediaRawData> empty(new MediaRawData());
-  empty->mTimecode = TimeUnit::FromMicroseconds(mLastInputDts);
-  bool gotFrame = false;
-  DecodedData results;
-  while (NS_SUCCEEDED(DoDecode(empty, nullptr, 0, &gotFrame, results)) &&
-         gotFrame) {
-  }
-  return DecodePromise::CreateAndResolve(Move(results), __func__);
-}
-
 RefPtr<MediaDataDecoder::FlushPromise>
 FFmpegVideoDecoder<LIBAV_VER>::ProcessFlush()
 {
   mPtsContext.Reset();
   mDurationMap.Clear();
   return FFmpegDataDecoder::ProcessFlush();
 }
 
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
@@ -47,17 +47,16 @@ public:
   ConversionRequired NeedsConversion() const override
   {
     return ConversionRequired::kNeedAVCC;
   }
 
   static AVCodecID GetCodecId(const nsACString& aMimeType);
 
 private:
-  RefPtr<DecodePromise> ProcessDrain() override;
   RefPtr<FlushPromise> ProcessFlush() override;
   MediaResult DoDecode(MediaRawData* aSample,
                        uint8_t* aData,
                        int aSize,
                        bool* aGotFrame,
                        DecodedData& aResults) override;
   void OutputDelayedFrames();
   bool NeedParser() const override
@@ -93,17 +92,16 @@ 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;
 
   DurationMap mDurationMap;
   const bool mLowLatency;
 };
 
 } // namespace mozilla
 
 #endif // __FFmpegVideoDecoder_h__