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