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
34namespace WebCore {
35
36class Document;
37class HTMLCanvasElement;
38class Image;
39
40class CanvasCaptureMediaStreamTrack final : public MediaStreamTrack {
41 WTF_MAKE_ISO_ALLOCATED(CanvasCaptureMediaStreamTrack);
42public:
43 static Ref<CanvasCaptureMediaStreamTrack> create(Document&, Ref<HTMLCanvasElement>&&, Optional<double>&& frameRequestRate);
44
45 HTMLCanvasElement& canvas() { return m_canvas.get(); }
46 void requestFrame() { static_cast<Source&>(source()).requestFrame(); }
47
48 RefPtr<MediaStreamTrack> clone() final;
49
50private:
51 class Source final : public RealtimeMediaSource, private CanvasObserver {
52 public:
53 static Ref<Source> create(HTMLCanvasElement&, Optional<double>&& frameRequestRate);
54
55 void requestFrame() { m_shouldEmitFrame = true; }
56 Optional<double> frameRequestRate() const { return m_frameRequestRate; }
57
58 private:
59 Source(HTMLCanvasElement&, Optional<double>&&);
60
61 // CanvasObserver API
62 void canvasChanged(CanvasBase&, const FloatRect&) final;
63 void canvasResized(CanvasBase&) final;
64 void canvasDestroyed(CanvasBase&) final;
65
66 // RealtimeMediaSource API
67 void startProducingData() final;
68 void stopProducingData() final;
69 const RealtimeMediaSourceCapabilities& capabilities() final { return RealtimeMediaSourceCapabilities::emptyCapabilities(); }
70 const RealtimeMediaSourceSettings& settings() final;
71 void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
72
73 void captureCanvas();
74 void requestFrameTimerFired();
75
76 bool m_shouldEmitFrame { true };
77 Optional<double> m_frameRequestRate;
78 Timer m_requestFrameTimer;
79 Timer m_canvasChangedTimer;
80 Optional<RealtimeMediaSourceSettings> m_currentSettings;
81 HTMLCanvasElement* m_canvas;
82 RefPtr<Image> m_currentImage;
83 };
84
85 CanvasCaptureMediaStreamTrack(Document&, Ref<HTMLCanvasElement>&&, Ref<Source>&&);
86 CanvasCaptureMediaStreamTrack(Document&, Ref<HTMLCanvasElement>&&, Ref<MediaStreamTrackPrivate>&&);
87
88 bool isCanvas() const final { return true; }
89
90 Ref<HTMLCanvasElement> m_canvas;
91};
92
93}
94
95SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::CanvasCaptureMediaStreamTrack)
96static bool isType(const WebCore::MediaStreamTrack& track) { return track.isCanvas(); }
97SPECIALIZE_TYPE_TRAITS_END()
98
99#endif // ENABLE(MEDIA_STREAM)
100