Add media stream release logging
[WebKit-https.git] / Source / WebCore / platform / mediastream / MediaStreamTrackPrivate.cpp
1 /*
2  * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
3  * Copyright (C) 2015 Ericsson AB. All rights reserved.
4  * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29 #include "MediaStreamTrackPrivate.h"
30
31 #if ENABLE(MEDIA_STREAM)
32
33 #include "GraphicsContext.h"
34 #include "IntRect.h"
35 #include <wtf/UUID.h>
36
37 #if PLATFORM(COCOA)
38 #include "WebAudioSourceProviderAVFObjC.h"
39 #elif ENABLE(WEB_AUDIO) && ENABLE(MEDIA_STREAM) && USE(LIBWEBRTC) && USE(GSTREAMER)
40 #include "AudioSourceProviderGStreamer.h"
41 #else
42 #include "WebAudioSourceProvider.h"
43 #endif
44
45 namespace WebCore {
46
47 Ref<MediaStreamTrackPrivate> MediaStreamTrackPrivate::create(Ref<RealtimeMediaSource>&& source)
48 {
49     return create(WTFMove(source), createCanonicalUUIDString());
50 }
51
52 Ref<MediaStreamTrackPrivate> MediaStreamTrackPrivate::create(Ref<RealtimeMediaSource>&& source, String&& id)
53 {
54     return adoptRef(*new MediaStreamTrackPrivate(WTFMove(source), WTFMove(id)));
55 }
56
57 MediaStreamTrackPrivate::MediaStreamTrackPrivate(Ref<RealtimeMediaSource>&& source, String&& id)
58     : m_source(WTFMove(source))
59     , m_id(WTFMove(id))
60 {
61     m_source->addObserver(*this);
62 }
63
64 MediaStreamTrackPrivate::~MediaStreamTrackPrivate()
65 {
66     m_source->removeObserver(*this);
67 }
68
69 void MediaStreamTrackPrivate::forEachObserver(const WTF::Function<void(Observer&)>& apply) const
70 {
71     Vector<Observer*> observersCopy;
72     {
73         auto locker = holdLock(m_observersLock);
74         observersCopy = copyToVector(m_observers);
75     }
76     for (auto* observer : observersCopy) {
77         auto locker = holdLock(m_observersLock);
78         // Make sure the observer has not been destroyed.
79         if (!m_observers.contains(observer))
80             continue;
81         apply(*observer);
82     }
83 }
84
85 void MediaStreamTrackPrivate::addObserver(MediaStreamTrackPrivate::Observer& observer)
86 {
87     auto locker = holdLock(m_observersLock);
88     m_observers.add(&observer);
89 }
90
91 void MediaStreamTrackPrivate::removeObserver(MediaStreamTrackPrivate::Observer& observer)
92 {
93     auto locker = holdLock(m_observersLock);
94     m_observers.remove(&observer);
95 }
96
97 const String& MediaStreamTrackPrivate::label() const
98 {
99     return m_source->name();
100 }
101
102 void MediaStreamTrackPrivate::setContentHint(HintValue hintValue)
103 {
104     m_contentHint = hintValue;
105 }
106     
107 bool MediaStreamTrackPrivate::muted() const
108 {
109     return m_source->muted();
110 }
111
112 bool MediaStreamTrackPrivate::isCaptureTrack() const
113 {
114     return m_source->isCaptureSource();
115 }
116
117 void MediaStreamTrackPrivate::setEnabled(bool enabled)
118 {
119     if (m_isEnabled == enabled)
120         return;
121
122     // Always update the enabled state regardless of the track being ended.
123     m_isEnabled = enabled;
124
125     forEachObserver([this](auto& observer) {
126         observer.trackEnabledChanged(*this);
127     });
128 }
129
130 void MediaStreamTrackPrivate::endTrack()
131 {
132     if (m_isEnded)
133         return;
134
135     // Set m_isEnded to true before telling the source it can stop, so if this is the
136     // only track using the source and it does stop, we will only call each observer's
137     // trackEnded method once.
138     m_isEnded = true;
139     updateReadyState();
140
141     m_source->requestToEnd(*this);
142
143     forEachObserver([this](auto& observer) {
144         observer.trackEnded(*this);
145     });
146 }
147
148 Ref<MediaStreamTrackPrivate> MediaStreamTrackPrivate::clone()
149 {
150     auto clonedMediaStreamTrackPrivate = create(m_source.copyRef());
151     clonedMediaStreamTrackPrivate->m_isEnabled = this->m_isEnabled;
152     clonedMediaStreamTrackPrivate->m_isEnded = this->m_isEnded;
153     clonedMediaStreamTrackPrivate->m_contentHint = this->m_contentHint;
154     clonedMediaStreamTrackPrivate->updateReadyState();
155
156     return clonedMediaStreamTrackPrivate;
157 }
158
159 RealtimeMediaSource::Type MediaStreamTrackPrivate::type() const
160 {
161     return m_source->type();
162 }
163
164 const RealtimeMediaSourceSettings& MediaStreamTrackPrivate::settings() const
165 {
166     return m_source->settings();
167 }
168
169 const RealtimeMediaSourceCapabilities& MediaStreamTrackPrivate::capabilities() const
170 {
171     return m_source->capabilities();
172 }
173
174 void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints& constraints, RealtimeMediaSource::ApplyConstraintsHandler&& completionHandler)
175 {
176     m_source->applyConstraints(constraints, WTFMove(completionHandler));
177 }
178
179 AudioSourceProvider* MediaStreamTrackPrivate::audioSourceProvider()
180 {
181 #if PLATFORM(COCOA)
182     if (!m_audioSourceProvider)
183         m_audioSourceProvider = WebAudioSourceProviderAVFObjC::create(*this);
184 #elif USE(LIBWEBRTC) && USE(GSTREAMER)
185     if (!m_audioSourceProvider)
186         m_audioSourceProvider = AudioSourceProviderGStreamer::create(*this);
187 #endif
188     return m_audioSourceProvider.get();
189 }
190
191 void MediaStreamTrackPrivate::sourceStarted()
192 {
193     forEachObserver([this](auto& observer) {
194         observer.trackStarted(*this);
195     });
196 }
197
198 void MediaStreamTrackPrivate::sourceStopped()
199 {
200     if (m_isEnded)
201         return;
202
203     m_isEnded = true;
204     updateReadyState();
205
206     forEachObserver([this](auto& observer) {
207         observer.trackEnded(*this);
208     });
209 }
210
211 void MediaStreamTrackPrivate::sourceMutedChanged()
212 {
213     forEachObserver([this](auto& observer) {
214         observer.trackMutedChanged(*this);
215     });
216 }
217
218 void MediaStreamTrackPrivate::sourceSettingsChanged()
219 {
220     forEachObserver([this](auto& observer) {
221         observer.trackSettingsChanged(*this);
222     });
223 }
224
225 bool MediaStreamTrackPrivate::preventSourceFromStopping()
226 {
227     // Do not allow the source to stop if we are still using it.
228     return !m_isEnded;
229 }
230
231 void MediaStreamTrackPrivate::videoSampleAvailable(MediaSample& mediaSample)
232 {
233     if (!m_haveProducedData) {
234         m_haveProducedData = true;
235         updateReadyState();
236     }
237
238     if (!enabled())
239         return;
240
241     mediaSample.setTrackID(id());
242     forEachObserver([&](auto& observer) {
243         observer.sampleBufferUpdated(*this, mediaSample);
244     });
245 }
246
247 // May get called on a background thread.
248 void MediaStreamTrackPrivate::audioSamplesAvailable(const MediaTime& mediaTime, const PlatformAudioData& data, const AudioStreamDescription& description, size_t sampleCount)
249 {
250     if (!m_haveProducedData) {
251         m_haveProducedData = true;
252         updateReadyState();
253     }
254
255     forEachObserver([&](auto& observer) {
256         observer.audioSamplesAvailable(*this, mediaTime, data, description, sampleCount);
257     });
258 }
259
260
261 void MediaStreamTrackPrivate::updateReadyState()
262 {
263     ReadyState state = ReadyState::None;
264
265     if (m_isEnded)
266         state = ReadyState::Ended;
267     else if (m_haveProducedData)
268         state = ReadyState::Live;
269
270     if (state == m_readyState)
271         return;
272
273     ALWAYS_LOG(LOGIDENTIFIER);
274
275     m_readyState = state;
276     forEachObserver([this](auto& observer) {
277         observer.readyStateChanged(*this);
278     });
279 }
280
281 #if !RELEASE_LOG_DISABLED
282 void MediaStreamTrackPrivate::setLogger(const Logger& newLogger, const void* newLogIdentifier)
283 {
284     m_logger = &newLogger;
285     m_logIdentifier = newLogIdentifier;
286     ALWAYS_LOG(LOGIDENTIFIER);
287     m_source->setLogger(newLogger, newLogIdentifier);
288 }
289
290 WTFLogChannel& MediaStreamTrackPrivate::logChannel() const
291 {
292     return LogWebRTC;
293 }
294 #endif
295
296 } // namespace WebCore
297
298 #endif // ENABLE(MEDIA_STREAM)