summaryrefslogtreecommitdiffstats
path: root/dom/media/platforms/omx/OmxDataDecoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/platforms/omx/OmxDataDecoder.h')
-rw-r--r--dom/media/platforms/omx/OmxDataDecoder.h224
1 files changed, 224 insertions, 0 deletions
diff --git a/dom/media/platforms/omx/OmxDataDecoder.h b/dom/media/platforms/omx/OmxDataDecoder.h
new file mode 100644
index 0000000000..69c388ecee
--- /dev/null
+++ b/dom/media/platforms/omx/OmxDataDecoder.h
@@ -0,0 +1,224 @@
+/* -*- 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(OmxDataDecoder_h_)
+# define OmxDataDecoder_h_
+
+# include "AudioCompactor.h"
+# include "ImageContainer.h"
+# include "MediaInfo.h"
+# include "OMX_Component.h"
+# include "OmxPromiseLayer.h"
+# include "PerformanceRecorder.h"
+# include "PlatformDecoderModule.h"
+# include "mozilla/Monitor.h"
+# include "mozilla/StateWatching.h"
+
+namespace mozilla {
+
+class MediaDataHelper;
+
+typedef OmxPromiseLayer::OmxCommandPromise OmxCommandPromise;
+typedef OmxPromiseLayer::OmxBufferPromise OmxBufferPromise;
+typedef OmxPromiseLayer::OmxBufferFailureHolder OmxBufferFailureHolder;
+typedef OmxPromiseLayer::OmxCommandFailureHolder OmxCommandFailureHolder;
+typedef OmxPromiseLayer::BufferData BufferData;
+typedef OmxPromiseLayer::BUFFERLIST BUFFERLIST;
+
+DDLoggedTypeDeclNameAndBase(OmxDataDecoder, MediaDataDecoder);
+
+/* OmxDataDecoder is the major class which performs followings:
+ * 1. Translate PDM function into OMX commands.
+ * 2. Keeping the buffers between client and component.
+ * 3. Manage the OMX state.
+ *
+ * From the definition in OpenMax spec. "2.2.1", there are 3 major roles in
+ * OpenMax IL.
+ *
+ * IL client:
+ * "The IL client may be a layer below the GUI application, such as GStreamer,
+ * or may be several layers below the GUI layer."
+ *
+ * OmxDataDecoder acts as the IL client.
+ *
+ * OpenMAX IL component:
+ * "A component that is intended to wrap functionality that is required in the
+ * target system."
+ *
+ * OmxPromiseLayer acts as the OpenMAX IL component.
+ *
+ * OpenMAX IL core:
+ * "Platform-specific code that has the functionality necessary to locate and
+ * then load an OpenMAX IL component into main memory."
+ *
+ * OmxPlatformLayer acts as the OpenMAX IL core.
+ */
+class OmxDataDecoder final : public MediaDataDecoder,
+ public DecoderDoctorLifeLogger<OmxDataDecoder> {
+ protected:
+ virtual ~OmxDataDecoder();
+
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OmxDataDecoder, final);
+
+ OmxDataDecoder(const TrackInfo& aTrackInfo,
+ layers::ImageContainer* aImageContainer,
+ Maybe<TrackingId> aTrackingId);
+
+ RefPtr<InitPromise> Init() override;
+ RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
+ RefPtr<DecodePromise> Drain() override;
+ RefPtr<FlushPromise> Flush() override;
+ RefPtr<ShutdownPromise> Shutdown() override;
+
+ nsCString GetDescriptionName() const override { return "omx decoder"_ns; }
+
+ nsCString GetCodecName() const override { return "unknown"_ns; }
+
+ ConversionRequired NeedsConversion() const override {
+ return ConversionRequired::kNeedAnnexB;
+ }
+
+ // Return true if event is handled.
+ bool Event(OMX_EVENTTYPE aEvent, OMX_U32 aData1, OMX_U32 aData2);
+
+ protected:
+ void InitializationTask();
+
+ void ResolveInitPromise(const char* aMethodName);
+
+ void RejectInitPromise(MediaResult aError, const char* aMethodName);
+
+ void OmxStateRunner();
+
+ void FillAndEmptyBuffers();
+
+ void FillBufferDone(BufferData* aData);
+
+ void FillBufferFailure(OmxBufferFailureHolder aFailureHolder);
+
+ void EmptyBufferDone(BufferData* aData);
+
+ void EmptyBufferFailure(OmxBufferFailureHolder aFailureHolder);
+
+ void NotifyError(
+ OMX_ERRORTYPE aOmxError, const char* aLine,
+ const MediaResult& aError = MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR));
+
+ // Configure audio/video codec.
+ // Some codec may just ignore this and rely on codec specific data in
+ // FillCodecConfigDataToOmx().
+ void ConfigCodec();
+
+ // Sending codec specific data to OMX component. OMX component could send a
+ // OMX_EventPortSettingsChanged back to client. And then client needs to
+ // disable port and reallocate buffer.
+ void FillCodecConfigDataToOmx();
+
+ void SendEosBuffer();
+
+ void EndOfStream();
+
+ // It could be called after codec specific data is sent and component found
+ // the port format is changed due to different codec specific.
+ void PortSettingsChanged();
+
+ void Output(BufferData* aData);
+
+ // Buffer can be released if its status is not OMX_COMPONENT or
+ // OMX_CLIENT_OUTPUT.
+ bool BuffersCanBeReleased(OMX_DIRTYPE aType);
+
+ OMX_DIRTYPE GetPortDirection(uint32_t aPortIndex);
+
+ RefPtr<ShutdownPromise> DoAsyncShutdown();
+
+ RefPtr<FlushPromise> DoFlush();
+
+ void FlushComplete(OMX_COMMANDTYPE aCommandType);
+
+ void FlushFailure(OmxCommandFailureHolder aFailureHolder);
+
+ BUFFERLIST* GetBuffers(OMX_DIRTYPE aType);
+
+ nsresult AllocateBuffers(OMX_DIRTYPE aType);
+
+ nsresult ReleaseBuffers(OMX_DIRTYPE aType);
+
+ BufferData* FindAvailableBuffer(OMX_DIRTYPE aType);
+
+ // aType could be OMX_DirMax for all types.
+ RefPtr<OmxPromiseLayer::OmxBufferPromise::AllPromiseType>
+ CollectBufferPromises(OMX_DIRTYPE aType);
+
+ // The Omx TaskQueue.
+ RefPtr<TaskQueue> mOmxTaskQueue;
+
+ nsCOMPtr<nsISerialEventTarget> mThread;
+ RefPtr<layers::ImageContainer> mImageContainer;
+
+ WatchManager<OmxDataDecoder> mWatchManager;
+
+ // It is accessed in omx TaskQueue.
+ Watchable<OMX_STATETYPE> mOmxState;
+
+ RefPtr<OmxPromiseLayer> mOmxLayer;
+
+ UniquePtr<TrackInfo> mTrackInfo;
+
+ // It is accessed in both omx and reader TaskQueue.
+ Atomic<bool> mFlushing;
+
+ // It is accessed in Omx/reader TaskQueue.
+ Atomic<bool> mShuttingDown;
+
+ // It is accessed in Omx TaskQeueu.
+ bool mCheckingInputExhausted;
+
+ // It is accessed in OMX TaskQueue.
+ MozPromiseHolder<InitPromise> mInitPromise;
+ MozPromiseHolder<DecodePromise> mDecodePromise;
+ MozPromiseHolder<DecodePromise> mDrainPromise;
+ MozPromiseHolder<FlushPromise> mFlushPromise;
+ MozPromiseHolder<ShutdownPromise> mShutdownPromise;
+ // Where decoded samples will be stored until the decode promise is resolved.
+ DecodedData mDecodedData;
+
+ void CompleteDrain();
+
+ // It is written in Omx TaskQueue. Read in Omx TaskQueue.
+ // It value means the port index which port settings is changed.
+ // -1 means no port setting changed.
+ //
+ // Note: when port setting changed, there should be no buffer operations
+ // via EmptyBuffer or FillBuffer.
+ Watchable<int32_t> mPortSettingsChanged;
+
+ // It is access in Omx TaskQueue.
+ nsTArray<RefPtr<MediaRawData>> mMediaRawDatas;
+
+ BUFFERLIST mInPortBuffers;
+
+ BUFFERLIST mOutPortBuffers;
+
+ RefPtr<MediaDataHelper> mMediaDataHelper;
+
+ const Maybe<TrackingId> mTrackingId;
+
+ // Accessed on Omx TaskQueue
+ PerformanceRecorderMulti<DecodeStage> mPerformanceRecorder;
+};
+
+template <class T>
+void InitOmxParameter(T* aParam) {
+ PodZero(aParam);
+ aParam->nSize = sizeof(T);
+ aParam->nVersion.s.nVersionMajor = 1;
+}
+
+} // namespace mozilla
+
+#endif /* OmxDataDecoder_h_ */