1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef mozilla_dom_CanvasCaptureMediaStream_h_ 7 #define mozilla_dom_CanvasCaptureMediaStream_h_ 8 9 #include "DOMMediaStream.h" 10 #include "mozilla/dom/HTMLCanvasElement.h" 11 #include "PrincipalHandle.h" 12 13 class nsIPrincipal; 14 15 namespace mozilla { 16 class DOMMediaStream; 17 class SourceMediaTrack; 18 19 namespace layers { 20 class Image; 21 } // namespace layers 22 23 namespace dom { 24 class CanvasCaptureMediaStream; 25 class HTMLCanvasElement; 26 class OutputStreamFrameListener; 27 28 /* 29 * The CanvasCaptureMediaStream is a MediaStream subclass that provides a video 30 * track containing frames from a canvas. See an architectural overview below. 31 * 32 * ---------------------------------------------------------------------------- 33 * === Main Thread === __________________________ 34 * | | 35 * | CanvasCaptureMediaStream | 36 * |__________________________| 37 * | 38 * | RequestFrame() 39 * v 40 * ________________________ 41 * ________ FrameCaptureRequested? | | 42 * | | ------------------------> | OutputStreamDriver | 43 * | Canvas | SetFrameCapture() | (FrameCaptureListener) | 44 * |________| ------------------------> |________________________| 45 * | 46 * | SetImage() - 47 * | AppendToTrack() 48 * | 49 * v 50 * __________________________ 51 * | | 52 * | MTG / SourceMediaTrack | 53 * |__________________________| 54 * ---------------------------------------------------------------------------- 55 */ 56 57 /* 58 * Base class for drivers of the output stream. 59 * It is up to each sub class to implement the NewFrame() callback of 60 * FrameCaptureListener. 61 */ 62 class OutputStreamDriver : public FrameCaptureListener { 63 public: 64 OutputStreamDriver(SourceMediaTrack* aSourceStream, 65 const PrincipalHandle& aPrincipalHandle); 66 67 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OutputStreamDriver); 68 69 /* 70 * Sub classes can SetImage() to update the image being appended to the 71 * output stream. It will be appended on the next NotifyPull from MTG. 72 */ 73 void SetImage(RefPtr<layers::Image>&& aImage, const TimeStamp& aTime); 74 75 /* 76 * Ends the track in mSourceStream when we know there won't be any more images 77 * requested for it. 78 */ 79 void EndTrack(); 80 81 /* 82 * Makes sure any internal resources this driver is holding that may create 83 * reference cycles are released. 84 */ Forget()85 virtual void Forget() {} 86 87 const RefPtr<SourceMediaTrack> mSourceStream; 88 const PrincipalHandle mPrincipalHandle; 89 90 protected: 91 virtual ~OutputStreamDriver(); 92 }; 93 94 class CanvasCaptureMediaStream : public DOMMediaStream { 95 public: 96 CanvasCaptureMediaStream(nsPIDOMWindowInner* aWindow, 97 HTMLCanvasElement* aCanvas); 98 99 NS_DECL_ISUPPORTS_INHERITED 100 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CanvasCaptureMediaStream, 101 DOMMediaStream) 102 103 nsresult Init(const dom::Optional<double>& aFPS, nsIPrincipal* aPrincipal); 104 105 JSObject* WrapObject(JSContext* aCx, 106 JS::Handle<JSObject*> aGivenProto) override; 107 108 // WebIDL Canvas()109 HTMLCanvasElement* Canvas() const { return mCanvas; } 110 void RequestFrame(); 111 112 dom::FrameCaptureListener* FrameCaptureListener(); 113 114 /** 115 * Stops capturing for this stream at mCanvas. 116 */ 117 void StopCapture(); 118 119 SourceMediaTrack* GetSourceStream() const; 120 121 protected: 122 ~CanvasCaptureMediaStream(); 123 124 private: 125 RefPtr<HTMLCanvasElement> mCanvas; 126 RefPtr<OutputStreamDriver> mOutputStreamDriver; 127 }; 128 129 } // namespace dom 130 } // namespace mozilla 131 132 #endif /* mozilla_dom_CanvasCaptureMediaStream_h_ */ 133