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

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

Issue 2288223002: Extract simulcast rate allocation outside of video encoder. (Closed)
Patch Set: Rebase, handle pause case in simulcast wrapper Created 4 years, 3 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 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 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
(...skipping 11 matching lines...) Expand all
22 #include "webrtc/base/checks.h" 22 #include "webrtc/base/checks.h"
23 #include "webrtc/base/timeutils.h" 23 #include "webrtc/base/timeutils.h"
24 #include "webrtc/base/trace_event.h" 24 #include "webrtc/base/trace_event.h"
25 #include "webrtc/common_types.h" 25 #include "webrtc/common_types.h"
26 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 26 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
27 #include "webrtc/modules/include/module_common_types.h" 27 #include "webrtc/modules/include/module_common_types.h"
28 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 28 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
29 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" 29 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
30 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" 30 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h"
31 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" 31 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h"
32 #include "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h"
32 #include "webrtc/system_wrappers/include/clock.h" 33 #include "webrtc/system_wrappers/include/clock.h"
33 34
34 namespace webrtc { 35 namespace webrtc {
35 namespace { 36 namespace {
36 37
37 enum { kVp8ErrorPropagationTh = 30 }; 38 enum { kVp8ErrorPropagationTh = 30 };
38 enum { kVp832ByteAlign = 32 }; 39 enum { kVp832ByteAlign = 32 };
39 40
40 // VP8 denoiser states. 41 // VP8 denoiser states.
41 enum denoiserState { 42 enum denoiserState {
(...skipping 10 matching lines...) Expand all
52 int GCD(int a, int b) { 53 int GCD(int a, int b) {
53 int c = a % b; 54 int c = a % b;
54 while (c != 0) { 55 while (c != 0) {
55 a = b; 56 a = b;
56 b = c; 57 b = c;
57 c = a % b; 58 c = a % b;
58 } 59 }
59 return b; 60 return b;
60 } 61 }
61 62
62 std::vector<int> GetStreamBitratesKbps(const VideoCodec& codec,
63 int bitrate_to_allocate_kbps) {
64 if (codec.numberOfSimulcastStreams <= 1) {
65 return std::vector<int>(1, bitrate_to_allocate_kbps);
66 }
67
68 std::vector<int> bitrates_kbps(codec.numberOfSimulcastStreams);
69 // Allocate min -> target bitrates as long as we have bitrate to spend.
70 size_t last_active_stream = 0;
71 for (size_t i = 0; i < static_cast<size_t>(codec.numberOfSimulcastStreams) &&
72 bitrate_to_allocate_kbps >=
73 static_cast<int>(codec.simulcastStream[i].minBitrate);
74 ++i) {
75 last_active_stream = i;
76 int allocated_bitrate_kbps =
77 std::min(static_cast<int>(codec.simulcastStream[i].targetBitrate),
78 bitrate_to_allocate_kbps);
79 bitrates_kbps[i] = allocated_bitrate_kbps;
80 bitrate_to_allocate_kbps -= allocated_bitrate_kbps;
81 }
82
83 // Spend additional bits on the highest-quality active layer, up to max
84 // bitrate.
85 // TODO(pbos): Consider spending additional bits on last_active_stream-1 down
86 // to 0 and not just the top layer when we have additional bitrate to spend.
87 int allocated_bitrate_kbps = std::min(
88 static_cast<int>(codec.simulcastStream[last_active_stream].maxBitrate -
89 bitrates_kbps[last_active_stream]),
90 bitrate_to_allocate_kbps);
91 bitrates_kbps[last_active_stream] += allocated_bitrate_kbps;
92 bitrate_to_allocate_kbps -= allocated_bitrate_kbps;
93
94 // Make sure we can always send something. Suspending below min bitrate is
95 // controlled outside the codec implementation and is not overriden by this.
96 if (bitrates_kbps[0] < static_cast<int>(codec.simulcastStream[0].minBitrate))
97 bitrates_kbps[0] = static_cast<int>(codec.simulcastStream[0].minBitrate);
98
99 return bitrates_kbps;
100 }
101
102 uint32_t SumStreamMaxBitrate(int streams, const VideoCodec& codec) { 63 uint32_t SumStreamMaxBitrate(int streams, const VideoCodec& codec) {
103 uint32_t bitrate_sum = 0; 64 uint32_t bitrate_sum = 0;
104 for (int i = 0; i < streams; ++i) { 65 for (int i = 0; i < streams; ++i) {
105 bitrate_sum += codec.simulcastStream[i].maxBitrate; 66 bitrate_sum += codec.simulcastStream[i].maxBitrate;
106 } 67 }
107 return bitrate_sum; 68 return bitrate_sum;
108 } 69 }
109 70
110 int NumberOfStreams(const VideoCodec& codec) { 71 int NumberOfStreams(const VideoCodec& codec) {
111 int streams = 72 int streams =
(...skipping 30 matching lines...) Expand all
142 } // namespace 103 } // namespace
143 104
144 VP8Encoder* VP8Encoder::Create() { 105 VP8Encoder* VP8Encoder::Create() {
145 return new VP8EncoderImpl(); 106 return new VP8EncoderImpl();
146 } 107 }
147 108
148 VP8Decoder* VP8Decoder::Create() { 109 VP8Decoder* VP8Decoder::Create() {
149 return new VP8DecoderImpl(); 110 return new VP8DecoderImpl();
150 } 111 }
151 112
152 const float kTl1MaxTimeToDropFrames = 20.0f;
153
154 VP8EncoderImpl::VP8EncoderImpl() 113 VP8EncoderImpl::VP8EncoderImpl()
155 : encoded_complete_callback_(NULL), 114 : encoded_complete_callback_(nullptr),
115 rate_allocator_(new SimulcastRateAllocator(codec_)),
156 inited_(false), 116 inited_(false),
157 timestamp_(0), 117 timestamp_(0),
158 feedback_mode_(false), 118 feedback_mode_(false),
159 qp_max_(56), // Setting for max quantizer. 119 qp_max_(56), // Setting for max quantizer.
160 cpu_speed_default_(-6), 120 cpu_speed_default_(-6),
161 rc_max_intra_target_(0), 121 rc_max_intra_target_(0),
162 token_partitions_(VP8_ONE_TOKENPARTITION), 122 token_partitions_(VP8_ONE_TOKENPARTITION),
163 down_scale_requested_(false), 123 down_scale_requested_(false),
164 down_scale_bitrate_(0), 124 down_scale_bitrate_(0),
165 tl0_frame_dropper_(),
166 tl1_frame_dropper_(kTl1MaxTimeToDropFrames),
167 key_frame_request_(kMaxSimulcastStreams, false), 125 key_frame_request_(kMaxSimulcastStreams, false),
168 quality_scaler_enabled_(false) { 126 quality_scaler_enabled_(false) {
169 uint32_t seed = rtc::Time32(); 127 uint32_t seed = rtc::Time32();
170 srand(seed); 128 srand(seed);
171 129
172 picture_id_.reserve(kMaxSimulcastStreams); 130 picture_id_.reserve(kMaxSimulcastStreams);
173 last_key_frame_picture_id_.reserve(kMaxSimulcastStreams); 131 last_key_frame_picture_id_.reserve(kMaxSimulcastStreams);
174 temporal_layers_.reserve(kMaxSimulcastStreams); 132 temporal_layers_.reserve(kMaxSimulcastStreams);
175 raw_images_.reserve(kMaxSimulcastStreams); 133 raw_images_.reserve(kMaxSimulcastStreams);
176 encoded_images_.reserve(kMaxSimulcastStreams); 134 encoded_images_.reserve(kMaxSimulcastStreams);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 // above some threshold (base temporal layer is down to 1/4 for 3 layers). 224 // above some threshold (base temporal layer is down to 1/4 for 3 layers).
267 // We may want to condition this on bitrate later. 225 // We may want to condition this on bitrate later.
268 if (new_framerate > 20) { 226 if (new_framerate > 20) {
269 configurations_[encoders_.size() - 1].rc_max_quantizer = 45; 227 configurations_[encoders_.size() - 1].rc_max_quantizer = 45;
270 } else { 228 } else {
271 // Go back to default value set in InitEncode. 229 // Go back to default value set in InitEncode.
272 configurations_[encoders_.size() - 1].rc_max_quantizer = qp_max_; 230 configurations_[encoders_.size() - 1].rc_max_quantizer = qp_max_;
273 } 231 }
274 } 232 }
275 233
276 std::vector<int> stream_bitrates = 234 std::vector<uint32_t> stream_bitrates =
277 GetStreamBitratesKbps(codec_, new_bitrate_kbit); 235 rate_allocator_->GetAllocation(new_bitrate_kbit);
278 size_t stream_idx = encoders_.size() - 1; 236 size_t stream_idx = encoders_.size() - 1;
279 for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) { 237 for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) {
280 if (encoders_.size() > 1) 238 if (encoders_.size() > 1)
281 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx); 239 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx);
282 240
283 unsigned int target_bitrate = stream_bitrates[stream_idx]; 241 unsigned int target_bitrate = stream_bitrates[stream_idx];
284 unsigned int max_bitrate = codec_.maxBitrate; 242 unsigned int max_bitrate = codec_.maxBitrate;
285 int framerate = new_framerate; 243 int framerate = new_framerate;
286 // TODO(holmer): This is a temporary hack for screensharing, where we 244 // TODO(holmer): This is a temporary hack for screensharing, where we
287 // interpret the startBitrate as the encoder target bitrate. This is 245 // interpret the startBitrate as the encoder target bitrate. This is
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 354
397 // TODO(andresp): crash if num temporal layers is bananas. 355 // TODO(andresp): crash if num temporal layers is bananas.
398 if (num_temporal_layers < 1) 356 if (num_temporal_layers < 1)
399 num_temporal_layers = 1; 357 num_temporal_layers = 1;
400 SetupTemporalLayers(number_of_streams, num_temporal_layers, *inst); 358 SetupTemporalLayers(number_of_streams, num_temporal_layers, *inst);
401 359
402 feedback_mode_ = inst->codecSpecific.VP8.feedbackModeOn; 360 feedback_mode_ = inst->codecSpecific.VP8.feedbackModeOn;
403 361
404 timestamp_ = 0; 362 timestamp_ = 0;
405 codec_ = *inst; 363 codec_ = *inst;
364 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
406 365
407 // Code expects simulcastStream resolutions to be correct, make sure they are 366 // Code expects simulcastStream resolutions to be correct, make sure they are
408 // filled even when there are no simulcast layers. 367 // filled even when there are no simulcast layers.
409 if (codec_.numberOfSimulcastStreams == 0) { 368 if (codec_.numberOfSimulcastStreams == 0) {
410 codec_.simulcastStream[0].width = codec_.width; 369 codec_.simulcastStream[0].width = codec_.width;
411 codec_.simulcastStream[0].height = codec_.height; 370 codec_.simulcastStream[0].height = codec_.height;
412 } 371 }
413 372
414 picture_id_.resize(number_of_streams); 373 picture_id_.resize(number_of_streams);
415 last_key_frame_picture_id_.resize(number_of_streams); 374 last_key_frame_picture_id_.resize(number_of_streams);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 522
564 if (encoders_.size() == 1) { 523 if (encoders_.size() == 1) {
565 configurations_[0].rc_target_bitrate = inst->startBitrate; 524 configurations_[0].rc_target_bitrate = inst->startBitrate;
566 temporal_layers_[0]->ConfigureBitrates(inst->startBitrate, inst->maxBitrate, 525 temporal_layers_[0]->ConfigureBitrates(inst->startBitrate, inst->maxBitrate,
567 inst->maxFramerate, 526 inst->maxFramerate,
568 &configurations_[0]); 527 &configurations_[0]);
569 } else { 528 } else {
570 // Note the order we use is different from webm, we have lowest resolution 529 // Note the order we use is different from webm, we have lowest resolution
571 // at position 0 and they have highest resolution at position 0. 530 // at position 0 and they have highest resolution at position 0.
572 int stream_idx = encoders_.size() - 1; 531 int stream_idx = encoders_.size() - 1;
573 std::vector<int> stream_bitrates = 532 std::vector<uint32_t> stream_bitrates =
574 GetStreamBitratesKbps(codec_, inst->startBitrate); 533 rate_allocator_->GetAllocation(inst->startBitrate);
575 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx); 534 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx);
576 configurations_[0].rc_target_bitrate = stream_bitrates[stream_idx]; 535 configurations_[0].rc_target_bitrate = stream_bitrates[stream_idx];
577 temporal_layers_[stream_idx]->ConfigureBitrates( 536 temporal_layers_[stream_idx]->ConfigureBitrates(
578 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate, 537 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate,
579 &configurations_[0]); 538 &configurations_[0]);
580 --stream_idx; 539 --stream_idx;
581 for (size_t i = 1; i < encoders_.size(); ++i, --stream_idx) { 540 for (size_t i = 1; i < encoders_.size(); ++i, --stream_idx) {
582 memcpy(&configurations_[i], &configurations_[0], 541 memcpy(&configurations_[i], &configurations_[0],
583 sizeof(configurations_[0])); 542 sizeof(configurations_[0]));
584 543
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 return -1; 1364 return -1;
1406 } 1365 }
1407 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != 1366 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) !=
1408 VPX_CODEC_OK) { 1367 VPX_CODEC_OK) {
1409 return -1; 1368 return -1;
1410 } 1369 }
1411 return 0; 1370 return 0;
1412 } 1371 }
1413 1372
1414 } // namespace webrtc 1373 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/codecs/vp8/vp8_impl.h ('k') | webrtc/modules/video_coding/utility/simulcast_rate_allocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698