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(×tamp_start, ×tamp_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