Home | History | Annotate | Download | only in video_coding
      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 
     26 int64_t VCMProcessTimer::Period() const {
     27   return _periodMs;
     28 }
     29 
     30 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 
     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:
     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 
     72 class 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 
    295 void VideoCodingModule::Codec(VideoCodecType codecType, VideoCodec* codec) {
    296   VCMCodecDataBase::Codec(codecType, codec);
    297 }
    298 
    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 
    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 
    315 void VideoCodingModule::Destroy(VideoCodingModule* module) {
    316   if (module != NULL) {
    317     delete static_cast<VideoCodingModuleImpl*>(module);
    318   }
    319 }
    320 }  // namespace webrtc
    321