michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et cindent: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef MediaRecorder_h michael@0: #define MediaRecorder_h michael@0: michael@0: #include "mozilla/dom/MediaRecorderBinding.h" michael@0: #include "mozilla/DOMEventTargetHelper.h" michael@0: michael@0: // Max size for allowing queue encoded data in memory michael@0: #define MAX_ALLOW_MEMORY_BUFFER 1024000 michael@0: namespace mozilla { michael@0: michael@0: class ErrorResult; michael@0: class DOMMediaStream; michael@0: class EncodedBufferCache; michael@0: class MediaEncoder; michael@0: class ProcessedMediaStream; michael@0: class MediaInputPort; michael@0: struct MediaRecorderOptions; michael@0: michael@0: namespace dom { michael@0: michael@0: /** michael@0: * Implementation of https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-capture/MediaRecorder.html michael@0: * The MediaRecorder accepts a mediaStream as input source passed from UA. When recorder starts, michael@0: * a MediaEncoder will be created and accept the mediaStream as input source. michael@0: * Encoder will get the raw data by track data changes, encode it by selected MIME Type, then store the encoded in EncodedBufferCache object. michael@0: * The encoded data will be extracted on every timeslice passed from Start function call or by RequestData function. michael@0: * Thread model: michael@0: * When the recorder starts, it creates a "Media Encoder" thread to read data from MediaEncoder object and store buffer in EncodedBufferCache object. michael@0: * Also extract the encoded data and create blobs on every timeslice passed from start function or RequestData function called by UA. michael@0: */ michael@0: michael@0: class MediaRecorder : public DOMEventTargetHelper michael@0: { michael@0: class Session; michael@0: friend class CreateAndDispatchBlobEventRunnable; michael@0: michael@0: public: michael@0: MediaRecorder(DOMMediaStream&, nsPIDOMWindow* aOwnerWindow); michael@0: virtual ~MediaRecorder(); michael@0: michael@0: // nsWrapperCache michael@0: virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; michael@0: michael@0: nsPIDOMWindow* GetParentObject() { return GetOwner(); } michael@0: michael@0: NS_DECL_ISUPPORTS_INHERITED michael@0: NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaRecorder, michael@0: DOMEventTargetHelper) michael@0: michael@0: // WebIDL michael@0: // Start recording. If timeSlice has been provided, mediaRecorder will michael@0: // raise a dataavailable event containing the Blob of collected data on every timeSlice milliseconds. michael@0: // If timeSlice isn't provided, UA should call the RequestData to obtain the Blob data, also set the mTimeSlice to zero. michael@0: void Start(const Optional& timeSlice, ErrorResult & aResult); michael@0: // Stop the recording activiy. Including stop the Media Encoder thread, un-hook the mediaStreamListener to encoder. michael@0: void Stop(ErrorResult& aResult); michael@0: // Pause the mTrackUnionStream michael@0: void Pause(ErrorResult& aResult); michael@0: michael@0: void Resume(ErrorResult& aResult); michael@0: // Extract encoded data Blob from EncodedBufferCache. michael@0: void RequestData(ErrorResult& aResult); michael@0: // Return the The DOMMediaStream passed from UA. michael@0: DOMMediaStream* Stream() const { return mStream; } michael@0: // The current state of the MediaRecorder object. michael@0: RecordingState State() const { return mState; } michael@0: // Return the current encoding MIME type selected by the MediaEncoder. michael@0: void GetMimeType(nsString &aMimeType); michael@0: michael@0: static already_AddRefed michael@0: Constructor(const GlobalObject& aGlobal, michael@0: DOMMediaStream& aStream, michael@0: const MediaRecorderOptions& aInitDict, michael@0: ErrorResult& aRv); michael@0: michael@0: // EventHandler michael@0: IMPL_EVENT_HANDLER(dataavailable) michael@0: IMPL_EVENT_HANDLER(error) michael@0: IMPL_EVENT_HANDLER(stop) michael@0: IMPL_EVENT_HANDLER(warning) michael@0: michael@0: protected: michael@0: MediaRecorder& operator = (const MediaRecorder& x) MOZ_DELETE; michael@0: // Create dataavailable event with Blob data and it runs in main thread michael@0: nsresult CreateAndDispatchBlobEvent(already_AddRefed&& aBlob); michael@0: // Creating a simple event to notify UA simple event. michael@0: void DispatchSimpleEvent(const nsAString & aStr); michael@0: // Creating a error event with message. michael@0: void NotifyError(nsresult aRv); michael@0: // Check if the recorder's principal is the subsume of mediaStream michael@0: bool CheckPrincipal(); michael@0: // Set encoded MIME type. michael@0: void SetMimeType(const nsString &aMimeType); michael@0: michael@0: MediaRecorder(const MediaRecorder& x) MOZ_DELETE; // prevent bad usage michael@0: // Remove session pointer. michael@0: void RemoveSession(Session* aSession); michael@0: // MediaStream passed from js context michael@0: nsRefPtr mStream; michael@0: // The current state of the MediaRecorder object. michael@0: RecordingState mState; michael@0: // Hold the sessions pointer in media recorder and clean in the destructor of recorder. michael@0: nsTArray mSessions; michael@0: // Thread safe for mMimeType. michael@0: Mutex mMutex; michael@0: // It specifies the container format as well as the audio and video capture formats. michael@0: nsString mMimeType; michael@0: }; michael@0: michael@0: } michael@0: } michael@0: michael@0: #endif