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