Support arbitrary video resolution in getUserMedia API
[WebKit-https.git] / Source / WebCore / Modules / mediastream / CanvasCaptureMediaStreamTrack.h
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #pragma once
26
27 #if ENABLE(MEDIA_STREAM)
28
29 #include "CanvasBase.h"
30 #include "MediaStreamTrack.h"
31 #include "Timer.h"
32 #include <wtf/TypeCasts.h>
33
34 namespace WebCore {
35
36 class HTMLCanvasElement;
37 class Image;
38 class ScriptExecutionContext;
39
40 class CanvasCaptureMediaStreamTrack final : public MediaStreamTrack {
41 public:
42     static Ref<CanvasCaptureMediaStreamTrack> create(ScriptExecutionContext&, Ref<HTMLCanvasElement>&&, std::optional<double>&& frameRequestRate);
43
44     HTMLCanvasElement& canvas() { return m_canvas.get(); }
45     void requestFrame() { m_source->requestFrame(); }
46
47     RefPtr<MediaStreamTrack> clone() final;
48
49 private:
50     class Source final : public RealtimeMediaSource, private CanvasObserver {
51     public:
52         static Ref<Source> create(HTMLCanvasElement&, std::optional<double>&& frameRequestRate);
53         
54         void requestFrame() { m_shouldEmitFrame = true; }
55         std::optional<double> frameRequestRate() const { return m_frameRequestRate; }
56
57     private:
58         Source(HTMLCanvasElement&, std::optional<double>&&);
59
60         // CanvasObserver API
61         void canvasChanged(CanvasBase&, const FloatRect&) final;
62         void canvasResized(CanvasBase&) final;
63         void canvasDestroyed(CanvasBase&) final;
64
65         // RealtimeMediaSource API
66         void startProducingData() final;
67         void stopProducingData()  final;
68         const RealtimeMediaSourceCapabilities& capabilities() final { return RealtimeMediaSourceCapabilities::emptyCapabilities(); }
69         const RealtimeMediaSourceSettings& settings() final { return m_settings; }
70
71         void captureCanvas();
72         void requestFrameTimerFired();
73
74         bool m_shouldEmitFrame { true };
75         std::optional<double> m_frameRequestRate;
76         Timer m_requestFrameTimer;
77         Timer m_canvasChangedTimer;
78         RealtimeMediaSourceSettings m_settings;
79         HTMLCanvasElement* m_canvas;
80         RefPtr<Image> m_currentImage;
81     };
82
83     CanvasCaptureMediaStreamTrack(ScriptExecutionContext&, Ref<HTMLCanvasElement>&&, Ref<Source>&&);
84
85     bool isCanvas() const final { return true; }
86
87     Ref<HTMLCanvasElement> m_canvas;
88     Ref<Source> m_source;
89 };
90
91 }
92
93 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::CanvasCaptureMediaStreamTrack)
94 static bool isType(const WebCore::MediaStreamTrack& track) { return track.isCanvas(); }
95 SPECIALIZE_TYPE_TRAITS_END()
96
97 #endif // ENABLE(MEDIA_STREAM)