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 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 // interpret the startBitrate as the encoder target bitrate. This is | 271 // interpret the startBitrate as the encoder target bitrate. This is |
272 // to allow for a different max bitrate, so if the codec can't meet | 272 // to allow for a different max bitrate, so if the codec can't meet |
273 // the target we still allow it to overshoot up to the max before dropping | 273 // the target we still allow it to overshoot up to the max before dropping |
274 // frames. This hack should be improved. | 274 // frames. This hack should be improved. |
275 if (codec_.targetBitrate > 0 && | 275 if (codec_.targetBitrate > 0 && |
276 (codec_.codecSpecific.VP8.numberOfTemporalLayers == 2 || | 276 (codec_.codecSpecific.VP8.numberOfTemporalLayers == 2 || |
277 codec_.simulcastStream[0].numberOfTemporalLayers == 2)) { | 277 codec_.simulcastStream[0].numberOfTemporalLayers == 2)) { |
278 int tl0_bitrate = std::min(codec_.targetBitrate, target_bitrate); | 278 int tl0_bitrate = std::min(codec_.targetBitrate, target_bitrate); |
279 max_bitrate = std::min(codec_.maxBitrate, target_bitrate); | 279 max_bitrate = std::min(codec_.maxBitrate, target_bitrate); |
280 target_bitrate = tl0_bitrate; | 280 target_bitrate = tl0_bitrate; |
281 framerate = -1; | |
282 } | 281 } |
283 configurations_[i].rc_target_bitrate = target_bitrate; | 282 configurations_[i].rc_target_bitrate = target_bitrate; |
284 temporal_layers_[stream_idx]->ConfigureBitrates(target_bitrate, | 283 temporal_layers_[stream_idx]->ConfigureBitrates(target_bitrate, |
285 max_bitrate, | 284 max_bitrate, |
286 framerate, | 285 framerate, |
287 &configurations_[i]); | 286 &configurations_[i]); |
288 if (vpx_codec_enc_config_set(&encoders_[i], &configurations_[i])) { | 287 if (vpx_codec_enc_config_set(&encoders_[i], &configurations_[i])) { |
289 return WEBRTC_VIDEO_CODEC_ERROR; | 288 return WEBRTC_VIDEO_CODEC_ERROR; |
290 } | 289 } |
291 } | 290 } |
(...skipping 13 matching lines...) Expand all Loading... |
305 void VP8EncoderImpl::SetupTemporalLayers(int num_streams, | 304 void VP8EncoderImpl::SetupTemporalLayers(int num_streams, |
306 int num_temporal_layers, | 305 int num_temporal_layers, |
307 const VideoCodec& codec) { | 306 const VideoCodec& codec) { |
308 const Config default_options; | 307 const Config default_options; |
309 const TemporalLayers::Factory& tl_factory = | 308 const TemporalLayers::Factory& tl_factory = |
310 (codec.extra_options ? codec.extra_options : &default_options) | 309 (codec.extra_options ? codec.extra_options : &default_options) |
311 ->Get<TemporalLayers::Factory>(); | 310 ->Get<TemporalLayers::Factory>(); |
312 if (num_streams == 1) { | 311 if (num_streams == 1) { |
313 if (codec.mode == kScreensharing) { | 312 if (codec.mode == kScreensharing) { |
314 // Special mode when screensharing on a single stream. | 313 // Special mode when screensharing on a single stream. |
315 temporal_layers_.push_back(new ScreenshareLayers(num_temporal_layers, | 314 temporal_layers_.push_back( |
316 rand(), | 315 new ScreenshareLayers(num_temporal_layers, rand())); |
317 &tl0_frame_dropper_, | |
318 &tl1_frame_dropper_)); | |
319 } else { | 316 } else { |
320 temporal_layers_.push_back( | 317 temporal_layers_.push_back( |
321 tl_factory.Create(num_temporal_layers, rand())); | 318 tl_factory.Create(num_temporal_layers, rand())); |
322 } | 319 } |
323 } else { | 320 } else { |
324 for (int i = 0; i < num_streams; ++i) { | 321 for (int i = 0; i < num_streams; ++i) { |
325 // TODO(andresp): crash if layers is invalid. | 322 // TODO(andresp): crash if layers is invalid. |
326 int layers = codec.simulcastStream[i].numberOfTemporalLayers; | 323 int layers = codec.simulcastStream[i].numberOfTemporalLayers; |
327 if (layers < 1) layers = 1; | 324 if (layers < 1) layers = 1; |
328 temporal_layers_.push_back(tl_factory.Create(layers, rand())); | 325 temporal_layers_.push_back(tl_factory.Create(layers, rand())); |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 codec_.codecSpecific.VP8.denoisingOn ? | 660 codec_.codecSpecific.VP8.denoisingOn ? |
664 denoiser_state : kDenoiserOff); | 661 denoiser_state : kDenoiserOff); |
665 } | 662 } |
666 for (size_t i = 0; i < encoders_.size(); ++i) { | 663 for (size_t i = 0; i < encoders_.size(); ++i) { |
667 vpx_codec_control(&(encoders_[i]), VP8E_SET_STATIC_THRESHOLD, 1); | 664 vpx_codec_control(&(encoders_[i]), VP8E_SET_STATIC_THRESHOLD, 1); |
668 vpx_codec_control(&(encoders_[i]), VP8E_SET_CPUUSED, cpu_speed_[i]); | 665 vpx_codec_control(&(encoders_[i]), VP8E_SET_CPUUSED, cpu_speed_[i]); |
669 vpx_codec_control(&(encoders_[i]), VP8E_SET_TOKEN_PARTITIONS, | 666 vpx_codec_control(&(encoders_[i]), VP8E_SET_TOKEN_PARTITIONS, |
670 static_cast<vp8e_token_partitions>(token_partitions_)); | 667 static_cast<vp8e_token_partitions>(token_partitions_)); |
671 vpx_codec_control(&(encoders_[i]), VP8E_SET_MAX_INTRA_BITRATE_PCT, | 668 vpx_codec_control(&(encoders_[i]), VP8E_SET_MAX_INTRA_BITRATE_PCT, |
672 rc_max_intra_target_); | 669 rc_max_intra_target_); |
| 670 // VP8E_SET_SCREEN_CONTENT_MODE 2 = screen content with more aggressive |
| 671 // rate control (drop frames on large target bitrate overshoot) |
673 vpx_codec_control(&(encoders_[i]), VP8E_SET_SCREEN_CONTENT_MODE, | 672 vpx_codec_control(&(encoders_[i]), VP8E_SET_SCREEN_CONTENT_MODE, |
674 codec_.mode == kScreensharing); | 673 codec_.mode == kScreensharing ? 2 : 0); |
675 } | 674 } |
676 inited_ = true; | 675 inited_ = true; |
677 return WEBRTC_VIDEO_CODEC_OK; | 676 return WEBRTC_VIDEO_CODEC_OK; |
678 } | 677 } |
679 | 678 |
680 uint32_t VP8EncoderImpl::MaxIntraTarget(uint32_t optimalBuffersize) { | 679 uint32_t VP8EncoderImpl::MaxIntraTarget(uint32_t optimalBuffersize) { |
681 // Set max to the optimal buffer level (normalized by target BR), | 680 // Set max to the optimal buffer level (normalized by target BR), |
682 // and scaled by a scalePar. | 681 // and scaled by a scalePar. |
683 // Max target size = scalePar * optimalBufferSize * targetBR[Kbps]. | 682 // Max target size = scalePar * optimalBufferSize * targetBR[Kbps]. |
684 // This values is presented in percentage of perFrameBw: | 683 // This values is presented in percentage of perFrameBw: |
685 // perFrameBw = targetBR[Kbps] * 1000 / frameRate. | 684 // perFrameBw = targetBR[Kbps] * 1000 / frameRate. |
686 // The target in % is as follows: | 685 // The target in % is as follows: |
687 | 686 |
688 float scalePar = 0.5; | 687 float scalePar = 0.5; |
689 uint32_t targetPct = optimalBuffersize * scalePar * codec_.maxFramerate / 10; | 688 uint32_t targetPct = optimalBuffersize * scalePar * codec_.maxFramerate / 10; |
690 | 689 |
691 // Don't go below 3 times the per frame bandwidth. | 690 // Don't go below 3 times the per frame bandwidth. |
692 const uint32_t minIntraTh = 300; | 691 const uint32_t minIntraTh = 300; |
693 return (targetPct < minIntraTh) ? minIntraTh: targetPct; | 692 return (targetPct < minIntraTh) ? minIntraTh: targetPct; |
694 } | 693 } |
695 | 694 |
696 int VP8EncoderImpl::Encode(const VideoFrame& frame, | 695 int VP8EncoderImpl::Encode(const VideoFrame& frame, |
697 const CodecSpecificInfo* codec_specific_info, | 696 const CodecSpecificInfo* codec_specific_info, |
698 const std::vector<VideoFrameType>* frame_types) { | 697 const std::vector<VideoFrameType>* frame_types) { |
699 TRACE_EVENT1("webrtc", "VP8::Encode", "timestamp", frame.timestamp()); | 698 TRACE_EVENT1("webrtc", "VP8::Encode", "timestamp", frame.timestamp()); |
700 | 699 |
701 if (!inited_) { | 700 if (!inited_) |
702 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 701 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
703 } | 702 if (frame.IsZeroSize()) |
704 if (frame.IsZeroSize()) { | |
705 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 703 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
706 } | 704 if (encoded_complete_callback_ == NULL) |
707 if (encoded_complete_callback_ == NULL) { | |
708 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 705 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
709 } | |
710 | 706 |
711 // Only apply scaling to improve for single-layer streams. The scaling metrics | 707 // Only apply scaling to improve for single-layer streams. The scaling metrics |
712 // use frame drops as a signal and is only applicable when we drop frames. | 708 // use frame drops as a signal and is only applicable when we drop frames. |
713 const bool use_quality_scaler = encoders_.size() == 1 && | 709 const bool use_quality_scaler = encoders_.size() == 1 && |
714 configurations_[0].rc_dropframe_thresh > 0 && | 710 configurations_[0].rc_dropframe_thresh > 0 && |
715 codec_.codecSpecific.VP8.automaticResizeOn; | 711 codec_.codecSpecific.VP8.automaticResizeOn; |
716 const VideoFrame& input_image = | 712 const VideoFrame& input_image = |
717 use_quality_scaler ? quality_scaler_.GetScaledFrame(frame) : frame; | 713 use_quality_scaler ? quality_scaler_.GetScaledFrame(frame) : frame; |
718 | 714 |
719 if (use_quality_scaler && (input_image.width() != codec_.width || | 715 if (use_quality_scaler && (input_image.width() != codec_.width || |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
844 } | 840 } |
845 } | 841 } |
846 } | 842 } |
847 } | 843 } |
848 // Set the encoder frame flags and temporal layer_id for each spatial stream. | 844 // Set the encoder frame flags and temporal layer_id for each spatial stream. |
849 // Note that |temporal_layers_| are defined starting from lowest resolution at | 845 // Note that |temporal_layers_| are defined starting from lowest resolution at |
850 // position 0 to highest resolution at position |encoders_.size() - 1|, | 846 // position 0 to highest resolution at position |encoders_.size() - 1|, |
851 // whereas |encoder_| is from highest to lowest resolution. | 847 // whereas |encoder_| is from highest to lowest resolution. |
852 size_t stream_idx = encoders_.size() - 1; | 848 size_t stream_idx = encoders_.size() - 1; |
853 for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) { | 849 for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) { |
| 850 // Allow the layers adapter to temporarily modify the configuration. This |
| 851 // change isn't stored in configurations_ so change will be discarded at |
| 852 // the next update. |
| 853 vpx_codec_enc_cfg_t temp_config; |
| 854 memcpy(&temp_config, &configurations_[i], sizeof(vpx_codec_enc_cfg_t)); |
| 855 if (temporal_layers_[stream_idx]->UpdateConfiguration(&temp_config)) { |
| 856 if (vpx_codec_enc_config_set(&encoders_[i], &temp_config)) |
| 857 return WEBRTC_VIDEO_CODEC_ERROR; |
| 858 } |
| 859 |
854 vpx_codec_control(&encoders_[i], VP8E_SET_FRAME_FLAGS, flags[stream_idx]); | 860 vpx_codec_control(&encoders_[i], VP8E_SET_FRAME_FLAGS, flags[stream_idx]); |
855 vpx_codec_control(&encoders_[i], | 861 vpx_codec_control(&encoders_[i], |
856 VP8E_SET_TEMPORAL_LAYER_ID, | 862 VP8E_SET_TEMPORAL_LAYER_ID, |
857 temporal_layers_[stream_idx]->CurrentLayerId()); | 863 temporal_layers_[stream_idx]->CurrentLayerId()); |
858 } | 864 } |
859 // TODO(holmer): Ideally the duration should be the timestamp diff of this | 865 // TODO(holmer): Ideally the duration should be the timestamp diff of this |
860 // frame and the next frame to be encoded, which we don't have. Instead we | 866 // frame and the next frame to be encoded, which we don't have. Instead we |
861 // would like to use the duration of the previous frame. Unfortunately the | 867 // would like to use the duration of the previous frame. Unfortunately the |
862 // rate control seems to be off with that setup. Using the average input | 868 // rate control seems to be off with that setup. Using the average input |
863 // frame rate to calculate an average duration for now. | 869 // frame rate to calculate an average duration for now. |
864 assert(codec_.maxFramerate > 0); | 870 assert(codec_.maxFramerate > 0); |
865 uint32_t duration = 90000 / codec_.maxFramerate; | 871 uint32_t duration = 90000 / codec_.maxFramerate; |
866 | 872 |
867 // Note we must pass 0 for |flags| field in encode call below since they are | 873 // Note we must pass 0 for |flags| field in encode call below since they are |
868 // set above in |vpx_codec_control| function for each encoder/spatial layer. | 874 // set above in |vpx_codec_control| function for each encoder/spatial layer. |
869 int error = vpx_codec_encode(&encoders_[0], &raw_images_[0], timestamp_, | 875 int error = vpx_codec_encode(&encoders_[0], &raw_images_[0], timestamp_, |
870 duration, 0, VPX_DL_REALTIME); | 876 duration, 0, VPX_DL_REALTIME); |
871 // Reset specific intra frame thresholds, following the key frame. | 877 // Reset specific intra frame thresholds, following the key frame. |
872 if (send_key_frame) { | 878 if (send_key_frame) { |
873 vpx_codec_control(&(encoders_[0]), VP8E_SET_MAX_INTRA_BITRATE_PCT, | 879 vpx_codec_control(&(encoders_[0]), VP8E_SET_MAX_INTRA_BITRATE_PCT, |
874 rc_max_intra_target_); | 880 rc_max_intra_target_); |
875 } | 881 } |
876 if (error) { | 882 if (error) |
877 return WEBRTC_VIDEO_CODEC_ERROR; | 883 return WEBRTC_VIDEO_CODEC_ERROR; |
878 } | |
879 timestamp_ += duration; | 884 timestamp_ += duration; |
880 return GetEncodedPartitions(input_image, only_predict_from_key_frame); | 885 return GetEncodedPartitions(input_image, only_predict_from_key_frame); |
881 } | 886 } |
882 | 887 |
883 // TODO(pbos): Make sure this works for properly for >1 encoders. | 888 // TODO(pbos): Make sure this works for properly for >1 encoders. |
884 int VP8EncoderImpl::UpdateCodecFrameSize(const VideoFrame& input_image) { | 889 int VP8EncoderImpl::UpdateCodecFrameSize(const VideoFrame& input_image) { |
885 codec_.width = input_image.width(); | 890 codec_.width = input_image.width(); |
886 codec_.height = input_image.height(); | 891 codec_.height = input_image.height(); |
887 // Update the cpu_speed setting for resolution change. | 892 // Update the cpu_speed setting for resolution change. |
888 vpx_codec_control(&(encoders_[0]), | 893 vpx_codec_control(&(encoders_[0]), |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 temporal_layers_[stream_idx]->PopulateCodecSpecific(base_layer_sync_point, | 931 temporal_layers_[stream_idx]->PopulateCodecSpecific(base_layer_sync_point, |
927 vp8Info, | 932 vp8Info, |
928 timestamp); | 933 timestamp); |
929 // Prepare next. | 934 // Prepare next. |
930 picture_id_[stream_idx] = (picture_id_[stream_idx] + 1) & 0x7FFF; | 935 picture_id_[stream_idx] = (picture_id_[stream_idx] + 1) & 0x7FFF; |
931 } | 936 } |
932 | 937 |
933 int VP8EncoderImpl::GetEncodedPartitions(const VideoFrame& input_image, | 938 int VP8EncoderImpl::GetEncodedPartitions(const VideoFrame& input_image, |
934 bool only_predicting_from_key_frame) { | 939 bool only_predicting_from_key_frame) { |
935 int stream_idx = static_cast<int>(encoders_.size()) - 1; | 940 int stream_idx = static_cast<int>(encoders_.size()) - 1; |
| 941 int result = WEBRTC_VIDEO_CODEC_OK; |
936 for (size_t encoder_idx = 0; encoder_idx < encoders_.size(); | 942 for (size_t encoder_idx = 0; encoder_idx < encoders_.size(); |
937 ++encoder_idx, --stream_idx) { | 943 ++encoder_idx, --stream_idx) { |
938 vpx_codec_iter_t iter = NULL; | 944 vpx_codec_iter_t iter = NULL; |
939 int part_idx = 0; | 945 int part_idx = 0; |
940 encoded_images_[encoder_idx]._length = 0; | 946 encoded_images_[encoder_idx]._length = 0; |
941 encoded_images_[encoder_idx]._frameType = kDeltaFrame; | 947 encoded_images_[encoder_idx]._frameType = kDeltaFrame; |
942 RTPFragmentationHeader frag_info; | 948 RTPFragmentationHeader frag_info; |
943 // token_partitions_ is number of bits used. | 949 // token_partitions_ is number of bits used. |
944 frag_info.VerifyAndAllocateFragmentationHeader((1 << token_partitions_) | 950 frag_info.VerifyAndAllocateFragmentationHeader((1 << token_partitions_) |
945 + 1); | 951 + 1); |
(...skipping 28 matching lines...) Expand all Loading... |
974 } | 980 } |
975 PopulateCodecSpecific(&codec_specific, *pkt, stream_idx, | 981 PopulateCodecSpecific(&codec_specific, *pkt, stream_idx, |
976 input_image.timestamp(), | 982 input_image.timestamp(), |
977 only_predicting_from_key_frame); | 983 only_predicting_from_key_frame); |
978 break; | 984 break; |
979 } | 985 } |
980 } | 986 } |
981 encoded_images_[encoder_idx]._timeStamp = input_image.timestamp(); | 987 encoded_images_[encoder_idx]._timeStamp = input_image.timestamp(); |
982 encoded_images_[encoder_idx].capture_time_ms_ = | 988 encoded_images_[encoder_idx].capture_time_ms_ = |
983 input_image.render_time_ms(); | 989 input_image.render_time_ms(); |
| 990 |
| 991 int qp = -1; |
| 992 vpx_codec_control(&encoders_[encoder_idx], VP8E_GET_LAST_QUANTIZER_64, &qp); |
984 temporal_layers_[stream_idx]->FrameEncoded( | 993 temporal_layers_[stream_idx]->FrameEncoded( |
985 encoded_images_[encoder_idx]._length, | 994 encoded_images_[encoder_idx]._length, |
986 encoded_images_[encoder_idx]._timeStamp); | 995 encoded_images_[encoder_idx]._timeStamp, qp); |
987 if (send_stream_[stream_idx]) { | 996 if (send_stream_[stream_idx]) { |
988 if (encoded_images_[encoder_idx]._length > 0) { | 997 if (encoded_images_[encoder_idx]._length > 0) { |
989 TRACE_COUNTER_ID1("webrtc", "EncodedFrameSize", encoder_idx, | 998 TRACE_COUNTER_ID1("webrtc", "EncodedFrameSize", encoder_idx, |
990 encoded_images_[encoder_idx]._length); | 999 encoded_images_[encoder_idx]._length); |
991 encoded_images_[encoder_idx]._encodedHeight = | 1000 encoded_images_[encoder_idx]._encodedHeight = |
992 codec_.simulcastStream[stream_idx].height; | 1001 codec_.simulcastStream[stream_idx].height; |
993 encoded_images_[encoder_idx]._encodedWidth = | 1002 encoded_images_[encoder_idx]._encodedWidth = |
994 codec_.simulcastStream[stream_idx].width; | 1003 codec_.simulcastStream[stream_idx].width; |
995 encoded_complete_callback_->Encoded(encoded_images_[encoder_idx], | 1004 encoded_complete_callback_->Encoded(encoded_images_[encoder_idx], |
996 &codec_specific, &frag_info); | 1005 &codec_specific, &frag_info); |
| 1006 } else if (codec_.mode == kScreensharing) { |
| 1007 result = WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT; |
997 } | 1008 } |
998 } else { | 1009 } else { |
999 // Required in case padding is applied to dropped frames. | 1010 // Required in case padding is applied to dropped frames. |
1000 encoded_images_[encoder_idx]._length = 0; | 1011 encoded_images_[encoder_idx]._length = 0; |
1001 encoded_images_[encoder_idx]._frameType = kSkipFrame; | 1012 encoded_images_[encoder_idx]._frameType = kSkipFrame; |
1002 codec_specific.codecType = kVideoCodecVP8; | 1013 codec_specific.codecType = kVideoCodecVP8; |
1003 CodecSpecificInfoVP8* vp8Info = &(codec_specific.codecSpecific.VP8); | 1014 CodecSpecificInfoVP8* vp8Info = &(codec_specific.codecSpecific.VP8); |
1004 vp8Info->pictureId = picture_id_[stream_idx]; | 1015 vp8Info->pictureId = picture_id_[stream_idx]; |
1005 vp8Info->simulcastIdx = stream_idx; | 1016 vp8Info->simulcastIdx = stream_idx; |
1006 vp8Info->keyIdx = kNoKeyIdx; | 1017 vp8Info->keyIdx = kNoKeyIdx; |
1007 encoded_complete_callback_->Encoded(encoded_images_[encoder_idx], | 1018 encoded_complete_callback_->Encoded(encoded_images_[encoder_idx], |
1008 &codec_specific, NULL); | 1019 &codec_specific, NULL); |
1009 } | 1020 } |
1010 } | 1021 } |
1011 if (encoders_.size() == 1 && send_stream_[0]) { | 1022 if (encoders_.size() == 1 && send_stream_[0]) { |
1012 if (encoded_images_[0]._length > 0) { | 1023 if (encoded_images_[0]._length > 0) { |
1013 int qp; | 1024 int qp; |
1014 vpx_codec_control(&encoders_[0], VP8E_GET_LAST_QUANTIZER_64, &qp); | 1025 vpx_codec_control(&encoders_[0], VP8E_GET_LAST_QUANTIZER_64, &qp); |
1015 quality_scaler_.ReportQP(qp); | 1026 quality_scaler_.ReportQP(qp); |
1016 } else { | 1027 } else { |
1017 quality_scaler_.ReportDroppedFrame(); | 1028 quality_scaler_.ReportDroppedFrame(); |
1018 } | 1029 } |
1019 } | 1030 } |
1020 return WEBRTC_VIDEO_CODEC_OK; | 1031 return result; |
1021 } | 1032 } |
1022 | 1033 |
1023 int VP8EncoderImpl::SetChannelParameters(uint32_t packetLoss, int64_t rtt) { | 1034 int VP8EncoderImpl::SetChannelParameters(uint32_t packetLoss, int64_t rtt) { |
1024 rps_.SetRtt(rtt); | 1035 rps_.SetRtt(rtt); |
1025 return WEBRTC_VIDEO_CODEC_OK; | 1036 return WEBRTC_VIDEO_CODEC_OK; |
1026 } | 1037 } |
1027 | 1038 |
1028 int VP8EncoderImpl::RegisterEncodeCompleteCallback( | 1039 int VP8EncoderImpl::RegisterEncodeCompleteCallback( |
1029 EncodedImageCallback* callback) { | 1040 EncodedImageCallback* callback) { |
1030 encoded_complete_callback_ = callback; | 1041 encoded_complete_callback_ = callback; |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1375 return -1; | 1386 return -1; |
1376 } | 1387 } |
1377 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) | 1388 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) |
1378 != VPX_CODEC_OK) { | 1389 != VPX_CODEC_OK) { |
1379 return -1; | 1390 return -1; |
1380 } | 1391 } |
1381 return 0; | 1392 return 0; |
1382 } | 1393 } |
1383 | 1394 |
1384 } // namespace webrtc | 1395 } // namespace webrtc |
OLD | NEW |