| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 num_frames_buffered_(0), | 52 num_frames_buffered_(0), |
| 53 stopped_(false), | 53 stopped_(false), |
| 54 protection_mode_(kProtectionNack), | 54 protection_mode_(kProtectionNack), |
| 55 stats_callback_(stats_callback), | 55 stats_callback_(stats_callback), |
| 56 last_log_non_decoded_ms_(-kLogNonDecodedIntervalMs) {} | 56 last_log_non_decoded_ms_(-kLogNonDecodedIntervalMs) {} |
| 57 | 57 |
| 58 FrameBuffer::~FrameBuffer() {} | 58 FrameBuffer::~FrameBuffer() {} |
| 59 | 59 |
| 60 FrameBuffer::ReturnReason FrameBuffer::NextFrame( | 60 FrameBuffer::ReturnReason FrameBuffer::NextFrame( |
| 61 int64_t max_wait_time_ms, | 61 int64_t max_wait_time_ms, |
| 62 std::unique_ptr<FrameObject>* frame_out, | 62 std::unique_ptr<FrameObject>* frame_out) { |
| 63 bool keyframe_required) { | |
| 64 TRACE_EVENT0("webrtc", "FrameBuffer::NextFrame"); | 63 TRACE_EVENT0("webrtc", "FrameBuffer::NextFrame"); |
| 65 int64_t latest_return_time_ms = | 64 int64_t latest_return_time_ms = |
| 66 clock_->TimeInMilliseconds() + max_wait_time_ms; | 65 clock_->TimeInMilliseconds() + max_wait_time_ms; |
| 67 int64_t wait_ms = max_wait_time_ms; | 66 int64_t wait_ms = max_wait_time_ms; |
| 68 int64_t now_ms = 0; | 67 int64_t now_ms = 0; |
| 69 | 68 |
| 70 do { | 69 do { |
| 71 now_ms = clock_->TimeInMilliseconds(); | 70 now_ms = clock_->TimeInMilliseconds(); |
| 72 { | 71 { |
| 73 rtc::CritScope lock(&crit_); | 72 rtc::CritScope lock(&crit_); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 99 ++continuous_end_it; | 98 ++continuous_end_it; |
| 100 | 99 |
| 101 for (; frame_it != continuous_end_it && frame_it != frames_.end(); | 100 for (; frame_it != continuous_end_it && frame_it != frames_.end(); |
| 102 ++frame_it) { | 101 ++frame_it) { |
| 103 if (!frame_it->second.continuous || | 102 if (!frame_it->second.continuous || |
| 104 frame_it->second.num_missing_decodable > 0) { | 103 frame_it->second.num_missing_decodable > 0) { |
| 105 continue; | 104 continue; |
| 106 } | 105 } |
| 107 | 106 |
| 108 FrameObject* frame = frame_it->second.frame.get(); | 107 FrameObject* frame = frame_it->second.frame.get(); |
| 109 | |
| 110 if (keyframe_required && !frame->is_keyframe()) | |
| 111 continue; | |
| 112 | |
| 113 next_frame_it_ = frame_it; | 108 next_frame_it_ = frame_it; |
| 114 if (frame->RenderTime() == -1) | 109 if (frame->RenderTime() == -1) |
| 115 frame->SetRenderTime(timing_->RenderTimeMs(frame->timestamp, now_ms)); | 110 frame->SetRenderTime(timing_->RenderTimeMs(frame->timestamp, now_ms)); |
| 116 wait_ms = timing_->MaxWaitingTime(frame->RenderTime(), now_ms); | 111 wait_ms = timing_->MaxWaitingTime(frame->RenderTime(), now_ms); |
| 117 | 112 |
| 118 // This will cause the frame buffer to prefer high framerate rather | 113 // This will cause the frame buffer to prefer high framerate rather |
| 119 // than high resolution in the case of the decoder not decoding fast | 114 // than high resolution in the case of the decoder not decoding fast |
| 120 // enough and the stream has multiple spatial and temporal layers. | 115 // enough and the stream has multiple spatial and temporal layers. |
| 121 if (wait_ms == 0) | 116 if (wait_ms == 0) |
| 122 continue; | 117 continue; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 timing_->set_min_playout_delay(playout_delay.min_ms); | 265 timing_->set_min_playout_delay(playout_delay.min_ms); |
| 271 | 266 |
| 272 if (playout_delay.max_ms >= 0) | 267 if (playout_delay.max_ms >= 0) |
| 273 timing_->set_max_playout_delay(playout_delay.max_ms); | 268 timing_->set_max_playout_delay(playout_delay.max_ms); |
| 274 } | 269 } |
| 275 | 270 |
| 276 int FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { | 271 int FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { |
| 277 TRACE_EVENT0("webrtc", "FrameBuffer::InsertFrame"); | 272 TRACE_EVENT0("webrtc", "FrameBuffer::InsertFrame"); |
| 278 RTC_DCHECK(frame); | 273 RTC_DCHECK(frame); |
| 279 if (stats_callback_) | 274 if (stats_callback_) |
| 280 stats_callback_->OnCompleteFrame(frame->is_keyframe(), frame->size()); | 275 stats_callback_->OnCompleteFrame(frame->num_references == 0, frame->size()); |
| 281 FrameKey key(frame->picture_id, frame->spatial_layer); | 276 FrameKey key(frame->picture_id, frame->spatial_layer); |
| 282 | 277 |
| 283 rtc::CritScope lock(&crit_); | 278 rtc::CritScope lock(&crit_); |
| 284 | 279 |
| 285 int last_continuous_picture_id = | 280 int last_continuous_picture_id = |
| 286 last_continuous_frame_it_ == frames_.end() | 281 last_continuous_frame_it_ == frames_.end() |
| 287 ? -1 | 282 ? -1 |
| 288 : last_continuous_frame_it_->first.picture_id; | 283 : last_continuous_frame_it_->first.picture_id; |
| 289 | 284 |
| 290 if (!ValidReferences(*frame)) { | 285 if (!ValidReferences(*frame)) { |
| 291 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id | 286 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id |
| 292 << ":" << static_cast<int>(key.spatial_layer) | 287 << ":" << static_cast<int>(key.spatial_layer) |
| 293 << ") has invalid frame references, dropping frame."; | 288 << ") has invalid frame references, dropping frame."; |
| 294 return last_continuous_picture_id; | 289 return last_continuous_picture_id; |
| 295 } | 290 } |
| 296 | 291 |
| 297 if (num_frames_buffered_ >= kMaxFramesBuffered) { | 292 if (num_frames_buffered_ >= kMaxFramesBuffered) { |
| 298 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id | 293 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id |
| 299 << ":" << static_cast<int>(key.spatial_layer) | 294 << ":" << static_cast<int>(key.spatial_layer) |
| 300 << ") could not be inserted due to the frame " | 295 << ") could not be inserted due to the frame " |
| 301 << "buffer being full, dropping frame."; | 296 << "buffer being full, dropping frame."; |
| 302 return last_continuous_picture_id; | 297 return last_continuous_picture_id; |
| 303 } | 298 } |
| 304 | 299 |
| 305 if (last_decoded_frame_it_ != frames_.end() && | 300 if (last_decoded_frame_it_ != frames_.end() && |
| 306 key <= last_decoded_frame_it_->first) { | 301 key <= last_decoded_frame_it_->first) { |
| 307 if (AheadOf(frame->timestamp, last_decoded_frame_timestamp_) && | 302 if (AheadOf(frame->timestamp, last_decoded_frame_timestamp_) && |
| 308 frame->is_keyframe()) { | 303 frame->num_references == 0) { |
| 309 // If this frame has a newer timestamp but an earlier picture id then we | 304 // If this frame has a newer timestamp but an earlier picture id then we |
| 310 // assume there has been a jump in the picture id due to some encoder | 305 // assume there has been a jump in the picture id due to some encoder |
| 311 // reconfiguration or some other reason. Even though this is not according | 306 // reconfiguration or some other reason. Even though this is not according |
| 312 // to spec we can still continue to decode from this frame if it is a | 307 // to spec we can still continue to decode from this frame if it is a |
| 313 // keyframe. | 308 // keyframe. |
| 314 LOG(LS_WARNING) << "A jump in picture id was detected, clearing buffer."; | 309 LOG(LS_WARNING) << "A jump in picture id was detected, clearing buffer."; |
| 315 ClearFramesAndHistory(); | 310 ClearFramesAndHistory(); |
| 316 last_continuous_picture_id = -1; | 311 last_continuous_picture_id = -1; |
| 317 } else { | 312 } else { |
| 318 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" | 313 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 frames_.clear(); | 554 frames_.clear(); |
| 560 last_decoded_frame_it_ = frames_.end(); | 555 last_decoded_frame_it_ = frames_.end(); |
| 561 last_continuous_frame_it_ = frames_.end(); | 556 last_continuous_frame_it_ = frames_.end(); |
| 562 next_frame_it_ = frames_.end(); | 557 next_frame_it_ = frames_.end(); |
| 563 num_frames_history_ = 0; | 558 num_frames_history_ = 0; |
| 564 num_frames_buffered_ = 0; | 559 num_frames_buffered_ = 0; |
| 565 } | 560 } |
| 566 | 561 |
| 567 } // namespace video_coding | 562 } // namespace video_coding |
| 568 } // namespace webrtc | 563 } // namespace webrtc |
| OLD | NEW |