SampleIterator.h (4295B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef DOM_MEDIA_MP4_SAMPLE_ITERATOR_H_ 6 #define DOM_MEDIA_MP4_SAMPLE_ITERATOR_H_ 7 8 #include "ByteStream.h" 9 #include "MP4Interval.h" 10 #include "MediaData.h" 11 #include "MediaResource.h" 12 #include "MoofParser.h" 13 #include "TimeUnits.h" 14 #include "mozilla/ResultVariant.h" 15 #include "nsISupportsImpl.h" 16 17 namespace mozilla { 18 19 struct CencSampleEncryptionInfoEntry; 20 class IndiceWrapper; 21 class MP4SampleIndex; 22 struct Sample; 23 24 class SampleIterator { 25 public: 26 explicit SampleIterator(MP4SampleIndex* aIndex); 27 ~SampleIterator(); 28 bool HasNext(); 29 already_AddRefed<mozilla::MediaRawData> GetNextHeader(); 30 Result<already_AddRefed<mozilla::MediaRawData>, MediaResult> GetNext(); 31 32 // The default seek mode finds the closest sync sample at or before the target 33 // time. Setting the mode to `First` allows seeking to the earliest sync 34 // sample instead, which is only used in a specific case. 35 enum class SyncSampleMode { Closest, First }; 36 void Seek(const media::TimeUnit& aTime, 37 SyncSampleMode aMode = SyncSampleMode::Closest); 38 39 media::TimeUnit GetNextKeyframeTime(); 40 41 private: 42 Result<Sample*, nsresult> Get(); 43 44 // Gets the sample description entry for the current moof, or nullptr if 45 // called without a valid current moof. 46 SampleDescriptionEntry* GetSampleDescriptionEntry(); 47 const CencSampleEncryptionInfoEntry* GetSampleEncryptionEntry() const; 48 49 // Determines the encryption scheme in use for the current sample. If the 50 // the scheme cannot be unambiguously determined, will return an error with 51 // the reason. 52 // 53 // Returns: Ok(CryptoScheme) if a crypto scheme, including None, can be 54 // determined, or Err(nsCString) if there is an issue determining the scheme. 55 Result<CryptoScheme, nsCString> GetEncryptionScheme(); 56 57 void Next(); 58 RefPtr<MP4SampleIndex> mIndex; 59 friend class MP4SampleIndex; 60 size_t mCurrentMoof; 61 size_t mCurrentSample; 62 }; 63 64 class MP4SampleIndex { 65 public: 66 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MP4SampleIndex) 67 68 struct Indice { 69 uint64_t start_offset; 70 uint64_t end_offset; 71 int64_t start_composition; 72 int64_t end_composition; 73 int64_t start_decode; 74 bool sync; 75 }; 76 77 struct MP4DataOffset { 78 MP4DataOffset(uint32_t aIndex, int64_t aStartOffset) 79 : mIndex(aIndex), mStartOffset(aStartOffset), mEndOffset(0) {} 80 81 bool operator==(int64_t aStartOffset) const { 82 return mStartOffset == aStartOffset; 83 } 84 85 bool operator!=(int64_t aStartOffset) const { 86 return mStartOffset != aStartOffset; 87 } 88 89 bool operator<(int64_t aStartOffset) const { 90 return mStartOffset < aStartOffset; 91 } 92 93 struct EndOffsetComparator { 94 bool Equals(const MP4DataOffset& a, const int64_t& b) const { 95 return a.mEndOffset == b; 96 } 97 98 bool LessThan(const MP4DataOffset& a, const int64_t& b) const { 99 return a.mEndOffset < b; 100 } 101 }; 102 103 uint32_t mIndex; 104 int64_t mStartOffset; 105 int64_t mEndOffset; 106 MP4Interval<media::TimeUnit> mTime; 107 }; 108 109 MP4SampleIndex(const mozilla::IndiceWrapper& aIndices, ByteStream* aSource, 110 uint32_t aTrackId, bool aIsAudio, uint32_t aTimeScale); 111 112 void UpdateMoofIndex(const mozilla::MediaByteRangeSet& aByteRanges, 113 bool aCanEvict); 114 void UpdateMoofIndex(const mozilla::MediaByteRangeSet& aByteRanges); 115 mozilla::media::TimeIntervals ConvertByteRangesToTimeRanges( 116 const mozilla::MediaByteRangeSet& aByteRanges); 117 uint64_t GetEvictionOffset(const media::TimeUnit& aTime); 118 bool IsFragmented() { return !!mMoofParser; } 119 120 friend class SampleIterator; 121 122 private: 123 ~MP4SampleIndex(); 124 void RegisterIterator(SampleIterator* aIterator); 125 void UnregisterIterator(SampleIterator* aIterator); 126 127 ByteStream* mSource; 128 FallibleTArray<Sample> mIndex; 129 FallibleTArray<MP4DataOffset> mDataOffset; 130 UniquePtr<MoofParser> mMoofParser; 131 nsTArray<SampleIterator*> mIterators; 132 133 // ConvertByteRangesToTimeRanges cache 134 mozilla::MediaByteRangeSet mLastCachedRanges; 135 mozilla::media::TimeIntervals mLastBufferedRanges; 136 bool mIsAudio; 137 }; 138 } // namespace mozilla 139 140 #endif