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

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

Issue 1734793003: Add stats (histograms) for vp8 screenshare layers (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 9 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"
11 11
12 #include <stdlib.h> 12 #include <stdlib.h>
13 13
14 #include <algorithm> 14 #include <algorithm>
15 15
16 #include "webrtc/base/checks.h" 16 #include "webrtc/base/checks.h"
17 #include "vpx/vpx_encoder.h" 17 #include "vpx/vpx_encoder.h"
18 #include "vpx/vp8cx.h" 18 #include "vpx/vp8cx.h"
19 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 19 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
20 #include "webrtc/system_wrappers/include/clock.h"
21 #include "webrtc/system_wrappers/include/metrics.h"
20 22
21 namespace webrtc { 23 namespace webrtc {
22 24
23 static const int kOneSecond90Khz = 90000; 25 static const int kOneSecond90Khz = 90000;
24 static const int kMinTimeBetweenSyncs = kOneSecond90Khz * 5; 26 static const int kMinTimeBetweenSyncs = kOneSecond90Khz * 5;
25 static const int kMaxTimeBetweenSyncs = kOneSecond90Khz * 10; 27 static const int kMaxTimeBetweenSyncs = kOneSecond90Khz * 10;
26 static const int kQpDeltaThresholdForSync = 8; 28 static const int kQpDeltaThresholdForSync = 8;
27 29
28 const double ScreenshareLayers::kMaxTL0FpsReduction = 2.5; 30 const double ScreenshareLayers::kMaxTL0FpsReduction = 2.5;
29 const double ScreenshareLayers::kAcceptableTargetOvershoot = 2.0; 31 const double ScreenshareLayers::kAcceptableTargetOvershoot = 2.0;
30 32
31 // Since this is TL0 we only allow updating and predicting from the LAST 33 // Since this is TL0 we only allow updating and predicting from the LAST
32 // reference frame. 34 // reference frame.
33 const int ScreenshareLayers::kTl0Flags = 35 const int ScreenshareLayers::kTl0Flags =
34 VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | 36 VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF |
35 VP8_EFLAG_NO_REF_ARF; 37 VP8_EFLAG_NO_REF_ARF;
36 38
37 // Allow predicting from both TL0 and TL1. 39 // Allow predicting from both TL0 and TL1.
38 const int ScreenshareLayers::kTl1Flags = 40 const int ScreenshareLayers::kTl1Flags =
39 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; 41 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
40 42
41 // Allow predicting from only TL0 to allow participants to switch to the high 43 // Allow predicting from only TL0 to allow participants to switch to the high
42 // bitrate stream. This means predicting only from the LAST reference frame, but 44 // bitrate stream. This means predicting only from the LAST reference frame, but
43 // only updating GF to not corrupt TL0. 45 // only updating GF to not corrupt TL0.
44 const int ScreenshareLayers::kTl1SyncFlags = 46 const int ScreenshareLayers::kTl1SyncFlags =
45 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | 47 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF |
46 VP8_EFLAG_NO_UPD_LAST; 48 VP8_EFLAG_NO_UPD_LAST;
47 49
48 ScreenshareLayers::ScreenshareLayers(int num_temporal_layers, 50 ScreenshareLayers::ScreenshareLayers(int num_temporal_layers,
49 uint8_t initial_tl0_pic_idx) 51 uint8_t initial_tl0_pic_idx,
50 : number_of_temporal_layers_(num_temporal_layers), 52 Clock* clock)
53 : clock_(clock),
54 number_of_temporal_layers_(num_temporal_layers),
51 last_base_layer_sync_(false), 55 last_base_layer_sync_(false),
52 tl0_pic_idx_(initial_tl0_pic_idx), 56 tl0_pic_idx_(initial_tl0_pic_idx),
53 active_layer_(-1), 57 active_layer_(-1),
54 last_timestamp_(-1), 58 last_timestamp_(-1),
55 last_sync_timestamp_(-1), 59 last_sync_timestamp_(-1),
56 min_qp_(-1), 60 min_qp_(-1),
57 max_qp_(-1), 61 max_qp_(-1),
58 max_debt_bytes_(0), 62 max_debt_bytes_(0),
59 frame_rate_(-1) { 63 frame_rate_(-1) {
60 RTC_CHECK_GT(num_temporal_layers, 0); 64 RTC_CHECK_GT(num_temporal_layers, 0);
61 RTC_CHECK_LE(num_temporal_layers, 2); 65 RTC_CHECK_LE(num_temporal_layers, 2);
62 } 66 }
63 67
68 ScreenshareLayers::~ScreenshareLayers() {
69 UpdateHistograms();
70 }
71
64 int ScreenshareLayers::CurrentLayerId() const { 72 int ScreenshareLayers::CurrentLayerId() const {
65 // Codec does not use temporal layers for screenshare. 73 // Codec does not use temporal layers for screenshare.
66 return 0; 74 return 0;
67 } 75 }
68 76
69 int ScreenshareLayers::EncodeFlags(uint32_t timestamp) { 77 int ScreenshareLayers::EncodeFlags(uint32_t timestamp) {
70 if (number_of_temporal_layers_ <= 1) { 78 if (number_of_temporal_layers_ <= 1) {
71 // No flags needed for 1 layer screenshare. 79 // No flags needed for 1 layer screenshare.
72 return 0; 80 return 0;
73 } 81 }
74 82
83 if (stats_.first_framt_time_ms_ == -1)
stefan-webrtc 2016/02/29 09:10:18 first_frame_time_ms_
sprang_webrtc 2016/02/29 12:43:17 Done.
84 stats_.first_framt_time_ms_ = clock_->TimeInMilliseconds();
85
75 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); 86 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp);
76 int flags = 0; 87 int flags = 0;
77 88
78 if (active_layer_ == -1 || 89 if (active_layer_ == -1 ||
79 layers_[active_layer_].state != TemporalLayer::State::kDropped) { 90 layers_[active_layer_].state != TemporalLayer::State::kDropped) {
80 if (layers_[0].debt_bytes_ > max_debt_bytes_) { 91 if (layers_[0].debt_bytes_ > max_debt_bytes_) {
81 // Must drop TL0, encode TL1 instead. 92 // Must drop TL0, encode TL1 instead.
82 if (layers_[1].debt_bytes_ > max_debt_bytes_) { 93 if (layers_[1].debt_bytes_ > max_debt_bytes_) {
83 // Must drop both TL0 and TL1. 94 // Must drop both TL0 and TL1.
84 active_layer_ = -1; 95 active_layer_ = -1;
(...skipping 12 matching lines...) Expand all
97 case 1: 108 case 1:
98 if (TimeToSync(unwrapped_timestamp)) { 109 if (TimeToSync(unwrapped_timestamp)) {
99 last_sync_timestamp_ = unwrapped_timestamp; 110 last_sync_timestamp_ = unwrapped_timestamp;
100 flags = kTl1SyncFlags; 111 flags = kTl1SyncFlags;
101 } else { 112 } else {
102 flags = kTl1Flags; 113 flags = kTl1Flags;
103 } 114 }
104 break; 115 break;
105 case -1: 116 case -1:
106 flags = -1; 117 flags = -1;
118 ++stats_.num_dropped_frames_;
107 break; 119 break;
108 default: 120 default:
109 flags = -1; 121 flags = -1;
110 RTC_NOTREACHED(); 122 RTC_NOTREACHED();
111 } 123 }
112 124
113 // Make sure both frame droppers leak out bits. 125 // Make sure both frame droppers leak out bits.
114 int64_t ts_diff; 126 int64_t ts_diff;
115 if (last_timestamp_ == -1) { 127 if (last_timestamp_ == -1) {
116 ts_diff = kOneSecond90Khz / (frame_rate_ <= 0 ? 5 : frame_rate_); 128 ts_diff = kOneSecond90Khz / (frame_rate_ <= 0 ? 5 : frame_rate_);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 181
170 void ScreenshareLayers::FrameEncoded(unsigned int size, 182 void ScreenshareLayers::FrameEncoded(unsigned int size,
171 uint32_t timestamp, 183 uint32_t timestamp,
172 int qp) { 184 int qp) {
173 if (number_of_temporal_layers_ == 1) 185 if (number_of_temporal_layers_ == 1)
174 return; 186 return;
175 187
176 RTC_DCHECK_NE(-1, active_layer_); 188 RTC_DCHECK_NE(-1, active_layer_);
177 if (size == 0) { 189 if (size == 0) {
178 layers_[active_layer_].state = TemporalLayer::State::kDropped; 190 layers_[active_layer_].state = TemporalLayer::State::kDropped;
191 ++stats_.num_overshoots_;
179 return; 192 return;
180 } 193 }
181 194
182 if (layers_[active_layer_].state == TemporalLayer::State::kDropped) { 195 if (layers_[active_layer_].state == TemporalLayer::State::kDropped) {
183 layers_[active_layer_].state = TemporalLayer::State::kQualityBoost; 196 layers_[active_layer_].state = TemporalLayer::State::kQualityBoost;
184 } 197 }
185 198
186 if (qp != -1) 199 if (qp != -1)
187 layers_[active_layer_].last_qp = qp; 200 layers_[active_layer_].last_qp = qp;
188 201
189 if (active_layer_ == 0) { 202 if (active_layer_ == 0) {
190 layers_[0].debt_bytes_ += size; 203 layers_[0].debt_bytes_ += size;
191 layers_[1].debt_bytes_ += size; 204 layers_[1].debt_bytes_ += size;
205 ++stats_.num_tl0_frames_;
206 stats_.tl0_target_bitrate_sum_ += layers_[0].target_rate_kbps_;
207 stats_.tl0_qp_sum_ += qp;
192 } else if (active_layer_ == 1) { 208 } else if (active_layer_ == 1) {
193 layers_[1].debt_bytes_ += size; 209 layers_[1].debt_bytes_ += size;
210 ++stats_.num_tl1_frames_;
211 stats_.tl1_target_bitrate_sum_ += layers_[1].target_rate_kbps_;
212 stats_.tl1_qp_sum_ += qp;
194 } 213 }
195 } 214 }
196 215
197 void ScreenshareLayers::PopulateCodecSpecific(bool base_layer_sync, 216 void ScreenshareLayers::PopulateCodecSpecific(bool base_layer_sync,
198 CodecSpecificInfoVP8* vp8_info, 217 CodecSpecificInfoVP8* vp8_info,
199 uint32_t timestamp) { 218 uint32_t timestamp) {
200 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); 219 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp);
201 if (number_of_temporal_layers_ == 1) { 220 if (number_of_temporal_layers_ == 1) {
202 vp8_info->temporalIdx = kNoTemporalIdx; 221 vp8_info->temporalIdx = kNoTemporalIdx;
203 vp8_info->layerSync = false; 222 vp8_info->layerSync = false;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 295
277 void ScreenshareLayers::TemporalLayer::UpdateDebt(int64_t delta_ms) { 296 void ScreenshareLayers::TemporalLayer::UpdateDebt(int64_t delta_ms) {
278 uint32_t debt_reduction_bytes = target_rate_kbps_ * delta_ms / 8; 297 uint32_t debt_reduction_bytes = target_rate_kbps_ * delta_ms / 8;
279 if (debt_reduction_bytes >= debt_bytes_) { 298 if (debt_reduction_bytes >= debt_bytes_) {
280 debt_bytes_ = 0; 299 debt_bytes_ = 0;
281 } else { 300 } else {
282 debt_bytes_ -= debt_reduction_bytes; 301 debt_bytes_ -= debt_reduction_bytes;
283 } 302 }
284 } 303 }
285 304
305 void ScreenshareLayers::UpdateHistograms() {
306 if (stats_.first_framt_time_ms_ == -1)
307 return;
308 int64_t duration_sec =
309 (clock_->TimeInMilliseconds() - stats_.first_framt_time_ms_ + 500) / 1000;
310 if (duration_sec >= metrics::kMinRunTimeInSeconds) {
311 RTC_HISTOGRAM_COUNTS_10000(
312 "WebRTC.Video.Screenshare.FrameRateLayer0",
313 (stats_.num_tl0_frames_ + (duration_sec / 2)) / duration_sec);
314 RTC_HISTOGRAM_COUNTS_10000(
315 "WebRTC.Video.Screenshare.FrameRateLayer1",
316 (stats_.num_tl1_frames_ + (duration_sec / 2)) / duration_sec);
stefan-webrtc 2016/02/29 09:10:18 Should this report tl0+tl1 instead, since that's t
sprang_webrtc 2016/02/29 12:43:17 I think I'd rather keep them separate. The total f
stefan-webrtc 2016/02/29 15:04:51 ack
317 RTC_HISTOGRAM_COUNTS_10000(
318 "WebRTC.Video.Screenshare.FramesPerDrop",
319 stats_.num_dropped_frames_ == 0 ? 0 : (stats_.num_tl0_frames_ +
320 stats_.num_tl1_frames_) /
321 stats_.num_dropped_frames_);
322 RTC_HISTOGRAM_COUNTS_10000(
323 "WebRTC.Video.Screenshare.FramesPerOvershoot",
324 stats_.num_overshoots_ == 0 ? 0 : (stats_.num_tl0_frames_ +
325 stats_.num_tl1_frames_) /
326 stats_.num_overshoots_);
327 if (stats_.num_tl0_frames_ > 0) {
328 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.AverageQpLayer0",
329 stats_.tl0_qp_sum_ / stats_.num_tl0_frames_);
330 RTC_HISTOGRAM_COUNTS_10000(
331 "WebRTC.Video.Screenshare.TargetBitrateLayer0",
332 stats_.tl0_target_bitrate_sum_ / stats_.num_tl0_frames_);
333 }
334 if (stats_.num_tl1_frames_ > 0) {
335 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.AverageQpLayer1",
336 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_);
337 RTC_HISTOGRAM_COUNTS_10000(
338 "WebRTC.Video.Screenshare.TargetBitrateLayer1",
339 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_);
340 }
341 }
342 }
343
286 } // namespace webrtc 344 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698