From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- dom/media/MediaFormatReader.h | 885 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 885 insertions(+) create mode 100644 dom/media/MediaFormatReader.h (limited to 'dom/media/MediaFormatReader.h') diff --git a/dom/media/MediaFormatReader.h b/dom/media/MediaFormatReader.h new file mode 100644 index 0000000000..ebbca0e179 --- /dev/null +++ b/dom/media/MediaFormatReader.h @@ -0,0 +1,885 @@ +/* -*- 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(MediaFormatReader_h_) +# define MediaFormatReader_h_ + +# include "FrameStatistics.h" +# include "MediaDataDemuxer.h" +# include "MediaEventSource.h" +# include "MediaMetadataManager.h" +# include "MediaPromiseDefs.h" +# include "PlatformDecoderModule.h" +# include "SeekTarget.h" +# include "mozilla/Atomics.h" +# include "mozilla/Maybe.h" +# include "mozilla/MozPromise.h" +# include "mozilla/Mutex.h" +# include "mozilla/StateMirroring.h" +# include "mozilla/StaticPrefs_media.h" +# include "mozilla/TaskQueue.h" +# include "mozilla/ThreadSafeWeakPtr.h" +# include "mozilla/dom/MediaDebugInfoBinding.h" + +namespace mozilla { + +class CDMProxy; +class GMPCrashHelper; +class MediaResource; +class VideoFrameContainer; + +struct WaitForDataRejectValue { + enum Reason { SHUTDOWN, CANCELED }; + + WaitForDataRejectValue(MediaData::Type aType, Reason aReason) + : mType(aType), mReason(aReason) {} + MediaData::Type mType; + Reason mReason; +}; + +struct SeekRejectValue { + MOZ_IMPLICIT SeekRejectValue(const MediaResult& aError) + : mType(MediaData::Type::NULL_DATA), mError(aError) {} + MOZ_IMPLICIT SeekRejectValue(nsresult aResult) + : mType(MediaData::Type::NULL_DATA), mError(aResult) {} + SeekRejectValue(MediaData::Type aType, const MediaResult& aError) + : mType(aType), mError(aError) {} + MediaData::Type mType; + MediaResult mError; +}; + +struct MetadataHolder { + UniquePtr mInfo; + UniquePtr mTags; +}; + +typedef void* MediaDecoderOwnerID; + +struct MOZ_STACK_CLASS MediaFormatReaderInit { + MediaResource* mResource = nullptr; + VideoFrameContainer* mVideoFrameContainer = nullptr; + FrameStatistics* mFrameStats = nullptr; + already_AddRefed mKnowsCompositor; + already_AddRefed mCrashHelper; + // Used in bug 1393399 for temporary telemetry. + MediaDecoderOwnerID mMediaDecoderOwnerID = nullptr; + Maybe mTrackingId; +}; + +DDLoggedTypeDeclName(MediaFormatReader); + +class MediaFormatReader final + : public SupportsThreadSafeWeakPtr, + public DecoderDoctorLifeLogger { + static const bool IsExclusive = true; + typedef TrackInfo::TrackType TrackType; + typedef MozPromise NotifyDataArrivedPromise; + + public: + MOZ_DECLARE_REFCOUNTED_TYPENAME(MediaFormatReader) + + using TrackSet = EnumSet; + using MetadataPromise = MozPromise; + + template + using DataPromise = MozPromise, MediaResult, IsExclusive>; + using AudioDataPromise = DataPromise; + using VideoDataPromise = DataPromise; + + using SeekPromise = MozPromise; + + // Note that, conceptually, WaitForData makes sense in a non-exclusive sense. + // But in the current architecture it's only ever used exclusively (by MDSM), + // so we mark it that way to verify our assumptions. If you have a use-case + // for multiple WaitForData consumers, feel free to flip the exclusivity here. + using WaitForDataPromise = + MozPromise; + + MediaFormatReader(MediaFormatReaderInit& aInit, MediaDataDemuxer* aDemuxer); + virtual ~MediaFormatReader(); + + // Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE + // on failure. + nsresult Init(); + + size_t SizeOfVideoQueueInFrames(); + size_t SizeOfAudioQueueInFrames(); + + // Requests one video sample from the reader. + RefPtr RequestVideoData( + const media::TimeUnit& aTimeThreshold, + bool aRequestNextVideoKeyFrame = false); + + // Requests one audio sample from the reader. + // + // The decode should be performed asynchronously, and the promise should + // be resolved when it is complete. + RefPtr RequestAudioData(); + + // The default implementation of AsyncReadMetadata is implemented in terms of + // synchronous ReadMetadata() calls. Implementations may also + // override AsyncReadMetadata to create a more proper async implementation. + RefPtr AsyncReadMetadata(); + + // Fills aInfo with the latest cached data required to present the media, + // ReadUpdatedMetadata will always be called once ReadMetadata has succeeded. + void ReadUpdatedMetadata(MediaInfo* aInfo); + + RefPtr Seek(const SeekTarget& aTarget); + + // Called once new data has been cached by the MediaResource. + // mBuffered should be recalculated and updated accordingly. + void NotifyDataArrived(); + + // Update ID for the external playback engine. Currently it's only used on + // Windows when the media engine playback is enabled. + void UpdateMediaEngineId(uint64_t aMediaEngineId); + + protected: + // Recomputes mBuffered. + void UpdateBuffered(); + + public: + // Called by MDSM in dormant state to release resources allocated by this + // reader. The reader can resume decoding by calling Seek() to a specific + // position. + void ReleaseResources(); + + bool OnTaskQueue() const { return OwnerThread()->IsCurrentThreadIn(); } + + // Resets all state related to decoding, emptying all buffers etc. + // Cancels all pending Request*Data() request callbacks, rejects any + // outstanding seek promises, and flushes the decode pipeline. The + // decoder must not call any of the callbacks for outstanding + // Request*Data() calls after this is called. Calls to Request*Data() + // made after this should be processed as usual. + // + // Normally this call preceedes a Seek() call, or shutdown. + // + // aParam is a set of TrackInfo::TrackType enums specifying which + // queues need to be reset, defaulting to both audio and video tracks. + nsresult ResetDecode(TrackSet aTracks); + + // Destroys the decoding state. The reader cannot be made usable again. + // This is different from ReleaseMediaResources() as it is irreversable, + // whereas ReleaseMediaResources() is. Must be called on the decode + // thread. + RefPtr Shutdown(); + + // Returns true if this decoder reader uses hardware accelerated video + // decoding. + bool VideoIsHardwareAccelerated() const; + + // By default, the state machine polls the reader once per second when it's + // in buffering mode. Some readers support a promise-based mechanism by which + // they notify the state machine when the data arrives. + bool IsWaitForDataSupported() const { return true; } + + RefPtr WaitForData(MediaData::Type aType); + + // The MediaDecoderStateMachine uses various heuristics that assume that + // raw media data is arriving sequentially from a network channel. This + // makes sense in the