| 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 timing_->set_min_playout_delay(playout_delay.min_ms); | 270 timing_->set_min_playout_delay(playout_delay.min_ms); |
| 266 | 271 |
| 267 if (playout_delay.max_ms >= 0) | 272 if (playout_delay.max_ms >= 0) |
| 268 timing_->set_max_playout_delay(playout_delay.max_ms); | 273 timing_->set_max_playout_delay(playout_delay.max_ms); |
| 269 } | 274 } |
| 270 | 275 |
| 271 int FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { | 276 int FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { |
| 272 TRACE_EVENT0("webrtc", "FrameBuffer::InsertFrame"); | 277 TRACE_EVENT0("webrtc", "FrameBuffer::InsertFrame"); |
| 273 RTC_DCHECK(frame); | 278 RTC_DCHECK(frame); |
| 274 if (stats_callback_) | 279 if (stats_callback_) |
| 275 stats_callback_->OnCompleteFrame(frame->num_references == 0, frame->size()); | 280 stats_callback_->OnCompleteFrame(frame->is_keyframe(), frame->size()); |
| 276 FrameKey key(frame->picture_id, frame->spatial_layer); | 281 FrameKey key(frame->picture_id, frame->spatial_layer); |
| 277 | 282 |
| 278 rtc::CritScope lock(&crit_); | 283 rtc::CritScope lock(&crit_); |
| 279 | 284 |
| 280 int last_continuous_picture_id = | 285 int last_continuous_picture_id = |
| 281 last_continuous_frame_it_ == frames_.end() | 286 last_continuous_frame_it_ == frames_.end() |
| 282 ? -1 | 287 ? -1 |
| 283 : last_continuous_frame_it_->first.picture_id; | 288 : last_continuous_frame_it_->first.picture_id; |
| 284 | 289 |
| 285 if (!ValidReferences(*frame)) { | 290 if (!ValidReferences(*frame)) { |
| 286 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id | 291 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id |
| 287 << ":" << static_cast<int>(key.spatial_layer) | 292 << ":" << static_cast<int>(key.spatial_layer) |
| 288 << ") has invalid frame references, dropping frame."; | 293 << ") has invalid frame references, dropping frame."; |
| 289 return last_continuous_picture_id; | 294 return last_continuous_picture_id; |
| 290 } | 295 } |
| 291 | 296 |
| 292 if (num_frames_buffered_ >= kMaxFramesBuffered) { | 297 if (num_frames_buffered_ >= kMaxFramesBuffered) { |
| 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 << ") could not be inserted due to the frame " | 300 << ") could not be inserted due to the frame " |
| 296 << "buffer being full, dropping frame."; | 301 << "buffer being full, dropping frame."; |
| 297 return last_continuous_picture_id; | 302 return last_continuous_picture_id; |
| 298 } | 303 } |
| 299 | 304 |
| 300 if (last_decoded_frame_it_ != frames_.end() && | 305 if (last_decoded_frame_it_ != frames_.end() && |
| 301 key <= last_decoded_frame_it_->first) { | 306 key <= last_decoded_frame_it_->first) { |
| 302 if (AheadOf(frame->timestamp, last_decoded_frame_timestamp_) && | 307 if (AheadOf(frame->timestamp, last_decoded_frame_timestamp_) && |
| 303 frame->num_references == 0) { | 308 frame->is_keyframe()) { |
| 304 // If this frame has a newer timestamp but an earlier picture id then we | 309 // If this frame has a newer timestamp but an earlier picture id then we |
| 305 // assume there has been a jump in the picture id due to some encoder | 310 // assume there has been a jump in the picture id due to some encoder |
| 306 // reconfiguration or some other reason. Even though this is not according | 311 // reconfiguration or some other reason. Even though this is not according |
| 307 // to spec we can still continue to decode from this frame if it is a | 312 // to spec we can still continue to decode from this frame if it is a |
| 308 // keyframe. | 313 // keyframe. |
| 309 LOG(LS_WARNING) << "A jump in picture id was detected, clearing buffer."; | 314 LOG(LS_WARNING) << "A jump in picture id was detected, clearing buffer."; |
| 310 ClearFramesAndHistory(); | 315 ClearFramesAndHistory(); |
| 311 last_continuous_picture_id = -1; | 316 last_continuous_picture_id = -1; |
| 312 } else { | 317 } else { |
| 313 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" | 318 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 frames_.clear(); | 559 frames_.clear(); |
| 555 last_decoded_frame_it_ = frames_.end(); | 560 last_decoded_frame_it_ = frames_.end(); |
| 556 last_continuous_frame_it_ = frames_.end(); | 561 last_continuous_frame_it_ = frames_.end(); |
| 557 next_frame_it_ = frames_.end(); | 562 next_frame_it_ = frames_.end(); |
| 558 num_frames_history_ = 0; | 563 num_frames_history_ = 0; |
| 559 num_frames_buffered_ = 0; | 564 num_frames_buffered_ = 0; |
| 560 } | 565 } |
| 561 | 566 |
| 562 } // namespace video_coding | 567 } // namespace video_coding |
| 563 } // namespace webrtc | 568 } // namespace webrtc |
| OLD | NEW |