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

Side by Side Diff: webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc

Issue 2753783002: Delete VP8 feedback mode. (Closed)
Patch Set: Rebased. Created 3 years, 9 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) 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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 } 127 }
128 128
129 VP8Decoder* VP8Decoder::Create() { 129 VP8Decoder* VP8Decoder::Create() {
130 return new VP8DecoderImpl(); 130 return new VP8DecoderImpl();
131 } 131 }
132 132
133 VP8EncoderImpl::VP8EncoderImpl() 133 VP8EncoderImpl::VP8EncoderImpl()
134 : encoded_complete_callback_(nullptr), 134 : encoded_complete_callback_(nullptr),
135 inited_(false), 135 inited_(false),
136 timestamp_(0), 136 timestamp_(0),
137 feedback_mode_(false),
138 qp_max_(56), // Setting for max quantizer. 137 qp_max_(56), // Setting for max quantizer.
139 cpu_speed_default_(-6), 138 cpu_speed_default_(-6),
140 number_of_cores_(0), 139 number_of_cores_(0),
141 rc_max_intra_target_(0), 140 rc_max_intra_target_(0),
142 token_partitions_(VP8_ONE_TOKENPARTITION), 141 token_partitions_(VP8_ONE_TOKENPARTITION),
143 down_scale_requested_(false), 142 down_scale_requested_(false),
144 down_scale_bitrate_(0), 143 down_scale_bitrate_(0),
145 use_gf_boost_(webrtc::field_trial::IsEnabled(kVp8GfBoostFieldTrial)), 144 use_gf_boost_(webrtc::field_trial::IsEnabled(kVp8GfBoostFieldTrial)),
146 key_frame_request_(kMaxSimulcastStreams, false) { 145 key_frame_request_(kMaxSimulcastStreams, false) {
147 uint32_t seed = rtc::Time32(); 146 uint32_t seed = rtc::Time32();
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 342 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
344 } 343 }
345 344
346 int num_temporal_layers = 345 int num_temporal_layers =
347 doing_simulcast ? inst->simulcastStream[0].numberOfTemporalLayers 346 doing_simulcast ? inst->simulcastStream[0].numberOfTemporalLayers
348 : inst->VP8().numberOfTemporalLayers; 347 : inst->VP8().numberOfTemporalLayers;
349 RTC_DCHECK_GT(num_temporal_layers, 0); 348 RTC_DCHECK_GT(num_temporal_layers, 0);
350 349
351 SetupTemporalLayers(number_of_streams, num_temporal_layers, *inst); 350 SetupTemporalLayers(number_of_streams, num_temporal_layers, *inst);
352 351
353 feedback_mode_ = inst->VP8().feedbackModeOn;
354
355 number_of_cores_ = number_of_cores; 352 number_of_cores_ = number_of_cores;
356 timestamp_ = 0; 353 timestamp_ = 0;
357 codec_ = *inst; 354 codec_ = *inst;
358 355
359 // Code expects simulcastStream resolutions to be correct, make sure they are 356 // Code expects simulcastStream resolutions to be correct, make sure they are
360 // filled even when there are no simulcast layers. 357 // filled even when there are no simulcast layers.
361 if (codec_.numberOfSimulcastStreams == 0) { 358 if (codec_.numberOfSimulcastStreams == 0) {
362 codec_.simulcastStream[0].width = codec_.width; 359 codec_.simulcastStream[0].width = codec_.width;
363 codec_.simulcastStream[0].height = codec_.height; 360 codec_.simulcastStream[0].height = codec_.height;
364 } 361 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 configurations_[0].rc_max_quantizer = qp_max_; 442 configurations_[0].rc_max_quantizer = qp_max_;
446 configurations_[0].rc_undershoot_pct = 100; 443 configurations_[0].rc_undershoot_pct = 100;
447 configurations_[0].rc_overshoot_pct = 15; 444 configurations_[0].rc_overshoot_pct = 15;
448 configurations_[0].rc_buf_initial_sz = 500; 445 configurations_[0].rc_buf_initial_sz = 500;
449 configurations_[0].rc_buf_optimal_sz = 600; 446 configurations_[0].rc_buf_optimal_sz = 600;
450 configurations_[0].rc_buf_sz = 1000; 447 configurations_[0].rc_buf_sz = 1000;
451 448
452 // Set the maximum target size of any key-frame. 449 // Set the maximum target size of any key-frame.
453 rc_max_intra_target_ = MaxIntraTarget(configurations_[0].rc_buf_optimal_sz); 450 rc_max_intra_target_ = MaxIntraTarget(configurations_[0].rc_buf_optimal_sz);
454 451
455 if (feedback_mode_) { 452 if (inst->VP8().keyFrameInterval > 0) {
456 // Disable periodic key frames if we get feedback from the decoder
457 // through SLI and RPSI.
458 configurations_[0].kf_mode = VPX_KF_DISABLED;
459 } else if (inst->VP8().keyFrameInterval > 0) {
460 configurations_[0].kf_mode = VPX_KF_AUTO; 453 configurations_[0].kf_mode = VPX_KF_AUTO;
461 configurations_[0].kf_max_dist = inst->VP8().keyFrameInterval; 454 configurations_[0].kf_max_dist = inst->VP8().keyFrameInterval;
462 } else { 455 } else {
463 configurations_[0].kf_mode = VPX_KF_DISABLED; 456 configurations_[0].kf_mode = VPX_KF_DISABLED;
464 } 457 }
465 458
466 // Allow the user to set the complexity for the base stream. 459 // Allow the user to set the complexity for the base stream.
467 switch (inst->VP8().complexity) { 460 switch (inst->VP8().complexity) {
468 case kComplexityHigh: 461 case kComplexityHigh:
469 cpu_speed_[0] = -5; 462 cpu_speed_[0] = -5;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 vpx_img_alloc(&raw_images_[i], VPX_IMG_FMT_I420, 526 vpx_img_alloc(&raw_images_[i], VPX_IMG_FMT_I420,
534 inst->simulcastStream[stream_idx].width, 527 inst->simulcastStream[stream_idx].width,
535 inst->simulcastStream[stream_idx].height, kVp832ByteAlign); 528 inst->simulcastStream[stream_idx].height, kVp832ByteAlign);
536 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx); 529 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx);
537 configurations_[i].rc_target_bitrate = stream_bitrates[stream_idx]; 530 configurations_[i].rc_target_bitrate = stream_bitrates[stream_idx];
538 temporal_layers_[stream_idx]->OnRatesUpdated( 531 temporal_layers_[stream_idx]->OnRatesUpdated(
539 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate); 532 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate);
540 temporal_layers_[stream_idx]->UpdateConfiguration(&configurations_[i]); 533 temporal_layers_[stream_idx]->UpdateConfiguration(&configurations_[i]);
541 } 534 }
542 535
543 rps_.Init();
544 return InitAndSetControlSettings(); 536 return InitAndSetControlSettings();
545 } 537 }
546 538
547 int VP8EncoderImpl::SetCpuSpeed(int width, int height) { 539 int VP8EncoderImpl::SetCpuSpeed(int width, int height) {
548 #if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID) 540 #if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID)
549 // On mobile platform, use a lower speed setting for lower resolutions for 541 // On mobile platform, use a lower speed setting for lower resolutions for
550 // CPUs with 4 or more cores. 542 // CPUs with 4 or more cores.
551 RTC_DCHECK_GT(number_of_cores_, 0); 543 RTC_DCHECK_GT(number_of_cores_, 0);
552 if (number_of_cores_ <= 3) 544 if (number_of_cores_ <= 3)
553 return -12; 545 return -12;
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 const uint32_t forceKeyFrameIntraTh = 100; 755 const uint32_t forceKeyFrameIntraTh = 100;
764 vpx_codec_control(&(encoders_[0]), VP8E_SET_MAX_INTRA_BITRATE_PCT, 756 vpx_codec_control(&(encoders_[0]), VP8E_SET_MAX_INTRA_BITRATE_PCT,
765 forceKeyFrameIntraTh); 757 forceKeyFrameIntraTh);
766 } 758 }
767 // Key frame request from caller. 759 // Key frame request from caller.
768 // Will update both golden and alt-ref. 760 // Will update both golden and alt-ref.
769 for (size_t i = 0; i < encoders_.size(); ++i) { 761 for (size_t i = 0; i < encoders_.size(); ++i) {
770 flags[i] = VPX_EFLAG_FORCE_KF; 762 flags[i] = VPX_EFLAG_FORCE_KF;
771 } 763 }
772 std::fill(key_frame_request_.begin(), key_frame_request_.end(), false); 764 std::fill(key_frame_request_.begin(), key_frame_request_.end(), false);
773 } else if (codec_specific_info &&
774 codec_specific_info->codecType == kVideoCodecVP8) {
775 if (feedback_mode_) {
776 // Handle RPSI and SLI messages and set up the appropriate encode flags.
777 bool sendRefresh = false;
778 if (codec_specific_info->codecSpecific.VP8.hasReceivedRPSI) {
779 rps_.ReceivedRPSI(codec_specific_info->codecSpecific.VP8.pictureIdRPSI);
780 }
781 if (codec_specific_info->codecSpecific.VP8.hasReceivedSLI) {
782 sendRefresh = rps_.ReceivedSLI(frame.timestamp());
783 }
784 for (size_t i = 0; i < encoders_.size(); ++i) {
785 flags[i] = rps_.EncodeFlags(picture_id_[i], sendRefresh,
786 frame.timestamp());
787 }
788 } else {
789 if (codec_specific_info->codecSpecific.VP8.hasReceivedRPSI) {
790 // Is this our last key frame? If not ignore.
791 // |picture_id_| is defined per spatial stream/layer, so check that
792 // |RPSI| matches the last key frame from any of the spatial streams.
793 // If so, then all spatial streams for this encoding will predict from
794 // its long-term reference (last key frame).
795 int RPSI = codec_specific_info->codecSpecific.VP8.pictureIdRPSI;
796 for (size_t i = 0; i < encoders_.size(); ++i) {
797 if (last_key_frame_picture_id_[i] == RPSI) {
798 // Request for a long term reference frame.
799 // Note 1: overwrites any temporal settings.
800 // Note 2: VP8_EFLAG_NO_UPD_ENTROPY is not needed as that flag is
801 // set by error_resilient mode.
802 for (size_t j = 0; j < encoders_.size(); ++j) {
803 flags[j] = VP8_EFLAG_NO_UPD_ARF;
804 flags[j] |= VP8_EFLAG_NO_REF_GF;
805 flags[j] |= VP8_EFLAG_NO_REF_LAST;
806 }
807 only_predict_from_key_frame = true;
808 break;
809 }
810 }
811 }
812 }
813 } 765 }
766
814 // Set the encoder frame flags and temporal layer_id for each spatial stream. 767 // Set the encoder frame flags and temporal layer_id for each spatial stream.
815 // Note that |temporal_layers_| are defined starting from lowest resolution at 768 // Note that |temporal_layers_| are defined starting from lowest resolution at
816 // position 0 to highest resolution at position |encoders_.size() - 1|, 769 // position 0 to highest resolution at position |encoders_.size() - 1|,
817 // whereas |encoder_| is from highest to lowest resolution. 770 // whereas |encoder_| is from highest to lowest resolution.
818 size_t stream_idx = encoders_.size() - 1; 771 size_t stream_idx = encoders_.size() - 1;
819 for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) { 772 for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) {
820 // Allow the layers adapter to temporarily modify the configuration. This 773 // Allow the layers adapter to temporarily modify the configuration. This
821 // change isn't stored in configurations_ so change will be discarded at 774 // change isn't stored in configurations_ so change will be discarded at
822 // the next update. 775 // the next update.
823 vpx_codec_enc_cfg_t temp_config; 776 vpx_codec_enc_cfg_t temp_config;
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 break; 906 break;
954 } 907 }
955 default: 908 default:
956 break; 909 break;
957 } 910 }
958 // End of frame 911 // End of frame
959 if ((pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT) == 0) { 912 if ((pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT) == 0) {
960 // check if encoded frame is a key frame 913 // check if encoded frame is a key frame
961 if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) { 914 if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
962 encoded_images_[encoder_idx]._frameType = kVideoFrameKey; 915 encoded_images_[encoder_idx]._frameType = kVideoFrameKey;
963 rps_.EncodedKeyFrame(picture_id_[stream_idx]);
964 } 916 }
965 PopulateCodecSpecific(&codec_specific, *pkt, stream_idx, 917 PopulateCodecSpecific(&codec_specific, *pkt, stream_idx,
966 input_image.timestamp(), 918 input_image.timestamp(),
967 only_predicting_from_key_frame); 919 only_predicting_from_key_frame);
968 break; 920 break;
969 } 921 }
970 } 922 }
971 encoded_images_[encoder_idx]._timeStamp = input_image.timestamp(); 923 encoded_images_[encoder_idx]._timeStamp = input_image.timestamp();
972 encoded_images_[encoder_idx].capture_time_ms_ = 924 encoded_images_[encoder_idx].capture_time_ms_ =
973 input_image.render_time_ms(); 925 input_image.render_time_ms();
(...skipping 30 matching lines...) Expand all
1004 } 956 }
1005 957
1006 VideoEncoder::ScalingSettings VP8EncoderImpl::GetScalingSettings() const { 958 VideoEncoder::ScalingSettings VP8EncoderImpl::GetScalingSettings() const {
1007 const bool enable_scaling = encoders_.size() == 1 && 959 const bool enable_scaling = encoders_.size() == 1 &&
1008 configurations_[0].rc_dropframe_thresh > 0 && 960 configurations_[0].rc_dropframe_thresh > 0 &&
1009 codec_.VP8().automaticResizeOn; 961 codec_.VP8().automaticResizeOn;
1010 return VideoEncoder::ScalingSettings(enable_scaling); 962 return VideoEncoder::ScalingSettings(enable_scaling);
1011 } 963 }
1012 964
1013 int VP8EncoderImpl::SetChannelParameters(uint32_t packetLoss, int64_t rtt) { 965 int VP8EncoderImpl::SetChannelParameters(uint32_t packetLoss, int64_t rtt) {
1014 rps_.SetRtt(rtt);
1015 return WEBRTC_VIDEO_CODEC_OK; 966 return WEBRTC_VIDEO_CODEC_OK;
1016 } 967 }
1017 968
1018 int VP8EncoderImpl::RegisterEncodeCompleteCallback( 969 int VP8EncoderImpl::RegisterEncodeCompleteCallback(
1019 EncodedImageCallback* callback) { 970 EncodedImageCallback* callback) {
1020 encoded_complete_callback_ = callback; 971 encoded_complete_callback_ = callback;
1021 return WEBRTC_VIDEO_CODEC_OK; 972 return WEBRTC_VIDEO_CODEC_OK;
1022 } 973 }
1023 974
1024 VP8DecoderImpl::VP8DecoderImpl() 975 VP8DecoderImpl::VP8DecoderImpl()
1025 : buffer_pool_(false, 300 /* max_number_of_buffers*/), 976 : buffer_pool_(false, 300 /* max_number_of_buffers*/),
1026 decode_complete_callback_(NULL), 977 decode_complete_callback_(NULL),
1027 inited_(false), 978 inited_(false),
1028 feedback_mode_(false),
1029 decoder_(NULL), 979 decoder_(NULL),
1030 image_format_(VPX_IMG_FMT_NONE), 980 image_format_(VPX_IMG_FMT_NONE),
1031 ref_frame_(NULL), 981 ref_frame_(NULL),
1032 propagation_cnt_(-1), 982 propagation_cnt_(-1),
1033 last_frame_width_(0), 983 last_frame_width_(0),
1034 last_frame_height_(0), 984 last_frame_height_(0),
1035 key_frame_required_(true), 985 key_frame_required_(true),
1036 use_postproc_arm_(webrtc::field_trial::FindFullName( 986 use_postproc_arm_(webrtc::field_trial::FindFullName(
1037 kVp8PostProcArmFieldTrial) == "Enabled") {} 987 kVp8PostProcArmFieldTrial) == "Enabled") {}
1038 988
1039 VP8DecoderImpl::~VP8DecoderImpl() { 989 VP8DecoderImpl::~VP8DecoderImpl() {
1040 inited_ = true; // in order to do the actual release 990 inited_ = true; // in order to do the actual release
1041 Release(); 991 Release();
1042 } 992 }
1043 993
1044 int VP8DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) { 994 int VP8DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) {
1045 int ret_val = Release(); 995 int ret_val = Release();
1046 if (ret_val < 0) { 996 if (ret_val < 0) {
1047 return ret_val; 997 return ret_val;
1048 } 998 }
1049 if (decoder_ == NULL) { 999 if (decoder_ == NULL) {
1050 decoder_ = new vpx_codec_ctx_t; 1000 decoder_ = new vpx_codec_ctx_t;
1051 memset(decoder_, 0, sizeof(*decoder_)); 1001 memset(decoder_, 0, sizeof(*decoder_));
1052 } 1002 }
1053 if (inst && inst->codecType == kVideoCodecVP8) {
1054 feedback_mode_ = inst->VP8().feedbackModeOn;
1055 }
1056 vpx_codec_dec_cfg_t cfg; 1003 vpx_codec_dec_cfg_t cfg;
1057 // Setting number of threads to a constant value (1) 1004 // Setting number of threads to a constant value (1)
1058 cfg.threads = 1; 1005 cfg.threads = 1;
1059 cfg.h = cfg.w = 0; // set after decode 1006 cfg.h = cfg.w = 0; // set after decode
1060 1007
1061 vpx_codec_flags_t flags = 0; 1008 vpx_codec_flags_t flags = 0;
1062 #if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID) 1009 #if defined(WEBRTC_ARCH_ARM) || defined(WEBRTC_ARCH_ARM64) || defined(ANDROID)
1063 if (use_postproc_arm_) { 1010 if (use_postproc_arm_) {
1064 flags = VPX_CODEC_USE_POSTPROC; 1011 flags = VPX_CODEC_USE_POSTPROC;
1065 } 1012 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 if (key_frame_required_) { 1081 if (key_frame_required_) {
1135 if (input_image._frameType != kVideoFrameKey) 1082 if (input_image._frameType != kVideoFrameKey)
1136 return WEBRTC_VIDEO_CODEC_ERROR; 1083 return WEBRTC_VIDEO_CODEC_ERROR;
1137 // We have a key frame - is it complete? 1084 // We have a key frame - is it complete?
1138 if (input_image._completeFrame) { 1085 if (input_image._completeFrame) {
1139 key_frame_required_ = false; 1086 key_frame_required_ = false;
1140 } else { 1087 } else {
1141 return WEBRTC_VIDEO_CODEC_ERROR; 1088 return WEBRTC_VIDEO_CODEC_ERROR;
1142 } 1089 }
1143 } 1090 }
1144 // Restrict error propagation using key frame requests. Disabled when 1091 // Restrict error propagation using key frame requests.
1145 // the feedback mode is enabled (RPS).
1146 // Reset on a key frame refresh. 1092 // Reset on a key frame refresh.
1147 if (!feedback_mode_) { 1093 if (input_image._frameType == kVideoFrameKey &&
1148 if (input_image._frameType == kVideoFrameKey && 1094 input_image._completeFrame) {
1149 input_image._completeFrame) {
1150 propagation_cnt_ = -1; 1095 propagation_cnt_ = -1;
1151 // Start count on first loss. 1096 // Start count on first loss.
1152 } else if ((!input_image._completeFrame || missing_frames) && 1097 } else if ((!input_image._completeFrame || missing_frames) &&
1153 propagation_cnt_ == -1) { 1098 propagation_cnt_ == -1) {
1154 propagation_cnt_ = 0; 1099 propagation_cnt_ = 0;
1155 } 1100 }
1156 if (propagation_cnt_ >= 0) { 1101 if (propagation_cnt_ >= 0) {
1157 propagation_cnt_++; 1102 propagation_cnt_++;
1158 }
1159 } 1103 }
1160 1104
1161 vpx_codec_iter_t iter = NULL; 1105 vpx_codec_iter_t iter = NULL;
1162 vpx_image_t* img; 1106 vpx_image_t* img;
1163 int ret; 1107 int ret;
1164 1108
1165 // Check for missing frames. 1109 // Check for missing frames.
1166 if (missing_frames) { 1110 if (missing_frames) {
1167 // Call decoder with zero data length to signal missing frames. 1111 // Call decoder with zero data length to signal missing frames.
1168 if (vpx_codec_decode(decoder_, NULL, 0, 0, VPX_DL_REALTIME)) { 1112 if (vpx_codec_decode(decoder_, NULL, 0, 0, VPX_DL_REALTIME)) {
(...skipping 24 matching lines...) Expand all
1193 vpx_codec_err_t vpx_ret = 1137 vpx_codec_err_t vpx_ret =
1194 vpx_codec_control(decoder_, VPXD_GET_LAST_QUANTIZER, &qp); 1138 vpx_codec_control(decoder_, VPXD_GET_LAST_QUANTIZER, &qp);
1195 RTC_DCHECK_EQ(vpx_ret, VPX_CODEC_OK); 1139 RTC_DCHECK_EQ(vpx_ret, VPX_CODEC_OK);
1196 ret = ReturnFrame(img, input_image._timeStamp, input_image.ntp_time_ms_, qp); 1140 ret = ReturnFrame(img, input_image._timeStamp, input_image.ntp_time_ms_, qp);
1197 if (ret != 0) { 1141 if (ret != 0) {
1198 // Reset to avoid requesting key frames too often. 1142 // Reset to avoid requesting key frames too often.
1199 if (ret < 0 && propagation_cnt_ > 0) 1143 if (ret < 0 && propagation_cnt_ > 0)
1200 propagation_cnt_ = 0; 1144 propagation_cnt_ = 0;
1201 return ret; 1145 return ret;
1202 } 1146 }
1203 if (feedback_mode_) {
1204 // Whenever we receive an incomplete key frame all reference buffers will
1205 // be corrupt. If that happens we must request new key frames until we
1206 // decode a complete key frame.
1207 if (input_image._frameType == kVideoFrameKey && !input_image._completeFrame)
1208 return WEBRTC_VIDEO_CODEC_ERROR;
1209 // Check for reference updates and last reference buffer corruption and
1210 // signal successful reference propagation or frame corruption to the
1211 // encoder.
1212 int reference_updates = 0;
1213 if (vpx_codec_control(decoder_, VP8D_GET_LAST_REF_UPDATES,
1214 &reference_updates)) {
1215 // Reset to avoid requesting key frames too often.
1216 if (propagation_cnt_ > 0) {
1217 propagation_cnt_ = 0;
1218 }
1219 return WEBRTC_VIDEO_CODEC_ERROR;
1220 }
1221 int corrupted = 0;
1222 if (vpx_codec_control(decoder_, VP8D_GET_FRAME_CORRUPTED, &corrupted)) {
1223 // Reset to avoid requesting key frames too often.
1224 if (propagation_cnt_ > 0)
1225 propagation_cnt_ = 0;
1226 return WEBRTC_VIDEO_CODEC_ERROR;
1227 }
1228 int16_t picture_id = -1;
1229 if (codec_specific_info) {
1230 picture_id = codec_specific_info->codecSpecific.VP8.pictureId;
1231 }
1232 if (picture_id > -1) {
1233 if (((reference_updates & VP8_GOLD_FRAME) ||
1234 (reference_updates & VP8_ALTR_FRAME)) &&
1235 !corrupted) {
1236 decode_complete_callback_->ReceivedDecodedReferenceFrame(picture_id);
1237 }
1238 decode_complete_callback_->ReceivedDecodedFrame(picture_id);
1239 }
1240 if (corrupted) {
1241 // we can decode but with artifacts
1242 return WEBRTC_VIDEO_CODEC_REQUEST_SLI;
1243 }
1244 }
1245 // Check Vs. threshold 1147 // Check Vs. threshold
1246 if (propagation_cnt_ > kVp8ErrorPropagationTh) { 1148 if (propagation_cnt_ > kVp8ErrorPropagationTh) {
1247 // Reset to avoid requesting key frames too often. 1149 // Reset to avoid requesting key frames too often.
1248 propagation_cnt_ = 0; 1150 propagation_cnt_ = 0;
1249 return WEBRTC_VIDEO_CODEC_ERROR; 1151 return WEBRTC_VIDEO_CODEC_ERROR;
1250 } 1152 }
1251 return WEBRTC_VIDEO_CODEC_OK; 1153 return WEBRTC_VIDEO_CODEC_OK;
1252 } 1154 }
1253 1155
1254 int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img, 1156 int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 return -1; 1227 return -1;
1326 } 1228 }
1327 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != 1229 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) !=
1328 VPX_CODEC_OK) { 1230 VPX_CODEC_OK) {
1329 return -1; 1231 return -1;
1330 } 1232 }
1331 return 0; 1233 return 0;
1332 } 1234 }
1333 1235
1334 } // namespace webrtc 1236 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/codecs/vp8/vp8_impl.h ('k') | webrtc/modules/video_coding/include/video_codec_interface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698