OLD | NEW |
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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 | 86 |
87 uint8_t ScreenshareLayers::Tl0PicIdx() const { | 87 uint8_t ScreenshareLayers::Tl0PicIdx() const { |
88 return tl0_pic_idx_; | 88 return tl0_pic_idx_; |
89 } | 89 } |
90 | 90 |
91 TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig( | 91 TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig( |
92 uint32_t timestamp) { | 92 uint32_t timestamp) { |
93 if (number_of_temporal_layers_ <= 1) { | 93 if (number_of_temporal_layers_ <= 1) { |
94 // No flags needed for 1 layer screenshare. | 94 // No flags needed for 1 layer screenshare. |
95 // TODO(pbos): Consider updating only last, and not all buffers. | 95 // TODO(pbos): Consider updating only last, and not all buffers. |
96 return TemporalLayers::FrameConfig(kReferenceAndUpdate, kReferenceAndUpdate, | 96 TemporalLayers::FrameConfig tl_config( |
97 kReferenceAndUpdate); | 97 kReferenceAndUpdate, kReferenceAndUpdate, kReferenceAndUpdate); |
| 98 tl_config.pattern_idx = static_cast<int>(kTl1); |
| 99 return tl_config; |
98 } | 100 } |
99 | 101 |
100 const int64_t now_ms = clock_->TimeInMilliseconds(); | 102 const int64_t now_ms = clock_->TimeInMilliseconds(); |
101 if (target_framerate_.value_or(0) > 0 && | 103 if (target_framerate_.value_or(0) > 0 && |
102 encode_framerate_.Rate(now_ms).value_or(0) > *target_framerate_) { | 104 encode_framerate_.Rate(now_ms).value_or(0) > *target_framerate_) { |
103 // Max framerate exceeded, drop frame. | 105 // Max framerate exceeded, drop frame. |
104 return TemporalLayers::FrameConfig(kNone, kNone, kNone); | 106 return TemporalLayers::FrameConfig(kNone, kNone, kNone); |
105 } | 107 } |
106 | 108 |
107 if (stats_.first_frame_time_ms_ == -1) | 109 if (stats_.first_frame_time_ms_ == -1) |
108 stats_.first_frame_time_ms_ = now_ms; | 110 stats_.first_frame_time_ms_ = now_ms; |
109 | 111 |
110 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); | 112 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); |
111 enum TemporalLayerState { kDrop, kTl0, kTl1, kTl1Sync }; | 113 TemporalLayerState layer_state = kDrop; |
112 enum TemporalLayerState layer_state = kDrop; | |
113 if (active_layer_ == -1 || | 114 if (active_layer_ == -1 || |
114 layers_[active_layer_].state != TemporalLayer::State::kDropped) { | 115 layers_[active_layer_].state != TemporalLayer::State::kDropped) { |
115 if (last_emitted_tl0_timestamp_ != -1 && | 116 if (last_emitted_tl0_timestamp_ != -1 && |
116 (unwrapped_timestamp - last_emitted_tl0_timestamp_) / 90 > | 117 (unwrapped_timestamp - last_emitted_tl0_timestamp_) / 90 > |
117 kMaxFrameIntervalMs) { | 118 kMaxFrameIntervalMs) { |
118 // Too long time has passed since the last frame was emitted, cancel | 119 // Too long time has passed since the last frame was emitted, cancel |
119 // enough debt to allow a single frame. | 120 // enough debt to allow a single frame. |
120 layers_[0].debt_bytes_ = max_debt_bytes_ - 1; | 121 layers_[0].debt_bytes_ = max_debt_bytes_ - 1; |
121 } | 122 } |
122 if (layers_[0].debt_bytes_ > max_debt_bytes_) { | 123 if (layers_[0].debt_bytes_ > max_debt_bytes_) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 int64_t ts_diff; | 157 int64_t ts_diff; |
157 if (last_timestamp_ == -1) { | 158 if (last_timestamp_ == -1) { |
158 ts_diff = kOneSecond90Khz / capture_framerate_.value_or(*target_framerate_); | 159 ts_diff = kOneSecond90Khz / capture_framerate_.value_or(*target_framerate_); |
159 } else { | 160 } else { |
160 ts_diff = unwrapped_timestamp - last_timestamp_; | 161 ts_diff = unwrapped_timestamp - last_timestamp_; |
161 } | 162 } |
162 // Make sure both frame droppers leak out bits. | 163 // Make sure both frame droppers leak out bits. |
163 layers_[0].UpdateDebt(ts_diff / 90); | 164 layers_[0].UpdateDebt(ts_diff / 90); |
164 layers_[1].UpdateDebt(ts_diff / 90); | 165 layers_[1].UpdateDebt(ts_diff / 90); |
165 last_timestamp_ = timestamp; | 166 last_timestamp_ = timestamp; |
| 167 TemporalLayers::FrameConfig tl_config; |
166 // TODO(pbos): Consider referencing but not updating the 'alt' buffer for all | 168 // TODO(pbos): Consider referencing but not updating the 'alt' buffer for all |
167 // layers. | 169 // layers. |
168 switch (layer_state) { | 170 switch (layer_state) { |
169 case kDrop: | 171 case kDrop: |
170 return TemporalLayers::FrameConfig(kNone, kNone, kNone); | 172 tl_config = TemporalLayers::FrameConfig(kNone, kNone, kNone); |
| 173 break; |
171 case kTl0: | 174 case kTl0: |
172 // TL0 only references and updates 'last'. | 175 // TL0 only references and updates 'last'. |
173 return TemporalLayers::FrameConfig(kReferenceAndUpdate, kNone, kNone); | 176 tl_config = |
| 177 TemporalLayers::FrameConfig(kReferenceAndUpdate, kNone, kNone); |
| 178 break; |
174 case kTl1: | 179 case kTl1: |
175 // TL1 references both 'last' and 'golden' but only updates 'golden'. | 180 // TL1 references both 'last' and 'golden' but only updates 'golden'. |
176 return TemporalLayers::FrameConfig(kReference, kReferenceAndUpdate, | 181 tl_config = |
177 kNone); | 182 TemporalLayers::FrameConfig(kReference, kReferenceAndUpdate, kNone); |
| 183 break; |
178 case kTl1Sync: | 184 case kTl1Sync: |
179 // 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 |
180 // 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 |
181 // and update 'golden' from this point on. | 187 // and update 'golden' from this point on. |
182 return TemporalLayers::FrameConfig(kReference, kUpdate, kNone, | 188 tl_config = TemporalLayers::FrameConfig(kReference, kUpdate, kNone); |
183 kLayerSync); | 189 break; |
184 } | 190 } |
185 RTC_NOTREACHED(); | 191 |
186 return TemporalLayers::FrameConfig(kNone, kNone, kNone); | 192 tl_config.pattern_idx = static_cast<int>(layer_state); |
| 193 return tl_config; |
187 } | 194 } |
188 | 195 |
189 std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps, | 196 std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps, |
190 int max_bitrate_kbps, | 197 int max_bitrate_kbps, |
191 int framerate) { | 198 int framerate) { |
192 RTC_DCHECK_GT(framerate, 0); | 199 RTC_DCHECK_GT(framerate, 0); |
193 if (!target_framerate_) { | 200 if (!target_framerate_) { |
194 // First OnRatesUpdated() is called during construction, with the configured | 201 // First OnRatesUpdated() is called during construction, with the configured |
195 // targets as parameters. | 202 // targets as parameters. |
196 target_framerate_.emplace(framerate); | 203 target_framerate_.emplace(framerate); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 bool frame_is_keyframe, | 265 bool frame_is_keyframe, |
259 const TemporalLayers::FrameConfig& tl_config, | 266 const TemporalLayers::FrameConfig& tl_config, |
260 CodecSpecificInfoVP8* vp8_info, | 267 CodecSpecificInfoVP8* vp8_info, |
261 uint32_t timestamp) { | 268 uint32_t timestamp) { |
262 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); | 269 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); |
263 if (number_of_temporal_layers_ == 1) { | 270 if (number_of_temporal_layers_ == 1) { |
264 vp8_info->temporalIdx = kNoTemporalIdx; | 271 vp8_info->temporalIdx = kNoTemporalIdx; |
265 vp8_info->layerSync = false; | 272 vp8_info->layerSync = false; |
266 vp8_info->tl0PicIdx = kNoTl0PicIdx; | 273 vp8_info->tl0PicIdx = kNoTl0PicIdx; |
267 } else { | 274 } else { |
268 // TODO(pbos): Add active_layer_ to TemporalLayers::FrameConfig (as | 275 TemporalLayerState layer_state = |
269 // pattern_idx) and make function const. | 276 static_cast<TemporalLayerState>(tl_config.pattern_idx); |
270 RTC_DCHECK_NE(-1, active_layer_); | 277 switch (layer_state) { |
271 vp8_info->temporalIdx = active_layer_; | 278 case kDrop: |
| 279 RTC_NOTREACHED(); |
| 280 break; |
| 281 case kTl0: |
| 282 vp8_info->temporalIdx = 0; |
| 283 break; |
| 284 case kTl1: |
| 285 case kTl1Sync: |
| 286 vp8_info->temporalIdx = 1; |
| 287 break; |
| 288 } |
272 if (frame_is_keyframe) { | 289 if (frame_is_keyframe) { |
273 vp8_info->temporalIdx = 0; | 290 vp8_info->temporalIdx = 0; |
274 last_sync_timestamp_ = unwrapped_timestamp; | 291 last_sync_timestamp_ = unwrapped_timestamp; |
275 } else if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { | 292 } else if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { |
276 // Regardless of pattern the frame after a base layer sync will always | 293 // Regardless of pattern the frame after a base layer sync will always |
277 // be a layer sync. | 294 // be a layer sync. |
278 last_sync_timestamp_ = unwrapped_timestamp; | 295 last_sync_timestamp_ = unwrapped_timestamp; |
279 } | 296 } |
280 vp8_info->layerSync = last_sync_timestamp_ != -1 && | 297 vp8_info->layerSync = last_sync_timestamp_ != -1 && |
281 last_sync_timestamp_ == unwrapped_timestamp; | 298 last_sync_timestamp_ == unwrapped_timestamp; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp", | 446 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp", |
430 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_); | 447 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_); |
431 RTC_HISTOGRAM_COUNTS_10000( | 448 RTC_HISTOGRAM_COUNTS_10000( |
432 "WebRTC.Video.Screenshare.Layer1.TargetBitrate", | 449 "WebRTC.Video.Screenshare.Layer1.TargetBitrate", |
433 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_); | 450 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_); |
434 } | 451 } |
435 } | 452 } |
436 } | 453 } |
437 | 454 |
438 } // namespace webrtc | 455 } // namespace webrtc |
OLD | NEW |