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 |