1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 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 #ifndef mozilla_dom_MediaSource_h_ 8 #define mozilla_dom_MediaSource_h_ 9 10 #include "MediaSourceDecoder.h" 11 #include "js/RootingAPI.h" 12 #include "mozilla/Assertions.h" 13 #include "mozilla/Attributes.h" 14 #include "mozilla/DOMEventTargetHelper.h" 15 #include "mozilla/MozPromise.h" 16 #include "mozilla/dom/MediaSourceBinding.h" 17 #include "nsCOMPtr.h" 18 #include "nsCycleCollectionNoteChild.h" 19 #include "nsCycleCollectionParticipant.h" 20 #include "nsID.h" 21 #include "nsISupports.h" 22 #include "nscore.h" 23 #include "TimeUnits.h" 24 25 struct JSContext; 26 class JSObject; 27 class nsPIDOMWindowInner; 28 29 namespace mozilla { 30 31 class AbstractThread; 32 class ErrorResult; 33 template <typename T> 34 class AsyncEventRunner; 35 class MediaResult; 36 37 namespace dom { 38 class MediaSource; 39 } // namespace dom 40 DDLoggedTypeName(dom::MediaSource); 41 42 namespace dom { 43 44 class GlobalObject; 45 class SourceBuffer; 46 class SourceBufferList; 47 template <typename T> 48 class Optional; 49 50 #define MOZILLA_DOM_MEDIASOURCE_IMPLEMENTATION_IID \ 51 { \ 52 0x3839d699, 0x22c5, 0x439f, { \ 53 0x94, 0xca, 0x0e, 0x0b, 0x26, 0xf9, 0xca, 0xbf \ 54 } \ 55 } 56 57 class MediaSource final : public DOMEventTargetHelper, 58 public DecoderDoctorLifeLogger<MediaSource> { 59 public: 60 /** WebIDL Methods. */ 61 static already_AddRefed<MediaSource> Constructor(const GlobalObject& aGlobal, 62 ErrorResult& aRv); 63 64 SourceBufferList* SourceBuffers(); 65 SourceBufferList* ActiveSourceBuffers(); 66 MediaSourceReadyState ReadyState(); 67 68 double Duration(); 69 void SetDuration(double aDuration, ErrorResult& aRv); 70 71 already_AddRefed<SourceBuffer> AddSourceBuffer(const nsAString& aType, 72 ErrorResult& aRv); 73 void RemoveSourceBuffer(SourceBuffer& aSourceBuffer, ErrorResult& aRv); 74 75 void EndOfStream(const Optional<MediaSourceEndOfStreamError>& aError, 76 ErrorResult& aRv); 77 void EndOfStream(const MediaResult& aError); 78 79 void SetLiveSeekableRange(double aStart, double aEnd, ErrorResult& aRv); 80 void ClearLiveSeekableRange(ErrorResult& aRv); 81 82 static bool IsTypeSupported(const GlobalObject&, const nsAString& aType); 83 // Throws on aRv if not supported. 84 static void IsTypeSupported(const nsAString& aType, 85 DecoderDoctorDiagnostics* aDiagnostics, 86 ErrorResult& aRv); 87 88 IMPL_EVENT_HANDLER(sourceopen); 89 IMPL_EVENT_HANDLER(sourceended); 90 IMPL_EVENT_HANDLER(sourceclose); 91 92 /** End WebIDL Methods. */ 93 94 NS_DECL_ISUPPORTS_INHERITED 95 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaSource, DOMEventTargetHelper) 96 NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_MEDIASOURCE_IMPLEMENTATION_IID) 97 98 nsPIDOMWindowInner* GetParentObject() const; 99 100 JSObject* WrapObject(JSContext* aCx, 101 JS::Handle<JSObject*> aGivenProto) override; 102 103 // Attach this MediaSource to Decoder aDecoder. Returns false if already 104 // attached. 105 bool Attach(MediaSourceDecoder* aDecoder); 106 void Detach(); 107 108 // Set mReadyState to aState and fire the required events at the MediaSource. 109 void SetReadyState(MediaSourceReadyState aState); 110 111 // Used by SourceBuffer to call CreateSubDecoder. GetDecoder()112 MediaSourceDecoder* GetDecoder() { return mDecoder; } 113 GetPrincipal()114 nsIPrincipal* GetPrincipal() { return mPrincipal; } 115 116 // Returns a structure describing the state of the MediaSource internal 117 // buffered data. Used for debugging purposes. 118 already_AddRefed<Promise> MozDebugReaderData(ErrorResult& aRv); 119 HasLiveSeekableRange()120 bool HasLiveSeekableRange() const { return mLiveSeekableRange.isSome(); } LiveSeekableRange()121 media::TimeInterval LiveSeekableRange() const { 122 return mLiveSeekableRange.value(); 123 } 124 AbstractMainThread()125 AbstractThread* AbstractMainThread() const { return mAbstractMainThread; } 126 127 // Resolve all CompletionPromise pending. 128 void CompletePendingTransactions(); 129 130 private: 131 // SourceBuffer uses SetDuration and SourceBufferIsActive 132 friend class mozilla::dom::SourceBuffer; 133 134 ~MediaSource(); 135 136 explicit MediaSource(nsPIDOMWindowInner* aWindow); 137 138 friend class AsyncEventRunner<MediaSource>; 139 void DispatchSimpleEvent(const char* aName); 140 void QueueAsyncSimpleEvent(const char* aName); 141 142 void DurationChange(double aNewDuration, ErrorResult& aRv); 143 144 // SetDuration with no checks. 145 void SetDuration(double aDuration); 146 147 typedef MozPromise<bool, MediaResult, /* IsExclusive = */ true> 148 ActiveCompletionPromise; 149 // Mark SourceBuffer as active and rebuild ActiveSourceBuffers. 150 // Return a MozPromise that will be resolved once all related operations are 151 // completed, or can't progress any further. 152 // Such as, transition of readyState from HAVE_NOTHING to HAVE_METADATA. 153 RefPtr<ActiveCompletionPromise> SourceBufferIsActive( 154 SourceBuffer* aSourceBuffer); 155 156 RefPtr<SourceBufferList> mSourceBuffers; 157 RefPtr<SourceBufferList> mActiveSourceBuffers; 158 159 RefPtr<MediaSourceDecoder> mDecoder; 160 // Ensures the media element remains alive to dispatch progress and 161 // durationchanged events. 162 RefPtr<HTMLMediaElement> mMediaElement; 163 164 RefPtr<nsIPrincipal> mPrincipal; 165 166 const RefPtr<AbstractThread> mAbstractMainThread; 167 168 MediaSourceReadyState mReadyState; 169 170 Maybe<media::TimeInterval> mLiveSeekableRange; 171 nsTArray<MozPromiseHolder<ActiveCompletionPromise>> mCompletionPromises; 172 }; 173 174 NS_DEFINE_STATIC_IID_ACCESSOR(MediaSource, 175 MOZILLA_DOM_MEDIASOURCE_IMPLEMENTATION_IID) 176 177 } // namespace dom 178 179 } // namespace mozilla 180 181 #endif /* mozilla_dom_MediaSource_h_ */ 182