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 INDEX_H_ 6 #define INDEX_H_ 7 8 #include "ByteStream.h" 9 #include "MediaData.h" 10 #include "MediaResource.h" 11 #include "MoofParser.h" 12 #include "mozilla/ResultVariant.h" 13 #include "MP4Interval.h" 14 #include "nsISupportsImpl.h" 15 #include "TimeUnits.h" 16 17 namespace mozilla { 18 class IndiceWrapper; 19 struct Sample; 20 struct CencSampleEncryptionInfoEntry; 21 22 class Index; 23 24 typedef int64_t Microseconds; 25 26 class SampleIterator { 27 public: 28 explicit SampleIterator(Index* aIndex); 29 ~SampleIterator(); 30 already_AddRefed<mozilla::MediaRawData> GetNext(); 31 void Seek(Microseconds aTime); 32 Microseconds GetNextKeyframeTime(); 33 34 private: 35 Sample* Get(); 36 37 // Gets the sample description entry for the current moof, or nullptr if 38 // called without a valid current moof. 39 SampleDescriptionEntry* GetSampleDescriptionEntry(); 40 CencSampleEncryptionInfoEntry* GetSampleEncryptionEntry(); 41 42 // Determines the encryption scheme in use for the current sample. If the 43 // the scheme cannot be unambiguously determined, will return an error with 44 // the reason. 45 // 46 // Returns: Ok(CryptoScheme) if a crypto scheme, including None, can be 47 // determined, or Err(nsCString) if there is an issue determining the scheme. 48 Result<CryptoScheme, nsCString> GetEncryptionScheme(); 49 50 void Next(); 51 RefPtr<Index> mIndex; 52 friend class Index; 53 size_t mCurrentMoof; 54 size_t mCurrentSample; 55 }; 56 57 class Index { 58 public: 59 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Index) 60 61 struct Indice { 62 uint64_t start_offset; 63 uint64_t end_offset; 64 uint64_t start_composition; 65 uint64_t end_composition; 66 uint64_t start_decode; 67 bool sync; 68 }; 69 70 struct MP4DataOffset { MP4DataOffsetMP4DataOffset71 MP4DataOffset(uint32_t aIndex, int64_t aStartOffset) 72 : mIndex(aIndex), mStartOffset(aStartOffset), mEndOffset(0) {} 73 74 bool operator==(int64_t aStartOffset) const { 75 return mStartOffset == aStartOffset; 76 } 77 78 bool operator!=(int64_t aStartOffset) const { 79 return mStartOffset != aStartOffset; 80 } 81 82 bool operator<(int64_t aStartOffset) const { 83 return mStartOffset < aStartOffset; 84 } 85 86 struct EndOffsetComparator { EqualsMP4DataOffset::EndOffsetComparator87 bool Equals(const MP4DataOffset& a, const int64_t& b) const { 88 return a.mEndOffset == b; 89 } 90 LessThanMP4DataOffset::EndOffsetComparator91 bool LessThan(const MP4DataOffset& a, const int64_t& b) const { 92 return a.mEndOffset < b; 93 } 94 }; 95 96 uint32_t mIndex; 97 int64_t mStartOffset; 98 int64_t mEndOffset; 99 MP4Interval<Microseconds> mTime; 100 }; 101 102 Index(const mozilla::IndiceWrapper& aIndices, ByteStream* aSource, 103 uint32_t aTrackId, bool aIsAudio); 104 105 void UpdateMoofIndex(const mozilla::MediaByteRangeSet& aByteRanges, 106 bool aCanEvict); 107 void UpdateMoofIndex(const mozilla::MediaByteRangeSet& aByteRanges); 108 Microseconds GetEndCompositionIfBuffered( 109 const mozilla::MediaByteRangeSet& aByteRanges); 110 mozilla::media::TimeIntervals ConvertByteRangesToTimeRanges( 111 const mozilla::MediaByteRangeSet& aByteRanges); 112 uint64_t GetEvictionOffset(Microseconds aTime); IsFragmented()113 bool IsFragmented() { return !!mMoofParser; } 114 115 friend class SampleIterator; 116 117 private: 118 ~Index(); 119 void RegisterIterator(SampleIterator* aIterator); 120 void UnregisterIterator(SampleIterator* aIterator); 121 122 ByteStream* mSource; 123 FallibleTArray<Sample> mIndex; 124 FallibleTArray<MP4DataOffset> mDataOffset; 125 UniquePtr<MoofParser> mMoofParser; 126 nsTArray<SampleIterator*> mIterators; 127 128 // ConvertByteRangesToTimeRanges cache 129 mozilla::MediaByteRangeSet mLastCachedRanges; 130 mozilla::media::TimeIntervals mLastBufferedRanges; 131 bool mIsAudio; 132 }; 133 } // namespace mozilla 134 135 #endif 136