Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1498)

Side by Side Diff: webrtc/modules/video_coding/frame_buffer2.cc

Issue 2138873003: Wire up VCMTiming in FrameBuffer2. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/video_coding/frame_buffer2.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 24 matching lines...) Expand all
35 const FrameKey& f2) const { 35 const FrameKey& f2) const {
36 // first = picture id 36 // first = picture id
37 // second = spatial layer 37 // second = spatial layer
38 if (f1.first == f2.first) 38 if (f1.first == f2.first)
39 return f1.second < f2.second; 39 return f1.second < f2.second;
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 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 inter_frame_delay_(clock_->TimeInMilliseconds()),
50 newest_picture_id_(-1), 51 newest_picture_id_(-1),
51 stopped_(false) {} 52 stopped_(false) {}
52 53
53 std::unique_ptr<FrameObject> FrameBuffer::NextFrame(int64_t max_wait_time_ms) { 54 std::unique_ptr<FrameObject> FrameBuffer::NextFrame(int64_t max_wait_time_ms) {
54 int64_t latest_return_time = clock_->TimeInMilliseconds() + max_wait_time_ms; 55 int64_t latest_return_time = clock_->TimeInMilliseconds() + max_wait_time_ms;
55 int64_t now = clock_->TimeInMilliseconds(); 56 int64_t now = clock_->TimeInMilliseconds();
56 int64_t wait_ms = max_wait_time_ms; 57 int64_t wait_ms = max_wait_time_ms;
57 while (true) { 58 while (true) {
58 std::map<FrameKey, std::unique_ptr<FrameObject>, FrameComp>::iterator 59 std::map<FrameKey, std::unique_ptr<FrameObject>, FrameComp>::iterator
59 next_frame; 60 next_frame_it;
60 { 61 {
61 rtc::CritScope lock(&crit_); 62 rtc::CritScope lock(&crit_);
62 frame_inserted_event_.Reset(); 63 frame_inserted_event_.Reset();
63 if (stopped_) 64 if (stopped_)
64 return std::unique_ptr<FrameObject>(); 65 return std::unique_ptr<FrameObject>();
65 66
66 now = clock_->TimeInMilliseconds(); 67 now = clock_->TimeInMilliseconds();
67 wait_ms = max_wait_time_ms; 68 wait_ms = max_wait_time_ms;
68 next_frame = frames_.end(); 69 next_frame_it = frames_.end();
69 for (auto frame_it = frames_.begin(); frame_it != frames_.end(); 70 for (auto frame_it = frames_.begin(); frame_it != frames_.end();
70 ++frame_it) { 71 ++frame_it) {
71 const FrameObject& frame = *frame_it->second; 72 const FrameObject& frame = *frame_it->second;
72 if (IsContinuous(frame)) { 73 if (IsContinuous(frame)) {
73 next_frame = frame_it; 74 next_frame_it = frame_it;
74 int64_t render_time = timing_->RenderTimeMs(frame.timestamp, now); 75 int64_t render_time =
76 next_frame_it->second->RenderTime() == -1
77 ? timing_->RenderTimeMs(frame.timestamp, now)
78 : next_frame_it->second->RenderTime();
75 wait_ms = timing_->MaxWaitingTime(render_time, now); 79 wait_ms = timing_->MaxWaitingTime(render_time, now);
80 frame_it->second->SetRenderTime(render_time);
76 81
77 // This will cause the frame buffer to prefer high framerate rather 82 // This will cause the frame buffer to prefer high framerate rather
78 // than high resolution in the case of the decoder not decoding fast 83 // than high resolution in the case of the decoder not decoding fast
79 // enough and the stream has multiple spatial and temporal layers. 84 // enough and the stream has multiple spatial and temporal layers.
80 if (wait_ms == 0) 85 if (wait_ms == 0)
81 continue; 86 continue;
82 87
83 break; 88 break;
84 } 89 }
85 } 90 }
86 } 91 }
87 92
93 wait_ms = std::min<int64_t>(wait_ms, latest_return_time - now);
94 wait_ms = std::max<int64_t>(wait_ms, 0);
88 // If the timout occures, return. Otherwise a new frame has been inserted 95 // If the timout occures, return. Otherwise a new frame has been inserted
stefan-webrtc 2016/07/12 16:55:38 If the timeout occurs
philipel 2016/07/13 09:21:49 Done.
89 // and the best frame to decode next will be selected again. 96 // and the best frame to decode next will be selected again.
90 wait_ms = std::min<int64_t>(wait_ms, latest_return_time - now);
91 wait_ms = std::max<int64_t>(wait_ms, 0);
92 if (!frame_inserted_event_.Wait(wait_ms)) { 97 if (!frame_inserted_event_.Wait(wait_ms)) {
93 rtc::CritScope lock(&crit_); 98 rtc::CritScope lock(&crit_);
94 if (next_frame != frames_.end()) { 99 if (next_frame_it != frames_.end()) {
95 // TODO(philipel): update jitter estimator with correct values. 100 int64_t received_timestamp = next_frame_it->second->ReceivedTime();
96 jitter_estimator_->UpdateEstimate(100, 100); 101 uint32_t timestamp = next_frame_it->second->Timestamp();
97 102
98 decoded_frames_.insert(next_frame->first); 103 int64_t frame_delay;
99 std::unique_ptr<FrameObject> frame = std::move(next_frame->second); 104 if (inter_frame_delay_.CalculateDelay(timestamp, &frame_delay,
100 frames_.erase(frames_.begin(), ++next_frame); 105 received_timestamp)) {
106 jitter_estimator_->UpdateEstimate(frame_delay,
107 next_frame_it->second->size);
108 }
109 timing_->SetJitterDelay(jitter_estimator_->GetJitterEstimate(1.0));
110 timing_->UpdateCurrentDelay(next_frame_it->second->RenderTime(),
111 clock_->TimeInMilliseconds());
112
113 decoded_frames_.insert(next_frame_it->first);
114 std::unique_ptr<FrameObject> frame = std::move(next_frame_it->second);
115 frames_.erase(frames_.begin(), ++next_frame_it);
101 return frame; 116 return frame;
stefan-webrtc 2016/07/12 16:55:39 Should we update the render time of this frame bef
philipel 2016/07/13 09:21:49 It could? If that's the case then it's going to be
stefan-webrtc 2016/07/14 12:17:30 It can since the inter arrival class might have up
philipel 2016/07/14 15:39:39 Yes and no. That part of the code only waits for a
102 } else { 117 } else {
103 return std::unique_ptr<FrameObject>(); 118 return std::unique_ptr<FrameObject>();
104 } 119 }
105 } 120 }
106 } 121 }
107 } 122 }
108 123
109 void FrameBuffer::Start() { 124 void FrameBuffer::Start() {
110 rtc::CritScope lock(&crit_); 125 rtc::CritScope lock(&crit_);
111 stopped_ = false; 126 stopped_ = false;
112 } 127 }
113 128
114 void FrameBuffer::Stop() { 129 void FrameBuffer::Stop() {
115 rtc::CritScope lock(&crit_); 130 rtc::CritScope lock(&crit_);
116 stopped_ = true; 131 stopped_ = true;
117 frame_inserted_event_.Set(); 132 frame_inserted_event_.Set();
118 } 133 }
119 134
120 void FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { 135 void FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) {
121 rtc::CritScope lock(&crit_); 136 rtc::CritScope lock(&crit_);
122 if (newest_picture_id_ == -1) 137 // If |newest_picture_id_ is -1 then this is the first frame we received.
stefan-webrtc 2016/07/12 16:55:38 |newest_picture_id_|
philipel 2016/07/13 09:21:49 Done.
138 if (newest_picture_id_ == -1) {
123 newest_picture_id_ = frame->picture_id; 139 newest_picture_id_ = frame->picture_id;
140 inter_frame_delay_.Reset(clock_->TimeInMilliseconds());
141 }
124 142
125 if (AheadOf<uint16_t>(frame->picture_id, newest_picture_id_)) 143 if (AheadOf<uint16_t>(frame->picture_id, newest_picture_id_))
126 newest_picture_id_ = frame->picture_id; 144 newest_picture_id_ = frame->picture_id;
127 145
128 // Remove frames as long as we have too many, |kMaxNumHistoryFrames|. 146 // Remove frames as long as we have too many, |kMaxNumHistoryFrames|.
129 while (decoded_frames_.size() > kMaxNumHistoryFrames) 147 while (decoded_frames_.size() > kMaxNumHistoryFrames)
130 decoded_frames_.erase(decoded_frames_.begin()); 148 decoded_frames_.erase(decoded_frames_.begin());
131 149
132 // Remove frames that are too old, |kMaxNumHistoryFrames|. 150 // Remove frames that are too old.
133 uint16_t old_picture_id = Subtract<1 << 16>(newest_picture_id_, kMaxFrameAge); 151 uint16_t old_picture_id = Subtract<1 << 16>(newest_picture_id_, kMaxFrameAge);
134 auto old_decoded_it = 152 auto old_decoded_it =
135 decoded_frames_.lower_bound(FrameKey(old_picture_id, 0)); 153 decoded_frames_.lower_bound(FrameKey(old_picture_id, 0));
136 decoded_frames_.erase(decoded_frames_.begin(), old_decoded_it); 154 decoded_frames_.erase(decoded_frames_.begin(), old_decoded_it);
137 155
138 FrameKey key(frame->picture_id, frame->spatial_layer); 156 FrameKey key(frame->picture_id, frame->spatial_layer);
139 frames_[key] = std::move(frame); 157 frames_[key] = std::move(frame);
140 frame_inserted_event_.Set(); 158 frame_inserted_event_.Set();
141 } 159 }
142 160
(...skipping 19 matching lines...) Expand all
162 FrameKey ref_key(frame.picture_id, frame.spatial_layer - 1); 180 FrameKey ref_key(frame.picture_id, frame.spatial_layer - 1);
163 if (decoded_frames_.find(ref_key) == decoded_frames_.end()) 181 if (decoded_frames_.find(ref_key) == decoded_frames_.end())
164 return false; 182 return false;
165 } 183 }
166 184
167 return true; 185 return true;
168 } 186 }
169 187
170 } // namespace video_coding 188 } // namespace video_coding
171 } // namespace webrtc 189 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/frame_buffer2.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698