/src/mozilla-central/dom/media/MediaRecorder.h
Line | Count | Source (jump to first uncovered line) |
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 | | #ifndef MediaRecorder_h |
8 | | #define MediaRecorder_h |
9 | | |
10 | | #include "mozilla/dom/MediaRecorderBinding.h" |
11 | | #include "mozilla/DOMEventTargetHelper.h" |
12 | | #include "mozilla/MozPromise.h" |
13 | | #include "nsIDocumentActivity.h" |
14 | | |
15 | | // Max size for allowing queue encoded data in memory |
16 | 0 | #define MAX_ALLOW_MEMORY_BUFFER 1024000 |
17 | | namespace mozilla { |
18 | | |
19 | | class AudioNodeStream; |
20 | | class DOMMediaStream; |
21 | | class ErrorResult; |
22 | | struct MediaRecorderOptions; |
23 | | class MediaStream; |
24 | | class GlobalObject; |
25 | | |
26 | | namespace dom { |
27 | | |
28 | | class AudioNode; |
29 | | class Blob; |
30 | | class DOMException; |
31 | | |
32 | | /** |
33 | | * Implementation of https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-capture/MediaRecorder.html |
34 | | * The MediaRecorder accepts a mediaStream as input source passed from UA. When recorder starts, |
35 | | * a MediaEncoder will be created and accept the mediaStream as input source. |
36 | | * Encoder will get the raw data by track data changes, encode it by selected MIME Type, then store the encoded in a MutableBlobStorage object. |
37 | | * The encoded data will be extracted on every timeslice passed from Start function call or by RequestData function. |
38 | | * Thread model: |
39 | | * When the recorder starts, it creates a "Media Encoder" thread to read data from MediaEncoder object and store buffer in MutableBlobStorage object. |
40 | | * Also extract the encoded data and create blobs on every timeslice passed from start function or RequestData function called by UA. |
41 | | */ |
42 | | |
43 | | class MediaRecorder final : public DOMEventTargetHelper, |
44 | | public nsIDocumentActivity |
45 | | { |
46 | | public: |
47 | | class Session; |
48 | | |
49 | | MediaRecorder(DOMMediaStream& aSourceMediaStream, |
50 | | nsPIDOMWindowInner* aOwnerWindow); |
51 | | MediaRecorder(AudioNode& aSrcAudioNode, uint32_t aSrcOutput, |
52 | | nsPIDOMWindowInner* aOwnerWindow); |
53 | | |
54 | | static nsTArray<RefPtr<Session>> GetSessions(); |
55 | | |
56 | | // nsWrapperCache |
57 | | JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; |
58 | | |
59 | | nsPIDOMWindowInner* GetParentObject() { return GetOwner(); } |
60 | | |
61 | | NS_DECL_ISUPPORTS_INHERITED |
62 | | NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaRecorder, |
63 | | DOMEventTargetHelper) |
64 | | |
65 | | // WebIDL |
66 | | // Start recording. If timeSlice has been provided, mediaRecorder will |
67 | | // raise a dataavailable event containing the Blob of collected data on every timeSlice milliseconds. |
68 | | // If timeSlice isn't provided, UA should call the RequestData to obtain the Blob data, also set the mTimeSlice to zero. |
69 | | void Start(const Optional<int32_t>& timeSlice, ErrorResult & aResult); |
70 | | // Stop the recording activiy. Including stop the Media Encoder thread, un-hook the mediaStreamListener to encoder. |
71 | | void Stop(ErrorResult& aResult); |
72 | | // Pause a recording. |
73 | | void Pause(ErrorResult& aResult); |
74 | | // Resume a paused recording. |
75 | | void Resume(ErrorResult& aResult); |
76 | | // Extract encoded data Blob from MutableBlobStorage. |
77 | | void RequestData(ErrorResult& aResult); |
78 | | // Return the The DOMMediaStream passed from UA. |
79 | | DOMMediaStream* Stream() const { return mDOMStream; } |
80 | | // The current state of the MediaRecorder object. |
81 | | RecordingState State() const { return mState; } |
82 | | // Return the current encoding MIME type selected by the MediaEncoder. |
83 | | void GetMimeType(nsString &aMimeType); |
84 | | |
85 | | static bool IsTypeSupported(GlobalObject& aGlobal, const nsAString& aType); |
86 | | static bool IsTypeSupported(const nsAString& aType); |
87 | | |
88 | | // Construct a recorder with a DOM media stream object as its source. |
89 | | static already_AddRefed<MediaRecorder> |
90 | | Constructor(const GlobalObject& aGlobal, |
91 | | DOMMediaStream& aStream, |
92 | | const MediaRecorderOptions& aInitDict, |
93 | | ErrorResult& aRv); |
94 | | // Construct a recorder with a Web Audio destination node as its source. |
95 | | static already_AddRefed<MediaRecorder> |
96 | | Constructor(const GlobalObject& aGlobal, |
97 | | AudioNode& aSrcAudioNode, |
98 | | uint32_t aSrcOutput, |
99 | | const MediaRecorderOptions& aInitDict, |
100 | | ErrorResult& aRv); |
101 | | |
102 | | /* |
103 | | * Measure the size of the buffer, and heap memory in bytes occupied by |
104 | | * mAudioEncoder and mVideoEncoder. |
105 | | */ |
106 | | typedef MozPromise<size_t, size_t, true> SizeOfPromise; |
107 | | RefPtr<SizeOfPromise> SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf); |
108 | | // EventHandler |
109 | | IMPL_EVENT_HANDLER(dataavailable) |
110 | | IMPL_EVENT_HANDLER(error) |
111 | | IMPL_EVENT_HANDLER(start) |
112 | | IMPL_EVENT_HANDLER(stop) |
113 | | IMPL_EVENT_HANDLER(warning) |
114 | | |
115 | | NS_DECL_NSIDOCUMENTACTIVITY |
116 | | |
117 | 0 | uint32_t GetAudioBitrate() { return mAudioBitsPerSecond; } |
118 | 0 | uint32_t GetVideoBitrate() { return mVideoBitsPerSecond; } |
119 | 0 | uint32_t GetBitrate() { return mBitsPerSecond; } |
120 | | protected: |
121 | | virtual ~MediaRecorder(); |
122 | | |
123 | | MediaRecorder& operator = (const MediaRecorder& x) = delete; |
124 | | // Create dataavailable event with Blob data and it runs in main thread |
125 | | nsresult CreateAndDispatchBlobEvent(Blob* aBlob); |
126 | | // Creating a simple event to notify UA simple event. |
127 | | void DispatchSimpleEvent(const nsAString & aStr); |
128 | | // Creating a error event with message. |
129 | | void NotifyError(nsresult aRv); |
130 | | // Set encoded MIME type. |
131 | | void SetMimeType(const nsString &aMimeType); |
132 | | void SetOptions(const MediaRecorderOptions& aInitDict); |
133 | | |
134 | | MediaRecorder(const MediaRecorder& x) = delete; // prevent bad usage |
135 | | // Remove session pointer. |
136 | | void RemoveSession(Session* aSession); |
137 | | // Create DOMExceptions capturing the JS stack for async errors. These are |
138 | | // created ahead of time rather than on demand when firing an error as the JS |
139 | | // stack of the operation that started the async behavior will not be |
140 | | // available at the time the error event is fired. Note, depending on when |
141 | | // this is called there may not be a JS stack to capture. |
142 | | void InitializeDomExceptions(); |
143 | | // Set the recorder state to inactive. This is needed to handle error states |
144 | | // in the recorder where state must transition to inactive before full |
145 | | // stoppage can be reached. |
146 | | void ForceInactive(); |
147 | | // Stop the recorder and its internal session. This should be used by |
148 | | // sessions that are in the process of being destroyed. |
149 | | void StopForSessionDestruction(); |
150 | | // DOM wrapper for source media stream. Will be null when input is audio node. |
151 | | RefPtr<DOMMediaStream> mDOMStream; |
152 | | // Source audio node. Will be null when input is a media stream. |
153 | | RefPtr<AudioNode> mAudioNode; |
154 | | // Source audio node's output index. Will be zero when input is a media stream. |
155 | | const uint32_t mAudioNodeOutput; |
156 | | |
157 | | // The current state of the MediaRecorder object. |
158 | | RecordingState mState; |
159 | | // Hold the sessions reference and clean it when the DestroyRunnable for a |
160 | | // session is running. |
161 | | nsTArray<RefPtr<Session> > mSessions; |
162 | | |
163 | | nsCOMPtr<nsIDocument> mDocument; |
164 | | |
165 | | // It specifies the container format as well as the audio and video capture formats. |
166 | | nsString mMimeType; |
167 | | |
168 | | uint32_t mAudioBitsPerSecond; |
169 | | uint32_t mVideoBitsPerSecond; |
170 | | uint32_t mBitsPerSecond; |
171 | | |
172 | | TimeStamp mStartTime; |
173 | | |
174 | | // DOMExceptions that are created early and possibly thrown in NotifyError. |
175 | | // Creating them early allows us to capture the JS stack for which cannot be |
176 | | // done at the time the error event is fired. |
177 | | RefPtr<DOMException> mSecurityDomException; |
178 | | RefPtr<DOMException> mUnknownDomException; |
179 | | |
180 | | private: |
181 | | // Register MediaRecorder into Document to listen the activity changes. |
182 | | void RegisterActivityObserver(); |
183 | | void UnRegisterActivityObserver(); |
184 | | |
185 | | bool CheckPermission(const nsString &aType); |
186 | | }; |
187 | | |
188 | | } // namespace dom |
189 | | } // namespace mozilla |
190 | | |
191 | | #endif |