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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 rate_allocator_(new SimulcastRateAllocator(codec_)), | 115 rate_allocator_(new SimulcastRateAllocator(codec_)), |
116 inited_(false), | 116 inited_(false), |
117 timestamp_(0), | 117 timestamp_(0), |
118 feedback_mode_(false), | 118 feedback_mode_(false), |
119 qp_max_(56), // Setting for max quantizer. | 119 qp_max_(56), // Setting for max quantizer. |
120 cpu_speed_default_(-6), | 120 cpu_speed_default_(-6), |
121 rc_max_intra_target_(0), | 121 rc_max_intra_target_(0), |
122 token_partitions_(VP8_ONE_TOKENPARTITION), | 122 token_partitions_(VP8_ONE_TOKENPARTITION), |
123 down_scale_requested_(false), | 123 down_scale_requested_(false), |
124 down_scale_bitrate_(0), | 124 down_scale_bitrate_(0), |
125 key_frame_request_(kMaxSimulcastStreams, false), | 125 key_frame_request_(kMaxSimulcastStreams, false) { |
126 quality_scaler_enabled_(false) { | |
127 uint32_t seed = rtc::Time32(); | 126 uint32_t seed = rtc::Time32(); |
128 srand(seed); | 127 srand(seed); |
129 | 128 |
130 picture_id_.reserve(kMaxSimulcastStreams); | 129 picture_id_.reserve(kMaxSimulcastStreams); |
131 last_key_frame_picture_id_.reserve(kMaxSimulcastStreams); | 130 last_key_frame_picture_id_.reserve(kMaxSimulcastStreams); |
132 temporal_layers_.reserve(kMaxSimulcastStreams); | 131 temporal_layers_.reserve(kMaxSimulcastStreams); |
133 raw_images_.reserve(kMaxSimulcastStreams); | 132 raw_images_.reserve(kMaxSimulcastStreams); |
134 encoded_images_.reserve(kMaxSimulcastStreams); | 133 encoded_images_.reserve(kMaxSimulcastStreams); |
135 send_stream_.reserve(kMaxSimulcastStreams); | 134 send_stream_.reserve(kMaxSimulcastStreams); |
136 cpu_speed_.assign(kMaxSimulcastStreams, -6); // Set default to -6. | 135 cpu_speed_.assign(kMaxSimulcastStreams, -6); // Set default to -6. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 max_bitrate = std::min(codec_.maxBitrate, target_bitrate); | 252 max_bitrate = std::min(codec_.maxBitrate, target_bitrate); |
254 target_bitrate = tl0_bitrate; | 253 target_bitrate = tl0_bitrate; |
255 } | 254 } |
256 configurations_[i].rc_target_bitrate = target_bitrate; | 255 configurations_[i].rc_target_bitrate = target_bitrate; |
257 temporal_layers_[stream_idx]->ConfigureBitrates( | 256 temporal_layers_[stream_idx]->ConfigureBitrates( |
258 target_bitrate, max_bitrate, framerate, &configurations_[i]); | 257 target_bitrate, max_bitrate, framerate, &configurations_[i]); |
259 if (vpx_codec_enc_config_set(&encoders_[i], &configurations_[i])) { | 258 if (vpx_codec_enc_config_set(&encoders_[i], &configurations_[i])) { |
260 return WEBRTC_VIDEO_CODEC_ERROR; | 259 return WEBRTC_VIDEO_CODEC_ERROR; |
261 } | 260 } |
262 } | 261 } |
263 quality_scaler_.ReportFramerate(new_framerate); | |
264 return WEBRTC_VIDEO_CODEC_OK; | 262 return WEBRTC_VIDEO_CODEC_OK; |
265 } | 263 } |
266 | 264 |
267 void VP8EncoderImpl::OnDroppedFrame() { | 265 void VP8EncoderImpl::OnDroppedFrame() { |
268 if (quality_scaler_enabled_) | |
269 quality_scaler_.ReportDroppedFrame(); | |
270 } | 266 } |
271 | 267 |
272 const char* VP8EncoderImpl::ImplementationName() const { | 268 const char* VP8EncoderImpl::ImplementationName() const { |
273 return "libvpx"; | 269 return "libvpx"; |
274 } | 270 } |
275 | 271 |
276 void VP8EncoderImpl::SetStreamState(bool send_stream, | 272 void VP8EncoderImpl::SetStreamState(bool send_stream, |
277 int stream_idx) { | 273 int stream_idx) { |
278 if (send_stream && !send_stream_[stream_idx]) { | 274 if (send_stream && !send_stream_[stream_idx]) { |
279 // Need a key frame if we have not sent this stream before. | 275 // Need a key frame if we have not sent this stream before. |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
549 inst->simulcastStream[stream_idx].height, kVp832ByteAlign); | 545 inst->simulcastStream[stream_idx].height, kVp832ByteAlign); |
550 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx); | 546 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx); |
551 configurations_[i].rc_target_bitrate = stream_bitrates[stream_idx]; | 547 configurations_[i].rc_target_bitrate = stream_bitrates[stream_idx]; |
552 temporal_layers_[stream_idx]->ConfigureBitrates( | 548 temporal_layers_[stream_idx]->ConfigureBitrates( |
553 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate, | 549 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate, |
554 &configurations_[i]); | 550 &configurations_[i]); |
555 } | 551 } |
556 } | 552 } |
557 | 553 |
558 rps_.Init(); | 554 rps_.Init(); |
559 quality_scaler_.Init(codec_.codecType, codec_.startBitrate, codec_.width, | |
560 codec_.height, codec_.maxFramerate); | |
561 | |
562 // Only apply scaling to improve for single-layer streams. The scaling metrics | |
563 // use frame drops as a signal and is only applicable when we drop frames. | |
564 quality_scaler_enabled_ = encoders_.size() == 1 && | |
565 configurations_[0].rc_dropframe_thresh > 0 && | |
566 codec_.codecSpecific.VP8.automaticResizeOn; | |
567 | |
568 return InitAndSetControlSettings(); | 555 return InitAndSetControlSettings(); |
569 } | 556 } |
570 | 557 |
571 int VP8EncoderImpl::SetCpuSpeed(int width, int height) { | 558 int VP8EncoderImpl::SetCpuSpeed(int width, int height) { |
572 #if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID) | 559 #if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID) |
573 // On mobile platform, always set to -12 to leverage between cpu usage | 560 // On mobile platform, always set to -12 to leverage between cpu usage |
574 // and video quality. | 561 // and video quality. |
575 return -12; | 562 return -12; |
576 #else | 563 #else |
577 // For non-ARM, increase encoding complexity (i.e., use lower speed setting) | 564 // For non-ARM, increase encoding complexity (i.e., use lower speed setting) |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
690 const CodecSpecificInfo* codec_specific_info, | 677 const CodecSpecificInfo* codec_specific_info, |
691 const std::vector<FrameType>* frame_types) { | 678 const std::vector<FrameType>* frame_types) { |
692 if (!inited_) | 679 if (!inited_) |
693 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 680 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
694 if (frame.IsZeroSize()) | 681 if (frame.IsZeroSize()) |
695 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 682 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
696 if (encoded_complete_callback_ == NULL) | 683 if (encoded_complete_callback_ == NULL) |
697 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 684 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
698 | 685 |
699 rtc::scoped_refptr<VideoFrameBuffer> input_image = frame.video_frame_buffer(); | 686 rtc::scoped_refptr<VideoFrameBuffer> input_image = frame.video_frame_buffer(); |
700 | 687 if (input_image->width() != codec_.width || |
magjed_webrtc
2016/10/26 14:28:37
Can this ever happen? You haven't kept this check
kthelgason
2016/10/26 19:02:49
I don't think so. There was no specific reason for
| |
701 if (quality_scaler_enabled_) { | 688 input_image->height() != codec_.height) { |
702 quality_scaler_.OnEncodeFrame(frame.width(), frame.height()); | 689 int ret = UpdateCodecFrameSize(input_image->width(), input_image->height()); |
703 input_image = quality_scaler_.GetScaledBuffer(input_image); | 690 if (ret < 0) |
704 | 691 return ret; |
705 if (input_image->width() != codec_.width || | |
706 input_image->height() != codec_.height) { | |
707 int ret = | |
708 UpdateCodecFrameSize(input_image->width(), input_image->height()); | |
709 if (ret < 0) | |
710 return ret; | |
711 } | |
712 } | 692 } |
713 | |
714 // Since we are extracting raw pointers from |input_image| to | 693 // Since we are extracting raw pointers from |input_image| to |
715 // |raw_images_[0]|, the resolution of these frames must match. Note that | 694 // |raw_images_[0]|, the resolution of these frames must match. Note that |
716 // |input_image| might be scaled from |frame|. In that case, the resolution of | 695 // |input_image| might be scaled from |frame|. In that case, the resolution of |
717 // |raw_images_[0]| should have been updated in UpdateCodecFrameSize. | 696 // |raw_images_[0]| should have been updated in UpdateCodecFrameSize. |
718 RTC_DCHECK_EQ(input_image->width(), static_cast<int>(raw_images_[0].d_w)); | 697 RTC_DCHECK_EQ(input_image->width(), static_cast<int>(raw_images_[0].d_w)); |
719 RTC_DCHECK_EQ(input_image->height(), static_cast<int>(raw_images_[0].d_h)); | 698 RTC_DCHECK_EQ(input_image->height(), static_cast<int>(raw_images_[0].d_h)); |
720 | 699 |
721 // Image in vpx_image_t format. | 700 // Image in vpx_image_t format. |
722 // Input image is const. VP8's raw image is not defined as const. | 701 // Input image is const. VP8's raw image is not defined as const. |
723 raw_images_[0].planes[VPX_PLANE_Y] = | 702 raw_images_[0].planes[VPX_PLANE_Y] = |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1000 encoded_images_[encoder_idx]._length, | 979 encoded_images_[encoder_idx]._length, |
1001 encoded_images_[encoder_idx]._timeStamp, qp); | 980 encoded_images_[encoder_idx]._timeStamp, qp); |
1002 if (send_stream_[stream_idx]) { | 981 if (send_stream_[stream_idx]) { |
1003 if (encoded_images_[encoder_idx]._length > 0) { | 982 if (encoded_images_[encoder_idx]._length > 0) { |
1004 TRACE_COUNTER_ID1("webrtc", "EncodedFrameSize", encoder_idx, | 983 TRACE_COUNTER_ID1("webrtc", "EncodedFrameSize", encoder_idx, |
1005 encoded_images_[encoder_idx]._length); | 984 encoded_images_[encoder_idx]._length); |
1006 encoded_images_[encoder_idx]._encodedHeight = | 985 encoded_images_[encoder_idx]._encodedHeight = |
1007 codec_.simulcastStream[stream_idx].height; | 986 codec_.simulcastStream[stream_idx].height; |
1008 encoded_images_[encoder_idx]._encodedWidth = | 987 encoded_images_[encoder_idx]._encodedWidth = |
1009 codec_.simulcastStream[stream_idx].width; | 988 codec_.simulcastStream[stream_idx].width; |
1010 encoded_images_[encoder_idx] | |
1011 .adapt_reason_.quality_resolution_downscales = | |
1012 quality_scaler_enabled_ ? quality_scaler_.downscale_shift() : -1; | |
1013 // Report once per frame (lowest stream always sent). | 989 // Report once per frame (lowest stream always sent). |
1014 encoded_images_[encoder_idx].adapt_reason_.bw_resolutions_disabled = | 990 encoded_images_[encoder_idx].adapt_reason_.bw_resolutions_disabled = |
1015 (stream_idx == 0) ? bw_resolutions_disabled : -1; | 991 (stream_idx == 0) ? bw_resolutions_disabled : -1; |
1016 int qp_128 = -1; | 992 int qp_128 = -1; |
1017 vpx_codec_control(&encoders_[encoder_idx], VP8E_GET_LAST_QUANTIZER, | 993 vpx_codec_control(&encoders_[encoder_idx], VP8E_GET_LAST_QUANTIZER, |
1018 &qp_128); | 994 &qp_128); |
1019 encoded_images_[encoder_idx].qp_ = qp_128; | 995 encoded_images_[encoder_idx].qp_ = qp_128; |
1020 encoded_complete_callback_->Encoded(encoded_images_[encoder_idx], | 996 encoded_complete_callback_->Encoded(encoded_images_[encoder_idx], |
1021 &codec_specific, &frag_info); | 997 &codec_specific, &frag_info); |
1022 } else if (codec_.mode == kScreensharing) { | 998 } else if (codec_.mode == kScreensharing) { |
1023 result = WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT; | 999 result = WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT; |
1024 } | 1000 } |
1025 } | 1001 } |
1026 } | 1002 } |
1027 if (encoders_.size() == 1 && send_stream_[0]) { | |
1028 if (encoded_images_[0]._length > 0) { | |
1029 int qp_128; | |
1030 vpx_codec_control(&encoders_[0], VP8E_GET_LAST_QUANTIZER, &qp_128); | |
1031 quality_scaler_.ReportQP(qp_128); | |
1032 } else { | |
1033 quality_scaler_.ReportDroppedFrame(); | |
1034 } | |
1035 } | |
1036 return result; | 1003 return result; |
1037 } | 1004 } |
1038 | 1005 |
1006 QualityScaler::Settings VP8EncoderImpl::GetQPThresholds() const { | |
1007 const bool enable_scaling = configurations_[0].rc_dropframe_thresh > 0 && | |
magjed_webrtc
2016/10/26 14:28:37
You have changed the order of the checks. I think
kthelgason
2016/10/26 19:02:50
Done.
| |
1008 codec_.codecSpecific.VP8.automaticResizeOn && | |
1009 encoders_.size() == 1; | |
1010 return QualityScaler::Settings(enable_scaling); | |
1011 } | |
1012 | |
1039 int VP8EncoderImpl::SetChannelParameters(uint32_t packetLoss, int64_t rtt) { | 1013 int VP8EncoderImpl::SetChannelParameters(uint32_t packetLoss, int64_t rtt) { |
1040 rps_.SetRtt(rtt); | 1014 rps_.SetRtt(rtt); |
1041 return WEBRTC_VIDEO_CODEC_OK; | 1015 return WEBRTC_VIDEO_CODEC_OK; |
1042 } | 1016 } |
1043 | 1017 |
1044 int VP8EncoderImpl::RegisterEncodeCompleteCallback( | 1018 int VP8EncoderImpl::RegisterEncodeCompleteCallback( |
1045 EncodedImageCallback* callback) { | 1019 EncodedImageCallback* callback) { |
1046 encoded_complete_callback_ = callback; | 1020 encoded_complete_callback_ = callback; |
1047 return WEBRTC_VIDEO_CODEC_OK; | 1021 return WEBRTC_VIDEO_CODEC_OK; |
1048 } | 1022 } |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1319 return -1; | 1293 return -1; |
1320 } | 1294 } |
1321 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != | 1295 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != |
1322 VPX_CODEC_OK) { | 1296 VPX_CODEC_OK) { |
1323 return -1; | 1297 return -1; |
1324 } | 1298 } |
1325 return 0; | 1299 return 0; |
1326 } | 1300 } |
1327 | 1301 |
1328 } // namespace webrtc | 1302 } // namespace webrtc |
OLD | NEW |