Bug 1464268 - Fix MediaRecorder comments. r=bryce

Differential Revision: https://phabricator.services.mozilla.com/D95729
This commit is contained in:
Andreas Pehrson 2021-02-11 13:39:01 +00:00
Родитель d40bae9b5a
Коммит 56768028df
2 изменённых файлов: 35 добавлений и 43 удалений

Просмотреть файл

@ -545,37 +545,27 @@ void SelectBitrates(uint32_t aBitsPerSecond, uint8_t aNumVideoTracks,
* In original design, all recording context is stored in MediaRecorder, which
* causes a problem if someone calls MediaRecorder::Stop and
* MediaRecorder::Start quickly. To prevent blocking main thread, media encoding
* is executed in a second thread, named as Read Thread. For the same reason, we
* do not wait Read Thread shutdown in MediaRecorder::Stop. If someone call
* MediaRecorder::Start before Read Thread shutdown, the same recording context
* in MediaRecorder might be access by two Reading Threads, which cause a
* problem. In the new design, we put recording context into Session object,
* including Read Thread. Each Session has its own recording context and Read
* Thread, problem is been resolved.
*
* Life cycle of a Session object.
* 1) Initialization Stage (in main thread)
* Setup media tracks in MTG, and bind MediaEncoder with Source Stream when
* mStream is available. Resource allocation, such as encoded data cache buffer
* and MediaEncoder. Create read thread. Automatically switch to Extract stage
* in the end of this stage. 2) Extract Stage (in Read Thread) Pull encoded A/V
* frames from MediaEncoder, dispatch to OnDataAvailable handler. Unless a
* client calls Session::Stop, Session object keeps stay in this stage. 3)
* Destroy Stage (in main thread) Switch from Extract stage to Destroy stage by
* calling Session::Stop. Release session resource and remove associated tracks
* from MTG.
* is executed in a second thread, named encoder thread. For the same reason, we
* do not await encoder thread shutdown in MediaRecorder::Stop.
* If someone calls MediaRecorder::Start before encoder thread shutdown, the
* same recording context in MediaRecorder might be accessed by two distinct
* encoder threads, which would be racy. With the recording context, including
* the encoder thread, in a Session object the problem is solved.
*
* Lifetime of MediaRecorder and Session objects.
* 1) MediaRecorder creates a Session in MediaRecorder::Start function and holds
* a reference to Session. Then the Session registers itself to a
* ShutdownBlocker and also holds a reference to MediaRecorder.
* 1) MediaRecorder creates a Session in MediaRecorder::Start() and holds
* a reference to it. Then the Session registers itself to a ShutdownBlocker
* and also holds a reference to MediaRecorder.
* Therefore, the reference dependency in gecko is:
* ShutdownBlocker -> Session <-> MediaRecorder, note that there is a cycle
* reference between Session and MediaRecorder.
* 2) A Session is destroyed after MediaRecorder::Stop has been called _and_ all
* encoded media data has been passed to OnDataAvailable handler. 3)
* MediaRecorder::Stop is called by user or the document is going to inactive or
* invisible.
* 2) A Session is destroyed after Session::DoSessionEndTask() has been called
* _and_ all encoded media data has been passed to OnDataAvailable handler.
* In some cases the encoded media can be discarded before being passed to
* the OnDataAvailable handler.
* 3) Session::DoSessionEndTask is called by an application through
* MediaRecorder::Stop(), from a MediaEncoder Shutdown notification, from the
* document going inactive or invisible, or from the ShutdownBlocker.
*/
class MediaRecorder::Session : public PrincipalChangeObserver<MediaStreamTrack>,
public DOMMediaStream::TrackListener {

Просмотреть файл

@ -31,17 +31,23 @@ class DOMException;
/**
* Implementation of
* https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-capture/MediaRecorder.html
* The MediaRecorder accepts a mediaStream as input source passed from UA. When
* recorder starts, a MediaEncoder will be created and accept the mediaStream as
* input source. Encoder will get the raw data by track data changes, encode it
* by selected MIME Type, then store the encoded in a MutableBlobStorage object.
* The encoded data will be extracted on every timeslice passed from Start
* function call or by RequestData function. Thread model: When the recorder
* starts, it creates a "Media Encoder" thread to read data from MediaEncoder
* object and store buffer in MutableBlobStorage object. Also extract the
* encoded data and create blobs on every timeslice passed from start function
* or RequestData function called by UA.
* https://w3c.github.io/mediacapture-record/MediaRecorder.html
*
* The MediaRecorder accepts a MediaStream as input passed from an application.
* When the MediaRecorder starts, a MediaEncoder will be created and accepts the
* MediaStreamTracks in the MediaStream as input source. For each track it
* creates a TrackEncoder.
*
* The MediaEncoder automatically encodes and muxes data from the tracks by the
* given MIME type, then it stores this data into a MutableBlobStorage object.
* When a timeslice is set and the MediaEncoder has stored enough data to fill
* the timeslice, it extracts a Blob from the storage and passes it to
* MediaRecorder. On RequestData() or Stop(), the MediaEncoder extracts the blob
* from the storage and returns it to MediaRecorder through a MozPromise.
*
* Thread model: When the recorder starts, it creates a worker thread (called
* the encoder thread) that does all the heavy lifting - encoding, time keeping,
* muxing.
*/
class MediaRecorder final : public DOMEventTargetHelper,
@ -61,13 +67,9 @@ class MediaRecorder final : public DOMEventTargetHelper,
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaRecorder, DOMEventTargetHelper)
// WebIDL
// Start recording. If timeSlice has been provided, mediaRecorder will
// raise a dataavailable event containing the Blob of collected data on every
// timeSlice milliseconds. If timeSlice isn't provided, UA should call the
// RequestData to obtain the Blob data, also set the mTimeSlice to zero.
// Start recording.
void Start(const Optional<uint32_t>& timeSlice, ErrorResult& aResult);
// Stop the recording activiy. Including stop the Media Encoder thread,
// un-hook the mediaStreamListener to encoder.
// Stop recording.
void Stop(ErrorResult& aResult);
// Pause a recording.
void Pause(ErrorResult& aResult);