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 29 matching lines...) Expand all Loading... |
40 return AheadOf(f2.first, f1.first); | 40 return AheadOf(f2.first, f1.first); |
41 } | 41 } |
42 | 42 |
43 FrameBuffer::FrameBuffer(Clock* clock, | 43 FrameBuffer::FrameBuffer(Clock* clock, |
44 VCMJitterEstimator* jitter_estimator, | 44 VCMJitterEstimator* jitter_estimator, |
45 const VCMTiming* timing) | 45 const VCMTiming* timing) |
46 : clock_(clock), | 46 : clock_(clock), |
47 frame_inserted_event_(false, false), | 47 frame_inserted_event_(false, false), |
48 jitter_estimator_(jitter_estimator), | 48 jitter_estimator_(jitter_estimator), |
49 timing_(timing), | 49 timing_(timing), |
50 newest_picture_id_(-1) {} | 50 newest_picture_id_(-1), |
| 51 stopped_(false) {} |
51 | 52 |
52 std::unique_ptr<FrameObject> FrameBuffer::NextFrame(int64_t max_wait_time_ms) { | 53 std::unique_ptr<FrameObject> FrameBuffer::NextFrame(int64_t max_wait_time_ms) { |
53 int64_t latest_return_time = clock_->TimeInMilliseconds() + max_wait_time_ms; | 54 int64_t latest_return_time = clock_->TimeInMilliseconds() + max_wait_time_ms; |
| 55 int64_t now = clock_->TimeInMilliseconds(); |
| 56 int64_t wait_ms = max_wait_time_ms; |
54 while (true) { | 57 while (true) { |
55 int64_t now = clock_->TimeInMilliseconds(); | 58 std::map<FrameKey, std::unique_ptr<FrameObject>, FrameComp>::iterator |
56 int64_t wait_ms = max_wait_time_ms; | 59 next_frame; |
| 60 { |
| 61 rtc::CritScope lock(&crit_); |
| 62 frame_inserted_event_.Reset(); |
| 63 if (stopped_) |
| 64 return std::unique_ptr<FrameObject>(); |
57 | 65 |
58 crit_.Enter(); | 66 now = clock_->TimeInMilliseconds(); |
59 frame_inserted_event_.Reset(); | 67 wait_ms = max_wait_time_ms; |
60 auto next_frame = frames_.end(); | 68 next_frame = frames_.end(); |
61 for (auto frame_it = frames_.begin(); frame_it != frames_.end(); | 69 for (auto frame_it = frames_.begin(); frame_it != frames_.end(); |
62 ++frame_it) { | 70 ++frame_it) { |
63 const FrameObject& frame = *frame_it->second; | 71 const FrameObject& frame = *frame_it->second; |
64 if (IsContinuous(frame)) { | 72 if (IsContinuous(frame)) { |
65 next_frame = frame_it; | 73 next_frame = frame_it; |
66 int64_t render_time = timing_->RenderTimeMs(frame.timestamp, now); | 74 int64_t render_time = timing_->RenderTimeMs(frame.timestamp, now); |
67 wait_ms = timing_->MaxWaitingTime(render_time, now); | 75 wait_ms = timing_->MaxWaitingTime(render_time, now); |
68 | 76 |
69 // This will cause the frame buffer to prefer high framerate rather | 77 // This will cause the frame buffer to prefer high framerate rather |
70 // than high resolution in the case of the decoder not decoding fast | 78 // than high resolution in the case of the decoder not decoding fast |
71 // enough and the stream has multiple spatial and temporal layers. | 79 // enough and the stream has multiple spatial and temporal layers. |
72 if (wait_ms == 0) | 80 if (wait_ms == 0) |
73 continue; | 81 continue; |
74 | 82 |
75 break; | 83 break; |
| 84 } |
76 } | 85 } |
77 } | 86 } |
78 crit_.Leave(); | |
79 | 87 |
80 // If the timout occures, return. Otherwise a new frame has been inserted | 88 // If the timout occures, return. Otherwise a new frame has been inserted |
81 // and the best frame to decode next will be selected again. | 89 // and the best frame to decode next will be selected again. |
82 wait_ms = std::min<int64_t>(wait_ms, latest_return_time - now); | 90 wait_ms = std::min<int64_t>(wait_ms, latest_return_time - now); |
83 wait_ms = std::max<int64_t>(wait_ms, 0); | 91 wait_ms = std::max<int64_t>(wait_ms, 0); |
84 if (!frame_inserted_event_.Wait(wait_ms)) { | 92 if (!frame_inserted_event_.Wait(wait_ms)) { |
85 crit_.Enter(); | 93 rtc::CritScope lock(&crit_); |
86 if (next_frame != frames_.end()) { | 94 if (next_frame != frames_.end()) { |
87 // TODO(philipel): update jitter estimator with correct values. | 95 // TODO(philipel): update jitter estimator with correct values. |
88 jitter_estimator_->UpdateEstimate(100, 100); | 96 jitter_estimator_->UpdateEstimate(100, 100); |
89 | 97 |
90 decoded_frames_.insert(next_frame->first); | 98 decoded_frames_.insert(next_frame->first); |
91 std::unique_ptr<FrameObject> frame = std::move(next_frame->second); | 99 std::unique_ptr<FrameObject> frame = std::move(next_frame->second); |
92 frames_.erase(frames_.begin(), ++next_frame); | 100 frames_.erase(frames_.begin(), ++next_frame); |
93 crit_.Leave(); | |
94 return frame; | 101 return frame; |
95 } else { | 102 } else { |
96 crit_.Leave(); | |
97 return std::unique_ptr<FrameObject>(); | 103 return std::unique_ptr<FrameObject>(); |
98 } | 104 } |
99 } | 105 } |
100 } | 106 } |
101 } | 107 } |
102 | 108 |
| 109 void FrameBuffer::Start() { |
| 110 rtc::CritScope lock(&crit_); |
| 111 stopped_ = false; |
| 112 } |
| 113 |
| 114 void FrameBuffer::Stop() { |
| 115 rtc::CritScope lock(&crit_); |
| 116 stopped_ = true; |
| 117 frame_inserted_event_.Set(); |
| 118 } |
| 119 |
103 void FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { | 120 void FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { |
104 rtc::CritScope lock(&crit_); | 121 rtc::CritScope lock(&crit_); |
105 if (newest_picture_id_ == -1) | 122 if (newest_picture_id_ == -1) |
106 newest_picture_id_ = frame->picture_id; | 123 newest_picture_id_ = frame->picture_id; |
107 | 124 |
108 if (AheadOf<uint16_t>(frame->picture_id, newest_picture_id_)) | 125 if (AheadOf<uint16_t>(frame->picture_id, newest_picture_id_)) |
109 newest_picture_id_ = frame->picture_id; | 126 newest_picture_id_ = frame->picture_id; |
110 | 127 |
111 // Remove frames as long as we have too many, |kMaxNumHistoryFrames|. | 128 // Remove frames as long as we have too many, |kMaxNumHistoryFrames|. |
112 while (decoded_frames_.size() > kMaxNumHistoryFrames) | 129 while (decoded_frames_.size() > kMaxNumHistoryFrames) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 FrameKey ref_key(frame.picture_id, frame.spatial_layer - 1); | 162 FrameKey ref_key(frame.picture_id, frame.spatial_layer - 1); |
146 if (decoded_frames_.find(ref_key) == decoded_frames_.end()) | 163 if (decoded_frames_.find(ref_key) == decoded_frames_.end()) |
147 return false; | 164 return false; |
148 } | 165 } |
149 | 166 |
150 return true; | 167 return true; |
151 } | 168 } |
152 | 169 |
153 } // namespace video_coding | 170 } // namespace video_coding |
154 } // namespace webrtc | 171 } // namespace webrtc |
OLD | NEW |