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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 encode_framerate_(1000.0f, 1000.0f), // 1 second window, second scale. | 71 encode_framerate_(1000.0f, 1000.0f), // 1 second window, second scale. |
72 bitrate_updated_(false) { | 72 bitrate_updated_(false) { |
73 RTC_CHECK_GT(number_of_temporal_layers_, 0); | 73 RTC_CHECK_GT(number_of_temporal_layers_, 0); |
74 RTC_CHECK_LE(number_of_temporal_layers_, kMaxNumTemporalLayers); | 74 RTC_CHECK_LE(number_of_temporal_layers_, kMaxNumTemporalLayers); |
75 } | 75 } |
76 | 76 |
77 ScreenshareLayers::~ScreenshareLayers() { | 77 ScreenshareLayers::~ScreenshareLayers() { |
78 UpdateHistograms(); | 78 UpdateHistograms(); |
79 } | 79 } |
80 | 80 |
81 int ScreenshareLayers::CurrentLayerId() const { | 81 int ScreenshareLayers::GetTemporalLayerId( |
82 TemporalLayers::FrameConfig tl_config) const { | |
82 // Codec does not use temporal layers for screenshare. | 83 // Codec does not use temporal layers for screenshare. |
83 return 0; | 84 return 0; |
84 } | 85 } |
85 | 86 |
86 TemporalReferences ScreenshareLayers::UpdateLayerConfig(uint32_t timestamp) { | 87 TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig( |
88 uint32_t timestamp) { | |
87 if (number_of_temporal_layers_ <= 1) { | 89 if (number_of_temporal_layers_ <= 1) { |
88 // No flags needed for 1 layer screenshare. | 90 // No flags needed for 1 layer screenshare. |
89 // TODO(pbos): Consider updating only last, and not all buffers. | 91 // TODO(pbos): Consider updating only last, and not all buffers. |
90 return TemporalReferences(kReferenceAndUpdate, kReferenceAndUpdate, | 92 return TemporalLayers::FrameConfig(kReferenceAndUpdate, kReferenceAndUpdate, |
91 kReferenceAndUpdate); | 93 kReferenceAndUpdate); |
92 } | 94 } |
93 | 95 |
94 const int64_t now_ms = clock_->TimeInMilliseconds(); | 96 const int64_t now_ms = clock_->TimeInMilliseconds(); |
95 if (target_framerate_.value_or(0) > 0 && | 97 if (target_framerate_.value_or(0) > 0 && |
96 encode_framerate_.Rate(now_ms).value_or(0) > *target_framerate_) { | 98 encode_framerate_.Rate(now_ms).value_or(0) > *target_framerate_) { |
97 // Max framerate exceeded, drop frame. | 99 // Max framerate exceeded, drop frame. |
98 return TemporalReferences(kNone, kNone, kNone); | 100 return TemporalLayers::FrameConfig(kNone, kNone, kNone); |
99 } | 101 } |
100 | 102 |
101 if (stats_.first_frame_time_ms_ == -1) | 103 if (stats_.first_frame_time_ms_ == -1) |
102 stats_.first_frame_time_ms_ = now_ms; | 104 stats_.first_frame_time_ms_ = now_ms; |
103 | 105 |
104 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); | 106 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); |
105 enum TemporalLayerState { kDrop, kTl0, kTl1, kTl1Sync }; | 107 enum TemporalLayerState { kDrop, kTl0, kTl1, kTl1Sync }; |
106 enum TemporalLayerState layer_state = kDrop; | 108 enum TemporalLayerState layer_state = kDrop; |
107 if (active_layer_ == -1 || | 109 if (active_layer_ == -1 || |
108 layers_[active_layer_].state != TemporalLayer::State::kDropped) { | 110 layers_[active_layer_].state != TemporalLayer::State::kDropped) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 ts_diff = unwrapped_timestamp - last_timestamp_; | 156 ts_diff = unwrapped_timestamp - last_timestamp_; |
155 } | 157 } |
156 // Make sure both frame droppers leak out bits. | 158 // Make sure both frame droppers leak out bits. |
157 layers_[0].UpdateDebt(ts_diff / 90); | 159 layers_[0].UpdateDebt(ts_diff / 90); |
158 layers_[1].UpdateDebt(ts_diff / 90); | 160 layers_[1].UpdateDebt(ts_diff / 90); |
159 last_timestamp_ = timestamp; | 161 last_timestamp_ = timestamp; |
160 // TODO(pbos): Consider referencing but not updating the 'alt' buffer for all | 162 // TODO(pbos): Consider referencing but not updating the 'alt' buffer for all |
161 // layers. | 163 // layers. |
162 switch (layer_state) { | 164 switch (layer_state) { |
163 case kDrop: | 165 case kDrop: |
164 return TemporalReferences(kNone, kNone, kNone); | 166 return TemporalLayers::FrameConfig(kNone, kNone, kNone); |
165 case kTl0: | 167 case kTl0: |
166 // TL0 only references and updates 'last'. | 168 // TL0 only references and updates 'last'. |
167 return TemporalReferences(kReferenceAndUpdate, kNone, kNone); | 169 return TemporalLayers::FrameConfig(kReferenceAndUpdate, kNone, kNone); |
168 case kTl1: | 170 case kTl1: |
169 // TL1 references both 'last' and 'golden' but only updates 'golden'. | 171 // TL1 references both 'last' and 'golden' but only updates 'golden'. |
170 return TemporalReferences(kReference, kReferenceAndUpdate, kNone); | 172 return TemporalLayers::FrameConfig(kReference, kReferenceAndUpdate, |
173 kNone); | |
171 case kTl1Sync: | 174 case kTl1Sync: |
172 // Predict from only TL0 to allow participants to switch to the high | 175 // Predict from only TL0 to allow participants to switch to the high |
173 // bitrate stream. Updates 'golden' so that TL1 can continue to refer to | 176 // bitrate stream. Updates 'golden' so that TL1 can continue to refer to |
174 // and update 'golden' from this point on. | 177 // and update 'golden' from this point on. |
175 return TemporalReferences(kReference, kUpdate, kNone, kLayerSync); | 178 return TemporalLayers::FrameConfig(kReference, kUpdate, kNone, |
179 kLayerSync); | |
176 } | 180 } |
177 RTC_NOTREACHED(); | 181 RTC_NOTREACHED(); |
178 return TemporalReferences(kNone, kNone, kNone); | 182 return TemporalLayers::FrameConfig(kNone, kNone, kNone); |
179 } | 183 } |
180 | 184 |
181 std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps, | 185 std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps, |
182 int max_bitrate_kbps, | 186 int max_bitrate_kbps, |
183 int framerate) { | 187 int framerate) { |
184 RTC_DCHECK_GT(framerate, 0); | 188 RTC_DCHECK_GT(framerate, 0); |
185 if (!target_framerate_) { | 189 if (!target_framerate_) { |
186 // First OnRatesUpdated() is called during construction, with the configured | 190 // First OnRatesUpdated() is called during construction, with the configured |
187 // targets as parameters. | 191 // targets as parameters. |
188 target_framerate_.emplace(framerate); | 192 target_framerate_.emplace(framerate); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 stats_.tl0_target_bitrate_sum_ += layers_[0].target_rate_kbps_; | 243 stats_.tl0_target_bitrate_sum_ += layers_[0].target_rate_kbps_; |
240 stats_.tl0_qp_sum_ += qp; | 244 stats_.tl0_qp_sum_ += qp; |
241 } else if (active_layer_ == 1) { | 245 } else if (active_layer_ == 1) { |
242 layers_[1].debt_bytes_ += size; | 246 layers_[1].debt_bytes_ += size; |
243 ++stats_.num_tl1_frames_; | 247 ++stats_.num_tl1_frames_; |
244 stats_.tl1_target_bitrate_sum_ += layers_[1].target_rate_kbps_; | 248 stats_.tl1_target_bitrate_sum_ += layers_[1].target_rate_kbps_; |
245 stats_.tl1_qp_sum_ += qp; | 249 stats_.tl1_qp_sum_ += qp; |
246 } | 250 } |
247 } | 251 } |
248 | 252 |
249 void ScreenshareLayers::PopulateCodecSpecific(bool frame_is_keyframe, | 253 void ScreenshareLayers::PopulateCodecSpecific( |
250 CodecSpecificInfoVP8* vp8_info, | 254 bool frame_is_keyframe, |
251 uint32_t timestamp) { | 255 TemporalLayers::FrameConfig tl_config, |
256 CodecSpecificInfoVP8* vp8_info, | |
257 uint32_t timestamp) { | |
252 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); | 258 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); |
253 if (number_of_temporal_layers_ == 1) { | 259 if (number_of_temporal_layers_ == 1) { |
254 vp8_info->temporalIdx = kNoTemporalIdx; | 260 vp8_info->temporalIdx = kNoTemporalIdx; |
255 vp8_info->layerSync = false; | 261 vp8_info->layerSync = false; |
256 vp8_info->tl0PicIdx = kNoTl0PicIdx; | 262 vp8_info->tl0PicIdx = kNoTl0PicIdx; |
257 } else { | 263 } else { |
264 // TODO(pbos): Add active_layer_ to TemporalLayers::FrameConfig (as | |
265 // pattern_idx) and | |
266 // make function const. | |
sprang_webrtc
2017/05/03 15:18:43
reflow comment
pbos-webrtc
2017/05/04 10:52:22
Oops, done, thanks. :)
| |
258 RTC_DCHECK_NE(-1, active_layer_); | 267 RTC_DCHECK_NE(-1, active_layer_); |
259 vp8_info->temporalIdx = active_layer_; | 268 vp8_info->temporalIdx = active_layer_; |
260 if (frame_is_keyframe) { | 269 if (frame_is_keyframe) { |
261 vp8_info->temporalIdx = 0; | 270 vp8_info->temporalIdx = 0; |
262 last_sync_timestamp_ = unwrapped_timestamp; | 271 last_sync_timestamp_ = unwrapped_timestamp; |
263 } else if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { | 272 } else if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) { |
264 // Regardless of pattern the frame after a base layer sync will always | 273 // Regardless of pattern the frame after a base layer sync will always |
265 // be a layer sync. | 274 // be a layer sync. |
266 last_sync_timestamp_ = unwrapped_timestamp; | 275 last_sync_timestamp_ = unwrapped_timestamp; |
267 } | 276 } |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp", | 426 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp", |
418 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_); | 427 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_); |
419 RTC_HISTOGRAM_COUNTS_10000( | 428 RTC_HISTOGRAM_COUNTS_10000( |
420 "WebRTC.Video.Screenshare.Layer1.TargetBitrate", | 429 "WebRTC.Video.Screenshare.Layer1.TargetBitrate", |
421 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_); | 430 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_); |
422 } | 431 } |
423 } | 432 } |
424 } | 433 } |
425 | 434 |
426 } // namespace webrtc | 435 } // namespace webrtc |
OLD | NEW |