| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1404 return -1; | 1363 return -1; |
| 1405 } | 1364 } |
| 1406 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != | 1365 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != |
| 1407 VPX_CODEC_OK) { | 1366 VPX_CODEC_OK) { |
| 1408 return -1; | 1367 return -1; |
| 1409 } | 1368 } |
| 1410 return 0; | 1369 return 0; |
| 1411 } | 1370 } |
| 1412 | 1371 |
| 1413 } // namespace webrtc | 1372 } // namespace webrtc |
| OLD | NEW |