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 "webrtc/modules/video_coding/video_coding_impl.h"
12
13 #include <algorithm>
14
15 #include "webrtc/common_types.h"
16 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
17 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
18 #include "webrtc/modules/video_coding/encoded_frame.h"
19 #include "webrtc/modules/video_coding/jitter_buffer.h"
20 #include "webrtc/modules/video_coding/packet.h"
21 #include "webrtc/system_wrappers/include/clock.h"
22
23 namespace webrtc {
24 namespace vcm {
25
Period() const26 int64_t VCMProcessTimer::Period() const {
27 return _periodMs;
28 }
29
TimeUntilProcess() const30 int64_t VCMProcessTimer::TimeUntilProcess() const {
31 const int64_t time_since_process = _clock->TimeInMilliseconds() - _latestMs;
32 const int64_t time_until_process = _periodMs - time_since_process;
33 return std::max<int64_t>(time_until_process, 0);
34 }
35
Processed()36 void VCMProcessTimer::Processed() {
37 _latestMs = _clock->TimeInMilliseconds();
38 }
39 } // namespace vcm
40
41 namespace {
42 // This wrapper provides a way to modify the callback without the need to expose
43 // a register method all the way down to the function calling it.
44 class EncodedImageCallbackWrapper : public EncodedImageCallback {
45 public:
EncodedImageCallbackWrapper()46 EncodedImageCallbackWrapper()
47 : cs_(CriticalSectionWrapper::CreateCriticalSection()), callback_(NULL) {}
48
~EncodedImageCallbackWrapper()49 virtual ~EncodedImageCallbackWrapper() {}
50
Register(EncodedImageCallback * callback)51 void Register(EncodedImageCallback* callback) {
52 CriticalSectionScoped cs(cs_.get());
53 callback_ = callback;
54 }
55
56 // TODO(andresp): Change to void as return value is ignored.
Encoded(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info,const RTPFragmentationHeader * fragmentation)57 virtual int32_t Encoded(const EncodedImage& encoded_image,
58 const CodecSpecificInfo* codec_specific_info,
59 const RTPFragmentationHeader* fragmentation) {
60 CriticalSectionScoped cs(cs_.get());
61 if (callback_)
62 return callback_->Encoded(encoded_image, codec_specific_info,
63 fragmentation);
64 return 0;
65 }
66
67 private:
68 rtc::scoped_ptr<CriticalSectionWrapper> cs_;
69 EncodedImageCallback* callback_ GUARDED_BY(cs_);
70 };
71
72 class VideoCodingModuleImpl : public VideoCodingModule {
73 public:
VideoCodingModuleImpl(Clock * clock,EventFactory * event_factory,bool owns_event_factory,VideoEncoderRateObserver * encoder_rate_observer,VCMQMSettingsCallback * qm_settings_callback)74 VideoCodingModuleImpl(Clock* clock,
75 EventFactory* event_factory,
76 bool owns_event_factory,
77 VideoEncoderRateObserver* encoder_rate_observer,
78 VCMQMSettingsCallback* qm_settings_callback)
79 : VideoCodingModule(),
80 sender_(clock,
81 &post_encode_callback_,
82 encoder_rate_observer,
83 qm_settings_callback),
84 receiver_(clock, event_factory),
85 own_event_factory_(owns_event_factory ? event_factory : NULL) {}
86
~VideoCodingModuleImpl()87 virtual ~VideoCodingModuleImpl() { own_event_factory_.reset(); }
88
TimeUntilNextProcess()89 int64_t TimeUntilNextProcess() override {
90 int64_t sender_time = sender_.TimeUntilNextProcess();
91 int64_t receiver_time = receiver_.TimeUntilNextProcess();
92 assert(sender_time >= 0);
93 assert(receiver_time >= 0);
94 return VCM_MIN(sender_time, receiver_time);
95 }
96
Process()97 int32_t Process() override {
98 int32_t sender_return = sender_.Process();
99 int32_t receiver_return = receiver_.Process();
100 if (sender_return != VCM_OK)
101 return sender_return;
102 return receiver_return;
103 }
104
RegisterSendCodec(const VideoCodec * sendCodec,uint32_t numberOfCores,uint32_t maxPayloadSize)105 int32_t RegisterSendCodec(const VideoCodec* sendCodec,
106 uint32_t numberOfCores,
107 uint32_t maxPayloadSize) override {
108 return sender_.RegisterSendCodec(sendCodec, numberOfCores, maxPayloadSize);
109 }
110
RegisterExternalEncoder(VideoEncoder * externalEncoder,uint8_t payloadType,bool internalSource)111 int32_t RegisterExternalEncoder(VideoEncoder* externalEncoder,
112 uint8_t payloadType,
113 bool internalSource) override {
114 sender_.RegisterExternalEncoder(externalEncoder, payloadType,
115 internalSource);
116 return 0;
117 }
118
Bitrate(unsigned int * bitrate) const119 int Bitrate(unsigned int* bitrate) const override {
120 return sender_.Bitrate(bitrate);
121 }
122
FrameRate(unsigned int * framerate) const123 int FrameRate(unsigned int* framerate) const override {
124 return sender_.FrameRate(framerate);
125 }
126
SetChannelParameters(uint32_t target_bitrate,uint8_t lossRate,int64_t rtt)127 int32_t SetChannelParameters(uint32_t target_bitrate, // bits/s.
128 uint8_t lossRate,
129 int64_t rtt) override {
130 return sender_.SetChannelParameters(target_bitrate, lossRate, rtt);
131 }
132
RegisterTransportCallback(VCMPacketizationCallback * transport)133 int32_t RegisterTransportCallback(
134 VCMPacketizationCallback* transport) override {
135 return sender_.RegisterTransportCallback(transport);
136 }
137
RegisterSendStatisticsCallback(VCMSendStatisticsCallback * sendStats)138 int32_t RegisterSendStatisticsCallback(
139 VCMSendStatisticsCallback* sendStats) override {
140 return sender_.RegisterSendStatisticsCallback(sendStats);
141 }
142
RegisterProtectionCallback(VCMProtectionCallback * protection)143 int32_t RegisterProtectionCallback(
144 VCMProtectionCallback* protection) override {
145 return sender_.RegisterProtectionCallback(protection);
146 }
147
SetVideoProtection(VCMVideoProtection videoProtection,bool enable)148 int32_t SetVideoProtection(VCMVideoProtection videoProtection,
149 bool enable) override {
150 // TODO(pbos): Remove enable from receive-side protection modes as well.
151 if (enable)
152 sender_.SetVideoProtection(videoProtection);
153 return receiver_.SetVideoProtection(videoProtection, enable);
154 }
155
AddVideoFrame(const VideoFrame & videoFrame,const VideoContentMetrics * contentMetrics,const CodecSpecificInfo * codecSpecificInfo)156 int32_t AddVideoFrame(const VideoFrame& videoFrame,
157 const VideoContentMetrics* contentMetrics,
158 const CodecSpecificInfo* codecSpecificInfo) override {
159 return sender_.AddVideoFrame(videoFrame, contentMetrics, codecSpecificInfo);
160 }
161
IntraFrameRequest(int stream_index)162 int32_t IntraFrameRequest(int stream_index) override {
163 return sender_.IntraFrameRequest(stream_index);
164 }
165
EnableFrameDropper(bool enable)166 int32_t EnableFrameDropper(bool enable) override {
167 return sender_.EnableFrameDropper(enable);
168 }
169
SuspendBelowMinBitrate()170 void SuspendBelowMinBitrate() override {
171 return sender_.SuspendBelowMinBitrate();
172 }
173
VideoSuspended() const174 bool VideoSuspended() const override { return sender_.VideoSuspended(); }
175
RegisterReceiveCodec(const VideoCodec * receiveCodec,int32_t numberOfCores,bool requireKeyFrame)176 int32_t RegisterReceiveCodec(const VideoCodec* receiveCodec,
177 int32_t numberOfCores,
178 bool requireKeyFrame) override {
179 return receiver_.RegisterReceiveCodec(receiveCodec, numberOfCores,
180 requireKeyFrame);
181 }
182
RegisterExternalDecoder(VideoDecoder * externalDecoder,uint8_t payloadType)183 void RegisterExternalDecoder(VideoDecoder* externalDecoder,
184 uint8_t payloadType) override {
185 receiver_.RegisterExternalDecoder(externalDecoder, payloadType);
186 }
187
RegisterReceiveCallback(VCMReceiveCallback * receiveCallback)188 int32_t RegisterReceiveCallback(
189 VCMReceiveCallback* receiveCallback) override {
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
RegisterDecoderTimingCallback(VCMDecoderTimingCallback * decoderTiming)198 int32_t RegisterDecoderTimingCallback(
199 VCMDecoderTimingCallback* decoderTiming) override {
200 return receiver_.RegisterDecoderTimingCallback(decoderTiming);
201 }
202
RegisterFrameTypeCallback(VCMFrameTypeCallback * frameTypeCallback)203 int32_t RegisterFrameTypeCallback(
204 VCMFrameTypeCallback* frameTypeCallback) override {
205 return receiver_.RegisterFrameTypeCallback(frameTypeCallback);
206 }
207
RegisterPacketRequestCallback(VCMPacketRequestCallback * callback)208 int32_t RegisterPacketRequestCallback(
209 VCMPacketRequestCallback* callback) override {
210 return receiver_.RegisterPacketRequestCallback(callback);
211 }
212
RegisterRenderBufferSizeCallback(VCMRenderBufferSizeCallback * callback)213 int RegisterRenderBufferSizeCallback(
214 VCMRenderBufferSizeCallback* callback) override {
215 return receiver_.RegisterRenderBufferSizeCallback(callback);
216 }
217
Decode(uint16_t maxWaitTimeMs)218 int32_t Decode(uint16_t maxWaitTimeMs) override {
219 return receiver_.Decode(maxWaitTimeMs);
220 }
221
ResetDecoder()222 int32_t ResetDecoder() override { return receiver_.ResetDecoder(); }
223
ReceiveCodec(VideoCodec * currentReceiveCodec) const224 int32_t ReceiveCodec(VideoCodec* currentReceiveCodec) const override {
225 return receiver_.ReceiveCodec(currentReceiveCodec);
226 }
227
ReceiveCodec() const228 VideoCodecType ReceiveCodec() const override {
229 return receiver_.ReceiveCodec();
230 }
231
IncomingPacket(const uint8_t * incomingPayload,size_t payloadLength,const WebRtcRTPHeader & rtpInfo)232 int32_t IncomingPacket(const uint8_t* incomingPayload,
233 size_t payloadLength,
234 const WebRtcRTPHeader& rtpInfo) override {
235 return receiver_.IncomingPacket(incomingPayload, payloadLength, rtpInfo);
236 }
237
SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs)238 int32_t SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs) override {
239 return receiver_.SetMinimumPlayoutDelay(minPlayoutDelayMs);
240 }
241
SetRenderDelay(uint32_t timeMS)242 int32_t SetRenderDelay(uint32_t timeMS) override {
243 return receiver_.SetRenderDelay(timeMS);
244 }
245
Delay() const246 int32_t Delay() const override { return receiver_.Delay(); }
247
DiscardedPackets() const248 uint32_t DiscardedPackets() const override {
249 return receiver_.DiscardedPackets();
250 }
251
SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,VCMDecodeErrorMode errorMode)252 int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,
253 VCMDecodeErrorMode errorMode) override {
254 return receiver_.SetReceiverRobustnessMode(robustnessMode, errorMode);
255 }
256
SetNackSettings(size_t max_nack_list_size,int max_packet_age_to_nack,int max_incomplete_time_ms)257 void SetNackSettings(size_t max_nack_list_size,
258 int max_packet_age_to_nack,
259 int max_incomplete_time_ms) override {
260 return receiver_.SetNackSettings(max_nack_list_size, max_packet_age_to_nack,
261 max_incomplete_time_ms);
262 }
263
SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode)264 void SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) override {
265 return receiver_.SetDecodeErrorMode(decode_error_mode);
266 }
267
SetMinReceiverDelay(int desired_delay_ms)268 int SetMinReceiverDelay(int desired_delay_ms) override {
269 return receiver_.SetMinReceiverDelay(desired_delay_ms);
270 }
271
SetReceiveChannelParameters(int64_t rtt)272 int32_t SetReceiveChannelParameters(int64_t rtt) override {
273 return receiver_.SetReceiveChannelParameters(rtt);
274 }
275
RegisterPreDecodeImageCallback(EncodedImageCallback * observer)276 void RegisterPreDecodeImageCallback(EncodedImageCallback* observer) override {
277 receiver_.RegisterPreDecodeImageCallback(observer);
278 }
279
RegisterPostEncodeImageCallback(EncodedImageCallback * observer)280 void RegisterPostEncodeImageCallback(
281 EncodedImageCallback* observer) override {
282 post_encode_callback_.Register(observer);
283 }
284
TriggerDecoderShutdown()285 void TriggerDecoderShutdown() override { receiver_.TriggerDecoderShutdown(); }
286
287 private:
288 EncodedImageCallbackWrapper post_encode_callback_;
289 vcm::VideoSender sender_;
290 vcm::VideoReceiver receiver_;
291 rtc::scoped_ptr<EventFactory> own_event_factory_;
292 };
293 } // namespace
294
Codec(VideoCodecType codecType,VideoCodec * codec)295 void VideoCodingModule::Codec(VideoCodecType codecType, VideoCodec* codec) {
296 VCMCodecDataBase::Codec(codecType, codec);
297 }
298
Create(Clock * clock,VideoEncoderRateObserver * encoder_rate_observer,VCMQMSettingsCallback * qm_settings_callback)299 VideoCodingModule* VideoCodingModule::Create(
300 Clock* clock,
301 VideoEncoderRateObserver* encoder_rate_observer,
302 VCMQMSettingsCallback* qm_settings_callback) {
303 return new VideoCodingModuleImpl(clock, new EventFactoryImpl, true,
304 encoder_rate_observer, qm_settings_callback);
305 }
306
Create(Clock * clock,EventFactory * event_factory)307 VideoCodingModule* VideoCodingModule::Create(Clock* clock,
308 EventFactory* event_factory) {
309 assert(clock);
310 assert(event_factory);
311 return new VideoCodingModuleImpl(clock, event_factory, false, nullptr,
312 nullptr);
313 }
314
Destroy(VideoCodingModule * module)315 void VideoCodingModule::Destroy(VideoCodingModule* module) {
316 if (module != NULL) {
317 delete static_cast<VideoCodingModuleImpl*>(module);
318 }
319 }
320 } // namespace webrtc
321