Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 if (inter_frame_delay_.CalculateDelay(frame->timestamp, &frame_delay, | 134 if (inter_frame_delay_.CalculateDelay(frame->timestamp, &frame_delay, |
| 135 frame->ReceivedTime())) { | 135 frame->ReceivedTime())) { |
| 136 jitter_estimator_->UpdateEstimate(frame_delay, frame->size()); | 136 jitter_estimator_->UpdateEstimate(frame_delay, frame->size()); |
| 137 } | 137 } |
| 138 | 138 |
| 139 float rtt_mult = protection_mode_ == kProtectionNackFEC ? 0.0 : 1.0; | 139 float rtt_mult = protection_mode_ == kProtectionNackFEC ? 0.0 : 1.0; |
| 140 timing_->SetJitterDelay(jitter_estimator_->GetJitterEstimate(rtt_mult)); | 140 timing_->SetJitterDelay(jitter_estimator_->GetJitterEstimate(rtt_mult)); |
| 141 timing_->UpdateCurrentDelay(frame->RenderTime(), now_ms); | 141 timing_->UpdateCurrentDelay(frame->RenderTime(), now_ms); |
| 142 } | 142 } |
| 143 | 143 |
| 144 // Gracefully handle bad RTP timestamps and render time issues. | |
| 145 if (HasBadRenderTiming(*frame, now_ms)) { | |
| 146 jitter_estimator_->Reset(); | |
| 147 timing_->Reset(); | |
| 148 frame->SetRenderTime(timing_->RenderTimeMs(frame->timestamp, now_ms)); | |
| 149 } | |
| 150 | |
| 144 UpdateJitterDelay(); | 151 UpdateJitterDelay(); |
| 145 PropagateDecodability(next_frame_it_->second); | 152 PropagateDecodability(next_frame_it_->second); |
| 146 | 153 |
| 147 // Sanity check for RTP timestamp monotonicity. | 154 // Sanity check for RTP timestamp monotonicity. |
| 148 if (last_decoded_frame_it_ != frames_.end()) { | 155 if (last_decoded_frame_it_ != frames_.end()) { |
| 149 const FrameKey& last_decoded_frame_key = last_decoded_frame_it_->first; | 156 const FrameKey& last_decoded_frame_key = last_decoded_frame_it_->first; |
| 150 const FrameKey& frame_key = next_frame_it_->first; | 157 const FrameKey& frame_key = next_frame_it_->first; |
| 151 | 158 |
| 152 const bool frame_is_higher_spatial_layer_of_last_decoded_frame = | 159 const bool frame_is_higher_spatial_layer_of_last_decoded_frame = |
| 153 last_decoded_frame_timestamp_ == frame->timestamp && | 160 last_decoded_frame_timestamp_ == frame->timestamp && |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 182 // If |next_frame_it_ == frames_.end()| and there is still time left, it | 189 // If |next_frame_it_ == frames_.end()| and there is still time left, it |
| 183 // means that the frame buffer was cleared as the thread in this function | 190 // means that the frame buffer was cleared as the thread in this function |
| 184 // was waiting to acquire |crit_| in order to return. Wait for the | 191 // was waiting to acquire |crit_| in order to return. Wait for the |
| 185 // remaining time and then return. | 192 // remaining time and then return. |
| 186 return NextFrame(latest_return_time_ms - now_ms, frame_out); | 193 return NextFrame(latest_return_time_ms - now_ms, frame_out); |
| 187 } | 194 } |
| 188 | 195 |
| 189 return kTimeout; | 196 return kTimeout; |
| 190 } | 197 } |
| 191 | 198 |
| 199 bool FrameBuffer::HasBadRenderTiming(const FrameObject& frame, int64_t now_ms) { | |
| 200 // Assume that render timing errors are due to changes in the video stream. | |
| 201 int64_t render_time_ms = frame.RenderTimeMs(); | |
| 202 const int64_t kMaxVideoDelayMs = 10000; | |
| 203 if (render_time_ms < 0) { | |
| 204 return true; | |
| 205 } else if (std::abs(render_time_ms - now_ms) > kMaxVideoDelayMs) { | |
|
philipel
2017/05/23 16:11:48
Now we don't need the "else if" any more :)
stefan-webrtc
2017/05/23 16:33:43
Done.
| |
| 206 int frame_delay = static_cast<int>(std::abs(render_time_ms - now_ms)); | |
| 207 LOG(LS_WARNING) << "A frame about to be decoded is out of the configured " | |
| 208 << "delay bounds (" << frame_delay << " > " | |
| 209 << kMaxVideoDelayMs | |
| 210 << "). Resetting the video jitter buffer."; | |
| 211 return true; | |
| 212 } else if (static_cast<int>(timing_->TargetVideoDelay()) > kMaxVideoDelayMs) { | |
|
philipel
2017/05/23 16:11:48
same here
stefan-webrtc
2017/05/23 16:33:42
Done.
| |
| 213 LOG(LS_WARNING) << "The video target delay has grown larger than " | |
| 214 << kMaxVideoDelayMs << " ms."; | |
| 215 return true; | |
| 216 } | |
| 217 return false; | |
| 218 } | |
| 219 | |
| 192 void FrameBuffer::SetProtectionMode(VCMVideoProtection mode) { | 220 void FrameBuffer::SetProtectionMode(VCMVideoProtection mode) { |
| 193 TRACE_EVENT0("webrtc", "FrameBuffer::SetProtectionMode"); | 221 TRACE_EVENT0("webrtc", "FrameBuffer::SetProtectionMode"); |
| 194 rtc::CritScope lock(&crit_); | 222 rtc::CritScope lock(&crit_); |
| 195 protection_mode_ = mode; | 223 protection_mode_ = mode; |
| 196 } | 224 } |
| 197 | 225 |
| 198 void FrameBuffer::Start() { | 226 void FrameBuffer::Start() { |
| 199 TRACE_EVENT0("webrtc", "FrameBuffer::Start"); | 227 TRACE_EVENT0("webrtc", "FrameBuffer::Start"); |
| 200 rtc::CritScope lock(&crit_); | 228 rtc::CritScope lock(&crit_); |
| 201 stopped_ = false; | 229 stopped_ = false; |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 489 frames_.clear(); | 517 frames_.clear(); |
| 490 last_decoded_frame_it_ = frames_.end(); | 518 last_decoded_frame_it_ = frames_.end(); |
| 491 last_continuous_frame_it_ = frames_.end(); | 519 last_continuous_frame_it_ = frames_.end(); |
| 492 next_frame_it_ = frames_.end(); | 520 next_frame_it_ = frames_.end(); |
| 493 num_frames_history_ = 0; | 521 num_frames_history_ = 0; |
| 494 num_frames_buffered_ = 0; | 522 num_frames_buffered_ = 0; |
| 495 } | 523 } |
| 496 | 524 |
| 497 } // namespace video_coding | 525 } // namespace video_coding |
| 498 } // namespace webrtc | 526 } // namespace webrtc |
| OLD | NEW |