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