1/*
2 * Copyright (C) 2017-2019 Apple Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted, provided that the following conditions
6 * are required to be met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Inc. nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. AND ITS CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#pragma once
30
31#if USE(LIBWEBRTC)
32
33#include "LibWebRTCMacros.h"
34#include "MediaStreamTrackPrivate.h"
35#include <Timer.h>
36
37ALLOW_UNUSED_PARAMETERS_BEGIN
38
39#include <webrtc/api/mediastreaminterface.h>
40#include <webrtc/common_video/include/i420_buffer_pool.h>
41
42ALLOW_UNUSED_PARAMETERS_END
43
44#include <wtf/LoggerHelper.h>
45#include <wtf/Optional.h>
46#include <wtf/ThreadSafeRefCounted.h>
47
48namespace WebCore {
49
50class RealtimeOutgoingVideoSource
51 : public ThreadSafeRefCounted<RealtimeOutgoingVideoSource, WTF::DestructionThread::Main>
52 , public webrtc::VideoTrackSourceInterface
53 , private MediaStreamTrackPrivate::Observer
54#if !RELEASE_LOG_DISABLED
55 , private LoggerHelper
56#endif
57{
58public:
59 static Ref<RealtimeOutgoingVideoSource> create(Ref<MediaStreamTrackPrivate>&& videoSource);
60 ~RealtimeOutgoingVideoSource();
61
62 void stop();
63 bool setSource(Ref<MediaStreamTrackPrivate>&&);
64 MediaStreamTrackPrivate& source() const { return m_videoSource.get(); }
65
66 void AddRef() const final { ref(); }
67 rtc::RefCountReleaseStatus Release() const final
68 {
69 deref();
70 return rtc::RefCountReleaseStatus::kOtherRefsRemained;
71 }
72
73 void setApplyRotation(bool shouldApplyRotation) { m_shouldApplyRotation = shouldApplyRotation; }
74
75protected:
76 explicit RealtimeOutgoingVideoSource(Ref<MediaStreamTrackPrivate>&&);
77
78 void sendFrame(rtc::scoped_refptr<webrtc::VideoFrameBuffer>&&);
79 bool isSilenced() const { return m_muted || !m_enabled; }
80
81 virtual rtc::scoped_refptr<webrtc::VideoFrameBuffer> createBlackFrame(size_t width, size_t height) = 0;
82
83 bool m_shouldApplyRotation { false };
84 webrtc::VideoRotation m_currentRotation { webrtc::kVideoRotation_0 };
85
86#if !RELEASE_LOG_DISABLED
87 // LoggerHelper API
88 const Logger& logger() const final { return m_logger.get(); }
89 const void* logIdentifier() const final { return m_logIdentifier; }
90 const char* logClassName() const final { return "RealtimeOutgoingVideoSource"; }
91 WTFLogChannel& logChannel() const final;
92#endif
93
94private:
95 void sendBlackFramesIfNeeded();
96 void sendOneBlackFrame();
97 void initializeFromSource();
98 void updateBlackFramesSending();
99
100 void observeSource();
101 void unobserveSource();
102
103 // Notifier API
104 void RegisterObserver(webrtc::ObserverInterface*) final { }
105 void UnregisterObserver(webrtc::ObserverInterface*) final { }
106
107 // VideoTrackSourceInterface API
108 bool is_screencast() const final { return false; }
109 absl::optional<bool> needs_denoising() const final { return absl::optional<bool>(); }
110 bool GetStats(Stats*) final { return false; };
111
112 // MediaSourceInterface API
113 SourceState state() const final { return SourceState(); }
114 bool remote() const final { return true; }
115
116 // rtc::VideoSourceInterface<webrtc::VideoFrame> API
117 void AddOrUpdateSink(rtc::VideoSinkInterface<webrtc::VideoFrame>*, const rtc::VideoSinkWants&) final;
118 void RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame>*) final;
119
120 void sourceMutedChanged();
121 void sourceEnabledChanged();
122
123 // MediaStreamTrackPrivate::Observer API
124 void trackMutedChanged(MediaStreamTrackPrivate&) final { sourceMutedChanged(); }
125 void trackEnabledChanged(MediaStreamTrackPrivate&) final { sourceEnabledChanged(); }
126 void trackSettingsChanged(MediaStreamTrackPrivate&) final { initializeFromSource(); }
127 void sampleBufferUpdated(MediaStreamTrackPrivate&, MediaSample&) override { }
128 void trackEnded(MediaStreamTrackPrivate&) final { }
129
130 Ref<MediaStreamTrackPrivate> m_videoSource;
131 Optional<RealtimeMediaSourceSettings> m_initialSettings;
132 Timer m_blackFrameTimer;
133 rtc::scoped_refptr<webrtc::VideoFrameBuffer> m_blackFrame;
134
135 mutable RecursiveLock m_sinksLock;
136 HashSet<rtc::VideoSinkInterface<webrtc::VideoFrame>*> m_sinks;
137
138 bool m_enabled { true };
139 bool m_muted { false };
140 uint32_t m_width { 0 };
141 uint32_t m_height { 0 };
142
143#if !RELEASE_LOG_DISABLED
144 Ref<const Logger> m_logger;
145 const void* m_logIdentifier;
146 MonotonicTime m_lastFrameLogTime;
147 unsigned m_frameCount { 0 };
148#endif
149};
150
151} // namespace WebCore
152
153#endif // USE(LIBWEBRTC)
154