Bug 1424416 - Add RequiresDrainning method to MediaDataDecoder and update impls. r?jya draft
authorBryce Van Dyk <bvandyk@mozilla.com>
Tue, 10 Apr 2018 12:09:27 -0400
changeset 779926 60a7a2a44163c8aba6ba8bcfa06d9587194517f4
parent 779146 30d72755b1749953d438199456f1524ce84ab5e5
child 779927 e8f5e8372b2a3caa5912685f853b7888a0f68f19
push id105908
push userbvandyk@mozilla.com
push dateTue, 10 Apr 2018 20:37:51 +0000
reviewersjya
bugs1424416
milestone61.0a1
Bug 1424416 - Add RequiresDrainning method to MediaDataDecoder and update impls. r?jya Add RequiresDraining method, which indicates if a decoder requires draining in order to output all frames in the event of an EOS or running out of data. By default decoders indicate they require draining. This provides safe default behaviour. For a number of decoders we can safely avoid draining, override the method for these. This will allow users of these decoders to simplify handling and offer performance improvements. MozReview-Commit-ID: 67ZrWhgFL5i
dom/media/platforms/PlatformDecoderModule.h
dom/media/platforms/agnostic/AOMDecoder.h
dom/media/platforms/agnostic/OpusDecoder.h
dom/media/platforms/agnostic/TheoraDecoder.h
dom/media/platforms/agnostic/VPXDecoder.h
dom/media/platforms/agnostic/VorbisDecoder.h
dom/media/platforms/agnostic/WAVDecoder.h
dom/media/platforms/apple/AppleATDecoder.cpp
dom/media/platforms/apple/AppleATDecoder.h
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -311,16 +311,28 @@ public:
   {
     return false;
   }
 
   // Return the name of the MediaDataDecoder, only used for decoding.
   // May be accessed in a non thread-safe fashion.
   virtual nsCString GetDescriptionName() const = 0;
 
+  // Return if a decoder needs to be drained in order to output all samples.
+  // Some decoders may buffer samples in order to decode expected future
+  // samples. In these cases the decoder must be drained to ensure all samples
+  // are output when reaching end of stream or running out of data. However,
+  // if a decoder does not buffer samples, then it does not need draining, and
+  // users can avoid doing so, which can benefit performance and simplify code.
+  // Even if a decoder does not require draining, a sane implementation of
+  // Drain() should be specified. It is safe to say a decoder requires draining
+  // even if it does not strictly need it. However bustages will result if a
+  // decoder reports it does not require draining when it does.
+  virtual bool RequiresDrainning() const { return true; }
+
   // Set a hint of seek target time to decoder. Decoder will drop any decoded
   // data which pts is smaller than this value. This threshold needs to be clear
   // after reset decoder.
   // Decoder may not honor this value. However, it'd be better that
   // video decoder implements this API to improve seek performance.
   // Note: it should be called before Input() or after Flush().
   virtual void SetSeekThreshold(const media::TimeUnit& aTime) { }
 
--- a/dom/media/platforms/agnostic/AOMDecoder.h
+++ b/dom/media/platforms/agnostic/AOMDecoder.h
@@ -27,16 +27,20 @@ public:
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   nsCString GetDescriptionName() const override
   {
     return NS_LITERAL_CSTRING("av1 libaom video decoder");
   }
+  bool RequiresDrainning() const override
+  {
+    return false;
+  }
 
   // Return true if aMimeType is a one of the strings used
   // by our demuxers to identify AV1 streams.
   static bool IsAV1(const nsACString& aMimeType);
 
   // Return true if aCodecType is a supported codec description.
   static bool IsSupportedCodec(const nsAString& aCodecType);
 
--- a/dom/media/platforms/agnostic/OpusDecoder.h
+++ b/dom/media/platforms/agnostic/OpusDecoder.h
@@ -32,16 +32,20 @@ public:
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   nsCString GetDescriptionName() const override
   {
     return NS_LITERAL_CSTRING("opus audio decoder");
   }
+  bool RequiresDrainning() const override
+  {
+    return false;
+  }
 
   // Return true if mimetype is Opus
   static bool IsOpus(const nsACString& aMimeType);
 
   // Pack pre-skip/CodecDelay, given in microseconds, into a
   // MediaByteBuffer. The decoder expects this value to come
   // from the container (if any) and to precede the OpusHead
   // block in the CodecSpecificConfig buffer to verify the
--- a/dom/media/platforms/agnostic/TheoraDecoder.h
+++ b/dom/media/platforms/agnostic/TheoraDecoder.h
@@ -31,16 +31,21 @@ public:
   // Return true if mimetype is a Theora codec
   static bool IsTheora(const nsACString& aMimeType);
 
   nsCString GetDescriptionName() const override
   {
     return NS_LITERAL_CSTRING("theora video decoder");
   }
 
+  bool RequiresDrainning() const override
+  {
+    return false;
+  }
+
 private:
   ~TheoraDecoder();
   nsresult DoDecodeHeader(const unsigned char* aData, size_t aLength);
 
   RefPtr<DecodePromise> ProcessDecode(MediaRawData* aSample);
 
   RefPtr<layers::KnowsCompositor> mImageAllocator;
   RefPtr<layers::ImageContainer> mImageContainer;
--- a/dom/media/platforms/agnostic/VPXDecoder.h
+++ b/dom/media/platforms/agnostic/VPXDecoder.h
@@ -30,16 +30,20 @@ public:
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   nsCString GetDescriptionName() const override
   {
     return NS_LITERAL_CSTRING("libvpx video decoder");
   }
+  bool RequiresDrainning() const override
+  {
+    return false;
+  }
 
   enum Codec: uint8_t
   {
     VP8 = 1 << 0,
     VP9 = 1 << 1,
     Unknown = 1 << 7,
   };
 
--- a/dom/media/platforms/agnostic/VorbisDecoder.h
+++ b/dom/media/platforms/agnostic/VorbisDecoder.h
@@ -32,16 +32,20 @@ public:
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   nsCString GetDescriptionName() const override
   {
     return NS_LITERAL_CSTRING("vorbis audio decoder");
   }
+  bool RequiresDrainning() const override
+  {
+    return false;
+  }
 
   // Return true if mimetype is Vorbis
   static bool IsVorbis(const nsACString& aMimeType);
   static const AudioConfig::Channel* VorbisLayout(uint32_t aChannels);
 
 private:
   nsresult DecodeHeader(const unsigned char* aData, size_t aLength);
   RefPtr<DecodePromise> ProcessDecode(MediaRawData* aSample);
--- a/dom/media/platforms/agnostic/WAVDecoder.h
+++ b/dom/media/platforms/agnostic/WAVDecoder.h
@@ -27,16 +27,20 @@ public:
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
   RefPtr<DecodePromise> Drain() override;
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
   nsCString GetDescriptionName() const override
   {
     return NS_LITERAL_CSTRING("wave audio decoder");
   }
+  bool RequiresDrainning() const override
+  {
+    return false;
+  }
 
 private:
   RefPtr<DecodePromise> ProcessDecode(MediaRawData* aSample);
   const AudioInfo& mInfo;
   const RefPtr<TaskQueue> mTaskQueue;
 };
 
 } // namespace mozilla
--- a/dom/media/platforms/apple/AppleATDecoder.cpp
+++ b/dom/media/platforms/apple/AppleATDecoder.cpp
@@ -110,17 +110,16 @@ AppleATDecoder::Flush()
   LOG("Flushing AudioToolbox AAC decoder");
   return InvokeAsync(mTaskQueue, this, __func__, &AppleATDecoder::ProcessFlush);
 }
 
 RefPtr<MediaDataDecoder::DecodePromise>
 AppleATDecoder::Drain()
 {
   LOG("Draining AudioToolbox AAC decoder");
-  RefPtr<AppleATDecoder> self = this;
   return InvokeAsync(mTaskQueue, __func__, [] {
     return DecodePromise::CreateAndResolve(DecodedData(), __func__);
   });
 }
 
 RefPtr<ShutdownPromise>
 AppleATDecoder::Shutdown()
 {
--- a/dom/media/platforms/apple/AppleATDecoder.h
+++ b/dom/media/platforms/apple/AppleATDecoder.h
@@ -34,16 +34,21 @@ public:
   RefPtr<FlushPromise> Flush() override;
   RefPtr<ShutdownPromise> Shutdown() override;
 
   nsCString GetDescriptionName() const override
   {
     return NS_LITERAL_CSTRING("apple coremedia decoder");
   }
 
+  bool RequiresDrainning() const override
+  {
+    return false;
+  }
+
   // Callbacks also need access to the config.
   const AudioInfo& mConfig;
 
   // Use to extract magic cookie for HE-AAC detection.
   nsTArray<uint8_t> mMagicCookie;
   // Will be set to true should an error occurred while attempting to retrieve
   // the magic cookie property.
   bool mFileStreamError;