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

Side by Side Diff: webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.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) 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 "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" 11 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 14
15 // NOTE(ajm): Path provided by gyp. 15 // NOTE(ajm): Path provided by gyp.
16 #include "libyuv/scale.h" // NOLINT 16 #include "libyuv/scale.h" // NOLINT
17 17
18 #include "webrtc/base/checks.h" 18 #include "webrtc/base/checks.h"
19 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" 19 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h"
20 #include "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h"
20 #include "webrtc/system_wrappers/include/clock.h" 21 #include "webrtc/system_wrappers/include/clock.h"
21 22
22 namespace { 23 namespace {
23 24
24 const unsigned int kDefaultMinQp = 2; 25 const unsigned int kDefaultMinQp = 2;
25 const unsigned int kDefaultMaxQp = 56; 26 const unsigned int kDefaultMaxQp = 56;
26 // Max qp for lowest spatial resolution when doing simulcast. 27 // Max qp for lowest spatial resolution when doing simulcast.
27 const unsigned int kLowestResMaxQp = 45; 28 const unsigned int kLowestResMaxQp = 45;
28 29
29 uint32_t SumStreamTargetBitrate(int streams, const webrtc::VideoCodec& codec) {
30 uint32_t bitrate_sum = 0;
31 for (int i = 0; i < streams; ++i) {
32 bitrate_sum += codec.simulcastStream[i].targetBitrate;
33 }
34 return bitrate_sum;
35 }
36
37 uint32_t SumStreamMaxBitrate(int streams, const webrtc::VideoCodec& codec) { 30 uint32_t SumStreamMaxBitrate(int streams, const webrtc::VideoCodec& codec) {
38 uint32_t bitrate_sum = 0; 31 uint32_t bitrate_sum = 0;
39 for (int i = 0; i < streams; ++i) { 32 for (int i = 0; i < streams; ++i) {
40 bitrate_sum += codec.simulcastStream[i].maxBitrate; 33 bitrate_sum += codec.simulcastStream[i].maxBitrate;
41 } 34 }
42 return bitrate_sum; 35 return bitrate_sum;
43 } 36 }
44 37
45 int NumberOfStreams(const webrtc::VideoCodec& codec) { 38 int NumberOfStreams(const webrtc::VideoCodec& codec) {
46 int streams = 39 int streams =
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 inst->numberOfSimulcastStreams > 1) { 78 inst->numberOfSimulcastStreams > 1) {
86 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 79 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
87 } 80 }
88 if (inst->codecSpecific.VP8.automaticResizeOn && 81 if (inst->codecSpecific.VP8.automaticResizeOn &&
89 inst->numberOfSimulcastStreams > 1) { 82 inst->numberOfSimulcastStreams > 1) {
90 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 83 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
91 } 84 }
92 return WEBRTC_VIDEO_CODEC_OK; 85 return WEBRTC_VIDEO_CODEC_OK;
93 } 86 }
94 87
95 // TL1 FrameDropper's max time to drop frames.
96 const float kTl1MaxTimeToDropFrames = 20.0f;
97
98 struct ScreenshareTemporalLayersFactory : webrtc::TemporalLayersFactory { 88 struct ScreenshareTemporalLayersFactory : webrtc::TemporalLayersFactory {
99 ScreenshareTemporalLayersFactory() 89 ScreenshareTemporalLayersFactory() {}
100 : tl1_frame_dropper_(kTl1MaxTimeToDropFrames) {}
101
102 virtual ~ScreenshareTemporalLayersFactory() {} 90 virtual ~ScreenshareTemporalLayersFactory() {}
103 91
104 virtual webrtc::TemporalLayers* Create(int num_temporal_layers, 92 virtual webrtc::TemporalLayers* Create(int num_temporal_layers,
105 uint8_t initial_tl0_pic_idx) const { 93 uint8_t initial_tl0_pic_idx) const {
106 return new webrtc::ScreenshareLayers(num_temporal_layers, rand(), 94 return new webrtc::ScreenshareLayers(num_temporal_layers, rand(),
107 webrtc::Clock::GetRealTimeClock()); 95 webrtc::Clock::GetRealTimeClock());
108 } 96 }
109
110 mutable webrtc::FrameDropper tl0_frame_dropper_;
111 mutable webrtc::FrameDropper tl1_frame_dropper_;
112 }; 97 };
113 98
114 // An EncodedImageCallback implementation that forwards on calls to a 99 // An EncodedImageCallback implementation that forwards on calls to a
115 // SimulcastEncoderAdapter, but with the stream index it's registered with as 100 // SimulcastEncoderAdapter, but with the stream index it's registered with as
116 // the first parameter to Encoded. 101 // the first parameter to Encoded.
117 class AdapterEncodedImageCallback : public webrtc::EncodedImageCallback { 102 class AdapterEncodedImageCallback : public webrtc::EncodedImageCallback {
118 public: 103 public:
119 AdapterEncodedImageCallback(webrtc::SimulcastEncoderAdapter* adapter, 104 AdapterEncodedImageCallback(webrtc::SimulcastEncoderAdapter* adapter,
120 size_t stream_idx) 105 size_t stream_idx)
121 : adapter_(adapter), stream_idx_(stream_idx) {} 106 : adapter_(adapter), stream_idx_(stream_idx) {}
(...skipping 10 matching lines...) Expand all
132 webrtc::SimulcastEncoderAdapter* const adapter_; 117 webrtc::SimulcastEncoderAdapter* const adapter_;
133 const size_t stream_idx_; 118 const size_t stream_idx_;
134 }; 119 };
135 120
136 } // namespace 121 } // namespace
137 122
138 namespace webrtc { 123 namespace webrtc {
139 124
140 SimulcastEncoderAdapter::SimulcastEncoderAdapter(VideoEncoderFactory* factory) 125 SimulcastEncoderAdapter::SimulcastEncoderAdapter(VideoEncoderFactory* factory)
141 : factory_(factory), 126 : factory_(factory),
142 encoded_complete_callback_(NULL), 127 encoded_complete_callback_(nullptr),
143 implementation_name_("SimulcastEncoderAdapter") { 128 implementation_name_("SimulcastEncoderAdapter") {
144 memset(&codec_, 0, sizeof(webrtc::VideoCodec)); 129 memset(&codec_, 0, sizeof(webrtc::VideoCodec));
130 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
145 } 131 }
146 132
147 SimulcastEncoderAdapter::~SimulcastEncoderAdapter() { 133 SimulcastEncoderAdapter::~SimulcastEncoderAdapter() {
148 Release(); 134 Release();
149 } 135 }
150 136
151 int SimulcastEncoderAdapter::Release() { 137 int SimulcastEncoderAdapter::Release() {
152 // TODO(pbos): Keep the last encoder instance but call ::Release() on it, then 138 // TODO(pbos): Keep the last encoder instance but call ::Release() on it, then
153 // re-use this instance in ::InitEncode(). This means that changing 139 // re-use this instance in ::InitEncode(). This means that changing
154 // resolutions doesn't require reallocation of the first encoder, but only 140 // resolutions doesn't require reallocation of the first encoder, but only
(...skipping 27 matching lines...) Expand all
182 } 168 }
183 169
184 int number_of_streams = NumberOfStreams(*inst); 170 int number_of_streams = NumberOfStreams(*inst);
185 const bool doing_simulcast = (number_of_streams > 1); 171 const bool doing_simulcast = (number_of_streams > 1);
186 172
187 if (doing_simulcast && !ValidSimulcastResolutions(*inst, number_of_streams)) { 173 if (doing_simulcast && !ValidSimulcastResolutions(*inst, number_of_streams)) {
188 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 174 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
189 } 175 }
190 176
191 codec_ = *inst; 177 codec_ = *inst;
178 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
179 std::vector<uint32_t> start_bitrates =
180 rate_allocator_->GetAllocation(codec_.startBitrate);
192 181
193 // Special mode when screensharing on a single stream. 182 // Special mode when screensharing on a single stream.
194 if (number_of_streams == 1 && inst->mode == kScreensharing) { 183 if (number_of_streams == 1 && inst->mode == kScreensharing) {
195 screensharing_tl_factory_.reset(new ScreenshareTemporalLayersFactory()); 184 screensharing_tl_factory_.reset(new ScreenshareTemporalLayersFactory());
196 codec_.codecSpecific.VP8.tl_factory = screensharing_tl_factory_.get(); 185 codec_.codecSpecific.VP8.tl_factory = screensharing_tl_factory_.get();
197 } 186 }
198 187
199 std::string implementation_name; 188 std::string implementation_name;
200 // Create |number_of_streams| of encoder instances and init them. 189 // Create |number_of_streams| of encoder instances and init them.
201 for (int i = 0; i < number_of_streams; ++i) { 190 for (int i = 0; i < number_of_streams; ++i) {
202 VideoCodec stream_codec; 191 VideoCodec stream_codec;
203 bool send_stream = true; 192 uint32_t start_bitrate_kbps = start_bitrates[i];
204 if (!doing_simulcast) { 193 if (!doing_simulcast) {
205 stream_codec = codec_; 194 stream_codec = codec_;
206 stream_codec.numberOfSimulcastStreams = 1; 195 stream_codec.numberOfSimulcastStreams = 1;
207 } else { 196 } else {
197 // Cap start bitrate to the min bitrate in order to avoid strange codec
198 // behavior. Since sending sending will be false, this should not matter.
199 start_bitrate_kbps =
200 std::max(codec_.simulcastStream[i].minBitrate, start_bitrate_kbps);
208 bool highest_resolution_stream = (i == (number_of_streams - 1)); 201 bool highest_resolution_stream = (i == (number_of_streams - 1));
209 PopulateStreamCodec(&codec_, i, number_of_streams, 202 PopulateStreamCodec(&codec_, i, start_bitrate_kbps,
210 highest_resolution_stream, &stream_codec, 203 highest_resolution_stream, &stream_codec);
211 &send_stream);
212 } 204 }
213 205
214 // TODO(ronghuawu): Remove once this is handled in VP8EncoderImpl. 206 // TODO(ronghuawu): Remove once this is handled in VP8EncoderImpl.
215 if (stream_codec.qpMax < kDefaultMinQp) { 207 if (stream_codec.qpMax < kDefaultMinQp) {
216 stream_codec.qpMax = kDefaultMaxQp; 208 stream_codec.qpMax = kDefaultMaxQp;
217 } 209 }
218 210
219 VideoEncoder* encoder = factory_->Create(); 211 VideoEncoder* encoder = factory_->Create();
220 ret = encoder->InitEncode(&stream_codec, number_of_cores, max_payload_size); 212 ret = encoder->InitEncode(&stream_codec, number_of_cores, max_payload_size);
221 if (ret < 0) { 213 if (ret < 0) {
222 Release(); 214 Release();
223 return ret; 215 return ret;
224 } 216 }
225 EncodedImageCallback* callback = new AdapterEncodedImageCallback(this, i); 217 EncodedImageCallback* callback = new AdapterEncodedImageCallback(this, i);
226 encoder->RegisterEncodeCompleteCallback(callback); 218 encoder->RegisterEncodeCompleteCallback(callback);
227 streaminfos_.push_back(StreamInfo(encoder, callback, stream_codec.width, 219 streaminfos_.push_back(StreamInfo(encoder, callback, stream_codec.width,
228 stream_codec.height, send_stream)); 220 stream_codec.height,
221 start_bitrate_kbps > 0));
229 if (i != 0) 222 if (i != 0)
230 implementation_name += ", "; 223 implementation_name += ", ";
231 implementation_name += streaminfos_[i].encoder->ImplementationName(); 224 implementation_name += streaminfos_[i].encoder->ImplementationName();
232 } 225 }
233 if (doing_simulcast) { 226 if (doing_simulcast) {
234 implementation_name_ = 227 implementation_name_ =
235 "SimulcastEncoderAdapter (" + implementation_name + ")"; 228 "SimulcastEncoderAdapter (" + implementation_name + ")";
236 } else { 229 } else {
237 implementation_name_ = implementation_name; 230 implementation_name_ = implementation_name;
238 } 231 }
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 uint32_t new_framerate) { 349 uint32_t new_framerate) {
357 if (!Initialized()) { 350 if (!Initialized()) {
358 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 351 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
359 } 352 }
360 if (new_framerate < 1) { 353 if (new_framerate < 1) {
361 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 354 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
362 } 355 }
363 if (codec_.maxBitrate > 0 && new_bitrate_kbit > codec_.maxBitrate) { 356 if (codec_.maxBitrate > 0 && new_bitrate_kbit > codec_.maxBitrate) {
364 new_bitrate_kbit = codec_.maxBitrate; 357 new_bitrate_kbit = codec_.maxBitrate;
365 } 358 }
359
360 std::vector<uint32_t> stream_bitrates;
366 if (new_bitrate_kbit > 0) { 361 if (new_bitrate_kbit > 0) {
367 // Make sure the bitrate fits the configured min bitrates. 0 is a special 362 // Make sure the bitrate fits the configured min bitrates. 0 is a special
368 // value that means paused, though, so leave it alone. 363 // value that means paused, though, so leave it alone.
369 if (new_bitrate_kbit < codec_.minBitrate) { 364 if (new_bitrate_kbit < codec_.minBitrate) {
370 new_bitrate_kbit = codec_.minBitrate; 365 new_bitrate_kbit = codec_.minBitrate;
371 } 366 }
372 if (codec_.numberOfSimulcastStreams > 0 && 367 if (codec_.numberOfSimulcastStreams > 0 &&
373 new_bitrate_kbit < codec_.simulcastStream[0].minBitrate) { 368 new_bitrate_kbit < codec_.simulcastStream[0].minBitrate) {
374 new_bitrate_kbit = codec_.simulcastStream[0].minBitrate; 369 new_bitrate_kbit = codec_.simulcastStream[0].minBitrate;
375 } 370 }
371 stream_bitrates = rate_allocator_->GetAllocation(new_bitrate_kbit);
376 } 372 }
377 codec_.maxFramerate = new_framerate; 373 codec_.maxFramerate = new_framerate;
378 374
379 bool send_stream = true; 375 // Disable any stream not in the current allocation.
380 uint32_t stream_bitrate = 0; 376 stream_bitrates.resize(streaminfos_.size(), 0U);
377
381 for (size_t stream_idx = 0; stream_idx < streaminfos_.size(); ++stream_idx) { 378 for (size_t stream_idx = 0; stream_idx < streaminfos_.size(); ++stream_idx) {
382 stream_bitrate = GetStreamBitrate(stream_idx, streaminfos_.size(), 379 uint32_t stream_bitrate_kbps = stream_bitrates[stream_idx];
383 new_bitrate_kbit, &send_stream);
384 // Need a key frame if we have not sent this stream before. 380 // Need a key frame if we have not sent this stream before.
385 if (send_stream && !streaminfos_[stream_idx].send_stream) { 381 if (stream_bitrate_kbps > 0 && !streaminfos_[stream_idx].send_stream) {
386 streaminfos_[stream_idx].key_frame_request = true; 382 streaminfos_[stream_idx].key_frame_request = true;
387 } 383 }
388 streaminfos_[stream_idx].send_stream = send_stream; 384 streaminfos_[stream_idx].send_stream = stream_bitrate_kbps > 0;
389 385
390 // TODO(holmer): This is a temporary hack for screensharing, where we 386 // TODO(holmer): This is a temporary hack for screensharing, where we
391 // interpret the startBitrate as the encoder target bitrate. This is 387 // interpret the startBitrate as the encoder target bitrate. This is
392 // to allow for a different max bitrate, so if the codec can't meet 388 // to allow for a different max bitrate, so if the codec can't meet
393 // the target we still allow it to overshoot up to the max before dropping 389 // the target we still allow it to overshoot up to the max before dropping
394 // frames. This hack should be improved. 390 // frames. This hack should be improved.
395 if (codec_.targetBitrate > 0 && 391 if (codec_.targetBitrate > 0 &&
396 (codec_.codecSpecific.VP8.numberOfTemporalLayers == 2 || 392 (codec_.codecSpecific.VP8.numberOfTemporalLayers == 2 ||
397 codec_.simulcastStream[0].numberOfTemporalLayers == 2)) { 393 codec_.simulcastStream[0].numberOfTemporalLayers == 2)) {
398 stream_bitrate = std::min(codec_.maxBitrate, stream_bitrate); 394 stream_bitrate_kbps = std::min(codec_.maxBitrate, stream_bitrate_kbps);
399 // TODO(ronghuawu): Can't change max bitrate via the VideoEncoder 395 // TODO(ronghuawu): Can't change max bitrate via the VideoEncoder
400 // interface. And VP8EncoderImpl doesn't take negative framerate. 396 // interface. And VP8EncoderImpl doesn't take negative framerate.
401 // max_bitrate = std::min(codec_.maxBitrate, stream_bitrate); 397 // max_bitrate = std::min(codec_.maxBitrate, stream_bitrate_kbps);
402 // new_framerate = -1; 398 // new_framerate = -1;
403 } 399 }
404 400
405 streaminfos_[stream_idx].encoder->SetRates(stream_bitrate, new_framerate); 401 streaminfos_[stream_idx].encoder->SetRates(stream_bitrate_kbps,
402 new_framerate);
406 } 403 }
407 404
408 return WEBRTC_VIDEO_CODEC_OK; 405 return WEBRTC_VIDEO_CODEC_OK;
409 } 406 }
410 407
411 EncodedImageCallback::Result SimulcastEncoderAdapter::OnEncodedImage( 408 EncodedImageCallback::Result SimulcastEncoderAdapter::OnEncodedImage(
412 size_t stream_idx, 409 size_t stream_idx,
413 const EncodedImage& encodedImage, 410 const EncodedImage& encodedImage,
414 const CodecSpecificInfo* codecSpecificInfo, 411 const CodecSpecificInfo* codecSpecificInfo,
415 const RTPFragmentationHeader* fragmentation) { 412 const RTPFragmentationHeader* fragmentation) {
416 CodecSpecificInfo stream_codec_specific = *codecSpecificInfo; 413 CodecSpecificInfo stream_codec_specific = *codecSpecificInfo;
417 stream_codec_specific.codec_name = implementation_name_.c_str(); 414 stream_codec_specific.codec_name = implementation_name_.c_str();
418 CodecSpecificInfoVP8* vp8Info = &(stream_codec_specific.codecSpecific.VP8); 415 CodecSpecificInfoVP8* vp8Info = &(stream_codec_specific.codecSpecific.VP8);
419 vp8Info->simulcastIdx = stream_idx; 416 vp8Info->simulcastIdx = stream_idx;
420 417
421 return encoded_complete_callback_->OnEncodedImage( 418 return encoded_complete_callback_->OnEncodedImage(
422 encodedImage, &stream_codec_specific, fragmentation); 419 encodedImage, &stream_codec_specific, fragmentation);
423 } 420 }
424 421
425 uint32_t SimulcastEncoderAdapter::GetStreamBitrate(
426 int stream_idx,
427 size_t total_number_of_streams,
428 uint32_t new_bitrate_kbit,
429 bool* send_stream) const {
430 if (total_number_of_streams == 1) {
431 *send_stream = true;
432 return new_bitrate_kbit;
433 }
434
435 // The bitrate needed to start sending this stream is given by the
436 // minimum bitrate allowed for encoding this stream, plus the sum target
437 // rates of all lower streams.
438 uint32_t sum_target_lower_streams =
439 SumStreamTargetBitrate(stream_idx, codec_);
440 uint32_t bitrate_to_send_this_layer =
441 codec_.simulcastStream[stream_idx].minBitrate + sum_target_lower_streams;
442 if (new_bitrate_kbit >= bitrate_to_send_this_layer) {
443 // We have enough bandwidth to send this stream.
444 *send_stream = true;
445 // Bitrate for this stream is the new bitrate (|new_bitrate_kbit|) minus the
446 // sum target rates of the lower streams, and capped to a maximum bitrate.
447 // The maximum cap depends on whether we send the next higher stream.
448 // If we will be sending the next higher stream, |max_rate| is given by
449 // current stream's |targetBitrate|, otherwise it's capped by |maxBitrate|.
450 if (stream_idx < codec_.numberOfSimulcastStreams - 1) {
451 unsigned int max_rate = codec_.simulcastStream[stream_idx].maxBitrate;
452 if (new_bitrate_kbit >=
453 SumStreamTargetBitrate(stream_idx + 1, codec_) +
454 codec_.simulcastStream[stream_idx + 1].minBitrate) {
455 max_rate = codec_.simulcastStream[stream_idx].targetBitrate;
456 }
457 return std::min(new_bitrate_kbit - sum_target_lower_streams, max_rate);
458 } else {
459 // For the highest stream (highest resolution), the |targetBitRate| and
460 // |maxBitrate| are not used. Any excess bitrate (above the targets of
461 // all lower streams) is given to this (highest resolution) stream.
462 return new_bitrate_kbit - sum_target_lower_streams;
463 }
464 } else {
465 // Not enough bitrate for this stream.
466 // Return our max bitrate of |stream_idx| - 1, but we don't send it. We need
467 // to keep this resolution coding in order for the multi-encoder to work.
468 *send_stream = false;
469 return codec_.simulcastStream[stream_idx - 1].maxBitrate;
470 }
471 }
472
473 void SimulcastEncoderAdapter::PopulateStreamCodec( 422 void SimulcastEncoderAdapter::PopulateStreamCodec(
474 const webrtc::VideoCodec* inst, 423 const webrtc::VideoCodec* inst,
475 int stream_index, 424 int stream_index,
476 size_t total_number_of_streams, 425 uint32_t start_bitrate_kbps,
477 bool highest_resolution_stream, 426 bool highest_resolution_stream,
478 webrtc::VideoCodec* stream_codec, 427 webrtc::VideoCodec* stream_codec) {
479 bool* send_stream) {
480 *stream_codec = *inst; 428 *stream_codec = *inst;
481 429
482 // Stream specific settings. 430 // Stream specific settings.
483 stream_codec->codecSpecific.VP8.numberOfTemporalLayers = 431 stream_codec->codecSpecific.VP8.numberOfTemporalLayers =
484 inst->simulcastStream[stream_index].numberOfTemporalLayers; 432 inst->simulcastStream[stream_index].numberOfTemporalLayers;
485 stream_codec->numberOfSimulcastStreams = 0; 433 stream_codec->numberOfSimulcastStreams = 0;
486 stream_codec->width = inst->simulcastStream[stream_index].width; 434 stream_codec->width = inst->simulcastStream[stream_index].width;
487 stream_codec->height = inst->simulcastStream[stream_index].height; 435 stream_codec->height = inst->simulcastStream[stream_index].height;
488 stream_codec->maxBitrate = inst->simulcastStream[stream_index].maxBitrate; 436 stream_codec->maxBitrate = inst->simulcastStream[stream_index].maxBitrate;
489 stream_codec->minBitrate = inst->simulcastStream[stream_index].minBitrate; 437 stream_codec->minBitrate = inst->simulcastStream[stream_index].minBitrate;
490 stream_codec->qpMax = inst->simulcastStream[stream_index].qpMax; 438 stream_codec->qpMax = inst->simulcastStream[stream_index].qpMax;
491 // Settings that are based on stream/resolution. 439 // Settings that are based on stream/resolution.
492 if (stream_index == 0) { 440 if (stream_index == 0) {
493 // Settings for lowest spatial resolutions. 441 // Settings for lowest spatial resolutions.
494 stream_codec->qpMax = kLowestResMaxQp; 442 stream_codec->qpMax = kLowestResMaxQp;
495 } 443 }
496 if (!highest_resolution_stream) { 444 if (!highest_resolution_stream) {
497 // For resolutions below CIF, set the codec |complexity| parameter to 445 // For resolutions below CIF, set the codec |complexity| parameter to
498 // kComplexityHigher, which maps to cpu_used = -4. 446 // kComplexityHigher, which maps to cpu_used = -4.
499 int pixels_per_frame = stream_codec->width * stream_codec->height; 447 int pixels_per_frame = stream_codec->width * stream_codec->height;
500 if (pixels_per_frame < 352 * 288) { 448 if (pixels_per_frame < 352 * 288) {
501 stream_codec->codecSpecific.VP8.complexity = webrtc::kComplexityHigher; 449 stream_codec->codecSpecific.VP8.complexity = webrtc::kComplexityHigher;
502 } 450 }
503 // Turn off denoising for all streams but the highest resolution. 451 // Turn off denoising for all streams but the highest resolution.
504 stream_codec->codecSpecific.VP8.denoisingOn = false; 452 stream_codec->codecSpecific.VP8.denoisingOn = false;
505 } 453 }
506 // TODO(ronghuawu): what to do with targetBitrate. 454 // TODO(ronghuawu): what to do with targetBitrate.
507 455
508 int stream_bitrate = GetStreamBitrate(stream_index, total_number_of_streams, 456 stream_codec->startBitrate = start_bitrate_kbps;
509 inst->startBitrate, send_stream);
510 stream_codec->startBitrate = stream_bitrate;
511 } 457 }
512 458
513 bool SimulcastEncoderAdapter::Initialized() const { 459 bool SimulcastEncoderAdapter::Initialized() const {
514 return !streaminfos_.empty(); 460 return !streaminfos_.empty();
515 } 461 }
516 462
517 void SimulcastEncoderAdapter::OnDroppedFrame() { 463 void SimulcastEncoderAdapter::OnDroppedFrame() {
518 streaminfos_[0].encoder->OnDroppedFrame(); 464 streaminfos_[0].encoder->OnDroppedFrame();
519 } 465 }
520 466
521 bool SimulcastEncoderAdapter::SupportsNativeHandle() const { 467 bool SimulcastEncoderAdapter::SupportsNativeHandle() const {
522 // We should not be calling this method before streaminfos_ are configured. 468 // We should not be calling this method before streaminfos_ are configured.
523 RTC_DCHECK(!streaminfos_.empty()); 469 RTC_DCHECK(!streaminfos_.empty());
524 for (const auto& streaminfo : streaminfos_) { 470 for (const auto& streaminfo : streaminfos_) {
525 if (!streaminfo.encoder->SupportsNativeHandle()) 471 if (!streaminfo.encoder->SupportsNativeHandle())
526 return false; 472 return false;
527 } 473 }
528 return true; 474 return true;
529 } 475 }
530 476
531 const char* SimulcastEncoderAdapter::ImplementationName() const { 477 const char* SimulcastEncoderAdapter::ImplementationName() const {
532 return implementation_name_.c_str(); 478 return implementation_name_.c_str();
533 } 479 }
534 480
535 } // namespace webrtc 481 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h ('k') | webrtc/modules/video_coding/codecs/vp8/vp8_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698