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

Side by Side Diff: webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc

Issue 2924993002: Move temporal-layer properties to FrameConfig. (Closed)
Patch Set: remove timestamp check, input frame doesn't repeat Created 3 years, 6 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
OLDNEW
1 /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 1 /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
2 * 2 *
3 * Use of this source code is governed by a BSD-style license 3 * Use of this source code is governed by a BSD-style license
4 * that can be found in the LICENSE file in the root of the source 4 * that can be found in the LICENSE file in the root of the source
5 * tree. An additional intellectual property rights grant can be found 5 * tree. An additional intellectual property rights grant can be found
6 * in the file PATENTS. All contributing project authors may 6 * in the file PATENTS. All contributing project authors may
7 * be found in the AUTHORS file in the root of the source tree. 7 * be found in the AUTHORS file in the root of the source tree.
8 */ 8 */
9 9
10 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" 10 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 encode_framerate_(1000.0f, 1000.0f), // 1 second window, second scale. 72 encode_framerate_(1000.0f, 1000.0f), // 1 second window, second scale.
73 bitrate_updated_(false) { 73 bitrate_updated_(false) {
74 RTC_CHECK_GT(number_of_temporal_layers_, 0); 74 RTC_CHECK_GT(number_of_temporal_layers_, 0);
75 RTC_CHECK_LE(number_of_temporal_layers_, kMaxNumTemporalLayers); 75 RTC_CHECK_LE(number_of_temporal_layers_, kMaxNumTemporalLayers);
76 } 76 }
77 77
78 ScreenshareLayers::~ScreenshareLayers() { 78 ScreenshareLayers::~ScreenshareLayers() {
79 UpdateHistograms(); 79 UpdateHistograms();
80 } 80 }
81 81
82 int ScreenshareLayers::GetTemporalLayerId(
83 const TemporalLayers::FrameConfig& tl_config) const {
84 // Codec does not use temporal layers for screenshare.
85 return 0;
86 }
87
88 uint8_t ScreenshareLayers::Tl0PicIdx() const { 82 uint8_t ScreenshareLayers::Tl0PicIdx() const {
89 return tl0_pic_idx_; 83 return tl0_pic_idx_;
90 } 84 }
91 85
92 TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig( 86 TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig(
93 uint32_t timestamp) { 87 uint32_t timestamp) {
94 if (number_of_temporal_layers_ <= 1) { 88 if (number_of_temporal_layers_ <= 1) {
95 // No flags needed for 1 layer screenshare. 89 // No flags needed for 1 layer screenshare.
96 // TODO(pbos): Consider updating only last, and not all buffers. 90 // TODO(pbos): Consider updating only last, and not all buffers.
97 TemporalLayers::FrameConfig tl_config( 91 TemporalLayers::FrameConfig tl_config(
98 kReferenceAndUpdate, kReferenceAndUpdate, kReferenceAndUpdate); 92 kReferenceAndUpdate, kReferenceAndUpdate, kReferenceAndUpdate);
99 tl_config.pattern_idx = static_cast<int>(TemporalLayerState::kTl1);
100 return tl_config; 93 return tl_config;
101 } 94 }
102 95
103 const int64_t now_ms = clock_->TimeInMilliseconds(); 96 const int64_t now_ms = clock_->TimeInMilliseconds();
104 if (target_framerate_.value_or(0) > 0 && 97 if (target_framerate_.value_or(0) > 0 &&
105 encode_framerate_.Rate(now_ms).value_or(0) > *target_framerate_) { 98 encode_framerate_.Rate(now_ms).value_or(0) > *target_framerate_) {
106 // Max framerate exceeded, drop frame. 99 // Max framerate exceeded, drop frame.
107 return TemporalLayers::FrameConfig(kNone, kNone, kNone); 100 return TemporalLayers::FrameConfig(kNone, kNone, kNone);
108 } 101 }
109 102
110 if (stats_.first_frame_time_ms_ == -1) 103 if (stats_.first_frame_time_ms_ == -1)
111 stats_.first_frame_time_ms_ = now_ms; 104 stats_.first_frame_time_ms_ = now_ms;
112 105
113 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); 106 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp);
114 int64_t ts_diff; 107 int64_t ts_diff;
115 if (last_timestamp_ == -1) { 108 if (last_timestamp_ == -1) {
116 ts_diff = kOneSecond90Khz / capture_framerate_.value_or(*target_framerate_); 109 ts_diff = kOneSecond90Khz / capture_framerate_.value_or(*target_framerate_);
117 } else { 110 } else {
118 ts_diff = unwrapped_timestamp - last_timestamp_; 111 ts_diff = unwrapped_timestamp - last_timestamp_;
119 } 112 }
120 // Make sure both frame droppers leak out bits. 113 // Make sure both frame droppers leak out bits.
121 layers_[0].UpdateDebt(ts_diff / 90); 114 layers_[0].UpdateDebt(ts_diff / 90);
122 layers_[1].UpdateDebt(ts_diff / 90); 115 layers_[1].UpdateDebt(ts_diff / 90);
123 last_timestamp_ = timestamp; 116 last_timestamp_ = timestamp;
124 117
125 TemporalLayerState layer_state = TemporalLayerState::kDrop; 118 TemporalLayerState layer_state =
119 TemporalLayerState::kDrop;
brandtr 2017/06/12 15:15:53 revert?
pbos-webrtc 2017/06/15 21:59:09 Done.
126 120
127 if (active_layer_ == -1 || 121 if (active_layer_ == -1 ||
128 layers_[active_layer_].state != TemporalLayer::State::kDropped) { 122 layers_[active_layer_].state != TemporalLayer::State::kDropped) {
129 if (last_emitted_tl0_timestamp_ != -1 && 123 if (last_emitted_tl0_timestamp_ != -1 &&
130 (unwrapped_timestamp - last_emitted_tl0_timestamp_) / 90 > 124 (unwrapped_timestamp - last_emitted_tl0_timestamp_) / 90 >
131 kMaxFrameIntervalMs) { 125 kMaxFrameIntervalMs) {
132 // Too long time has passed since the last frame was emitted, cancel 126 // Too long time has passed since the last frame was emitted, cancel
133 // enough debt to allow a single frame. 127 // enough debt to allow a single frame.
134 layers_[0].debt_bytes_ = max_debt_bytes_ - 1; 128 layers_[0].debt_bytes_ = max_debt_bytes_ - 1;
135 } 129 }
136 if (layers_[0].debt_bytes_ > max_debt_bytes_) { 130 if (layers_[0].debt_bytes_ > max_debt_bytes_) {
137 // Must drop TL0, encode TL1 instead. 131 // Must drop TL0, encode TL1 instead.
138 if (layers_[1].debt_bytes_ > max_debt_bytes_) { 132 if (layers_[1].debt_bytes_ > max_debt_bytes_) {
139 // Must drop both TL0 and TL1. 133 // Must drop both TL0 and TL1.
140 active_layer_ = -1; 134 active_layer_ = -1;
141 } else { 135 } else {
142 active_layer_ = 1; 136 active_layer_ = 1;
143 } 137 }
144 } else { 138 } else {
145 active_layer_ = 0; 139 active_layer_ = 0;
146 } 140 }
147 } 141 }
148 142
143 bool layer_sync = false;
149 switch (active_layer_) { 144 switch (active_layer_) {
150 case 0: 145 case 0:
151 layer_state = TemporalLayerState::kTl0; 146 layer_state = TemporalLayerState::kTl0;
152 last_emitted_tl0_timestamp_ = unwrapped_timestamp; 147 last_emitted_tl0_timestamp_ = unwrapped_timestamp;
153 break; 148 break;
154 case 1: 149 case 1:
155 if (TimeToSync(unwrapped_timestamp)) { 150 if (TimeToSync(unwrapped_timestamp)) {
151 layer_sync = true;
156 last_sync_timestamp_ = unwrapped_timestamp; 152 last_sync_timestamp_ = unwrapped_timestamp;
157 layer_state = TemporalLayerState::kTl1Sync; 153 layer_state = TemporalLayerState::kTl1Sync;
158 } else { 154 } else {
159 layer_state = TemporalLayerState::kTl1; 155 layer_state = TemporalLayerState::kTl1;
160 } 156 }
161 break; 157 break;
162 case -1: 158 case -1:
163 layer_state = TemporalLayerState::kDrop; 159 layer_state = TemporalLayerState::kDrop;
164 ++stats_.num_dropped_frames_; 160 ++stats_.num_dropped_frames_;
165 break; 161 break;
166 default: 162 default:
167 RTC_NOTREACHED(); 163 RTC_NOTREACHED();
168 } 164 }
169 165
170 TemporalLayers::FrameConfig tl_config; 166 TemporalLayers::FrameConfig tl_config;
171 // TODO(pbos): Consider referencing but not updating the 'alt' buffer for all 167 // TODO(pbos): Consider referencing but not updating the 'alt' buffer for all
172 // layers. 168 // layers.
173 switch (layer_state) { 169 switch (layer_state) {
174 case TemporalLayerState::kDrop: 170 case TemporalLayerState::kDrop:
175 tl_config = TemporalLayers::FrameConfig(kNone, kNone, kNone); 171 tl_config = TemporalLayers::FrameConfig(kNone, kNone, kNone);
176 break; 172 break;
177 case TemporalLayerState::kTl0: 173 case TemporalLayerState::kTl0:
178 // TL0 only references and updates 'last'. 174 // TL0 only references and updates 'last'.
179 tl_config = 175 tl_config =
180 TemporalLayers::FrameConfig(kReferenceAndUpdate, kNone, kNone); 176 TemporalLayers::FrameConfig(kReferenceAndUpdate, kNone, kNone);
brandtr 2017/06/12 15:15:53 Add tl_config.packetizer_temporal_idx = 0; explici
pbos-webrtc 2017/06/15 21:59:09 Done.
181 break; 177 break;
182 case TemporalLayerState::kTl1: 178 case TemporalLayerState::kTl1:
183 // TL1 references both 'last' and 'golden' but only updates 'golden'. 179 // TL1 references both 'last' and 'golden' but only updates 'golden'.
184 tl_config = 180 tl_config =
185 TemporalLayers::FrameConfig(kReference, kReferenceAndUpdate, kNone); 181 TemporalLayers::FrameConfig(kReference, kReferenceAndUpdate, kNone);
182 tl_config.packetizer_temporal_idx = 1;
186 break; 183 break;
187 case TemporalLayerState::kTl1Sync: 184 case TemporalLayerState::kTl1Sync:
188 // Predict from only TL0 to allow participants to switch to the high 185 // Predict from only TL0 to allow participants to switch to the high
189 // bitrate stream. Updates 'golden' so that TL1 can continue to refer to 186 // bitrate stream. Updates 'golden' so that TL1 can continue to refer to
190 // and update 'golden' from this point on. 187 // and update 'golden' from this point on.
191 tl_config = TemporalLayers::FrameConfig(kReference, kUpdate, kNone); 188 tl_config = TemporalLayers::FrameConfig(kReference, kUpdate, kNone);
189 tl_config.packetizer_temporal_idx = 1;
192 break; 190 break;
193 } 191 }
194 192
195 tl_config.pattern_idx = static_cast<int>(layer_state); 193 tl_config.layer_sync = layer_sync;
196 return tl_config; 194 return tl_config;
197 } 195 }
198 196
199 std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps, 197 std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps,
200 int max_bitrate_kbps, 198 int max_bitrate_kbps,
201 int framerate) { 199 int framerate) {
202 RTC_DCHECK_GT(framerate, 0); 200 RTC_DCHECK_GT(framerate, 0);
203 if (!target_framerate_) { 201 if (!target_framerate_) {
204 // First OnRatesUpdated() is called during construction, with the configured 202 // First OnRatesUpdated() is called during construction, with the configured
205 // targets as parameters. 203 // targets as parameters.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 stats_.tl1_target_bitrate_sum_ += layers_[1].target_rate_kbps_; 260 stats_.tl1_target_bitrate_sum_ += layers_[1].target_rate_kbps_;
263 stats_.tl1_qp_sum_ += qp; 261 stats_.tl1_qp_sum_ += qp;
264 } 262 }
265 } 263 }
266 264
267 void ScreenshareLayers::PopulateCodecSpecific( 265 void ScreenshareLayers::PopulateCodecSpecific(
268 bool frame_is_keyframe, 266 bool frame_is_keyframe,
269 const TemporalLayers::FrameConfig& tl_config, 267 const TemporalLayers::FrameConfig& tl_config,
270 CodecSpecificInfoVP8* vp8_info, 268 CodecSpecificInfoVP8* vp8_info,
271 uint32_t timestamp) { 269 uint32_t timestamp) {
272 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp);
273 if (number_of_temporal_layers_ == 1) { 270 if (number_of_temporal_layers_ == 1) {
274 vp8_info->temporalIdx = kNoTemporalIdx; 271 vp8_info->temporalIdx = kNoTemporalIdx;
275 vp8_info->layerSync = false; 272 vp8_info->layerSync = false;
276 vp8_info->tl0PicIdx = kNoTl0PicIdx; 273 vp8_info->tl0PicIdx = kNoTl0PicIdx;
277 } else { 274 } else {
278 TemporalLayerState layer_state = 275 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp);
279 static_cast<TemporalLayerState>(tl_config.pattern_idx); 276 vp8_info->temporalIdx = tl_config.packetizer_temporal_idx;
280 switch (layer_state) { 277 vp8_info->layerSync = tl_config.layer_sync;
281 case TemporalLayerState::kDrop:
282 RTC_NOTREACHED();
283 break;
284 case TemporalLayerState::kTl0:
285 vp8_info->temporalIdx = 0;
286 break;
287 case TemporalLayerState::kTl1:
288 case TemporalLayerState::kTl1Sync:
289 vp8_info->temporalIdx = 1;
290 break;
291 }
292 if (frame_is_keyframe) { 278 if (frame_is_keyframe) {
293 vp8_info->temporalIdx = 0; 279 vp8_info->temporalIdx = 0;
294 last_sync_timestamp_ = unwrapped_timestamp; 280 last_sync_timestamp_ = unwrapped_timestamp;
281 vp8_info->layerSync = true;
295 } else if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { 282 } else if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) {
296 // Regardless of pattern the frame after a base layer sync will always 283 // Regardless of pattern the frame after a base layer sync will always
297 // be a layer sync. 284 // be a layer sync.
298 last_sync_timestamp_ = unwrapped_timestamp; 285 last_sync_timestamp_ = unwrapped_timestamp;
286 vp8_info->layerSync = true;
299 } 287 }
300 vp8_info->layerSync = last_sync_timestamp_ != -1 &&
301 last_sync_timestamp_ == unwrapped_timestamp;
302 if (vp8_info->temporalIdx == 0) { 288 if (vp8_info->temporalIdx == 0) {
303 tl0_pic_idx_++; 289 tl0_pic_idx_++;
304 } 290 }
305 last_base_layer_sync_ = frame_is_keyframe; 291 last_base_layer_sync_ = frame_is_keyframe;
306 vp8_info->tl0PicIdx = tl0_pic_idx_; 292 vp8_info->tl0PicIdx = tl0_pic_idx_;
307 } 293 }
308 } 294 }
309 295
310 bool ScreenshareLayers::TimeToSync(int64_t timestamp) const { 296 bool ScreenshareLayers::TimeToSync(int64_t timestamp) const {
311 RTC_DCHECK_EQ(1, active_layer_); 297 RTC_DCHECK_EQ(1, active_layer_);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp", 446 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp",
461 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_); 447 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_);
462 RTC_HISTOGRAM_COUNTS_10000( 448 RTC_HISTOGRAM_COUNTS_10000(
463 "WebRTC.Video.Screenshare.Layer1.TargetBitrate", 449 "WebRTC.Video.Screenshare.Layer1.TargetBitrate",
464 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_); 450 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_);
465 } 451 }
466 } 452 }
467 } 453 }
468 454
469 } // namespace webrtc 455 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698