1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/video_coding/video_coding_impl.h"
12
13 #include <algorithm>
14 #include <utility>
15
16 #include "common_types.h" // NOLINT(build/include)
17 #include "common_video/include/video_bitrate_allocator.h"
18 #include "common_video/libyuv/include/webrtc_libyuv.h"
19 #include "modules/video_coding/codecs/vp8/temporal_layers.h"
20 #include "modules/video_coding/encoded_frame.h"
21 #include "modules/video_coding/include/video_codec_initializer.h"
22 #include "modules/video_coding/include/video_codec_interface.h"
23 #include "modules/video_coding/jitter_buffer.h"
24 #include "modules/video_coding/packet.h"
25 #include "modules/video_coding/timing.h"
26 #include "rtc_base/criticalsection.h"
27 #include "rtc_base/thread_checker.h"
28 #include "system_wrappers/include/clock.h"
29
30 namespace webrtc {
31 namespace vcm {
32
Period() const33 int64_t VCMProcessTimer::Period() const {
34 return _periodMs;
35 }
36
TimeUntilProcess() const37 int64_t VCMProcessTimer::TimeUntilProcess() const {
38 const int64_t time_since_process = _clock->TimeInMilliseconds() - _latestMs;
39 const int64_t time_until_process = _periodMs - time_since_process;
40 return std::max<int64_t>(time_until_process, 0);
41 }
42
Processed()43 void VCMProcessTimer::Processed() {
44 _latestMs = _clock->TimeInMilliseconds();
45 }
46 } // namespace vcm
47
48 namespace {
49 // This wrapper provides a way to modify the callback without the need to expose
50 // a register method all the way down to the function calling it.
51 class EncodedImageCallbackWrapper : public EncodedImageCallback {
52 public:
EncodedImageCallbackWrapper()53 EncodedImageCallbackWrapper() : callback_(nullptr) {}
54
~EncodedImageCallbackWrapper()55 virtual ~EncodedImageCallbackWrapper() {}
56
Register(EncodedImageCallback * callback)57 void Register(EncodedImageCallback* callback) {
58 rtc::CritScope lock(&cs_);
59 callback_ = callback;
60 }
61
OnEncodedImage(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info,const RTPFragmentationHeader * fragmentation)62 virtual Result OnEncodedImage(const EncodedImage& encoded_image,
63 const CodecSpecificInfo* codec_specific_info,
64 const RTPFragmentationHeader* fragmentation) {
65 rtc::CritScope lock(&cs_);
66 if (callback_) {
67 return callback_->OnEncodedImage(encoded_image, codec_specific_info,
68 fragmentation);
69 }
70 return Result(Result::ERROR_SEND_FAILED);
71 }
72
73 private:
74 rtc::CriticalSection cs_;
75 EncodedImageCallback* callback_ RTC_GUARDED_BY(cs_);
76 };
77
78 class VideoCodingModuleImpl : public VideoCodingModule {
79 public:
VideoCodingModuleImpl(Clock * clock,EventFactory * event_factory,NackSender * nack_sender,KeyFrameRequestSender * keyframe_request_sender,EncodedImageCallback * pre_decode_image_callback)80 VideoCodingModuleImpl(Clock* clock,
81 EventFactory* event_factory,
82 NackSender* nack_sender,
83 KeyFrameRequestSender* keyframe_request_sender,
84 EncodedImageCallback* pre_decode_image_callback)
85 : VideoCodingModule(),
86 sender_(clock, &post_encode_callback_),
87 timing_(new VCMTiming(clock)),
88 receiver_(clock,
89 event_factory,
90 pre_decode_image_callback,
91 timing_.get(),
92 nack_sender,
93 keyframe_request_sender) {}
94
~VideoCodingModuleImpl()95 virtual ~VideoCodingModuleImpl() {}
96
TimeUntilNextProcess()97 int64_t TimeUntilNextProcess() override {
98 int64_t receiver_time = receiver_.TimeUntilNextProcess();
99 RTC_DCHECK_GE(receiver_time, 0);
100 return receiver_time;
101 }
102
Process()103 void Process() override {
104 receiver_.Process();
105 }
106
RegisterSendCodec(const VideoCodec * sendCodec,uint32_t numberOfCores,uint32_t maxPayloadSize)107 int32_t RegisterSendCodec(const VideoCodec* sendCodec,
108 uint32_t numberOfCores,
109 uint32_t maxPayloadSize) override {
110 if (sendCodec != nullptr && sendCodec->codecType == kVideoCodecVP8) {
111 // Set up a rate allocator and temporal layers factory for this vp8
112 // instance. The codec impl will have a raw pointer to the TL factory,
113 // and will call it when initializing. Since this can happen
114 // asynchronously keep the instance alive until destruction or until a
115 // new send codec is registered.
116 VideoCodec vp8_codec = *sendCodec;
117 std::unique_ptr<TemporalLayersFactory> tl_factory(
118 new TemporalLayersFactory());
119 vp8_codec.VP8()->tl_factory = tl_factory.get();
120 rate_allocator_ = VideoCodecInitializer::CreateBitrateAllocator(
121 vp8_codec, std::move(tl_factory));
122 return sender_.RegisterSendCodec(&vp8_codec, numberOfCores,
123 maxPayloadSize);
124 }
125 return sender_.RegisterSendCodec(sendCodec, numberOfCores, maxPayloadSize);
126 }
127
RegisterExternalEncoder(VideoEncoder * externalEncoder,uint8_t payloadType,bool internalSource)128 int32_t RegisterExternalEncoder(VideoEncoder* externalEncoder,
129 uint8_t payloadType,
130 bool internalSource) override {
131 sender_.RegisterExternalEncoder(externalEncoder, payloadType,
132 internalSource);
133 return 0;
134 }
135
Bitrate(unsigned int * bitrate) const136 int Bitrate(unsigned int* bitrate) const override {
137 return sender_.Bitrate(bitrate);
138 }
139
FrameRate(unsigned int * framerate) const140 int FrameRate(unsigned int* framerate) const override {
141 return sender_.FrameRate(framerate);
142 }
143
SetChannelParameters(uint32_t target_bitrate,uint8_t lossRate,int64_t rtt)144 int32_t SetChannelParameters(uint32_t target_bitrate, // bits/s.
145 uint8_t lossRate,
146 int64_t rtt) override {
147 return sender_.SetChannelParameters(target_bitrate, lossRate, rtt,
148 rate_allocator_.get(), nullptr);
149 }
150
RegisterProtectionCallback(VCMProtectionCallback * protection)151 int32_t RegisterProtectionCallback(
152 VCMProtectionCallback* protection) override {
153 return sender_.RegisterProtectionCallback(protection);
154 }
155
SetVideoProtection(VCMVideoProtection videoProtection,bool enable)156 int32_t SetVideoProtection(VCMVideoProtection videoProtection,
157 bool enable) override {
158 // TODO(pbos): Remove enable from receive-side protection modes as well.
159 return receiver_.SetVideoProtection(videoProtection, enable);
160 }
161
AddVideoFrame(const VideoFrame & videoFrame,const CodecSpecificInfo * codecSpecificInfo)162 int32_t AddVideoFrame(const VideoFrame& videoFrame,
163 const CodecSpecificInfo* codecSpecificInfo) override {
164 return sender_.AddVideoFrame(videoFrame, codecSpecificInfo);
165 }
166
IntraFrameRequest(size_t stream_index)167 int32_t IntraFrameRequest(size_t stream_index) override {
168 return sender_.IntraFrameRequest(stream_index);
169 }
170
EnableFrameDropper(bool enable)171 int32_t EnableFrameDropper(bool enable) override {
172 return sender_.EnableFrameDropper(enable);
173 }
174
RegisterReceiveCodec(const VideoCodec * receiveCodec,int32_t numberOfCores,bool requireKeyFrame)175 int32_t RegisterReceiveCodec(const VideoCodec* receiveCodec,
176 int32_t numberOfCores,
177 bool requireKeyFrame) override {
178 return receiver_.RegisterReceiveCodec(receiveCodec, numberOfCores,
179 requireKeyFrame);
180 }
181
RegisterExternalDecoder(VideoDecoder * externalDecoder,uint8_t payloadType)182 void RegisterExternalDecoder(VideoDecoder* externalDecoder,
183 uint8_t payloadType) override {
184 receiver_.RegisterExternalDecoder(externalDecoder, payloadType);
185 }
186
RegisterReceiveCallback(VCMReceiveCallback * receiveCallback)187 int32_t RegisterReceiveCallback(
188 VCMReceiveCallback* receiveCallback) override {
189 RTC_DCHECK(construction_thread_.CalledOnValidThread());
190 return receiver_.RegisterReceiveCallback(receiveCallback);
191 }
192
RegisterReceiveStatisticsCallback(VCMReceiveStatisticsCallback * receiveStats)193 int32_t RegisterReceiveStatisticsCallback(
194 VCMReceiveStatisticsCallback* receiveStats) override {
195 return receiver_.RegisterReceiveStatisticsCallback(receiveStats);
196 }
197
RegisterFrameTypeCallback(VCMFrameTypeCallback * frameTypeCallback)198 int32_t RegisterFrameTypeCallback(
199 VCMFrameTypeCallback* frameTypeCallback) override {
200 return receiver_.RegisterFrameTypeCallback(frameTypeCallback);
201 }
202
RegisterPacketRequestCallback(VCMPacketRequestCallback * callback)203 int32_t RegisterPacketRequestCallback(
204 VCMPacketRequestCallback* callback) override {
205 RTC_DCHECK(construction_thread_.CalledOnValidThread());
206 return receiver_.RegisterPacketRequestCallback(callback);
207 }
208
Decode(uint16_t maxWaitTimeMs)209 int32_t Decode(uint16_t maxWaitTimeMs) override {
210 return receiver_.Decode(maxWaitTimeMs);
211 }
212
IncomingPacket(const uint8_t * incomingPayload,size_t payloadLength,const WebRtcRTPHeader & rtpInfo)213 int32_t IncomingPacket(const uint8_t* incomingPayload,
214 size_t payloadLength,
215 const WebRtcRTPHeader& rtpInfo) override {
216 return receiver_.IncomingPacket(incomingPayload, payloadLength, rtpInfo);
217 }
218
SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs)219 int32_t SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs) override {
220 return receiver_.SetMinimumPlayoutDelay(minPlayoutDelayMs);
221 }
222
SetRenderDelay(uint32_t timeMS)223 int32_t SetRenderDelay(uint32_t timeMS) override {
224 return receiver_.SetRenderDelay(timeMS);
225 }
226
Delay() const227 int32_t Delay() const override { return receiver_.Delay(); }
228
SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,VCMDecodeErrorMode errorMode)229 int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,
230 VCMDecodeErrorMode errorMode) override {
231 return receiver_.SetReceiverRobustnessMode(robustnessMode, errorMode);
232 }
233
SetNackSettings(size_t max_nack_list_size,int max_packet_age_to_nack,int max_incomplete_time_ms)234 void SetNackSettings(size_t max_nack_list_size,
235 int max_packet_age_to_nack,
236 int max_incomplete_time_ms) override {
237 return receiver_.SetNackSettings(max_nack_list_size, max_packet_age_to_nack,
238 max_incomplete_time_ms);
239 }
240
SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode)241 void SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) override {
242 return receiver_.SetDecodeErrorMode(decode_error_mode);
243 }
244
SetMinReceiverDelay(int desired_delay_ms)245 int SetMinReceiverDelay(int desired_delay_ms) override {
246 return receiver_.SetMinReceiverDelay(desired_delay_ms);
247 }
248
SetReceiveChannelParameters(int64_t rtt)249 int32_t SetReceiveChannelParameters(int64_t rtt) override {
250 return receiver_.SetReceiveChannelParameters(rtt);
251 }
252
RegisterPostEncodeImageCallback(EncodedImageCallback * observer)253 void RegisterPostEncodeImageCallback(
254 EncodedImageCallback* observer) override {
255 post_encode_callback_.Register(observer);
256 }
257
TriggerDecoderShutdown()258 void TriggerDecoderShutdown() override { receiver_.TriggerDecoderShutdown(); }
259
260 private:
261 rtc::ThreadChecker construction_thread_;
262 EncodedImageCallbackWrapper post_encode_callback_;
263 vcm::VideoSender sender_;
264 std::unique_ptr<VideoBitrateAllocator> rate_allocator_;
265 std::unique_ptr<VCMTiming> timing_;
266 vcm::VideoReceiver receiver_;
267 };
268 } // namespace
269
270 // DEPRECATED. Create method for current interface, will be removed when the
271 // new jitter buffer is in place.
Create(Clock * clock,EventFactory * event_factory)272 VideoCodingModule* VideoCodingModule::Create(Clock* clock,
273 EventFactory* event_factory) {
274 RTC_DCHECK(clock);
275 RTC_DCHECK(event_factory);
276 return new VideoCodingModuleImpl(clock, event_factory, nullptr, nullptr,
277 nullptr);
278 }
279
280 } // namespace webrtc
281