2763189dbe14f384f6fa2705194e430e70c2eaa3
[WebKit-https.git] / Source / WebCore / platform / mediastream / mac / DisplayCaptureSourceCocoa.cpp
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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "DisplayCaptureSourceCocoa.h"
28
29 #if ENABLE(MEDIA_STREAM)
30
31 #include "Logging.h"
32 #include "RealtimeMediaSource.h"
33 #include "RealtimeMediaSourceCenter.h"
34 #include "RealtimeMediaSourceSettings.h"
35 #include "Timer.h"
36 #include <CoreMedia/CMSync.h>
37 #include <mach/mach_time.h>
38 #include <pal/avfoundation/MediaTimeAVFoundation.h>
39 #include <pal/cf/CoreMediaSoftLink.h>
40 #include <pal/spi/cf/CoreAudioSPI.h>
41 #include <sys/time.h>
42 #include <wtf/CurrentTime.h>
43 #include <wtf/MainThread.h>
44 #include <wtf/NeverDestroyed.h>
45
46 namespace WebCore {
47 using namespace PAL;
48
49 DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa(const String& name)
50     : RealtimeMediaSource("", Type::Video, name)
51     , m_timer(RunLoop::current(), this, &DisplayCaptureSourceCocoa::emitFrame)
52 {
53 }
54
55 DisplayCaptureSourceCocoa::~DisplayCaptureSourceCocoa()
56 {
57 #if PLATFORM(IOS)
58     RealtimeMediaSourceCenter::singleton().videoFactory().unsetActiveSource(*this);
59 #endif
60 }
61
62 const RealtimeMediaSourceCapabilities& DisplayCaptureSourceCocoa::capabilities() const
63 {
64     if (!m_capabilities) {
65         RealtimeMediaSourceCapabilities capabilities(settings().supportedConstraints());
66
67         // FIXME: what should these be?
68         capabilities.setWidth(CapabilityValueOrRange(72, 2880));
69         capabilities.setHeight(CapabilityValueOrRange(45, 1800));
70         capabilities.setFrameRate(CapabilityValueOrRange(.01, 60.0));
71
72         m_capabilities = WTFMove(capabilities);
73     }
74     return m_capabilities.value();
75 }
76
77 const RealtimeMediaSourceSettings& DisplayCaptureSourceCocoa::settings() const
78 {
79     if (!m_currentSettings) {
80         RealtimeMediaSourceSettings settings;
81         settings.setFrameRate(frameRate());
82         auto size = this->size();
83         if (size.width() && size.height()) {
84             settings.setWidth(size.width());
85             settings.setHeight(size.height());
86         }
87
88         RealtimeMediaSourceSupportedConstraints supportedConstraints;
89         supportedConstraints.setSupportsFrameRate(true);
90         supportedConstraints.setSupportsWidth(true);
91         supportedConstraints.setSupportsHeight(true);
92         supportedConstraints.setSupportsAspectRatio(true);
93         settings.setSupportedConstraints(supportedConstraints);
94
95         m_currentSettings = WTFMove(settings);
96     }
97     return m_currentSettings.value();
98 }
99
100 void DisplayCaptureSourceCocoa::settingsDidChange()
101 {
102     m_currentSettings = std::nullopt;
103     RealtimeMediaSource::settingsDidChange();
104 }
105
106 void DisplayCaptureSourceCocoa::startProducingData()
107 {
108 #if PLATFORM(IOS)
109     RealtimeMediaSourceCenter::singleton().videoFactory().setActiveSource(*this);
110 #endif
111
112     m_startTime = MonotonicTime::now();
113     m_timer.startRepeating(1_ms * lround(1000 / frameRate()));
114 }
115
116 void DisplayCaptureSourceCocoa::stopProducingData()
117 {
118     m_timer.stop();
119     m_elapsedTime += MonotonicTime::now() - m_startTime;
120     m_startTime = MonotonicTime::nan();
121 }
122
123 Seconds DisplayCaptureSourceCocoa::elapsedTime()
124 {
125     if (std::isnan(m_startTime))
126         return m_elapsedTime;
127
128     return m_elapsedTime + (MonotonicTime::now() - m_startTime);
129 }
130
131 bool DisplayCaptureSourceCocoa::applyFrameRate(double rate)
132 {
133     if (m_timer.isActive())
134         m_timer.startRepeating(1_ms * lround(1000 / rate));
135
136     return true;
137 }
138
139 void DisplayCaptureSourceCocoa::emitFrame()
140 {
141     if (muted())
142         return;
143
144     generateFrame();
145 }
146
147 } // namespace WebCore
148
149 #endif // ENABLE(MEDIA_STREAM)