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

Side by Side Diff: webrtc/media/engine/simulcast.cc

Issue 2643763002: Revert of Add experimental simulcast screen content mode (Closed)
Patch Set: Created 3 years, 11 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
« no previous file with comments | « webrtc/media/engine/simulcast.h ('k') | webrtc/media/engine/webrtcvideoengine2.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include <stdio.h> 11 #include <stdio.h>
12 12
13 #include "webrtc/base/arraysize.h" 13 #include "webrtc/base/arraysize.h"
14 #include "webrtc/base/common.h" 14 #include "webrtc/base/common.h"
15 #include "webrtc/base/logging.h" 15 #include "webrtc/base/logging.h"
16 #include "webrtc/media/base/streamparams.h" 16 #include "webrtc/media/base/streamparams.h"
17 #include "webrtc/media/engine/constants.h"
18 #include "webrtc/media/engine/simulcast.h" 17 #include "webrtc/media/engine/simulcast.h"
19 #include "webrtc/system_wrappers/include/field_trial.h" 18 #include "webrtc/system_wrappers/include/field_trial.h"
20 19
21 namespace cricket { 20 namespace cricket {
22 21
23 struct SimulcastFormat { 22 struct SimulcastFormat {
24 int width; 23 int width;
25 int height; 24 int height;
26 // The maximum number of simulcast layers can be used for 25 // The maximum number of simulcast layers can be used for
27 // resolutions at |widthxheigh|. 26 // resolutions at |widthxheigh|.
(...skipping 15 matching lines...) Expand all
43 const SimulcastFormat kSimulcastFormats[] = { 42 const SimulcastFormat kSimulcastFormats[] = {
44 {1920, 1080, 3, 5000, 4000, 800}, 43 {1920, 1080, 3, 5000, 4000, 800},
45 {1280, 720, 3, 2500, 2500, 600}, 44 {1280, 720, 3, 2500, 2500, 600},
46 {960, 540, 3, 900, 900, 450}, 45 {960, 540, 3, 900, 900, 450},
47 {640, 360, 2, 700, 500, 150}, 46 {640, 360, 2, 700, 500, 150},
48 {480, 270, 2, 450, 350, 150}, 47 {480, 270, 2, 450, 350, 150},
49 {320, 180, 1, 200, 150, 30}, 48 {320, 180, 1, 200, 150, 30},
50 {0, 0, 1, 200, 150, 30} 49 {0, 0, 1, 200, 150, 30}
51 }; 50 };
52 51
53 const int kDefaultScreenshareSimulcastStreams = 2;
54
55 // Multiway: Number of temporal layers for each simulcast stream, for maximum 52 // Multiway: Number of temporal layers for each simulcast stream, for maximum
56 // possible number of simulcast streams |kMaxSimulcastStreams|. The array 53 // possible number of simulcast streams |kMaxSimulcastStreams|. The array
57 // goes from lowest resolution at position 0 to highest resolution. 54 // goes from lowest resolution at position 0 to highest resolution.
58 // For example, first three elements correspond to say: QVGA, VGA, WHD. 55 // For example, first three elements correspond to say: QVGA, VGA, WHD.
59 static const int 56 static const int
60 kDefaultConferenceNumberOfTemporalLayers[webrtc::kMaxSimulcastStreams] = 57 kDefaultConferenceNumberOfTemporalLayers[webrtc::kMaxSimulcastStreams] =
61 {3, 3, 3, 3}; 58 {3, 3, 3, 3};
62 59
63 void GetSimulcastSsrcs(const StreamParams& sp, std::vector<uint32_t>* ssrcs) { 60 void GetSimulcastSsrcs(const StreamParams& sp, std::vector<uint32_t>* ssrcs) {
64 const SsrcGroup* sim_group = sp.get_ssrc_group(kSimSsrcGroupSemantics); 61 const SsrcGroup* sim_group = sp.get_ssrc_group(kSimSsrcGroupSemantics);
(...skipping 10 matching lines...) Expand all
75 int temp = *width; 72 int temp = *width;
76 *width = *height; 73 *width = *height;
77 *height = temp; 74 *height = temp;
78 } 75 }
79 } 76 }
80 77
81 int FindSimulcastFormatIndex(int width, int height) { 78 int FindSimulcastFormatIndex(int width, int height) {
82 MaybeExchangeWidthHeight(&width, &height); 79 MaybeExchangeWidthHeight(&width, &height);
83 80
84 for (uint32_t i = 0; i < arraysize(kSimulcastFormats); ++i) { 81 for (uint32_t i = 0; i < arraysize(kSimulcastFormats); ++i) {
85 if (width * height >= 82 if (width >= kSimulcastFormats[i].width &&
86 kSimulcastFormats[i].width * kSimulcastFormats[i].height) { 83 height >= kSimulcastFormats[i].height) {
87 return i; 84 return i;
88 } 85 }
89 } 86 }
90 return -1; 87 return -1;
91 } 88 }
92 89
93 int FindSimulcastFormatIndex(int width, int height, size_t max_layers) { 90 int FindSimulcastFormatIndex(int width, int height, size_t max_layers) {
94 MaybeExchangeWidthHeight(&width, &height); 91 MaybeExchangeWidthHeight(&width, &height);
95 92
96 for (uint32_t i = 0; i < arraysize(kSimulcastFormats); ++i) { 93 for (uint32_t i = 0; i < arraysize(kSimulcastFormats); ++i) {
97 if (width * height >= 94 if (width >= kSimulcastFormats[i].width &&
98 kSimulcastFormats[i].width * kSimulcastFormats[i].height && 95 height >= kSimulcastFormats[i].height &&
99 max_layers == kSimulcastFormats[i].max_layers) { 96 max_layers == kSimulcastFormats[i].max_layers) {
100 return i; 97 return i;
101 } 98 }
102 } 99 }
103 return -1; 100 return -1;
104 } 101 }
105 102
106 // Simulcast stream width and height must both be dividable by 103 // Simulcast stream width and height must both be dividable by
107 // |2 ^ simulcast_layers - 1|. 104 // |2 ^ simulcast_layers - 1|.
108 int NormalizeSimulcastSize(int size, size_t simulcast_layers) { 105 int NormalizeSimulcastSize(int size, size_t simulcast_layers) {
109 const int base2_exponent = static_cast<int>(simulcast_layers) - 1; 106 const int base2_exponent = static_cast<int>(simulcast_layers) - 1;
110 return ((size >> base2_exponent) << base2_exponent); 107 return ((size >> base2_exponent) << base2_exponent);
111 } 108 }
112 109
113 size_t FindSimulcastMaxLayers(int width, int height) { 110 size_t FindSimulcastMaxLayers(int width, int height) {
114 int index = FindSimulcastFormatIndex(width, height); 111 int index = FindSimulcastFormatIndex(width, height);
115 if (index == -1) { 112 if (index == -1) {
116 return -1; 113 return -1;
117 } 114 }
118 return kSimulcastFormats[index].max_layers; 115 return kSimulcastFormats[index].max_layers;
119 } 116 }
120 117
121 // TODO(marpan): Investigate if we should return 0 instead of -1 in 118 // TODO(marpan): Investigate if we should return 0 instead of -1 in
122 // FindSimulcast[Max/Target/Min]Bitrate functions below, since the 119 // FindSimulcast[Max/Target/Min]Bitrate functions below, since the
123 // codec struct max/min/targeBitrates are unsigned. 120 // codec struct max/min/targeBitrates are unsigned.
124 int FindSimulcastMaxBitrateBps(int width, int height) { 121 int FindSimulcastMaxBitrateBps(int width, int height, size_t max_layers) {
125 const int format_index = FindSimulcastFormatIndex(width, height); 122 const int format_index = FindSimulcastFormatIndex(width, height);
126 if (format_index == -1) { 123 if (format_index == -1) {
127 return -1; 124 return -1;
128 } 125 }
129 return kSimulcastFormats[format_index].max_bitrate_kbps * 1000; 126 return kSimulcastFormats[format_index].max_bitrate_kbps * 1000;
130 } 127 }
131 128
132 int FindSimulcastTargetBitrateBps(int width, int height) { 129 int FindSimulcastTargetBitrateBps(int width,
130 int height,
131 size_t max_layers) {
133 const int format_index = FindSimulcastFormatIndex(width, height); 132 const int format_index = FindSimulcastFormatIndex(width, height);
134 if (format_index == -1) { 133 if (format_index == -1) {
135 return -1; 134 return -1;
136 } 135 }
137 return kSimulcastFormats[format_index].target_bitrate_kbps * 1000; 136 return kSimulcastFormats[format_index].target_bitrate_kbps * 1000;
138 } 137 }
139 138
140 int FindSimulcastMinBitrateBps(int width, int height) { 139 int FindSimulcastMinBitrateBps(int width, int height, size_t max_layers) {
141 const int format_index = FindSimulcastFormatIndex(width, height); 140 const int format_index = FindSimulcastFormatIndex(width, height);
142 if (format_index == -1) { 141 if (format_index == -1) {
143 return -1; 142 return -1;
144 } 143 }
145 return kSimulcastFormats[format_index].min_bitrate_kbps * 1000; 144 return kSimulcastFormats[format_index].min_bitrate_kbps * 1000;
146 } 145 }
147 146
148 bool SlotSimulcastMaxResolution(size_t max_layers, int* width, int* height) { 147 bool SlotSimulcastMaxResolution(size_t max_layers, int* width, int* height) {
149 int index = FindSimulcastFormatIndex(*width, *height, max_layers); 148 int index = FindSimulcastFormatIndex(*width, *height, max_layers);
150 if (index == -1) { 149 if (index == -1) {
(...skipping 10 matching lines...) Expand all
161 160
162 int GetTotalMaxBitrateBps(const std::vector<webrtc::VideoStream>& streams) { 161 int GetTotalMaxBitrateBps(const std::vector<webrtc::VideoStream>& streams) {
163 int total_max_bitrate_bps = 0; 162 int total_max_bitrate_bps = 0;
164 for (size_t s = 0; s < streams.size() - 1; ++s) { 163 for (size_t s = 0; s < streams.size() - 1; ++s) {
165 total_max_bitrate_bps += streams[s].target_bitrate_bps; 164 total_max_bitrate_bps += streams[s].target_bitrate_bps;
166 } 165 }
167 total_max_bitrate_bps += streams.back().max_bitrate_bps; 166 total_max_bitrate_bps += streams.back().max_bitrate_bps;
168 return total_max_bitrate_bps; 167 return total_max_bitrate_bps;
169 } 168 }
170 169
171 std::vector<webrtc::VideoStream> GetSimulcastConfig(size_t max_streams, 170 std::vector<webrtc::VideoStream> GetSimulcastConfig(
172 int width, 171 size_t max_streams,
173 int height, 172 int width,
174 int max_bitrate_bps, 173 int height,
175 int max_qp, 174 int max_bitrate_bps,
176 int max_framerate, 175 int max_qp,
177 bool is_screencast) { 176 int max_framerate) {
178 size_t num_simulcast_layers; 177 size_t simulcast_layers = FindSimulcastMaxLayers(width, height);
179 if (is_screencast) { 178 if (simulcast_layers > max_streams) {
180 num_simulcast_layers =
181 UseSimulcastScreenshare() ? kDefaultScreenshareSimulcastStreams : 1;
182 } else {
183 num_simulcast_layers = FindSimulcastMaxLayers(width, height);
184 }
185
186 if (num_simulcast_layers > max_streams) {
187 // If the number of SSRCs in the group differs from our target 179 // If the number of SSRCs in the group differs from our target
188 // number of simulcast streams for current resolution, switch down 180 // number of simulcast streams for current resolution, switch down
189 // to a resolution that matches our number of SSRCs. 181 // to a resolution that matches our number of SSRCs.
190 if (!SlotSimulcastMaxResolution(max_streams, &width, &height)) { 182 if (!SlotSimulcastMaxResolution(max_streams, &width, &height)) {
191 return std::vector<webrtc::VideoStream>(); 183 return std::vector<webrtc::VideoStream>();
192 } 184 }
193 num_simulcast_layers = max_streams; 185 simulcast_layers = max_streams;
194 } 186 }
195 std::vector<webrtc::VideoStream> streams; 187 std::vector<webrtc::VideoStream> streams;
196 streams.resize(num_simulcast_layers); 188 streams.resize(simulcast_layers);
197 189
198 if (!is_screencast) { 190 // Format width and height has to be divisible by |2 ^ number_streams - 1|.
199 // Format width and height has to be divisible by |2 ^ number_streams - 1|. 191 width = NormalizeSimulcastSize(width, simulcast_layers);
200 width = NormalizeSimulcastSize(width, num_simulcast_layers); 192 height = NormalizeSimulcastSize(height, simulcast_layers);
201 height = NormalizeSimulcastSize(height, num_simulcast_layers);
202 }
203 193
204 // Add simulcast sub-streams from lower resolution to higher resolutions. 194 // Add simulcast sub-streams from lower resolution to higher resolutions.
205 // Add simulcast streams, from highest resolution (|s| = number_streams -1) 195 // Add simulcast streams, from highest resolution (|s| = number_streams -1)
206 // to lowest resolution at |s| = 0. 196 // to lowest resolution at |s| = 0.
207 for (size_t s = num_simulcast_layers - 1;; --s) { 197 for (size_t s = simulcast_layers - 1;; --s) {
208 streams[s].width = width; 198 streams[s].width = width;
209 streams[s].height = height; 199 streams[s].height = height;
210 // TODO(pbos): Fill actual temporal-layer bitrate thresholds. 200 // TODO(pbos): Fill actual temporal-layer bitrate thresholds.
201 streams[s].temporal_layer_thresholds_bps.resize(
202 kDefaultConferenceNumberOfTemporalLayers[s] - 1);
203 streams[s].max_bitrate_bps =
204 FindSimulcastMaxBitrateBps(width, height, simulcast_layers);
205 streams[s].target_bitrate_bps =
206 FindSimulcastTargetBitrateBps(width, height, simulcast_layers);
207 streams[s].min_bitrate_bps =
208 FindSimulcastMinBitrateBps(width, height, simulcast_layers);
211 streams[s].max_qp = max_qp; 209 streams[s].max_qp = max_qp;
212 if (is_screencast && s == 0) { 210 streams[s].max_framerate = max_framerate;
213 ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault();
214 // For legacy screenshare in conference mode, tl0 and tl1 bitrates are
215 // piggybacked on the VideoCodec struct as target and max bitrates,
216 // respectively. See eg. webrtc::VP8EncoderImpl::SetRates().
217 streams[s].min_bitrate_bps = kMinVideoBitrateKbps * 1000;
218 streams[s].target_bitrate_bps = config.tl0_bitrate_kbps * 1000;
219 streams[s].max_bitrate_bps = config.tl1_bitrate_kbps * 1000;
220 streams[s].temporal_layer_thresholds_bps.clear();
221 streams[s].temporal_layer_thresholds_bps.push_back(
222 config.tl0_bitrate_kbps * 1000);
223 streams[s].max_framerate = 5;
224 } else {
225 streams[s].temporal_layer_thresholds_bps.resize(
226 kDefaultConferenceNumberOfTemporalLayers[s] - 1);
227 streams[s].max_bitrate_bps = FindSimulcastMaxBitrateBps(width, height);
228 streams[s].target_bitrate_bps =
229 FindSimulcastTargetBitrateBps(width, height);
230 streams[s].min_bitrate_bps = FindSimulcastMinBitrateBps(width, height);
231 streams[s].max_framerate = max_framerate;
232 }
233
234 width /= 2; 211 width /= 2;
235 height /= 2; 212 height /= 2;
236 if (s == 0) 213 if (s == 0) {
237 break; 214 break;
215 }
238 } 216 }
239 217
240 // Spend additional bits to boost the max stream. 218 // Spend additional bits to boost the max stream.
241 int bitrate_left_bps = max_bitrate_bps - GetTotalMaxBitrateBps(streams); 219 int bitrate_left_bps = max_bitrate_bps - GetTotalMaxBitrateBps(streams);
242 if (bitrate_left_bps > 0) { 220 if (bitrate_left_bps > 0) {
243 streams.back().max_bitrate_bps += bitrate_left_bps; 221 streams.back().max_bitrate_bps += bitrate_left_bps;
244 } 222 }
245 223
246 return streams; 224 return streams;
247 } 225 }
248 226
249 static const int kScreenshareMinBitrateKbps = 50; 227 static const int kScreenshareMinBitrateKbps = 50;
250 static const int kScreenshareMaxBitrateKbps = 6000; 228 static const int kScreenshareMaxBitrateKbps = 6000;
251 static const int kScreenshareDefaultTl0BitrateKbps = 200; 229 static const int kScreenshareDefaultTl0BitrateKbps = 200;
252 static const int kScreenshareDefaultTl1BitrateKbps = 1000; 230 static const int kScreenshareDefaultTl1BitrateKbps = 1000;
253 231
254 static const char* kScreencastLayerFieldTrialName = 232 static const char* kScreencastLayerFieldTrialName =
255 "WebRTC-ScreenshareLayerRates"; 233 "WebRTC-ScreenshareLayerRates";
256 static const char* kSimulcastScreenshareFieldTrialName =
257 "WebRTC-SimulcastScreenshare";
258 234
259 ScreenshareLayerConfig::ScreenshareLayerConfig(int tl0_bitrate, int tl1_bitrate) 235 ScreenshareLayerConfig::ScreenshareLayerConfig(int tl0_bitrate, int tl1_bitrate)
260 : tl0_bitrate_kbps(tl0_bitrate), tl1_bitrate_kbps(tl1_bitrate) { 236 : tl0_bitrate_kbps(tl0_bitrate), tl1_bitrate_kbps(tl1_bitrate) {
261 } 237 }
262 238
263 ScreenshareLayerConfig ScreenshareLayerConfig::GetDefault() { 239 ScreenshareLayerConfig ScreenshareLayerConfig::GetDefault() {
264 std::string group = 240 std::string group =
265 webrtc::field_trial::FindFullName(kScreencastLayerFieldTrialName); 241 webrtc::field_trial::FindFullName(kScreencastLayerFieldTrialName);
266 242
267 ScreenshareLayerConfig config(kScreenshareDefaultTl0BitrateKbps, 243 ScreenshareLayerConfig config(kScreenshareDefaultTl0BitrateKbps,
(...skipping 22 matching lines...) Expand all
290 tl1_bitrate > kScreenshareMaxBitrateKbps || tl0_bitrate > tl1_bitrate) { 266 tl1_bitrate > kScreenshareMaxBitrateKbps || tl0_bitrate > tl1_bitrate) {
291 return false; 267 return false;
292 } 268 }
293 269
294 config->tl0_bitrate_kbps = tl0_bitrate; 270 config->tl0_bitrate_kbps = tl0_bitrate;
295 config->tl1_bitrate_kbps = tl1_bitrate; 271 config->tl1_bitrate_kbps = tl1_bitrate;
296 272
297 return true; 273 return true;
298 } 274 }
299 275
300 bool UseSimulcastScreenshare() {
301 return webrtc::field_trial::FindFullName(
302 kSimulcastScreenshareFieldTrialName) == "Enabled";
303 }
304
305 } // namespace cricket 276 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/media/engine/simulcast.h ('k') | webrtc/media/engine/webrtcvideoengine2.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698