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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 // |codecSpecific.VP8.resilience| = |kResilientStream| at higher level | 426 // |codecSpecific.VP8.resilience| = |kResilientStream| at higher level |
427 // code if we want to get error resilience on. | 427 // code if we want to get error resilience on. |
428 configurations_[0].g_error_resilient = 1; | 428 configurations_[0].g_error_resilient = 1; |
429 break; | 429 break; |
430 case kResilientStream: | 430 case kResilientStream: |
431 configurations_[0].g_error_resilient = 1; // TODO(holmer): Replace with | 431 configurations_[0].g_error_resilient = 1; // TODO(holmer): Replace with |
432 // VPX_ERROR_RESILIENT_DEFAULT when we | 432 // VPX_ERROR_RESILIENT_DEFAULT when we |
433 // drop support for libvpx 9.6.0. | 433 // drop support for libvpx 9.6.0. |
434 break; | 434 break; |
435 case kResilientFrames: | 435 case kResilientFrames: |
436 #ifdef INDEPENDENT_PARTITIONS | |
437 configurations_[0] - g_error_resilient = | |
438 VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS; | |
439 break; | |
440 #else | |
441 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; // Not supported | 436 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; // Not supported |
442 #endif | |
443 } | 437 } |
444 | 438 |
445 // rate control settings | 439 // rate control settings |
446 configurations_[0].rc_dropframe_thresh = | 440 configurations_[0].rc_dropframe_thresh = |
447 inst->codecSpecific.VP8.frameDroppingOn ? 30 : 0; | 441 inst->codecSpecific.VP8.frameDroppingOn ? 30 : 0; |
448 configurations_[0].rc_end_usage = VPX_CBR; | 442 configurations_[0].rc_end_usage = VPX_CBR; |
449 configurations_[0].g_pass = VPX_RC_ONE_PASS; | 443 configurations_[0].g_pass = VPX_RC_ONE_PASS; |
450 // TODO(hellner): investigate why the following two lines produce | 444 // TODO(hellner): investigate why the following two lines produce |
451 // automaticResizeOn value of 3 when running | 445 // automaticResizeOn value of 3 when running |
452 // WebRtcVideoMediaChannelTest.GetStatsMultipleSendStreams inside the talk | 446 // WebRtcVideoMediaChannelTest.GetStatsMultipleSendStreams inside the talk |
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 } | 1077 } |
1084 vpx_codec_dec_cfg_t cfg; | 1078 vpx_codec_dec_cfg_t cfg; |
1085 // Setting number of threads to a constant value (1) | 1079 // Setting number of threads to a constant value (1) |
1086 cfg.threads = 1; | 1080 cfg.threads = 1; |
1087 cfg.h = cfg.w = 0; // set after decode | 1081 cfg.h = cfg.w = 0; // set after decode |
1088 | 1082 |
1089 vpx_codec_flags_t flags = 0; | 1083 vpx_codec_flags_t flags = 0; |
1090 #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \ | 1084 #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \ |
1091 !defined(ANDROID) | 1085 !defined(ANDROID) |
1092 flags = VPX_CODEC_USE_POSTPROC; | 1086 flags = VPX_CODEC_USE_POSTPROC; |
1093 #ifdef INDEPENDENT_PARTITIONS | |
1094 flags |= VPX_CODEC_USE_INPUT_PARTITION; | |
1095 #endif | |
1096 #endif | 1087 #endif |
1097 | 1088 |
1098 if (vpx_codec_dec_init(decoder_, vpx_codec_vp8_dx(), &cfg, flags)) { | 1089 if (vpx_codec_dec_init(decoder_, vpx_codec_vp8_dx(), &cfg, flags)) { |
1099 return WEBRTC_VIDEO_CODEC_MEMORY; | 1090 return WEBRTC_VIDEO_CODEC_MEMORY; |
1100 } | 1091 } |
1101 | 1092 |
1102 // Save VideoCodec instance for later; mainly for duplicating the decoder. | 1093 // Save VideoCodec instance for later; mainly for duplicating the decoder. |
1103 if (&codec_ != inst) | 1094 if (&codec_ != inst) |
1104 codec_ = *inst; | 1095 codec_ = *inst; |
1105 propagation_cnt_ = -1; | 1096 propagation_cnt_ = -1; |
(...skipping 16 matching lines...) Expand all Loading... |
1122 if (decode_complete_callback_ == NULL) { | 1113 if (decode_complete_callback_ == NULL) { |
1123 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 1114 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
1124 } | 1115 } |
1125 if (input_image._buffer == NULL && input_image._length > 0) { | 1116 if (input_image._buffer == NULL && input_image._length > 0) { |
1126 // Reset to avoid requesting key frames too often. | 1117 // Reset to avoid requesting key frames too often. |
1127 if (propagation_cnt_ > 0) | 1118 if (propagation_cnt_ > 0) |
1128 propagation_cnt_ = 0; | 1119 propagation_cnt_ = 0; |
1129 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 1120 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
1130 } | 1121 } |
1131 | 1122 |
1132 #ifdef INDEPENDENT_PARTITIONS | |
1133 if (fragmentation == NULL) { | |
1134 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | |
1135 } | |
1136 #endif | |
1137 | |
1138 #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \ | 1123 #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \ |
1139 !defined(ANDROID) | 1124 !defined(ANDROID) |
1140 vp8_postproc_cfg_t ppcfg; | 1125 vp8_postproc_cfg_t ppcfg; |
1141 // MFQE enabled to reduce key frame popping. | 1126 // MFQE enabled to reduce key frame popping. |
1142 ppcfg.post_proc_flag = VP8_MFQE | VP8_DEBLOCK; | 1127 ppcfg.post_proc_flag = VP8_MFQE | VP8_DEBLOCK; |
1143 // For VGA resolutions and lower, enable the demacroblocker postproc. | 1128 // For VGA resolutions and lower, enable the demacroblocker postproc. |
1144 if (last_frame_width_ * last_frame_height_ <= 640 * 360) { | 1129 if (last_frame_width_ * last_frame_height_ <= 640 * 360) { |
1145 ppcfg.post_proc_flag |= VP8_DEMACROBLOCK; | 1130 ppcfg.post_proc_flag |= VP8_DEMACROBLOCK; |
1146 } | 1131 } |
1147 // Strength of deblocking filter. Valid range:[0,16] | 1132 // Strength of deblocking filter. Valid range:[0,16] |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1187 if (vpx_codec_decode(decoder_, NULL, 0, 0, VPX_DL_REALTIME)) { | 1172 if (vpx_codec_decode(decoder_, NULL, 0, 0, VPX_DL_REALTIME)) { |
1188 // Reset to avoid requesting key frames too often. | 1173 // Reset to avoid requesting key frames too often. |
1189 if (propagation_cnt_ > 0) | 1174 if (propagation_cnt_ > 0) |
1190 propagation_cnt_ = 0; | 1175 propagation_cnt_ = 0; |
1191 return WEBRTC_VIDEO_CODEC_ERROR; | 1176 return WEBRTC_VIDEO_CODEC_ERROR; |
1192 } | 1177 } |
1193 img = vpx_codec_get_frame(decoder_, &iter); | 1178 img = vpx_codec_get_frame(decoder_, &iter); |
1194 iter = NULL; | 1179 iter = NULL; |
1195 } | 1180 } |
1196 | 1181 |
1197 #ifdef INDEPENDENT_PARTITIONS | |
1198 if (DecodePartitions(inputImage, fragmentation)) { | |
1199 // Reset to avoid requesting key frames too often. | |
1200 if (propagation_cnt_ > 0) { | |
1201 propagation_cnt_ = 0; | |
1202 } | |
1203 return WEBRTC_VIDEO_CODEC_ERROR; | |
1204 } | |
1205 #else | |
1206 uint8_t* buffer = input_image._buffer; | 1182 uint8_t* buffer = input_image._buffer; |
1207 if (input_image._length == 0) { | 1183 if (input_image._length == 0) { |
1208 buffer = NULL; // Triggers full frame concealment. | 1184 buffer = NULL; // Triggers full frame concealment. |
1209 } | 1185 } |
1210 if (vpx_codec_decode(decoder_, buffer, input_image._length, 0, | 1186 if (vpx_codec_decode(decoder_, buffer, input_image._length, 0, |
1211 VPX_DL_REALTIME)) { | 1187 VPX_DL_REALTIME)) { |
1212 // Reset to avoid requesting key frames too often. | 1188 // Reset to avoid requesting key frames too often. |
1213 if (propagation_cnt_ > 0) { | 1189 if (propagation_cnt_ > 0) { |
1214 propagation_cnt_ = 0; | 1190 propagation_cnt_ = 0; |
1215 } | 1191 } |
1216 return WEBRTC_VIDEO_CODEC_ERROR; | 1192 return WEBRTC_VIDEO_CODEC_ERROR; |
1217 } | 1193 } |
1218 #endif | |
1219 | 1194 |
1220 img = vpx_codec_get_frame(decoder_, &iter); | 1195 img = vpx_codec_get_frame(decoder_, &iter); |
1221 ret = ReturnFrame(img, input_image._timeStamp, input_image.ntp_time_ms_); | 1196 ret = ReturnFrame(img, input_image._timeStamp, input_image.ntp_time_ms_); |
1222 if (ret != 0) { | 1197 if (ret != 0) { |
1223 // Reset to avoid requesting key frames too often. | 1198 // Reset to avoid requesting key frames too often. |
1224 if (ret < 0 && propagation_cnt_ > 0) | 1199 if (ret < 0 && propagation_cnt_ > 0) |
1225 propagation_cnt_ = 0; | 1200 propagation_cnt_ = 0; |
1226 return ret; | 1201 return ret; |
1227 } | 1202 } |
1228 if (feedback_mode_) { | 1203 if (feedback_mode_) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1269 } | 1244 } |
1270 // Check Vs. threshold | 1245 // Check Vs. threshold |
1271 if (propagation_cnt_ > kVp8ErrorPropagationTh) { | 1246 if (propagation_cnt_ > kVp8ErrorPropagationTh) { |
1272 // Reset to avoid requesting key frames too often. | 1247 // Reset to avoid requesting key frames too often. |
1273 propagation_cnt_ = 0; | 1248 propagation_cnt_ = 0; |
1274 return WEBRTC_VIDEO_CODEC_ERROR; | 1249 return WEBRTC_VIDEO_CODEC_ERROR; |
1275 } | 1250 } |
1276 return WEBRTC_VIDEO_CODEC_OK; | 1251 return WEBRTC_VIDEO_CODEC_OK; |
1277 } | 1252 } |
1278 | 1253 |
1279 int VP8DecoderImpl::DecodePartitions( | |
1280 const EncodedImage& input_image, | |
1281 const RTPFragmentationHeader* fragmentation) { | |
1282 for (int i = 0; i < fragmentation->fragmentationVectorSize; ++i) { | |
1283 const uint8_t* partition = | |
1284 input_image._buffer + fragmentation->fragmentationOffset[i]; | |
1285 const uint32_t partition_length = fragmentation->fragmentationLength[i]; | |
1286 if (vpx_codec_decode(decoder_, partition, partition_length, 0, | |
1287 VPX_DL_REALTIME)) { | |
1288 return WEBRTC_VIDEO_CODEC_ERROR; | |
1289 } | |
1290 } | |
1291 // Signal end of frame data. If there was no frame data this will trigger | |
1292 // a full frame concealment. | |
1293 if (vpx_codec_decode(decoder_, NULL, 0, 0, VPX_DL_REALTIME)) | |
1294 return WEBRTC_VIDEO_CODEC_ERROR; | |
1295 return WEBRTC_VIDEO_CODEC_OK; | |
1296 } | |
1297 | |
1298 int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img, | 1254 int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img, |
1299 uint32_t timestamp, | 1255 uint32_t timestamp, |
1300 int64_t ntp_time_ms) { | 1256 int64_t ntp_time_ms) { |
1301 if (img == NULL) { | 1257 if (img == NULL) { |
1302 // Decoder OK and NULL image => No show frame | 1258 // Decoder OK and NULL image => No show frame |
1303 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; | 1259 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; |
1304 } | 1260 } |
1305 last_frame_width_ = img->d_w; | 1261 last_frame_width_ = img->d_w; |
1306 last_frame_height_ = img->d_h; | 1262 last_frame_height_ = img->d_h; |
1307 // Allocate memory for decoded image. | 1263 // Allocate memory for decoded image. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1363 return -1; | 1319 return -1; |
1364 } | 1320 } |
1365 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != | 1321 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != |
1366 VPX_CODEC_OK) { | 1322 VPX_CODEC_OK) { |
1367 return -1; | 1323 return -1; |
1368 } | 1324 } |
1369 return 0; | 1325 return 0; |
1370 } | 1326 } |
1371 | 1327 |
1372 } // namespace webrtc | 1328 } // namespace webrtc |
OLD | NEW |