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 "mozilla/Atomics.h" 11 #include "mozilla/Maybe.h" 12 #include "mozilla/Monitor.h" 13 #include "AutoTaskQueue.h" 14 15 #include "MediaDataDemuxer.h" 16 #include "MediaResource.h" 17 #include "MediaSource.h" 18 #include "TrackBuffersManager.h" 19 20 namespace mozilla { 21 22 class AbstractThread; 23 class MediaResult; 24 class MediaSourceTrackDemuxer; 25 26 DDLoggedTypeDeclNameAndBase(MediaSourceDemuxer, MediaDataDemuxer); 27 DDLoggedTypeNameAndBase(MediaSourceTrackDemuxer, MediaTrackDemuxer); 28 29 class MediaSourceDemuxer : public MediaDataDemuxer, 30 public DecoderDoctorLifeLogger<MediaSourceDemuxer> { 31 public: 32 explicit MediaSourceDemuxer(AbstractThread* aAbstractMainThread); 33 34 RefPtr<InitPromise> Init() override; 35 36 uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override; 37 38 already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer( 39 TrackInfo::TrackType aType, uint32_t aTrackNumber) override; 40 41 bool IsSeekable() const override; 42 43 UniquePtr<EncryptionInfo> GetCrypto() override; 44 ShouldComputeStartTime()45 bool ShouldComputeStartTime() const override { return false; } 46 47 /* interface for TrackBuffersManager */ 48 void AttachSourceBuffer(RefPtr<TrackBuffersManager>& aSourceBuffer); 49 void DetachSourceBuffer(RefPtr<TrackBuffersManager>& aSourceBuffer); GetTaskQueue()50 AutoTaskQueue* GetTaskQueue() { return mTaskQueue; } 51 void NotifyInitDataArrived(); 52 53 // Returns a string describing the state of the MediaSource internal 54 // buffered data. Used for debugging purposes. 55 void GetMozDebugReaderData(nsACString& aString); 56 57 void AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes); 58 59 // Gap allowed between frames. 60 // Due to inaccuracies in determining buffer end 61 // frames (Bug 1065207). This value is based on videos seen in the wild. 62 static constexpr media::TimeUnit EOS_FUZZ = 63 media::TimeUnit::FromMicroseconds(500000); 64 65 private: 66 ~MediaSourceDemuxer(); 67 friend class MediaSourceTrackDemuxer; 68 // Scan source buffers and update information. 69 bool ScanSourceBuffersForContent(); 70 RefPtr<TrackBuffersManager> GetManager(TrackInfo::TrackType aType); 71 TrackInfo* GetTrackInfo(TrackInfo::TrackType); 72 void DoAttachSourceBuffer(RefPtr<TrackBuffersManager>&& aSourceBuffer); 73 void DoDetachSourceBuffer(RefPtr<TrackBuffersManager>&& aSourceBuffer); OnTaskQueue()74 bool OnTaskQueue() { 75 return !GetTaskQueue() || GetTaskQueue()->IsCurrentThreadIn(); 76 } 77 78 RefPtr<AutoTaskQueue> mTaskQueue; 79 nsTArray<RefPtr<MediaSourceTrackDemuxer>> mDemuxers; 80 81 nsTArray<RefPtr<TrackBuffersManager>> mSourceBuffers; 82 83 MozPromiseHolder<InitPromise> mInitPromise; 84 85 // Monitor to protect members below across multiple threads. 86 mutable Monitor mMonitor; 87 RefPtr<TrackBuffersManager> mAudioTrack; 88 RefPtr<TrackBuffersManager> mVideoTrack; 89 MediaInfo mInfo; 90 }; 91 92 class MediaSourceTrackDemuxer 93 : public MediaTrackDemuxer, 94 public DecoderDoctorLifeLogger<MediaSourceTrackDemuxer> { 95 public: 96 MediaSourceTrackDemuxer(MediaSourceDemuxer* aParent, 97 TrackInfo::TrackType aType, 98 TrackBuffersManager* aManager); 99 100 UniquePtr<TrackInfo> GetInfo() const override; 101 102 RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) override; 103 104 RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) override; 105 106 void Reset() override; 107 108 nsresult GetNextRandomAccessPoint(media::TimeUnit* aTime) override; 109 110 RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint( 111 const media::TimeUnit& aTimeThreshold) override; 112 113 media::TimeIntervals GetBuffered() override; 114 115 void BreakCycles() override; 116 GetSamplesMayBlock()117 bool GetSamplesMayBlock() const override { return false; } 118 119 bool HasManager(TrackBuffersManager* aManager) const; 120 void DetachManager(); 121 122 private: OnTaskQueue()123 bool OnTaskQueue() const { 124 MOZ_ASSERT(mParent); 125 auto taskQueue = mParent->GetTaskQueue(); 126 MOZ_ASSERT(taskQueue); 127 return taskQueue->IsCurrentThreadIn(); 128 } 129 130 RefPtr<SeekPromise> DoSeek(const media::TimeUnit& aTime); 131 RefPtr<SamplesPromise> DoGetSamples(int32_t aNumSamples); 132 RefPtr<SkipAccessPointPromise> DoSkipToNextRandomAccessPoint( 133 const media::TimeUnit& aTimeThreadshold); 134 already_AddRefed<MediaRawData> GetSample(MediaResult& aError); 135 // Return the timestamp of the next keyframe after mLastSampleIndex. 136 media::TimeUnit GetNextRandomAccessPoint(); 137 138 RefPtr<MediaSourceDemuxer> mParent; 139 TrackInfo::TrackType mType; 140 // Monitor protecting members below accessed from multiple threads. 141 Monitor mMonitor; 142 media::TimeUnit mNextRandomAccessPoint; 143 // Would be accessed in MFR's demuxer proxy task queue and TaskQueue, and 144 // only be set on the TaskQueue. It can be accessed while on TaskQueue without 145 // the need for the lock. 146 RefPtr<TrackBuffersManager> mManager; 147 148 Maybe<RefPtr<MediaRawData>> mNextSample; 149 // Set to true following a reset. Ensure that the next sample demuxed 150 // is available at position 0. 151 bool mReset; 152 153 // Amount of pre-roll time when seeking. 154 // Set to 80ms if track is Opus. 155 const media::TimeUnit mPreRoll; 156 }; 157 158 } // namespace mozilla 159 160 #endif 161