• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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