[WTF] Move currentCPUTime and sleep(Seconds) to CPUTime.h and Seconds.h respectively
[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/MainThread.h>
43 #include <wtf/NeverDestroyed.h>
44
45 namespace WebCore {
46 using namespace PAL;
47
48 DisplayCaptureSourceCocoa::DisplayCaptureSourceCocoa(const String& name)
49     : RealtimeMediaSource("", Type::Video, name)
50     , m_timer(RunLoop::current(), this, &DisplayCaptureSourceCocoa::emitFrame)
51 {
52 }
53
54 DisplayCaptureSourceCocoa::~DisplayCaptureSourceCocoa()
55 {
56 #if PLATFORM(IOS)
57     RealtimeMediaSourceCenter::singleton().videoFactory().unsetActiveSource(*this);
58 #endif
59 }
60
61 const RealtimeMediaSourceCapabilities& DisplayCaptureSourceCocoa::capabilities() const
62 {
63     if (!m_capabilities) {
64         RealtimeMediaSourceCapabilities capabilities(settings().supportedConstraints());
65
66         // FIXME: what should these be?
67         capabilities.setWidth(CapabilityValueOrRange(72, 2880));
68         capabilities.setHeight(CapabilityValueOrRange(45, 1800));
69         capabilities.setFrameRate(CapabilityValueOrRange(.01, 60.0));
70
71         m_capabilities = WTFMove(capabilities);
72     }
73     return m_capabilities.value();
74 }
75
76 const RealtimeMediaSourceSettings& DisplayCaptureSourceCocoa::settings() const
77 {
78     if (!m_currentSettings) {
79         RealtimeMediaSourceSettings settings;
80         settings.setFrameRate(frameRate());
81         auto size = this->size();
82         if (size.width() && size.height()) {
83             settings.setWidth(size.width());
84             settings.setHeight(size.height());
85         }
86
87         RealtimeMediaSourceSupportedConstraints supportedConstraints;
88         supportedConstraints.setSupportsFrameRate(true);
89         supportedConstraints.setSupportsWidth(true);
90         supportedConstraints.setSupportsHeight(true);
91         supportedConstraints.setSupportsAspectRatio(true);
92         settings.setSupportedConstraints(supportedConstraints);
93
94         m_currentSettings = WTFMove(settings);
95     }
96     return m_currentSettings.value();
97 }
98
99 void DisplayCaptureSourceCocoa::settingsDidChange()
100 {
101     m_currentSettings = std::nullopt;
102     RealtimeMediaSource::settingsDidChange();
103 }
104
105 void DisplayCaptureSourceCocoa::startProducingData()
106 {
107 #if PLATFORM(IOS)
108     RealtimeMediaSourceCenter::singleton().videoFactory().setActiveSource(*this);
109 #endif
110
111     m_startTime = MonotonicTime::now();
112     m_timer.startRepeating(1_ms * lround(1000 / frameRate()));
113 }
114
115 void DisplayCaptureSourceCocoa::stopProducingData()
116 {
117     m_timer.stop();
118     m_elapsedTime += MonotonicTime::now() - m_startTime;
119     m_startTime = MonotonicTime::nan();
120 }
121
122 Seconds DisplayCaptureSourceCocoa::elapsedTime()
123 {
124     if (std::isnan(m_startTime))
125         return m_elapsedTime;
126
127     return m_elapsedTime + (MonotonicTime::now() - m_startTime);
128 }
129
130 bool DisplayCaptureSourceCocoa::applyFrameRate(double rate)
131 {
132     if (m_timer.isActive())
133         m_timer.startRepeating(1_ms * lround(1000 / rate));
134
135     return true;
136 }
137
138 void DisplayCaptureSourceCocoa::emitFrame()
139 {
140     if (muted())
141         return;
142
143     generateFrame();
144 }
145
146 } // namespace WebCore
147
148 #endif // ENABLE(MEDIA_STREAM)