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