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