| OLD | NEW |
| 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 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 if (inst->maxFramerate < 1) { | 67 if (inst->maxFramerate < 1) { |
| 68 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 68 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 69 } | 69 } |
| 70 // allow zero to represent an unspecified maxBitRate | 70 // allow zero to represent an unspecified maxBitRate |
| 71 if (inst->maxBitrate > 0 && inst->startBitrate > inst->maxBitrate) { | 71 if (inst->maxBitrate > 0 && inst->startBitrate > inst->maxBitrate) { |
| 72 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 72 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 73 } | 73 } |
| 74 if (inst->width <= 1 || inst->height <= 1) { | 74 if (inst->width <= 1 || inst->height <= 1) { |
| 75 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 75 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 76 } | 76 } |
| 77 if (inst->codecSpecific.VP8.feedbackModeOn && | 77 if (inst->VP8().feedbackModeOn && inst->numberOfSimulcastStreams > 1) { |
| 78 inst->numberOfSimulcastStreams > 1) { | |
| 79 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 78 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 80 } | 79 } |
| 81 if (inst->codecSpecific.VP8.automaticResizeOn && | 80 if (inst->VP8().automaticResizeOn && inst->numberOfSimulcastStreams > 1) { |
| 82 inst->numberOfSimulcastStreams > 1) { | |
| 83 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 81 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 84 } | 82 } |
| 85 return WEBRTC_VIDEO_CODEC_OK; | 83 return WEBRTC_VIDEO_CODEC_OK; |
| 86 } | 84 } |
| 87 | 85 |
| 88 struct ScreenshareTemporalLayersFactory : webrtc::TemporalLayersFactory { | 86 struct ScreenshareTemporalLayersFactory : webrtc::TemporalLayersFactory { |
| 89 ScreenshareTemporalLayersFactory() {} | 87 ScreenshareTemporalLayersFactory() {} |
| 90 virtual ~ScreenshareTemporalLayersFactory() {} | 88 virtual ~ScreenshareTemporalLayersFactory() {} |
| 91 | 89 |
| 92 virtual webrtc::TemporalLayers* Create(int num_temporal_layers, | 90 virtual webrtc::TemporalLayers* Create(int num_temporal_layers, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 } | 173 } |
| 176 | 174 |
| 177 codec_ = *inst; | 175 codec_ = *inst; |
| 178 rate_allocator_.reset(new SimulcastRateAllocator(codec_)); | 176 rate_allocator_.reset(new SimulcastRateAllocator(codec_)); |
| 179 std::vector<uint32_t> start_bitrates = | 177 std::vector<uint32_t> start_bitrates = |
| 180 rate_allocator_->GetAllocation(codec_.startBitrate); | 178 rate_allocator_->GetAllocation(codec_.startBitrate); |
| 181 | 179 |
| 182 // Special mode when screensharing on a single stream. | 180 // Special mode when screensharing on a single stream. |
| 183 if (number_of_streams == 1 && inst->mode == kScreensharing) { | 181 if (number_of_streams == 1 && inst->mode == kScreensharing) { |
| 184 screensharing_tl_factory_.reset(new ScreenshareTemporalLayersFactory()); | 182 screensharing_tl_factory_.reset(new ScreenshareTemporalLayersFactory()); |
| 185 codec_.codecSpecific.VP8.tl_factory = screensharing_tl_factory_.get(); | 183 codec_.VP8()->tl_factory = screensharing_tl_factory_.get(); |
| 186 } | 184 } |
| 187 | 185 |
| 188 std::string implementation_name; | 186 std::string implementation_name; |
| 189 // Create |number_of_streams| of encoder instances and init them. | 187 // Create |number_of_streams| of encoder instances and init them. |
| 190 for (int i = 0; i < number_of_streams; ++i) { | 188 for (int i = 0; i < number_of_streams; ++i) { |
| 191 VideoCodec stream_codec; | 189 VideoCodec stream_codec; |
| 192 uint32_t start_bitrate_kbps = start_bitrates[i]; | 190 uint32_t start_bitrate_kbps = start_bitrates[i]; |
| 193 if (!doing_simulcast) { | 191 if (!doing_simulcast) { |
| 194 stream_codec = codec_; | 192 stream_codec = codec_; |
| 195 stream_codec.numberOfSimulcastStreams = 1; | 193 stream_codec.numberOfSimulcastStreams = 1; |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 streaminfos_[stream_idx].key_frame_request = true; | 377 streaminfos_[stream_idx].key_frame_request = true; |
| 380 } | 378 } |
| 381 streaminfos_[stream_idx].send_stream = stream_bitrate_kbps > 0; | 379 streaminfos_[stream_idx].send_stream = stream_bitrate_kbps > 0; |
| 382 | 380 |
| 383 // TODO(holmer): This is a temporary hack for screensharing, where we | 381 // TODO(holmer): This is a temporary hack for screensharing, where we |
| 384 // interpret the startBitrate as the encoder target bitrate. This is | 382 // interpret the startBitrate as the encoder target bitrate. This is |
| 385 // to allow for a different max bitrate, so if the codec can't meet | 383 // to allow for a different max bitrate, so if the codec can't meet |
| 386 // the target we still allow it to overshoot up to the max before dropping | 384 // the target we still allow it to overshoot up to the max before dropping |
| 387 // frames. This hack should be improved. | 385 // frames. This hack should be improved. |
| 388 if (codec_.targetBitrate > 0 && | 386 if (codec_.targetBitrate > 0 && |
| 389 (codec_.codecSpecific.VP8.numberOfTemporalLayers == 2 || | 387 (codec_.VP8()->numberOfTemporalLayers == 2 || |
| 390 codec_.simulcastStream[0].numberOfTemporalLayers == 2)) { | 388 codec_.simulcastStream[0].numberOfTemporalLayers == 2)) { |
| 391 stream_bitrate_kbps = std::min(codec_.maxBitrate, stream_bitrate_kbps); | 389 stream_bitrate_kbps = std::min(codec_.maxBitrate, stream_bitrate_kbps); |
| 392 // TODO(ronghuawu): Can't change max bitrate via the VideoEncoder | 390 // TODO(ronghuawu): Can't change max bitrate via the VideoEncoder |
| 393 // interface. And VP8EncoderImpl doesn't take negative framerate. | 391 // interface. And VP8EncoderImpl doesn't take negative framerate. |
| 394 // max_bitrate = std::min(codec_.maxBitrate, stream_bitrate_kbps); | 392 // max_bitrate = std::min(codec_.maxBitrate, stream_bitrate_kbps); |
| 395 // new_framerate = -1; | 393 // new_framerate = -1; |
| 396 } | 394 } |
| 397 | 395 |
| 398 streaminfos_[stream_idx].encoder->SetRates(stream_bitrate_kbps, | 396 streaminfos_[stream_idx].encoder->SetRates(stream_bitrate_kbps, |
| 399 new_framerate); | 397 new_framerate); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 418 | 416 |
| 419 void SimulcastEncoderAdapter::PopulateStreamCodec( | 417 void SimulcastEncoderAdapter::PopulateStreamCodec( |
| 420 const webrtc::VideoCodec* inst, | 418 const webrtc::VideoCodec* inst, |
| 421 int stream_index, | 419 int stream_index, |
| 422 uint32_t start_bitrate_kbps, | 420 uint32_t start_bitrate_kbps, |
| 423 bool highest_resolution_stream, | 421 bool highest_resolution_stream, |
| 424 webrtc::VideoCodec* stream_codec) { | 422 webrtc::VideoCodec* stream_codec) { |
| 425 *stream_codec = *inst; | 423 *stream_codec = *inst; |
| 426 | 424 |
| 427 // Stream specific settings. | 425 // Stream specific settings. |
| 428 stream_codec->codecSpecific.VP8.numberOfTemporalLayers = | 426 stream_codec->VP8()->numberOfTemporalLayers = |
| 429 inst->simulcastStream[stream_index].numberOfTemporalLayers; | 427 inst->simulcastStream[stream_index].numberOfTemporalLayers; |
| 430 stream_codec->numberOfSimulcastStreams = 0; | 428 stream_codec->numberOfSimulcastStreams = 0; |
| 431 stream_codec->width = inst->simulcastStream[stream_index].width; | 429 stream_codec->width = inst->simulcastStream[stream_index].width; |
| 432 stream_codec->height = inst->simulcastStream[stream_index].height; | 430 stream_codec->height = inst->simulcastStream[stream_index].height; |
| 433 stream_codec->maxBitrate = inst->simulcastStream[stream_index].maxBitrate; | 431 stream_codec->maxBitrate = inst->simulcastStream[stream_index].maxBitrate; |
| 434 stream_codec->minBitrate = inst->simulcastStream[stream_index].minBitrate; | 432 stream_codec->minBitrate = inst->simulcastStream[stream_index].minBitrate; |
| 435 stream_codec->qpMax = inst->simulcastStream[stream_index].qpMax; | 433 stream_codec->qpMax = inst->simulcastStream[stream_index].qpMax; |
| 436 // Settings that are based on stream/resolution. | 434 // Settings that are based on stream/resolution. |
| 437 if (stream_index == 0) { | 435 if (stream_index == 0) { |
| 438 // Settings for lowest spatial resolutions. | 436 // Settings for lowest spatial resolutions. |
| 439 stream_codec->qpMax = kLowestResMaxQp; | 437 stream_codec->qpMax = kLowestResMaxQp; |
| 440 } | 438 } |
| 441 if (!highest_resolution_stream) { | 439 if (!highest_resolution_stream) { |
| 442 // For resolutions below CIF, set the codec |complexity| parameter to | 440 // For resolutions below CIF, set the codec |complexity| parameter to |
| 443 // kComplexityHigher, which maps to cpu_used = -4. | 441 // kComplexityHigher, which maps to cpu_used = -4. |
| 444 int pixels_per_frame = stream_codec->width * stream_codec->height; | 442 int pixels_per_frame = stream_codec->width * stream_codec->height; |
| 445 if (pixels_per_frame < 352 * 288) { | 443 if (pixels_per_frame < 352 * 288) { |
| 446 stream_codec->codecSpecific.VP8.complexity = webrtc::kComplexityHigher; | 444 stream_codec->VP8()->complexity = webrtc::kComplexityHigher; |
| 447 } | 445 } |
| 448 // Turn off denoising for all streams but the highest resolution. | 446 // Turn off denoising for all streams but the highest resolution. |
| 449 stream_codec->codecSpecific.VP8.denoisingOn = false; | 447 stream_codec->VP8()->denoisingOn = false; |
| 450 } | 448 } |
| 451 // TODO(ronghuawu): what to do with targetBitrate. | 449 // TODO(ronghuawu): what to do with targetBitrate. |
| 452 | 450 |
| 453 stream_codec->startBitrate = start_bitrate_kbps; | 451 stream_codec->startBitrate = start_bitrate_kbps; |
| 454 } | 452 } |
| 455 | 453 |
| 456 bool SimulcastEncoderAdapter::Initialized() const { | 454 bool SimulcastEncoderAdapter::Initialized() const { |
| 457 return !streaminfos_.empty(); | 455 return !streaminfos_.empty(); |
| 458 } | 456 } |
| 459 | 457 |
| 460 void SimulcastEncoderAdapter::OnDroppedFrame() { | 458 void SimulcastEncoderAdapter::OnDroppedFrame() { |
| 461 streaminfos_[0].encoder->OnDroppedFrame(); | 459 streaminfos_[0].encoder->OnDroppedFrame(); |
| 462 } | 460 } |
| 463 | 461 |
| 464 bool SimulcastEncoderAdapter::SupportsNativeHandle() const { | 462 bool SimulcastEncoderAdapter::SupportsNativeHandle() const { |
| 465 // We should not be calling this method before streaminfos_ are configured. | 463 // We should not be calling this method before streaminfos_ are configured. |
| 466 RTC_DCHECK(!streaminfos_.empty()); | 464 RTC_DCHECK(!streaminfos_.empty()); |
| 467 for (const auto& streaminfo : streaminfos_) { | 465 for (const auto& streaminfo : streaminfos_) { |
| 468 if (!streaminfo.encoder->SupportsNativeHandle()) | 466 if (!streaminfo.encoder->SupportsNativeHandle()) |
| 469 return false; | 467 return false; |
| 470 } | 468 } |
| 471 return true; | 469 return true; |
| 472 } | 470 } |
| 473 | 471 |
| 474 const char* SimulcastEncoderAdapter::ImplementationName() const { | 472 const char* SimulcastEncoderAdapter::ImplementationName() const { |
| 475 return implementation_name_.c_str(); | 473 return implementation_name_.c_str(); |
| 476 } | 474 } |
| 477 | 475 |
| 478 } // namespace webrtc | 476 } // namespace webrtc |
| OLD | NEW |