blob: 8955e54db70d5dc6aabbb68eb7ace54d98d42597 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
mflodman@webrtc.orgc80d9d92012-02-06 10:11:25 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
philipel5908c712015-12-21 08:23:20 -080011#include "webrtc/modules/video_coding/video_coding_impl.h"
12
13#include <algorithm>
14
pbos@webrtc.orga4407322013-07-16 12:32:05 +000015#include "webrtc/common_types.h"
16#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
sprang3911c262016-04-15 01:24:14 -070017#include "webrtc/base/criticalsection.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010018#include "webrtc/modules/video_coding/include/video_codec_interface.h"
19#include "webrtc/modules/video_coding/encoded_frame.h"
20#include "webrtc/modules/video_coding/jitter_buffer.h"
21#include "webrtc/modules/video_coding/packet.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010022#include "webrtc/system_wrappers/include/clock.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000023
agalusza@google.coma7e360e2013-08-01 03:15:08 +000024namespace webrtc {
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +000025namespace vcm {
niklase@google.com470e71d2011-07-07 08:21:25 +000026
philipel5908c712015-12-21 08:23:20 -080027int64_t VCMProcessTimer::Period() const {
28 return _periodMs;
niklase@google.com470e71d2011-07-07 08:21:25 +000029}
30
philipel5908c712015-12-21 08:23:20 -080031int64_t VCMProcessTimer::TimeUntilProcess() const {
32 const int64_t time_since_process = _clock->TimeInMilliseconds() - _latestMs;
33 const int64_t time_until_process = _periodMs - time_since_process;
34 return std::max<int64_t>(time_until_process, 0);
niklase@google.com470e71d2011-07-07 08:21:25 +000035}
36
philipel5908c712015-12-21 08:23:20 -080037void VCMProcessTimer::Processed() {
38 _latestMs = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +000039}
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +000040} // namespace vcm
niklase@google.com470e71d2011-07-07 08:21:25 +000041
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +000042namespace {
andresp@webrtc.org1df9dc32014-01-09 08:01:57 +000043// This wrapper provides a way to modify the callback without the need to expose
44// a register method all the way down to the function calling it.
45class EncodedImageCallbackWrapper : public EncodedImageCallback {
46 public:
47 EncodedImageCallbackWrapper()
48 : cs_(CriticalSectionWrapper::CreateCriticalSection()), callback_(NULL) {}
49
50 virtual ~EncodedImageCallbackWrapper() {}
51
52 void Register(EncodedImageCallback* callback) {
53 CriticalSectionScoped cs(cs_.get());
54 callback_ = callback;
55 }
56
pbos@webrtc.org273a4142014-12-01 15:23:21 +000057 virtual int32_t Encoded(const EncodedImage& encoded_image,
andresp@webrtc.org1df9dc32014-01-09 08:01:57 +000058 const CodecSpecificInfo* codec_specific_info,
59 const RTPFragmentationHeader* fragmentation) {
60 CriticalSectionScoped cs(cs_.get());
61 if (callback_)
philipel5908c712015-12-21 08:23:20 -080062 return callback_->Encoded(encoded_image, codec_specific_info,
63 fragmentation);
andresp@webrtc.org1df9dc32014-01-09 08:01:57 +000064 return 0;
65 }
66
67 private:
kwiberg3f55dea2016-02-29 05:51:59 -080068 std::unique_ptr<CriticalSectionWrapper> cs_;
andresp@webrtc.org1df9dc32014-01-09 08:01:57 +000069 EncodedImageCallback* callback_ GUARDED_BY(cs_);
70};
71
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +000072class VideoCodingModuleImpl : public VideoCodingModule {
73 public:
stefan@webrtc.org34c5da62014-04-11 14:08:35 +000074 VideoCodingModuleImpl(Clock* clock,
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +000075 EventFactory* event_factory,
mflodmanfcf54bd2015-04-14 21:28:08 +020076 VideoEncoderRateObserver* encoder_rate_observer,
philipel83f831a2016-03-12 03:30:23 -080077 NackSender* nack_sender,
sprang3911c262016-04-15 01:24:14 -070078 KeyFrameRequestSender* keyframe_request_sender,
79 EncodedImageCallback* pre_decode_image_callback)
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +000080 : VideoCodingModule(),
Peter Boströmad6fc5a2016-05-12 03:01:31 +020081 sender_(clock, &post_encode_callback_, encoder_rate_observer, nullptr),
philipel83f831a2016-03-12 03:30:23 -080082 receiver_(clock,
83 event_factory,
sprang3911c262016-04-15 01:24:14 -070084 pre_decode_image_callback,
philipel83f831a2016-03-12 03:30:23 -080085 nack_sender,
Peter Boström0b250722016-04-22 18:23:15 +020086 keyframe_request_sender) {}
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +000087
Peter Boström0b250722016-04-22 18:23:15 +020088 virtual ~VideoCodingModuleImpl() {}
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +000089
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000090 int64_t TimeUntilNextProcess() override {
pbos0fa9b222015-11-13 05:59:57 -080091 int64_t sender_time = sender_.TimeUntilNextProcess();
92 int64_t receiver_time = receiver_.TimeUntilNextProcess();
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +000093 assert(sender_time >= 0);
94 assert(receiver_time >= 0);
95 return VCM_MIN(sender_time, receiver_time);
96 }
97
pbosa26ac922016-02-25 04:50:01 -080098 void Process() override {
99 sender_.Process();
100 receiver_.Process();
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000101 }
102
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000103 int32_t RegisterSendCodec(const VideoCodec* sendCodec,
104 uint32_t numberOfCores,
105 uint32_t maxPayloadSize) override {
pbos0fa9b222015-11-13 05:59:57 -0800106 return sender_.RegisterSendCodec(sendCodec, numberOfCores, maxPayloadSize);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000107 }
108
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000109 int32_t RegisterExternalEncoder(VideoEncoder* externalEncoder,
110 uint8_t payloadType,
111 bool internalSource) override {
Peter Boström795dbe42015-11-27 14:09:07 +0100112 sender_.RegisterExternalEncoder(externalEncoder, payloadType,
113 internalSource);
114 return 0;
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000115 }
116
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000117 int Bitrate(unsigned int* bitrate) const override {
pbos0fa9b222015-11-13 05:59:57 -0800118 return sender_.Bitrate(bitrate);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000119 }
120
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000121 int FrameRate(unsigned int* framerate) const override {
pbos0fa9b222015-11-13 05:59:57 -0800122 return sender_.FrameRate(framerate);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000123 }
124
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000125 int32_t SetChannelParameters(uint32_t target_bitrate, // bits/s.
126 uint8_t lossRate,
127 int64_t rtt) override {
pbos0fa9b222015-11-13 05:59:57 -0800128 return sender_.SetChannelParameters(target_bitrate, lossRate, rtt);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000129 }
130
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000131 int32_t RegisterProtectionCallback(
132 VCMProtectionCallback* protection) override {
pbos0fa9b222015-11-13 05:59:57 -0800133 return sender_.RegisterProtectionCallback(protection);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000134 }
135
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000136 int32_t SetVideoProtection(VCMVideoProtection videoProtection,
137 bool enable) override {
pbosba8c15b2015-07-14 09:36:34 -0700138 // TODO(pbos): Remove enable from receive-side protection modes as well.
pbos0fa9b222015-11-13 05:59:57 -0800139 return receiver_.SetVideoProtection(videoProtection, enable);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000140 }
141
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700142 int32_t AddVideoFrame(const VideoFrame& videoFrame,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000143 const CodecSpecificInfo* codecSpecificInfo) override {
Peter Boströmad6fc5a2016-05-12 03:01:31 +0200144 return sender_.AddVideoFrame(videoFrame, codecSpecificInfo);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000145 }
146
perkj600246e2016-05-04 11:26:51 -0700147 int32_t IntraFrameRequest(size_t stream_index) override {
pbos0fa9b222015-11-13 05:59:57 -0800148 return sender_.IntraFrameRequest(stream_index);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000149 }
150
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000151 int32_t EnableFrameDropper(bool enable) override {
pbos0fa9b222015-11-13 05:59:57 -0800152 return sender_.EnableFrameDropper(enable);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000153 }
154
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000155 int32_t RegisterReceiveCodec(const VideoCodec* receiveCodec,
156 int32_t numberOfCores,
157 bool requireKeyFrame) override {
pbos0fa9b222015-11-13 05:59:57 -0800158 return receiver_.RegisterReceiveCodec(receiveCodec, numberOfCores,
159 requireKeyFrame);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000160 }
161
Peter Boström795dbe42015-11-27 14:09:07 +0100162 void RegisterExternalDecoder(VideoDecoder* externalDecoder,
perkj796cfaf2015-12-10 09:27:38 -0800163 uint8_t payloadType) override {
164 receiver_.RegisterExternalDecoder(externalDecoder, payloadType);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000165 }
166
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000167 int32_t RegisterReceiveCallback(
168 VCMReceiveCallback* receiveCallback) override {
pbos0fa9b222015-11-13 05:59:57 -0800169 return receiver_.RegisterReceiveCallback(receiveCallback);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000170 }
171
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000172 int32_t RegisterReceiveStatisticsCallback(
173 VCMReceiveStatisticsCallback* receiveStats) override {
pbos0fa9b222015-11-13 05:59:57 -0800174 return receiver_.RegisterReceiveStatisticsCallback(receiveStats);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000175 }
176
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000177 int32_t RegisterDecoderTimingCallback(
178 VCMDecoderTimingCallback* decoderTiming) override {
pbos0fa9b222015-11-13 05:59:57 -0800179 return receiver_.RegisterDecoderTimingCallback(decoderTiming);
fischman@webrtc.org37bb4972013-10-23 23:59:45 +0000180 }
181
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000182 int32_t RegisterFrameTypeCallback(
183 VCMFrameTypeCallback* frameTypeCallback) override {
pbos0fa9b222015-11-13 05:59:57 -0800184 return receiver_.RegisterFrameTypeCallback(frameTypeCallback);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000185 }
186
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000187 int32_t RegisterPacketRequestCallback(
188 VCMPacketRequestCallback* callback) override {
pbos0fa9b222015-11-13 05:59:57 -0800189 return receiver_.RegisterPacketRequestCallback(callback);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000190 }
191
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000192 int32_t Decode(uint16_t maxWaitTimeMs) override {
pbos0fa9b222015-11-13 05:59:57 -0800193 return receiver_.Decode(maxWaitTimeMs);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000194 }
195
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000196 int32_t ReceiveCodec(VideoCodec* currentReceiveCodec) const override {
pbos0fa9b222015-11-13 05:59:57 -0800197 return receiver_.ReceiveCodec(currentReceiveCodec);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000198 }
199
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000200 VideoCodecType ReceiveCodec() const override {
pbos0fa9b222015-11-13 05:59:57 -0800201 return receiver_.ReceiveCodec();
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000202 }
203
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000204 int32_t IncomingPacket(const uint8_t* incomingPayload,
205 size_t payloadLength,
206 const WebRtcRTPHeader& rtpInfo) override {
pbos0fa9b222015-11-13 05:59:57 -0800207 return receiver_.IncomingPacket(incomingPayload, payloadLength, rtpInfo);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000208 }
209
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000210 int32_t SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs) override {
pbos0fa9b222015-11-13 05:59:57 -0800211 return receiver_.SetMinimumPlayoutDelay(minPlayoutDelayMs);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000212 }
213
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000214 int32_t SetRenderDelay(uint32_t timeMS) override {
pbos0fa9b222015-11-13 05:59:57 -0800215 return receiver_.SetRenderDelay(timeMS);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000216 }
217
pbos0fa9b222015-11-13 05:59:57 -0800218 int32_t Delay() const override { return receiver_.Delay(); }
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000219
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000220 uint32_t DiscardedPackets() const override {
pbos0fa9b222015-11-13 05:59:57 -0800221 return receiver_.DiscardedPackets();
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000222 }
223
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000224 int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,
225 VCMDecodeErrorMode errorMode) override {
pbos0fa9b222015-11-13 05:59:57 -0800226 return receiver_.SetReceiverRobustnessMode(robustnessMode, errorMode);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000227 }
228
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000229 void SetNackSettings(size_t max_nack_list_size,
230 int max_packet_age_to_nack,
231 int max_incomplete_time_ms) override {
pbos0fa9b222015-11-13 05:59:57 -0800232 return receiver_.SetNackSettings(max_nack_list_size, max_packet_age_to_nack,
233 max_incomplete_time_ms);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000234 }
235
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000236 void SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) override {
pbos0fa9b222015-11-13 05:59:57 -0800237 return receiver_.SetDecodeErrorMode(decode_error_mode);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000238 }
239
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000240 int SetMinReceiverDelay(int desired_delay_ms) override {
pbos0fa9b222015-11-13 05:59:57 -0800241 return receiver_.SetMinReceiverDelay(desired_delay_ms);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000242 }
243
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000244 int32_t SetReceiveChannelParameters(int64_t rtt) override {
pbos0fa9b222015-11-13 05:59:57 -0800245 return receiver_.SetReceiveChannelParameters(rtt);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000246 }
247
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000248 void RegisterPostEncodeImageCallback(
249 EncodedImageCallback* observer) override {
andresp@webrtc.org1df9dc32014-01-09 08:01:57 +0000250 post_encode_callback_.Register(observer);
sprang@webrtc.org40709352013-11-26 11:41:59 +0000251 }
252
pbos0fa9b222015-11-13 05:59:57 -0800253 void TriggerDecoderShutdown() override { receiver_.TriggerDecoderShutdown(); }
pbos@webrtc.org4dd40d62015-02-17 13:22:43 +0000254
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000255 private:
andresp@webrtc.org1df9dc32014-01-09 08:01:57 +0000256 EncodedImageCallbackWrapper post_encode_callback_;
pbos0fa9b222015-11-13 05:59:57 -0800257 vcm::VideoSender sender_;
258 vcm::VideoReceiver receiver_;
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000259};
260} // namespace
261
Peter Boström7776e782016-01-07 15:42:47 +0100262void VideoCodingModule::Codec(VideoCodecType codecType, VideoCodec* codec) {
Peter Boström92f8dbd2015-11-24 13:55:55 +0100263 VCMCodecDataBase::Codec(codecType, codec);
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000264}
265
philipel83f831a2016-03-12 03:30:23 -0800266// Create method for current interface, will be removed when the
267// new jitter buffer is in place.
pbos@webrtc.org891d4832015-02-26 13:15:22 +0000268VideoCodingModule* VideoCodingModule::Create(
mflodmanfcf54bd2015-04-14 21:28:08 +0200269 Clock* clock,
270 VideoEncoderRateObserver* encoder_rate_observer,
271 VCMQMSettingsCallback* qm_settings_callback) {
philipel83f831a2016-03-12 03:30:23 -0800272 return VideoCodingModule::Create(clock, encoder_rate_observer,
273 qm_settings_callback,
274 nullptr, // NackSender
sprang3911c262016-04-15 01:24:14 -0700275 nullptr, // KeyframeRequestSender
276 nullptr); // Pre-decode image callback
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000277}
278
philipel83f831a2016-03-12 03:30:23 -0800279// Create method for the new jitter buffer.
280VideoCodingModule* VideoCodingModule::Create(
281 Clock* clock,
282 VideoEncoderRateObserver* encoder_rate_observer,
283 VCMQMSettingsCallback* qm_settings_callback,
284 NackSender* nack_sender,
sprang3911c262016-04-15 01:24:14 -0700285 KeyFrameRequestSender* keyframe_request_sender,
286 EncodedImageCallback* pre_decode_image_callback) {
Peter Boströmad6fc5a2016-05-12 03:01:31 +0200287 return new VideoCodingModuleImpl(clock, nullptr, encoder_rate_observer,
288 nack_sender, keyframe_request_sender,
289 pre_decode_image_callback);
philipel83f831a2016-03-12 03:30:23 -0800290}
291
292// Create method for current interface, will be removed when the
293// new jitter buffer is in place.
philipel5908c712015-12-21 08:23:20 -0800294VideoCodingModule* VideoCodingModule::Create(Clock* clock,
295 EventFactory* event_factory) {
philipel83f831a2016-03-12 03:30:23 -0800296 return VideoCodingModule::Create(clock, event_factory,
297 nullptr, // NackSender
298 nullptr); // KeyframeRequestSender
299}
300
301// Create method for the new jitter buffer.
302VideoCodingModule* VideoCodingModule::Create(
303 Clock* clock,
304 EventFactory* event_factory,
305 NackSender* nack_sender,
306 KeyFrameRequestSender* keyframe_request_sender) {
andresp@webrtc.orgf7eb75b2013-09-14 00:25:28 +0000307 assert(clock);
308 assert(event_factory);
Peter Boströmad6fc5a2016-05-12 03:01:31 +0200309 return new VideoCodingModuleImpl(clock, event_factory, nullptr, nack_sender,
310 keyframe_request_sender, nullptr);
niklase@google.com470e71d2011-07-07 08:21:25 +0000311}
312
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000313} // namespace webrtc