summaryrefslogtreecommitdiffstats
path: root/dom/media/platforms/PlatformDecoderModule.h
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/media/platforms/PlatformDecoderModule.h
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/media/platforms/PlatformDecoderModule.h')
-rw-r--r--dom/media/platforms/PlatformDecoderModule.h309
1 files changed, 309 insertions, 0 deletions
diff --git a/dom/media/platforms/PlatformDecoderModule.h b/dom/media/platforms/PlatformDecoderModule.h
new file mode 100644
index 000000000..7480d8ff9
--- /dev/null
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -0,0 +1,309 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#if !defined(PlatformDecoderModule_h_)
+#define PlatformDecoderModule_h_
+
+#include "MediaDecoderReader.h"
+#include "MediaInfo.h"
+#include "mozilla/MozPromise.h"
+#include "mozilla/layers/LayersTypes.h"
+#include "mozilla/layers/KnowsCompositor.h"
+#include "nsTArray.h"
+#include "mozilla/RefPtr.h"
+#include "GMPService.h"
+#include <queue>
+#include "MediaResult.h"
+
+namespace mozilla {
+class TrackInfo;
+class AudioInfo;
+class VideoInfo;
+class MediaRawData;
+class DecoderDoctorDiagnostics;
+
+namespace layers {
+class ImageContainer;
+} // namespace layers
+
+namespace dom {
+class RemoteDecoderModule;
+}
+
+class MediaDataDecoder;
+class MediaDataDecoderCallback;
+class TaskQueue;
+class CDMProxy;
+
+static LazyLogModule sPDMLog("PlatformDecoderModule");
+
+struct MOZ_STACK_CLASS CreateDecoderParams final {
+ explicit CreateDecoderParams(const TrackInfo& aConfig)
+ : mConfig(aConfig)
+ {}
+
+ template <typename T1, typename... Ts>
+ CreateDecoderParams(const TrackInfo& aConfig, T1&& a1, Ts&&... args)
+ : mConfig(aConfig)
+ {
+ Set(mozilla::Forward<T1>(a1), mozilla::Forward<Ts>(args)...);
+ }
+
+ const VideoInfo& VideoConfig() const
+ {
+ MOZ_ASSERT(mConfig.IsVideo());
+ return *mConfig.GetAsVideoInfo();
+ }
+
+ const AudioInfo& AudioConfig() const
+ {
+ MOZ_ASSERT(mConfig.IsAudio());
+ return *mConfig.GetAsAudioInfo();
+ }
+
+ layers::LayersBackend GetLayersBackend() const
+ {
+ if (mKnowsCompositor) {
+ return mKnowsCompositor->GetCompositorBackendType();
+ }
+ return layers::LayersBackend::LAYERS_NONE;
+ }
+
+ const TrackInfo& mConfig;
+ TaskQueue* mTaskQueue = nullptr;
+ MediaDataDecoderCallback* mCallback = nullptr;
+ DecoderDoctorDiagnostics* mDiagnostics = nullptr;
+ layers::ImageContainer* mImageContainer = nullptr;
+ MediaResult* mError = nullptr;
+ RefPtr<layers::KnowsCompositor> mKnowsCompositor;
+ RefPtr<GMPCrashHelper> mCrashHelper;
+ bool mUseBlankDecoder = false;
+
+private:
+ void Set(TaskQueue* aTaskQueue) { mTaskQueue = aTaskQueue; }
+ void Set(MediaDataDecoderCallback* aCallback) { mCallback = aCallback; }
+ void Set(DecoderDoctorDiagnostics* aDiagnostics) { mDiagnostics = aDiagnostics; }
+ void Set(layers::ImageContainer* aImageContainer) { mImageContainer = aImageContainer; }
+ void Set(MediaResult* aError) { mError = aError; }
+ void Set(GMPCrashHelper* aCrashHelper) { mCrashHelper = aCrashHelper; }
+ void Set(bool aUseBlankDecoder) { mUseBlankDecoder = aUseBlankDecoder; }
+ void Set(layers::KnowsCompositor* aKnowsCompositor) { mKnowsCompositor = aKnowsCompositor; }
+ template <typename T1, typename T2, typename... Ts>
+ void Set(T1&& a1, T2&& a2, Ts&&... args)
+ {
+ Set(mozilla::Forward<T1>(a1));
+ Set(mozilla::Forward<T2>(a2), mozilla::Forward<Ts>(args)...);
+ }
+};
+
+// The PlatformDecoderModule interface is used by the MediaFormatReader to
+// abstract access to decoders provided by various
+// platforms.
+// Each platform (Windows, MacOSX, Linux, B2G etc) must implement a
+// PlatformDecoderModule to provide access to its decoders in order to get
+// decompressed H.264/AAC from the MediaFormatReader.
+//
+// Decoding is asynchronous, and should be performed on the task queue
+// provided if the underlying platform isn't already exposing an async API.
+//
+// A cross-platform decoder module that discards input and produces "blank"
+// output samples exists for testing, and is created when the pref
+// "media.use-blank-decoder" is true.
+
+class PlatformDecoderModule {
+public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PlatformDecoderModule)
+
+ // Perform any per-instance initialization.
+ // This is called on the decode task queue.
+ virtual nsresult Startup() { return NS_OK; };
+
+ // Indicates if the PlatformDecoderModule supports decoding of aMimeType.
+ virtual bool SupportsMimeType(const nsACString& aMimeType,
+ DecoderDoctorDiagnostics* aDiagnostics) const = 0;
+ virtual bool Supports(const TrackInfo& aTrackInfo,
+ DecoderDoctorDiagnostics* aDiagnostics) const
+ {
+ // By default, fall back to SupportsMimeType with just the MIME string.
+ // (So PDMs do not need to override this method -- yet.)
+ return SupportsMimeType(aTrackInfo.mMimeType, aDiagnostics);
+ }
+
+ enum class ConversionRequired : uint8_t {
+ kNeedNone,
+ kNeedAVCC,
+ kNeedAnnexB,
+ };
+
+ // Indicates that the decoder requires a specific format.
+ // The PlatformDecoderModule will convert the demuxed data accordingly before
+ // feeding it to MediaDataDecoder::Input.
+ virtual ConversionRequired DecoderNeedsConversion(const TrackInfo& aConfig) const = 0;
+
+protected:
+ PlatformDecoderModule() {}
+ virtual ~PlatformDecoderModule() {}
+
+ friend class H264Converter;
+ friend class PDMFactory;
+ friend class dom::RemoteDecoderModule;
+
+ // Creates a Video decoder. The layers backend is passed in so that
+ // decoders can determine whether hardware accelerated decoding can be used.
+ // Asynchronous decoding of video should be done in runnables dispatched
+ // to aVideoTaskQueue. If the task queue isn't needed, the decoder should
+ // not hold a reference to it.
+ // Output and errors should be returned to the reader via aCallback.
+ // On Windows the task queue's threads in have MSCOM initialized with
+ // COINIT_MULTITHREADED.
+ // Returns nullptr if the decoder can't be created.
+ // It is safe to store a reference to aConfig.
+ // This is called on the decode task queue.
+ virtual already_AddRefed<MediaDataDecoder>
+ CreateVideoDecoder(const CreateDecoderParams& aParams) = 0;
+
+ // Creates an Audio decoder with the specified properties.
+ // Asynchronous decoding of audio should be done in runnables dispatched to
+ // aAudioTaskQueue. If the task queue isn't needed, the decoder should
+ // not hold a reference to it.
+ // Output and errors should be returned to the reader via aCallback.
+ // Returns nullptr if the decoder can't be created.
+ // On Windows the task queue's threads in have MSCOM initialized with
+ // COINIT_MULTITHREADED.
+ // It is safe to store a reference to aConfig.
+ // This is called on the decode task queue.
+ virtual already_AddRefed<MediaDataDecoder>
+ CreateAudioDecoder(const CreateDecoderParams& aParams) = 0;
+};
+
+// A callback used by MediaDataDecoder to return output/errors to the
+// MediaFormatReader.
+// Implementation is threadsafe, and can be called on any thread.
+class MediaDataDecoderCallback {
+public:
+ virtual ~MediaDataDecoderCallback() {}
+
+ // Called by MediaDataDecoder when a sample has been decoded.
+ virtual void Output(MediaData* aData) = 0;
+
+ // Denotes an error in the decoding process. The reader will stop calling
+ // the decoder.
+ virtual void Error(const MediaResult& aError) = 0;
+
+ // Denotes that the last input sample has been inserted into the decoder,
+ // and no more output can be produced unless more input is sent.
+ // A frame decoding session is completed once InputExhausted has been called.
+ // MediaDataDecoder::Input will not be called again until InputExhausted has
+ // been called.
+ virtual void InputExhausted() = 0;
+
+ virtual void DrainComplete() = 0;
+
+ virtual void ReleaseMediaResources() {}
+
+ virtual bool OnReaderTaskQueue() = 0;
+
+ // Denotes that a pending encryption key is preventing more input being fed
+ // into the decoder. This only needs to be overridden for callbacks that
+ // handle encryption. E.g. benchmarking does not use eme, so this need
+ // not be overridden in that case.
+ virtual void WaitingForKey() {}
+};
+
+// MediaDataDecoder is the interface exposed by decoders created by the
+// PlatformDecoderModule's Create*Decoder() functions. The type of
+// media data that the decoder accepts as valid input and produces as
+// output is determined when the MediaDataDecoder is created.
+//
+// Unless otherwise noted, all functions are only called on the decode task
+// queue. An exception is the MediaDataDecoder in
+// MediaFormatReader::IsVideoAccelerated() for which all calls (Init(),
+// IsHardwareAccelerated(), and Shutdown()) are from the main thread.
+//
+// Don't block inside these functions, unless it's explicitly noted that you
+// should (like in Flush()).
+//
+// Decoding is done asynchronously. Any async work can be done on the
+// TaskQueue passed into the PlatformDecoderModules's Create*Decoder()
+// function. This may not be necessary for platforms with async APIs
+// for decoding.
+//
+// If an error occurs at any point after the Init promise has been
+// completed, then Error() must be called on the associated
+// MediaDataDecoderCallback.
+class MediaDataDecoder {
+protected:
+ virtual ~MediaDataDecoder() {};
+
+public:
+ typedef TrackInfo::TrackType TrackType;
+ typedef MozPromise<TrackType, MediaResult, /* IsExclusive = */ true> InitPromise;
+
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataDecoder)
+
+ // Initialize the decoder. The decoder should be ready to decode once
+ // promise resolves. The decoder should do any initialization here, rather
+ // than in its constructor or PlatformDecoderModule::Create*Decoder(),
+ // so that if the MediaFormatReader needs to shutdown during initialization,
+ // it can call Shutdown() to cancel this operation. Any initialization
+ // that requires blocking the calling thread in this function *must*
+ // be done here so that it can be canceled by calling Shutdown()!
+ virtual RefPtr<InitPromise> Init() = 0;
+
+ // Inserts a sample into the decoder's decode pipeline.
+ virtual void Input(MediaRawData* aSample) = 0;
+
+ // Causes all samples in the decoding pipeline to be discarded. When
+ // this function returns, the decoder must be ready to accept new input
+ // for decoding. This function is called when the demuxer seeks, before
+ // decoding resumes after the seek.
+ // While the reader calls Flush(), it ignores all output sent to it;
+ // it is safe (but pointless) to send output while Flush is called.
+ // The MediaFormatReader will not call Input() while it's calling Flush().
+ virtual void Flush() = 0;
+
+ // Causes all complete samples in the pipeline that can be decoded to be
+ // output. If the decoder can't produce samples from the current output,
+ // it drops the input samples. The decoder may be holding onto samples
+ // that are required to decode samples that it expects to get in future.
+ // This is called when the demuxer reaches end of stream.
+ // The MediaFormatReader will not call Input() while it's calling Drain().
+ // This function is asynchronous. The MediaDataDecoder must call
+ // MediaDataDecoderCallback::DrainComplete() once all remaining
+ // samples have been output.
+ virtual void Drain() = 0;
+
+ // Cancels all init/input/drain operations, and shuts down the
+ // decoder. The platform decoder should clean up any resources it's using
+ // and release memory etc. Shutdown() must block until the decoder has
+ // completed shutdown. The reader calls Flush() before calling Shutdown().
+ // The reader will delete the decoder once Shutdown() returns.
+ // The MediaDataDecoderCallback *must* not be called after Shutdown() has
+ // returned.
+ virtual void Shutdown() = 0;
+
+ // Called from the state machine task queue or main thread.
+ // Decoder needs to decide whether or not hardware accelearation is supported
+ // after creating. It doesn't need to call Init() before calling this function.
+ virtual bool IsHardwareAccelerated(nsACString& aFailureReason) const { return false; }
+
+ // Return the name of the MediaDataDecoder, only used for decoding.
+ // Only return a static const string, as the information may be accessed
+ // in a non thread-safe fashion.
+ virtual const char* GetDescriptionName() const = 0;
+
+ // 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) {}
+};
+
+} // namespace mozilla
+
+#endif