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 |