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 29 matching lines...) Expand all Loading... | |
40 const int ScreenshareLayers::kTl1Flags = | 40 const int ScreenshareLayers::kTl1Flags = |
41 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; |
42 | 42 |
43 // 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 |
44 // 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 |
45 // only updating GF to not corrupt TL0. | 45 // only updating GF to not corrupt TL0. |
46 const int ScreenshareLayers::kTl1SyncFlags = | 46 const int ScreenshareLayers::kTl1SyncFlags = |
47 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 | |
48 VP8_EFLAG_NO_UPD_LAST; | 48 VP8_EFLAG_NO_UPD_LAST; |
49 | 49 |
50 // Always emit a frame with certain interval, even if bitrate targets have | |
51 // been exceeded. | |
52 const int ScreenshareLayers::kMaxFrameIntervalMs = 2000; | |
53 | |
50 ScreenshareLayers::ScreenshareLayers(int num_temporal_layers, | 54 ScreenshareLayers::ScreenshareLayers(int num_temporal_layers, |
51 uint8_t initial_tl0_pic_idx, | 55 uint8_t initial_tl0_pic_idx, |
52 Clock* clock) | 56 Clock* clock) |
53 : clock_(clock), | 57 : clock_(clock), |
54 number_of_temporal_layers_(num_temporal_layers), | 58 number_of_temporal_layers_(num_temporal_layers), |
55 last_base_layer_sync_(false), | 59 last_base_layer_sync_(false), |
56 tl0_pic_idx_(initial_tl0_pic_idx), | 60 tl0_pic_idx_(initial_tl0_pic_idx), |
57 active_layer_(-1), | 61 active_layer_(-1), |
58 last_timestamp_(-1), | 62 last_timestamp_(-1), |
59 last_sync_timestamp_(-1), | 63 last_sync_timestamp_(-1), |
64 last_emitted_tl0_timestamp_(-1), | |
60 min_qp_(-1), | 65 min_qp_(-1), |
61 max_qp_(-1), | 66 max_qp_(-1), |
62 max_debt_bytes_(0), | 67 max_debt_bytes_(0), |
63 frame_rate_(-1) { | 68 frame_rate_(-1) { |
64 RTC_CHECK_GT(num_temporal_layers, 0); | 69 RTC_CHECK_GT(num_temporal_layers, 0); |
65 RTC_CHECK_LE(num_temporal_layers, 2); | 70 RTC_CHECK_LE(num_temporal_layers, 2); |
66 } | 71 } |
67 | 72 |
68 ScreenshareLayers::~ScreenshareLayers() { | 73 ScreenshareLayers::~ScreenshareLayers() { |
69 UpdateHistograms(); | 74 UpdateHistograms(); |
70 } | 75 } |
71 | 76 |
72 int ScreenshareLayers::CurrentLayerId() const { | 77 int ScreenshareLayers::CurrentLayerId() const { |
73 // Codec does not use temporal layers for screenshare. | 78 // Codec does not use temporal layers for screenshare. |
74 return 0; | 79 return 0; |
75 } | 80 } |
76 | 81 |
77 int ScreenshareLayers::EncodeFlags(uint32_t timestamp) { | 82 int ScreenshareLayers::EncodeFlags(uint32_t timestamp) { |
78 if (number_of_temporal_layers_ <= 1) { | 83 if (number_of_temporal_layers_ <= 1) { |
79 // No flags needed for 1 layer screenshare. | 84 // No flags needed for 1 layer screenshare. |
80 return 0; | 85 return 0; |
81 } | 86 } |
82 | 87 |
83 if (stats_.first_frame_time_ms_ == -1) | 88 if (stats_.first_frame_time_ms_ == -1) |
84 stats_.first_frame_time_ms_ = clock_->TimeInMilliseconds(); | 89 stats_.first_frame_time_ms_ = clock_->TimeInMilliseconds(); |
85 | 90 |
86 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); | 91 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); |
87 int flags = 0; | 92 int flags = 0; |
88 | |
89 if (active_layer_ == -1 || | 93 if (active_layer_ == -1 || |
90 layers_[active_layer_].state != TemporalLayer::State::kDropped) { | 94 layers_[active_layer_].state != TemporalLayer::State::kDropped) { |
95 if (last_emitted_tl0_timestamp_ != -1 && | |
96 (unwrapped_timestamp - last_emitted_tl0_timestamp_) / 90 > | |
97 kMaxFrameIntervalMs) { | |
98 // Too long time has passed since the last frame was emitted, cancel debt. | |
99 layers_[0].debt_bytes_ = 0; | |
stefan-webrtc
2016/04/11 10:29:22
Is it correct to cancel the whole debt? Instead we
sprang_webrtc
2016/04/11 11:02:53
You mean if the frames would end up being reeealy
| |
100 } | |
91 if (layers_[0].debt_bytes_ > max_debt_bytes_) { | 101 if (layers_[0].debt_bytes_ > max_debt_bytes_) { |
92 // Must drop TL0, encode TL1 instead. | 102 // Must drop TL0, encode TL1 instead. |
93 if (layers_[1].debt_bytes_ > max_debt_bytes_) { | 103 if (layers_[1].debt_bytes_ > max_debt_bytes_) { |
94 // Must drop both TL0 and TL1. | 104 // Must drop both TL0 and TL1. |
95 active_layer_ = -1; | 105 active_layer_ = -1; |
96 } else { | 106 } else { |
97 active_layer_ = 1; | 107 active_layer_ = 1; |
98 } | 108 } |
99 } else { | 109 } else { |
100 active_layer_ = 0; | 110 active_layer_ = 0; |
101 } | 111 } |
102 } | 112 } |
103 | 113 |
104 switch (active_layer_) { | 114 switch (active_layer_) { |
105 case 0: | 115 case 0: |
106 flags = kTl0Flags; | 116 flags = kTl0Flags; |
117 last_emitted_tl0_timestamp_ = unwrapped_timestamp; | |
107 break; | 118 break; |
108 case 1: | 119 case 1: |
109 if (TimeToSync(unwrapped_timestamp)) { | 120 if (TimeToSync(unwrapped_timestamp)) { |
110 last_sync_timestamp_ = unwrapped_timestamp; | 121 last_sync_timestamp_ = unwrapped_timestamp; |
111 flags = kTl1SyncFlags; | 122 flags = kTl1SyncFlags; |
112 } else { | 123 } else { |
113 flags = kTl1Flags; | 124 flags = kTl1Flags; |
114 } | 125 } |
115 break; | 126 break; |
116 case -1: | 127 case -1: |
117 flags = -1; | 128 flags = -1; |
118 ++stats_.num_dropped_frames_; | 129 ++stats_.num_dropped_frames_; |
119 break; | 130 break; |
120 default: | 131 default: |
121 flags = -1; | 132 flags = -1; |
122 RTC_NOTREACHED(); | 133 RTC_NOTREACHED(); |
123 } | 134 } |
124 | 135 |
125 // Make sure both frame droppers leak out bits. | |
126 int64_t ts_diff; | 136 int64_t ts_diff; |
127 if (last_timestamp_ == -1) { | 137 if (last_timestamp_ == -1) { |
128 ts_diff = kOneSecond90Khz / (frame_rate_ <= 0 ? 5 : frame_rate_); | 138 ts_diff = kOneSecond90Khz / (frame_rate_ <= 0 ? 5 : frame_rate_); |
129 } else { | 139 } else { |
130 ts_diff = unwrapped_timestamp - last_timestamp_; | 140 ts_diff = unwrapped_timestamp - last_timestamp_; |
131 } | 141 } |
132 | 142 // Make sure both frame droppers leak out bits. |
133 layers_[0].UpdateDebt(ts_diff / 90); | 143 layers_[0].UpdateDebt(ts_diff / 90); |
134 layers_[1].UpdateDebt(ts_diff / 90); | 144 layers_[1].UpdateDebt(ts_diff / 90); |
135 last_timestamp_ = timestamp; | 145 last_timestamp_ = timestamp; |
136 return flags; | 146 return flags; |
137 } | 147 } |
138 | 148 |
139 bool ScreenshareLayers::ConfigureBitrates(int bitrate_kbps, | 149 bool ScreenshareLayers::ConfigureBitrates(int bitrate_kbps, |
140 int max_bitrate_kbps, | 150 int max_bitrate_kbps, |
141 int framerate, | 151 int framerate, |
142 vpx_codec_enc_cfg_t* cfg) { | 152 vpx_codec_enc_cfg_t* cfg) { |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
334 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp", | 344 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp", |
335 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_); | 345 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_); |
336 RTC_HISTOGRAM_COUNTS_10000( | 346 RTC_HISTOGRAM_COUNTS_10000( |
337 "WebRTC.Video.Screenshare.Layer1.TargetBitrate", | 347 "WebRTC.Video.Screenshare.Layer1.TargetBitrate", |
338 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_); | 348 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_); |
339 } | 349 } |
340 } | 350 } |
341 } | 351 } |
342 | 352 |
343 } // namespace webrtc | 353 } // namespace webrtc |
OLD | NEW |