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 CAPTURETASK_H
8 #define CAPTURETASK_H
9 
10 #include "MediaTrackGraph.h"
11 #include "MediaTrackListener.h"
12 #include "PrincipalChangeObserver.h"
13 
14 namespace mozilla {
15 
16 namespace dom {
17 class BlobImpl;
18 class ImageCapture;
19 class MediaStreamTrack;
20 }  // namespace dom
21 
22 /**
23  * CaptureTask retrieves image from MediaTrack and encodes the image to jpeg in
24  * ImageEncoder. The whole procedures start at AttachTrack(), it will add this
25  * class into MediaTrack and retrieves an image in MediaTrackGraph thread.
26  * Once the image is retrieved, it will be sent to ImageEncoder and the encoded
27  * blob will be sent out via encoder callback in main thread.
28  *
29  * CaptureTask holds a reference of ImageCapture to ensure ImageCapture won't be
30  * released during the period of the capturing process described above.
31  */
32 class CaptureTask : public DirectMediaTrackListener,
33                     public dom::PrincipalChangeObserver<dom::MediaStreamTrack> {
34  public:
35   class MediaTrackEventListener;
36 
37   // DirectMediaTrackListener methods
38   void NotifyRealtimeTrackData(MediaTrackGraph* aGraph, TrackTime aTrackOffset,
39                                const MediaSegment& aMedia) override;
40 
41   // PrincipalChangeObserver<MediaStreamTrack> methods
42   void PrincipalChanged(dom::MediaStreamTrack* aMediaStreamTrack) override;
43 
44   // CaptureTask methods.
45 
46   // It is called when aBlob is ready to post back to script in company with
47   // aRv == NS_OK. If aRv is not NS_OK, it will post an error event to script.
48   //
49   // Note:
50   //   this function should be called on main thread.
51   nsresult TaskComplete(already_AddRefed<dom::BlobImpl> aBlobImpl,
52                         nsresult aRv);
53 
54   // Add listeners into MediaStreamTrack and PrincipalChangeObserver.
55   // It should be on main thread only.
56   void AttachTrack();
57 
58   // Remove listeners from MediaStreamTrack and PrincipalChangeObserver.
59   // It should be on main thread only.
60   void DetachTrack();
61 
62   // CaptureTask should be created on main thread.
63   explicit CaptureTask(dom::ImageCapture* aImageCapture);
64 
65  protected:
66   virtual ~CaptureTask() = default;
67 
68   // Post a runnable on main thread to end this task and call TaskComplete to
69   // post error event to script. It is called off-main-thread.
70   void PostTrackEndEvent();
71 
72   // The ImageCapture associates with this task. This reference count should not
73   // change in this class unless it clears this reference after a blob or error
74   // event to script.
75   RefPtr<dom::ImageCapture> mImageCapture;
76 
77   RefPtr<MediaTrackEventListener> mEventListener;
78 
79   // True when an image is retrieved from the video track, or MediaTrackGraph
80   // sends a track finish, end, or removed event. Any thread.
81   Atomic<bool> mImageGrabbedOrTrackEnd;
82 
83   // True after MediaStreamTrack principal changes while waiting for a photo
84   // to finish and we should raise a security error.
85   bool mPrincipalChanged;
86 };
87 
88 }  // namespace mozilla
89 
90 #endif  // CAPTURETASK_H
91