MediaSourceDemuxer.h (6416B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #if !defined(MediaSourceDemuxer_h_) 8 # define MediaSourceDemuxer_h_ 9 10 # include "MediaDataDemuxer.h" 11 # include "MediaResource.h" 12 # include "MediaSource.h" 13 # include "TrackBuffersManager.h" 14 # include "mozilla/EventTargetAndLockCapability.h" 15 # include "mozilla/Maybe.h" 16 # include "mozilla/TaskQueue.h" 17 # include "mozilla/dom/MediaDebugInfoBinding.h" 18 19 namespace mozilla { 20 21 class AbstractThread; 22 class MediaResult; 23 class MediaSourceTrackDemuxer; 24 25 DDLoggedTypeDeclNameAndBase(MediaSourceDemuxer, MediaDataDemuxer); 26 DDLoggedTypeNameAndBase(MediaSourceTrackDemuxer, MediaTrackDemuxer); 27 28 class MediaSourceDemuxer : public MediaDataDemuxer, 29 public DecoderDoctorLifeLogger<MediaSourceDemuxer> { 30 public: 31 explicit MediaSourceDemuxer(AbstractThread* aAbstractMainThread); 32 33 RefPtr<InitPromise> Init() override; 34 35 uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override; 36 37 already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer( 38 TrackInfo::TrackType aType, uint32_t aTrackNumber) override; 39 40 bool IsSeekable() const override; 41 42 UniquePtr<EncryptionInfo> GetCrypto() override; 43 44 bool ShouldComputeStartTime() const override { return false; } 45 46 /* interface for TrackBuffersManager */ 47 void AttachSourceBuffer(const RefPtr<TrackBuffersManager>& aSourceBuffer); 48 void DetachSourceBuffer(const RefPtr<TrackBuffersManager>& aSourceBuffer); 49 TaskQueue* GetTaskQueue() { return mTaskQueue; } 50 void NotifyInitDataArrived(); 51 52 // Populates aInfo with info describing the state of the MediaSource internal 53 // buffered data. Used for debugging purposes. 54 // aInfo should *not* be accessed until the returned promise has been resolved 55 // or rejected. 56 RefPtr<GenericPromise> GetDebugInfo( 57 dom::MediaSourceDemuxerDebugInfo& aInfo) const; 58 59 void AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes); 60 61 // Gap allowed between frames. 62 // Due to inaccuracies in determining buffer end 63 // frames (Bug 1065207). This value is based on videos seen in the wild. 64 static constexpr media::TimeUnit EOS_FUZZ = 65 media::TimeUnit::FromMicroseconds(500000); 66 67 // Largest gap allowed between muxed streams with different 68 // start times. The specs suggest up to a "reasonably short" gap of 69 // one second, which we use here. 70 // See: https://www.w3.org/TR/media-source-2/#presentation-start-time 71 static constexpr media::TimeUnit EOS_FUZZ_START = 72 media::TimeUnit::FromMicroseconds(1000000); 73 74 private: 75 ~MediaSourceDemuxer(); 76 friend class MediaSourceTrackDemuxer; 77 // Scan source buffers and update information. 78 bool ScanSourceBuffersForContent(); 79 RefPtr<TrackBuffersManager> GetManager(TrackInfo::TrackType aType) 80 MOZ_REQUIRES(mMutex); 81 TrackInfo* GetTrackInfo(TrackInfo::TrackType) MOZ_REQUIRES(mMutex); 82 void DoAttachSourceBuffer(RefPtr<TrackBuffersManager>&& aSourceBuffer); 83 void DoDetachSourceBuffer(const RefPtr<TrackBuffersManager>& aSourceBuffer); 84 bool OnTaskQueue() { 85 return !GetTaskQueue() || GetTaskQueue()->IsCurrentThreadIn(); 86 } 87 88 RefPtr<TaskQueue> mTaskQueue; 89 // Accessed on mTaskQueue or from destructor 90 nsTArray<RefPtr<TrackBuffersManager>> mSourceBuffers; 91 MozPromiseHolder<InitPromise> mInitPromise; 92 93 // Mutex to protect members below across multiple threads. 94 mutable Mutex mMutex; 95 nsTArray<RefPtr<MediaSourceTrackDemuxer>> mDemuxers MOZ_GUARDED_BY(mMutex); 96 RefPtr<TrackBuffersManager> mAudioTrack MOZ_GUARDED_BY(mMutex); 97 RefPtr<TrackBuffersManager> mVideoTrack MOZ_GUARDED_BY(mMutex); 98 MediaInfo mInfo MOZ_GUARDED_BY(mMutex); 99 }; 100 101 class MediaSourceTrackDemuxer 102 : public MediaTrackDemuxer, 103 public DecoderDoctorLifeLogger<MediaSourceTrackDemuxer> { 104 public: 105 MediaSourceTrackDemuxer(MediaSourceDemuxer* aParent, 106 TrackInfo::TrackType aType, 107 TrackBuffersManager* aManager) 108 MOZ_REQUIRES(aParent->mMutex); 109 110 UniquePtr<TrackInfo> GetInfo() const override; 111 112 RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) override; 113 114 RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) override; 115 116 void Reset() override; 117 118 nsresult GetNextRandomAccessPoint(media::TimeUnit* aTime) override; 119 120 RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint( 121 const media::TimeUnit& aTimeThreshold) override; 122 123 media::TimeIntervals GetBuffered() override; 124 125 void BreakCycles() override; 126 127 bool GetSamplesMayBlock() const override { return false; } 128 129 bool HasManager(TrackBuffersManager* aManager) const; 130 void DetachManager(); 131 132 private: 133 mozilla::Mutex& Mutex() MOZ_RETURN_CAPABILITY(mLock.Lock()) { 134 return mLock.Lock(); 135 } 136 const EventTargetCapability<mozilla::TaskQueue>& TaskQueue() const 137 MOZ_RETURN_CAPABILITY(mLock.Target()) { 138 return mLock.Target(); 139 } 140 141 RefPtr<SeekPromise> DoSeek(const media::TimeUnit& aTime); 142 RefPtr<SamplesPromise> DoGetSamples(int32_t aNumSamples); 143 RefPtr<SkipAccessPointPromise> DoSkipToNextRandomAccessPoint( 144 const media::TimeUnit& aTimeThreadshold); 145 already_AddRefed<MediaRawData> GetSample(MediaResult& aError); 146 // Return the timestamp of the next keyframe after mLastSampleIndex. 147 media::TimeUnit GetNextRandomAccessPoint(); 148 149 RefPtr<MediaSourceDemuxer> mParent; 150 151 TrackInfo::TrackType mType; 152 // Mutex protecting members below accessed from multiple threads. 153 EventTargetAndLockCapability<mozilla::TaskQueue, mozilla::Mutex> mLock; 154 media::TimeUnit mNextRandomAccessPoint MOZ_GUARDED_BY(mLock); 155 // Would be accessed in MFR's demuxer proxy task queue and TaskQueue, and 156 // only be set on the TaskQueue. It can be accessed while on TaskQueue without 157 // the need for the lock. 158 RefPtr<TrackBuffersManager> mManager MOZ_GUARDED_BY(mLock); 159 160 // Only accessed on TaskQueue 161 Maybe<RefPtr<MediaRawData>> mNextSample; 162 // Set to true following a reset. Ensure that the next sample demuxed 163 // is available at position 0. 164 // Only accessed on TaskQueue 165 bool mReset; 166 167 // Amount of pre-roll time when seeking. 168 // Set to 80ms if track is Opus. 169 const media::TimeUnit mPreRoll; 170 }; 171 172 } // namespace mozilla 173 174 #endif