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 23namespace webrtc { 24namespace vcm { 25 26int64_t VCMProcessTimer::Period() const { 27 return _periodMs; 28} 29 30int64_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 36void VCMProcessTimer::Processed() { 37 _latestMs = _clock->TimeInMilliseconds(); 38} 39} // namespace vcm 40 41namespace { 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. 44class EncodedImageCallbackWrapper : public EncodedImageCallback { 45 public: 46 EncodedImageCallbackWrapper() 47 : cs_(CriticalSectionWrapper::CreateCriticalSection()), callback_(NULL) {} 48 49 virtual ~EncodedImageCallbackWrapper() {} 50 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. 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 72class VideoCodingModuleImpl : public VideoCodingModule { 73 public: 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 87 virtual ~VideoCodingModuleImpl() { own_event_factory_.reset(); } 88 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 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 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 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 119 int Bitrate(unsigned int* bitrate) const override { 120 return sender_.Bitrate(bitrate); 121 } 122 123 int FrameRate(unsigned int* framerate) const override { 124 return sender_.FrameRate(framerate); 125 } 126 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 133 int32_t RegisterTransportCallback( 134 VCMPacketizationCallback* transport) override { 135 return sender_.RegisterTransportCallback(transport); 136 } 137 138 int32_t RegisterSendStatisticsCallback( 139 VCMSendStatisticsCallback* sendStats) override { 140 return sender_.RegisterSendStatisticsCallback(sendStats); 141 } 142 143 int32_t RegisterProtectionCallback( 144 VCMProtectionCallback* protection) override { 145 return sender_.RegisterProtectionCallback(protection); 146 } 147 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 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 162 int32_t IntraFrameRequest(int stream_index) override { 163 return sender_.IntraFrameRequest(stream_index); 164 } 165 166 int32_t EnableFrameDropper(bool enable) override { 167 return sender_.EnableFrameDropper(enable); 168 } 169 170 void SuspendBelowMinBitrate() override { 171 return sender_.SuspendBelowMinBitrate(); 172 } 173 174 bool VideoSuspended() const override { return sender_.VideoSuspended(); } 175 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 183 void RegisterExternalDecoder(VideoDecoder* externalDecoder, 184 uint8_t payloadType) override { 185 receiver_.RegisterExternalDecoder(externalDecoder, payloadType); 186 } 187 188 int32_t RegisterReceiveCallback( 189 VCMReceiveCallback* receiveCallback) override { 190 return receiver_.RegisterReceiveCallback(receiveCallback); 191 } 192 193 int32_t RegisterReceiveStatisticsCallback( 194 VCMReceiveStatisticsCallback* receiveStats) override { 195 return receiver_.RegisterReceiveStatisticsCallback(receiveStats); 196 } 197 198 int32_t RegisterDecoderTimingCallback( 199 VCMDecoderTimingCallback* decoderTiming) override { 200 return receiver_.RegisterDecoderTimingCallback(decoderTiming); 201 } 202 203 int32_t RegisterFrameTypeCallback( 204 VCMFrameTypeCallback* frameTypeCallback) override { 205 return receiver_.RegisterFrameTypeCallback(frameTypeCallback); 206 } 207 208 int32_t RegisterPacketRequestCallback( 209 VCMPacketRequestCallback* callback) override { 210 return receiver_.RegisterPacketRequestCallback(callback); 211 } 212 213 int RegisterRenderBufferSizeCallback( 214 VCMRenderBufferSizeCallback* callback) override { 215 return receiver_.RegisterRenderBufferSizeCallback(callback); 216 } 217 218 int32_t Decode(uint16_t maxWaitTimeMs) override { 219 return receiver_.Decode(maxWaitTimeMs); 220 } 221 222 int32_t ResetDecoder() override { return receiver_.ResetDecoder(); } 223 224 int32_t ReceiveCodec(VideoCodec* currentReceiveCodec) const override { 225 return receiver_.ReceiveCodec(currentReceiveCodec); 226 } 227 228 VideoCodecType ReceiveCodec() const override { 229 return receiver_.ReceiveCodec(); 230 } 231 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 238 int32_t SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs) override { 239 return receiver_.SetMinimumPlayoutDelay(minPlayoutDelayMs); 240 } 241 242 int32_t SetRenderDelay(uint32_t timeMS) override { 243 return receiver_.SetRenderDelay(timeMS); 244 } 245 246 int32_t Delay() const override { return receiver_.Delay(); } 247 248 uint32_t DiscardedPackets() const override { 249 return receiver_.DiscardedPackets(); 250 } 251 252 int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode, 253 VCMDecodeErrorMode errorMode) override { 254 return receiver_.SetReceiverRobustnessMode(robustnessMode, errorMode); 255 } 256 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 264 void SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) override { 265 return receiver_.SetDecodeErrorMode(decode_error_mode); 266 } 267 268 int SetMinReceiverDelay(int desired_delay_ms) override { 269 return receiver_.SetMinReceiverDelay(desired_delay_ms); 270 } 271 272 int32_t SetReceiveChannelParameters(int64_t rtt) override { 273 return receiver_.SetReceiveChannelParameters(rtt); 274 } 275 276 void RegisterPreDecodeImageCallback(EncodedImageCallback* observer) override { 277 receiver_.RegisterPreDecodeImageCallback(observer); 278 } 279 280 void RegisterPostEncodeImageCallback( 281 EncodedImageCallback* observer) override { 282 post_encode_callback_.Register(observer); 283 } 284 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 295void VideoCodingModule::Codec(VideoCodecType codecType, VideoCodec* codec) { 296 VCMCodecDataBase::Codec(codecType, codec); 297} 298 299VideoCodingModule* 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 307VideoCodingModule* 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 315void VideoCodingModule::Destroy(VideoCodingModule* module) { 316 if (module != NULL) { 317 delete static_cast<VideoCodingModuleImpl*>(module); 318 } 319} 320} // namespace webrtc 321