| 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 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 // Allow zero to represent an unspecified maxBitRate | 234 // Allow zero to represent an unspecified maxBitRate |
| 235 if (inst->maxBitrate > 0 && inst->startBitrate > inst->maxBitrate) { | 235 if (inst->maxBitrate > 0 && inst->startBitrate > inst->maxBitrate) { |
| 236 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 236 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 237 } | 237 } |
| 238 if (inst->width < 1 || inst->height < 1) { | 238 if (inst->width < 1 || inst->height < 1) { |
| 239 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 239 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 240 } | 240 } |
| 241 if (number_of_cores < 1) { | 241 if (number_of_cores < 1) { |
| 242 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 242 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 243 } | 243 } |
| 244 if (inst->codecSpecific.VP9.numberOfTemporalLayers > 3) { | 244 if (inst->VP9().numberOfTemporalLayers > 3) { |
| 245 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 245 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 246 } | 246 } |
| 247 // libvpx currently supports only one or two spatial layers. | 247 // libvpx currently supports only one or two spatial layers. |
| 248 if (inst->codecSpecific.VP9.numberOfSpatialLayers > 2) { | 248 if (inst->VP9().numberOfSpatialLayers > 2) { |
| 249 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 249 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 250 } | 250 } |
| 251 | 251 |
| 252 int ret_val = Release(); | 252 int ret_val = Release(); |
| 253 if (ret_val < 0) { | 253 if (ret_val < 0) { |
| 254 return ret_val; | 254 return ret_val; |
| 255 } | 255 } |
| 256 if (encoder_ == NULL) { | 256 if (encoder_ == NULL) { |
| 257 encoder_ = new vpx_codec_ctx_t; | 257 encoder_ = new vpx_codec_ctx_t; |
| 258 } | 258 } |
| 259 if (config_ == NULL) { | 259 if (config_ == NULL) { |
| 260 config_ = new vpx_codec_enc_cfg_t; | 260 config_ = new vpx_codec_enc_cfg_t; |
| 261 } | 261 } |
| 262 timestamp_ = 0; | 262 timestamp_ = 0; |
| 263 if (&codec_ != inst) { | 263 if (&codec_ != inst) { |
| 264 codec_ = *inst; | 264 codec_ = *inst; |
| 265 } | 265 } |
| 266 | 266 |
| 267 num_spatial_layers_ = inst->codecSpecific.VP9.numberOfSpatialLayers; | 267 num_spatial_layers_ = inst->VP9().numberOfSpatialLayers; |
| 268 num_temporal_layers_ = inst->codecSpecific.VP9.numberOfTemporalLayers; | 268 num_temporal_layers_ = inst->VP9().numberOfTemporalLayers; |
| 269 if (num_temporal_layers_ == 0) | 269 if (num_temporal_layers_ == 0) |
| 270 num_temporal_layers_ = 1; | 270 num_temporal_layers_ = 1; |
| 271 | 271 |
| 272 // Random start 16 bits is enough. | 272 // Random start 16 bits is enough. |
| 273 picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF; // NOLINT | 273 picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF; // NOLINT |
| 274 // Allocate memory for encoded image | 274 // Allocate memory for encoded image |
| 275 if (encoded_image_._buffer != NULL) { | 275 if (encoded_image_._buffer != NULL) { |
| 276 delete[] encoded_image_._buffer; | 276 delete[] encoded_image_._buffer; |
| 277 } | 277 } |
| 278 encoded_image_._size = CalcBufferSize(kI420, codec_.width, codec_.height); | 278 encoded_image_._size = CalcBufferSize(kI420, codec_.width, codec_.height); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 290 config_->g_w = codec_.width; | 290 config_->g_w = codec_.width; |
| 291 config_->g_h = codec_.height; | 291 config_->g_h = codec_.height; |
| 292 config_->rc_target_bitrate = inst->startBitrate; // in kbit/s | 292 config_->rc_target_bitrate = inst->startBitrate; // in kbit/s |
| 293 config_->g_error_resilient = 1; | 293 config_->g_error_resilient = 1; |
| 294 // Setting the time base of the codec. | 294 // Setting the time base of the codec. |
| 295 config_->g_timebase.num = 1; | 295 config_->g_timebase.num = 1; |
| 296 config_->g_timebase.den = 90000; | 296 config_->g_timebase.den = 90000; |
| 297 config_->g_lag_in_frames = 0; // 0- no frame lagging | 297 config_->g_lag_in_frames = 0; // 0- no frame lagging |
| 298 config_->g_threads = 1; | 298 config_->g_threads = 1; |
| 299 // Rate control settings. | 299 // Rate control settings. |
| 300 config_->rc_dropframe_thresh = | 300 config_->rc_dropframe_thresh = inst->VP9().frameDroppingOn ? 30 : 0; |
| 301 inst->codecSpecific.VP9.frameDroppingOn ? 30 : 0; | |
| 302 config_->rc_end_usage = VPX_CBR; | 301 config_->rc_end_usage = VPX_CBR; |
| 303 config_->g_pass = VPX_RC_ONE_PASS; | 302 config_->g_pass = VPX_RC_ONE_PASS; |
| 304 config_->rc_min_quantizer = 2; | 303 config_->rc_min_quantizer = 2; |
| 305 config_->rc_max_quantizer = 52; | 304 config_->rc_max_quantizer = 52; |
| 306 config_->rc_undershoot_pct = 50; | 305 config_->rc_undershoot_pct = 50; |
| 307 config_->rc_overshoot_pct = 50; | 306 config_->rc_overshoot_pct = 50; |
| 308 config_->rc_buf_initial_sz = 500; | 307 config_->rc_buf_initial_sz = 500; |
| 309 config_->rc_buf_optimal_sz = 600; | 308 config_->rc_buf_optimal_sz = 600; |
| 310 config_->rc_buf_sz = 1000; | 309 config_->rc_buf_sz = 1000; |
| 311 // Set the maximum target size of any key-frame. | 310 // Set the maximum target size of any key-frame. |
| 312 rc_max_intra_target_ = MaxIntraTarget(config_->rc_buf_optimal_sz); | 311 rc_max_intra_target_ = MaxIntraTarget(config_->rc_buf_optimal_sz); |
| 313 if (inst->codecSpecific.VP9.keyFrameInterval > 0) { | 312 if (inst->VP9().keyFrameInterval > 0) { |
| 314 config_->kf_mode = VPX_KF_AUTO; | 313 config_->kf_mode = VPX_KF_AUTO; |
| 315 config_->kf_max_dist = inst->codecSpecific.VP9.keyFrameInterval; | 314 config_->kf_max_dist = inst->VP9().keyFrameInterval; |
| 316 // Needs to be set (in svc mode) to get correct periodic key frame interval | 315 // Needs to be set (in svc mode) to get correct periodic key frame interval |
| 317 // (will have no effect in non-svc). | 316 // (will have no effect in non-svc). |
| 318 config_->kf_min_dist = config_->kf_max_dist; | 317 config_->kf_min_dist = config_->kf_max_dist; |
| 319 } else { | 318 } else { |
| 320 config_->kf_mode = VPX_KF_DISABLED; | 319 config_->kf_mode = VPX_KF_DISABLED; |
| 321 } | 320 } |
| 322 config_->rc_resize_allowed = | 321 config_->rc_resize_allowed = inst->VP9().automaticResizeOn ? 1 : 0; |
| 323 inst->codecSpecific.VP9.automaticResizeOn ? 1 : 0; | |
| 324 // Determine number of threads based on the image size and #cores. | 322 // Determine number of threads based on the image size and #cores. |
| 325 config_->g_threads = | 323 config_->g_threads = |
| 326 NumberOfThreads(config_->g_w, config_->g_h, number_of_cores); | 324 NumberOfThreads(config_->g_w, config_->g_h, number_of_cores); |
| 327 | 325 |
| 328 cpu_speed_ = GetCpuSpeed(config_->g_w, config_->g_h); | 326 cpu_speed_ = GetCpuSpeed(config_->g_w, config_->g_h); |
| 329 | 327 |
| 330 // TODO(asapersson): Check configuration of temporal switch up and increase | 328 // TODO(asapersson): Check configuration of temporal switch up and increase |
| 331 // pattern length. | 329 // pattern length. |
| 332 is_flexible_mode_ = inst->codecSpecific.VP9.flexibleMode; | 330 is_flexible_mode_ = inst->VP9().flexibleMode; |
| 333 if (is_flexible_mode_) { | 331 if (is_flexible_mode_) { |
| 334 config_->temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; | 332 config_->temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; |
| 335 config_->ts_number_layers = num_temporal_layers_; | 333 config_->ts_number_layers = num_temporal_layers_; |
| 336 if (codec_.mode == kScreensharing) | 334 if (codec_.mode == kScreensharing) |
| 337 spatial_layer_->ConfigureBitrate(inst->startBitrate, 0); | 335 spatial_layer_->ConfigureBitrate(inst->startBitrate, 0); |
| 338 } else if (num_temporal_layers_ == 1) { | 336 } else if (num_temporal_layers_ == 1) { |
| 339 gof_.SetGofInfoVP9(kTemporalStructureMode1); | 337 gof_.SetGofInfoVP9(kTemporalStructureMode1); |
| 340 config_->temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING; | 338 config_->temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING; |
| 341 config_->ts_number_layers = 1; | 339 config_->ts_number_layers = 1; |
| 342 config_->ts_rate_decimator[0] = 1; | 340 config_->ts_rate_decimator[0] = 1; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 414 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 417 } | 415 } |
| 418 | 416 |
| 419 if (vpx_codec_enc_init(encoder_, vpx_codec_vp9_cx(), config_, 0)) { | 417 if (vpx_codec_enc_init(encoder_, vpx_codec_vp9_cx(), config_, 0)) { |
| 420 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 418 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 421 } | 419 } |
| 422 vpx_codec_control(encoder_, VP8E_SET_CPUUSED, cpu_speed_); | 420 vpx_codec_control(encoder_, VP8E_SET_CPUUSED, cpu_speed_); |
| 423 vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT, | 421 vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT, |
| 424 rc_max_intra_target_); | 422 rc_max_intra_target_); |
| 425 vpx_codec_control(encoder_, VP9E_SET_AQ_MODE, | 423 vpx_codec_control(encoder_, VP9E_SET_AQ_MODE, |
| 426 inst->codecSpecific.VP9.adaptiveQpMode ? 3 : 0); | 424 inst->VP9().adaptiveQpMode ? 3 : 0); |
| 427 | 425 |
| 428 vpx_codec_control( | 426 vpx_codec_control( |
| 429 encoder_, VP9E_SET_SVC, | 427 encoder_, VP9E_SET_SVC, |
| 430 (num_temporal_layers_ > 1 || num_spatial_layers_ > 1) ? 1 : 0); | 428 (num_temporal_layers_ > 1 || num_spatial_layers_ > 1) ? 1 : 0); |
| 431 if (num_temporal_layers_ > 1 || num_spatial_layers_ > 1) { | 429 if (num_temporal_layers_ > 1 || num_spatial_layers_ > 1) { |
| 432 vpx_codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, | 430 vpx_codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, |
| 433 &svc_internal_.svc_params); | 431 &svc_internal_.svc_params); |
| 434 } | 432 } |
| 435 // Register callback for getting each spatial layer. | 433 // Register callback for getting each spatial layer. |
| 436 vpx_codec_priv_output_cx_pkt_cb_pair_t cbp = { | 434 vpx_codec_priv_output_cx_pkt_cb_pair_t cbp = { |
| 437 VP9EncoderImpl::EncoderOutputCodedPacketCallback, | 435 VP9EncoderImpl::EncoderOutputCodedPacketCallback, |
| 438 reinterpret_cast<void*>(this)}; | 436 reinterpret_cast<void*>(this)}; |
| 439 vpx_codec_control(encoder_, VP9E_REGISTER_CX_CALLBACK, | 437 vpx_codec_control(encoder_, VP9E_REGISTER_CX_CALLBACK, |
| 440 reinterpret_cast<void*>(&cbp)); | 438 reinterpret_cast<void*>(&cbp)); |
| 441 | 439 |
| 442 // Control function to set the number of column tiles in encoding a frame, in | 440 // Control function to set the number of column tiles in encoding a frame, in |
| 443 // log2 unit: e.g., 0 = 1 tile column, 1 = 2 tile columns, 2 = 4 tile columns. | 441 // log2 unit: e.g., 0 = 1 tile column, 1 = 2 tile columns, 2 = 4 tile columns. |
| 444 // The number tile columns will be capped by the encoder based on image size | 442 // The number tile columns will be capped by the encoder based on image size |
| 445 // (minimum width of tile column is 256 pixels, maximum is 4096). | 443 // (minimum width of tile column is 256 pixels, maximum is 4096). |
| 446 vpx_codec_control(encoder_, VP9E_SET_TILE_COLUMNS, (config_->g_threads >> 1)); | 444 vpx_codec_control(encoder_, VP9E_SET_TILE_COLUMNS, (config_->g_threads >> 1)); |
| 447 #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \ | 445 #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \ |
| 448 !defined(ANDROID) | 446 !defined(ANDROID) |
| 449 // Note denoiser is still off by default until further testing/optimization, | 447 // Note denoiser is still off by default until further testing/optimization, |
| 450 // i.e., codecSpecific.VP9.denoisingOn == 0. | 448 // i.e., VP9().denoisingOn == 0. |
| 451 vpx_codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY, | 449 vpx_codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY, |
| 452 inst->codecSpecific.VP9.denoisingOn ? 1 : 0); | 450 inst->VP9().denoisingOn ? 1 : 0); |
| 453 #endif | 451 #endif |
| 454 if (codec_.mode == kScreensharing) { | 452 if (codec_.mode == kScreensharing) { |
| 455 // Adjust internal parameters to screen content. | 453 // Adjust internal parameters to screen content. |
| 456 vpx_codec_control(encoder_, VP9E_SET_TUNE_CONTENT, 1); | 454 vpx_codec_control(encoder_, VP9E_SET_TUNE_CONTENT, 1); |
| 457 } | 455 } |
| 458 // Enable encoder skip of static/low content blocks. | 456 // Enable encoder skip of static/low content blocks. |
| 459 vpx_codec_control(encoder_, VP8E_SET_STATIC_THRESHOLD, 1); | 457 vpx_codec_control(encoder_, VP8E_SET_STATIC_THRESHOLD, 1); |
| 460 inited_ = true; | 458 inited_ = true; |
| 461 return WEBRTC_VIDEO_CODEC_OK; | 459 return WEBRTC_VIDEO_CODEC_OK; |
| 462 } | 460 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 | 554 |
| 557 void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific, | 555 void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific, |
| 558 const vpx_codec_cx_pkt& pkt, | 556 const vpx_codec_cx_pkt& pkt, |
| 559 uint32_t timestamp) { | 557 uint32_t timestamp) { |
| 560 assert(codec_specific != NULL); | 558 assert(codec_specific != NULL); |
| 561 codec_specific->codecType = kVideoCodecVP9; | 559 codec_specific->codecType = kVideoCodecVP9; |
| 562 CodecSpecificInfoVP9* vp9_info = &(codec_specific->codecSpecific.VP9); | 560 CodecSpecificInfoVP9* vp9_info = &(codec_specific->codecSpecific.VP9); |
| 563 // TODO(asapersson): Set correct value. | 561 // TODO(asapersson): Set correct value. |
| 564 vp9_info->inter_pic_predicted = | 562 vp9_info->inter_pic_predicted = |
| 565 (pkt.data.frame.flags & VPX_FRAME_IS_KEY) ? false : true; | 563 (pkt.data.frame.flags & VPX_FRAME_IS_KEY) ? false : true; |
| 566 vp9_info->flexible_mode = codec_.codecSpecific.VP9.flexibleMode; | 564 vp9_info->flexible_mode = codec_.VP9()->flexibleMode; |
| 567 vp9_info->ss_data_available = ((pkt.data.frame.flags & VPX_FRAME_IS_KEY) && | 565 vp9_info->ss_data_available = |
| 568 !codec_.codecSpecific.VP9.flexibleMode) | 566 ((pkt.data.frame.flags & VPX_FRAME_IS_KEY) && !codec_.VP9()->flexibleMode) |
| 569 ? true | 567 ? true |
| 570 : false; | 568 : false; |
| 571 | 569 |
| 572 vpx_svc_layer_id_t layer_id = {0}; | 570 vpx_svc_layer_id_t layer_id = {0}; |
| 573 vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); | 571 vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); |
| 574 | 572 |
| 575 assert(num_temporal_layers_ > 0); | 573 assert(num_temporal_layers_ > 0); |
| 576 assert(num_spatial_layers_ > 0); | 574 assert(num_spatial_layers_ > 0); |
| 577 if (num_temporal_layers_ == 1) { | 575 if (num_temporal_layers_ == 1) { |
| 578 assert(layer_id.temporal_layer_id == 0); | 576 assert(layer_id.temporal_layer_id == 0); |
| 579 vp9_info->temporal_idx = kNoTemporalIdx; | 577 vp9_info->temporal_idx = kNoTemporalIdx; |
| 580 } else { | 578 } else { |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 frame_buffer_pool_.ClearPool(); | 989 frame_buffer_pool_.ClearPool(); |
| 992 inited_ = false; | 990 inited_ = false; |
| 993 return WEBRTC_VIDEO_CODEC_OK; | 991 return WEBRTC_VIDEO_CODEC_OK; |
| 994 } | 992 } |
| 995 | 993 |
| 996 const char* VP9DecoderImpl::ImplementationName() const { | 994 const char* VP9DecoderImpl::ImplementationName() const { |
| 997 return "libvpx"; | 995 return "libvpx"; |
| 998 } | 996 } |
| 999 | 997 |
| 1000 } // namespace webrtc | 998 } // namespace webrtc |
| OLD | NEW |