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/receiver.h"
12
13#include <assert.h>
14
15#include <cstdlib>
16#include <utility>
17#include <vector>
18
19#include "webrtc/base/logging.h"
20#include "webrtc/base/trace_event.h"
21#include "webrtc/modules/video_coding/encoded_frame.h"
22#include "webrtc/modules/video_coding/internal_defines.h"
23#include "webrtc/modules/video_coding/media_opt_util.h"
24#include "webrtc/system_wrappers/include/clock.h"
25
26namespace webrtc {
27
28enum { kMaxReceiverDelayMs = 10000 };
29
30VCMReceiver::VCMReceiver(VCMTiming* timing,
31                         Clock* clock,
32                         EventFactory* event_factory)
33    : VCMReceiver(timing,
34                  clock,
35                  rtc::scoped_ptr<EventWrapper>(event_factory->CreateEvent()),
36                  rtc::scoped_ptr<EventWrapper>(event_factory->CreateEvent())) {
37}
38
39VCMReceiver::VCMReceiver(VCMTiming* timing,
40                         Clock* clock,
41                         rtc::scoped_ptr<EventWrapper> receiver_event,
42                         rtc::scoped_ptr<EventWrapper> jitter_buffer_event)
43    : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
44      clock_(clock),
45      jitter_buffer_(clock_, std::move(jitter_buffer_event)),
46      timing_(timing),
47      render_wait_event_(std::move(receiver_event)),
48      max_video_delay_ms_(kMaxVideoDelayMs) {
49  Reset();
50}
51
52VCMReceiver::~VCMReceiver() {
53  render_wait_event_->Set();
54  delete crit_sect_;
55}
56
57void VCMReceiver::Reset() {
58  CriticalSectionScoped cs(crit_sect_);
59  if (!jitter_buffer_.Running()) {
60    jitter_buffer_.Start();
61  } else {
62    jitter_buffer_.Flush();
63  }
64}
65
66void VCMReceiver::UpdateRtt(int64_t rtt) {
67  jitter_buffer_.UpdateRtt(rtt);
68}
69
70int32_t VCMReceiver::InsertPacket(const VCMPacket& packet,
71                                  uint16_t frame_width,
72                                  uint16_t frame_height) {
73  // Insert the packet into the jitter buffer. The packet can either be empty or
74  // contain media at this point.
75  bool retransmitted = false;
76  const VCMFrameBufferEnum ret =
77      jitter_buffer_.InsertPacket(packet, &retransmitted);
78  if (ret == kOldPacket) {
79    return VCM_OK;
80  } else if (ret == kFlushIndicator) {
81    return VCM_FLUSH_INDICATOR;
82  } else if (ret < 0) {
83    return VCM_JITTER_BUFFER_ERROR;
84  }
85  if (ret == kCompleteSession && !retransmitted) {
86    // We don't want to include timestamps which have suffered from
87    // retransmission here, since we compensate with extra retransmission
88    // delay within the jitter estimate.
89    timing_->IncomingTimestamp(packet.timestamp, clock_->TimeInMilliseconds());
90  }
91  return VCM_OK;
92}
93
94void VCMReceiver::TriggerDecoderShutdown() {
95  jitter_buffer_.Stop();
96  render_wait_event_->Set();
97}
98
99VCMEncodedFrame* VCMReceiver::FrameForDecoding(uint16_t max_wait_time_ms,
100                                               int64_t* next_render_time_ms,
101                                               bool prefer_late_decoding) {
102  const int64_t start_time_ms = clock_->TimeInMilliseconds();
103  uint32_t frame_timestamp = 0;
104  // Exhaust wait time to get a complete frame for decoding.
105  bool found_frame =
106      jitter_buffer_.NextCompleteTimestamp(max_wait_time_ms, &frame_timestamp);
107
108  if (!found_frame)
109    found_frame = jitter_buffer_.NextMaybeIncompleteTimestamp(&frame_timestamp);
110
111  if (!found_frame)
112    return NULL;
113
114  // We have a frame - Set timing and render timestamp.
115  timing_->SetJitterDelay(jitter_buffer_.EstimatedJitterMs());
116  const int64_t now_ms = clock_->TimeInMilliseconds();
117  timing_->UpdateCurrentDelay(frame_timestamp);
118  *next_render_time_ms = timing_->RenderTimeMs(frame_timestamp, now_ms);
119  // Check render timing.
120  bool timing_error = false;
121  // Assume that render timing errors are due to changes in the video stream.
122  if (*next_render_time_ms < 0) {
123    timing_error = true;
124  } else if (std::abs(*next_render_time_ms - now_ms) > max_video_delay_ms_) {
125    int frame_delay = static_cast<int>(std::abs(*next_render_time_ms - now_ms));
126    LOG(LS_WARNING) << "A frame about to be decoded is out of the configured "
127                    << "delay bounds (" << frame_delay << " > "
128                    << max_video_delay_ms_
129                    << "). Resetting the video jitter buffer.";
130    timing_error = true;
131  } else if (static_cast<int>(timing_->TargetVideoDelay()) >
132             max_video_delay_ms_) {
133    LOG(LS_WARNING) << "The video target delay has grown larger than "
134                    << max_video_delay_ms_ << " ms. Resetting jitter buffer.";
135    timing_error = true;
136  }
137
138  if (timing_error) {
139    // Timing error => reset timing and flush the jitter buffer.
140    jitter_buffer_.Flush();
141    timing_->Reset();
142    return NULL;
143  }
144
145  if (prefer_late_decoding) {
146    // Decode frame as close as possible to the render timestamp.
147    const int32_t available_wait_time =
148        max_wait_time_ms -
149        static_cast<int32_t>(clock_->TimeInMilliseconds() - start_time_ms);
150    uint16_t new_max_wait_time =
151        static_cast<uint16_t>(VCM_MAX(available_wait_time, 0));
152    uint32_t wait_time_ms = timing_->MaxWaitingTime(
153        *next_render_time_ms, clock_->TimeInMilliseconds());
154    if (new_max_wait_time < wait_time_ms) {
155      // We're not allowed to wait until the frame is supposed to be rendered,
156      // waiting as long as we're allowed to avoid busy looping, and then return
157      // NULL. Next call to this function might return the frame.
158      render_wait_event_->Wait(new_max_wait_time);
159      return NULL;
160    }
161    // Wait until it's time to render.
162    render_wait_event_->Wait(wait_time_ms);
163  }
164
165  // Extract the frame from the jitter buffer and set the render time.
166  VCMEncodedFrame* frame = jitter_buffer_.ExtractAndSetDecode(frame_timestamp);
167  if (frame == NULL) {
168    return NULL;
169  }
170  frame->SetRenderTime(*next_render_time_ms);
171  TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", frame->TimeStamp(), "SetRenderTS",
172                          "render_time", *next_render_time_ms);
173  if (!frame->Complete()) {
174    // Update stats for incomplete frames.
175    bool retransmitted = false;
176    const int64_t last_packet_time_ms =
177        jitter_buffer_.LastPacketTime(frame, &retransmitted);
178    if (last_packet_time_ms >= 0 && !retransmitted) {
179      // We don't want to include timestamps which have suffered from
180      // retransmission here, since we compensate with extra retransmission
181      // delay within the jitter estimate.
182      timing_->IncomingTimestamp(frame_timestamp, last_packet_time_ms);
183    }
184  }
185  return frame;
186}
187
188void VCMReceiver::ReleaseFrame(VCMEncodedFrame* frame) {
189  jitter_buffer_.ReleaseFrame(frame);
190}
191
192void VCMReceiver::ReceiveStatistics(uint32_t* bitrate, uint32_t* framerate) {
193  assert(bitrate);
194  assert(framerate);
195  jitter_buffer_.IncomingRateStatistics(framerate, bitrate);
196}
197
198uint32_t VCMReceiver::DiscardedPackets() const {
199  return jitter_buffer_.num_discarded_packets();
200}
201
202void VCMReceiver::SetNackMode(VCMNackMode nackMode,
203                              int64_t low_rtt_nack_threshold_ms,
204                              int64_t high_rtt_nack_threshold_ms) {
205  CriticalSectionScoped cs(crit_sect_);
206  // Default to always having NACK enabled in hybrid mode.
207  jitter_buffer_.SetNackMode(nackMode, low_rtt_nack_threshold_ms,
208                             high_rtt_nack_threshold_ms);
209}
210
211void VCMReceiver::SetNackSettings(size_t max_nack_list_size,
212                                  int max_packet_age_to_nack,
213                                  int max_incomplete_time_ms) {
214  jitter_buffer_.SetNackSettings(max_nack_list_size, max_packet_age_to_nack,
215                                 max_incomplete_time_ms);
216}
217
218VCMNackMode VCMReceiver::NackMode() const {
219  CriticalSectionScoped cs(crit_sect_);
220  return jitter_buffer_.nack_mode();
221}
222
223std::vector<uint16_t> VCMReceiver::NackList(bool* request_key_frame) {
224  return jitter_buffer_.GetNackList(request_key_frame);
225}
226
227void VCMReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) {
228  jitter_buffer_.SetDecodeErrorMode(decode_error_mode);
229}
230
231VCMDecodeErrorMode VCMReceiver::DecodeErrorMode() const {
232  return jitter_buffer_.decode_error_mode();
233}
234
235int VCMReceiver::SetMinReceiverDelay(int desired_delay_ms) {
236  CriticalSectionScoped cs(crit_sect_);
237  if (desired_delay_ms < 0 || desired_delay_ms > kMaxReceiverDelayMs) {
238    return -1;
239  }
240  max_video_delay_ms_ = desired_delay_ms + kMaxVideoDelayMs;
241  // Initializing timing to the desired delay.
242  timing_->set_min_playout_delay(desired_delay_ms);
243  return 0;
244}
245
246int VCMReceiver::RenderBufferSizeMs() {
247  uint32_t timestamp_start = 0u;
248  uint32_t timestamp_end = 0u;
249  // Render timestamps are computed just prior to decoding. Therefore this is
250  // only an estimate based on frames' timestamps and current timing state.
251  jitter_buffer_.RenderBufferSize(&timestamp_start, &timestamp_end);
252  if (timestamp_start == timestamp_end) {
253    return 0;
254  }
255  // Update timing.
256  const int64_t now_ms = clock_->TimeInMilliseconds();
257  timing_->SetJitterDelay(jitter_buffer_.EstimatedJitterMs());
258  // Get render timestamps.
259  uint32_t render_start = timing_->RenderTimeMs(timestamp_start, now_ms);
260  uint32_t render_end = timing_->RenderTimeMs(timestamp_end, now_ms);
261  return render_end - render_start;
262}
263
264void VCMReceiver::RegisterStatsCallback(
265    VCMReceiveStatisticsCallback* callback) {
266  jitter_buffer_.RegisterStatsCallback(callback);
267}
268
269}  // namespace webrtc
270