tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MediaRecorder.h (6984B)


      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/DOMEventTargetHelper.h"
     11 #include "mozilla/MozPromise.h"
     12 #include "mozilla/dom/MediaRecorderBinding.h"
     13 #include "nsIDocumentActivity.h"
     14 
     15 // Max size for allowing queue encoded data in memory
     16 #define MAX_ALLOW_MEMORY_BUFFER 1024000
     17 namespace mozilla {
     18 
     19 class AudioNodeTrack;
     20 class DOMMediaStream;
     21 class ErrorResult;
     22 struct MediaRecorderOptions;
     23 class GlobalObject;
     24 
     25 namespace dom {
     26 
     27 class AudioNode;
     28 class BlobImpl;
     29 class Document;
     30 class DOMException;
     31 
     32 /**
     33 * Implementation of
     34 * https://w3c.github.io/mediacapture-record/MediaRecorder.html
     35 *
     36 * The MediaRecorder accepts a MediaStream as input passed from an application.
     37 * When the MediaRecorder starts, a MediaEncoder will be created and accepts the
     38 * MediaStreamTracks in the MediaStream as input source. For each track it
     39 * creates a TrackEncoder.
     40 *
     41 * The MediaEncoder automatically encodes and muxes data from the tracks by the
     42 * given MIME type, then it stores this data into a MutableBlobStorage object.
     43 * When a timeslice is set and the MediaEncoder has stored enough data to fill
     44 * the timeslice, it extracts a Blob from the storage and passes it to
     45 * MediaRecorder. On RequestData() or Stop(), the MediaEncoder extracts the blob
     46 * from the storage and returns it to MediaRecorder through a MozPromise.
     47 *
     48 * Thread model: When the recorder starts, it creates a worker thread (called
     49 * the encoder thread) that does all the heavy lifting - encoding, time keeping,
     50 * muxing.
     51 */
     52 
     53 class MediaRecorder final : public DOMEventTargetHelper,
     54                            public nsIDocumentActivity {
     55 public:
     56  class Session;
     57 
     58  explicit MediaRecorder(nsPIDOMWindowInner* aOwnerWindow);
     59 
     60  static nsTArray<RefPtr<Session>> GetSessions();
     61 
     62  // nsWrapperCache
     63  JSObject* WrapObject(JSContext* aCx,
     64                       JS::Handle<JSObject*> aGivenProto) override;
     65 
     66  NS_DECL_ISUPPORTS_INHERITED
     67  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaRecorder, DOMEventTargetHelper)
     68 
     69  // WebIDL
     70  // Start recording.
     71  void Start(const Optional<uint32_t>& timeSlice, ErrorResult& aResult);
     72  // Stop recording.
     73  void Stop(ErrorResult& aResult);
     74  // Pause a recording.
     75  void Pause(ErrorResult& aResult);
     76  // Resume a paused recording.
     77  void Resume(ErrorResult& aResult);
     78  // Extracts buffered data and fires the dataavailable event.
     79  void RequestData(ErrorResult& aResult);
     80  // Return the The DOMMediaStream passed from UA.
     81  DOMMediaStream* Stream() const { return mStream; }
     82  // Return the current encoding MIME type selected by the MediaEncoder.
     83  void GetMimeType(nsString& aMimeType);
     84  // The current state of the MediaRecorder object.
     85  RecordingState State() const { return mState; }
     86 
     87  static bool IsTypeSupported(GlobalObject& aGlobal,
     88                              const nsAString& aMIMEType);
     89  static bool IsTypeSupported(const nsAString& aMIMEType);
     90 
     91  // Construct a recorder with a DOM media stream object as its source.
     92  static already_AddRefed<MediaRecorder> Constructor(
     93      const GlobalObject& aGlobal, DOMMediaStream& aStream,
     94      const MediaRecorderOptions& aOptions, ErrorResult& aRv);
     95  // Construct a recorder with a Web Audio destination node as its source.
     96  static already_AddRefed<MediaRecorder> Constructor(
     97      const GlobalObject& aGlobal, AudioNode& aAudioNode,
     98      uint32_t aAudioNodeOutput, const MediaRecorderOptions& aOptions,
     99      ErrorResult& aRv);
    100 
    101  /*
    102   * Measure the size of the buffer, and heap memory in bytes occupied by
    103   * mAudioEncoder and mVideoEncoder.
    104   */
    105  typedef MozPromise<size_t, size_t, true> SizeOfPromise;
    106  RefPtr<SizeOfPromise> SizeOfExcludingThis(
    107      mozilla::MallocSizeOf aMallocSizeOf);
    108  // EventHandler
    109  IMPL_EVENT_HANDLER(start)
    110  IMPL_EVENT_HANDLER(stop)
    111  IMPL_EVENT_HANDLER(dataavailable)
    112  IMPL_EVENT_HANDLER(pause)
    113  IMPL_EVENT_HANDLER(resume)
    114  IMPL_EVENT_HANDLER(error)
    115 
    116  NS_DECL_NSIDOCUMENTACTIVITY
    117 
    118  uint32_t AudioBitsPerSecond() const { return mAudioBitsPerSecond; }
    119  uint32_t VideoBitsPerSecond() const { return mVideoBitsPerSecond; }
    120 
    121 protected:
    122  virtual ~MediaRecorder();
    123 
    124  MediaRecorder& operator=(const MediaRecorder& x) = delete;
    125  // Create dataavailable event with Blob data and it runs in main thread
    126  nsresult CreateAndDispatchBlobEvent(BlobImpl* aBlobImpl);
    127  // Creating a simple event to notify UA simple event.
    128  void DispatchSimpleEvent(const nsAString& aStr);
    129  // Creating a error event with message.
    130  void NotifyError(nsresult aRv);
    131 
    132  MediaRecorder(const MediaRecorder& x) = delete;  // prevent bad usage
    133  // Remove session pointer.
    134  void RemoveSession(Session* aSession);
    135  // Create DOMExceptions capturing the JS stack for async errors. These are
    136  // created ahead of time rather than on demand when firing an error as the JS
    137  // stack of the operation that started the async behavior will not be
    138  // available at the time the error event is fired. Note, depending on when
    139  // this is called there may not be a JS stack to capture.
    140  void InitializeDomExceptions();
    141  // Runs the "Inactivate the recorder" algorithm.
    142  void Inactivate();
    143  // Stop the recorder and its internal session. This should be used by
    144  // sessions that are in the process of being destroyed.
    145  void StopForSessionDestruction();
    146  // DOM wrapper for source media stream. Will be null when input is audio node.
    147  RefPtr<DOMMediaStream> mStream;
    148  // Source audio node. Will be null when input is a media stream.
    149  RefPtr<AudioNode> mAudioNode;
    150  // Source audio node's output index. Will be zero when input is a media
    151  // stream.
    152  uint32_t mAudioNodeOutput = 0;
    153 
    154  // The current state of the MediaRecorder object.
    155  RecordingState mState = RecordingState::Inactive;
    156  // Hold the sessions reference and clean it when the DestroyRunnable for a
    157  // session is running.
    158  nsTArray<RefPtr<Session>> mSessions;
    159 
    160  RefPtr<Document> mDocument;
    161 
    162  nsString mMimeType;
    163  nsString mConstrainedMimeType;
    164 
    165  uint32_t mAudioBitsPerSecond = 0;
    166  uint32_t mVideoBitsPerSecond = 0;
    167  Maybe<uint32_t> mConstrainedBitsPerSecond;
    168 
    169  // DOMExceptions that are created early and possibly thrown in NotifyError.
    170  // Creating them early allows us to capture the JS stack for which cannot be
    171  // done at the time the error event is fired.
    172  RefPtr<DOMException> mOtherDomException;
    173  RefPtr<DOMException> mSecurityDomException;
    174  RefPtr<DOMException> mUnknownDomException;
    175 
    176 private:
    177  // Register MediaRecorder into Document to listen the activity changes.
    178  void RegisterActivityObserver();
    179  void UnRegisterActivityObserver();
    180 
    181  bool CheckPermission(const nsString& aType);
    182 };
    183 
    184 }  // namespace dom
    185 }  // namespace mozilla
    186 
    187 #endif