From cc02721090369ee06735f8efe73996d00f59cf5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Spr=C3=A5ng?= Date: Sun, 13 Dec 2020 14:50:59 +0100 Subject: [PATCH] Extend LibvpxInterface with VP9 support and use it from LibvpxVp9Encoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:12274 Change-Id: I7a66a91f6a21ba482347af3c8af53544f9eb2269 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/196900 Commit-Queue: Erik Språng Reviewed-by: Sergey Silkin Cr-Commit-Position: refs/heads/master@{#32822} --- .../codecs/interface/libvpx_interface.cc | 169 +++++++++++++++++- .../codecs/interface/libvpx_interface.h | 26 ++- .../codecs/interface/mock_libvpx_interface.h | 37 ++++ .../codecs/vp9/libvpx_vp9_encoder.cc | 111 ++++++------ 4 files changed, 287 insertions(+), 56 deletions(-) diff --git a/modules/video_coding/codecs/interface/libvpx_interface.cc b/modules/video_coding/codecs/interface/libvpx_interface.cc index 8ab7bf5f99..b24922f921 100644 --- a/modules/video_coding/codecs/interface/libvpx_interface.cc +++ b/modules/video_coding/codecs/interface/libvpx_interface.cc @@ -93,17 +93,45 @@ class LibvpxFacade : public LibvpxInterface { return vpx_codec_control(ctx, VP8E_SET_ARNR_MAXFRAMES, param); case VP8E_SET_ARNR_STRENGTH: return vpx_codec_control(ctx, VP8E_SET_ARNR_STRENGTH, param); - case VP8E_SET_ARNR_TYPE: - RTC_NOTREACHED() << "VP8E_SET_ARNR_TYPE is deprecated."; - return VPX_CODEC_UNSUP_FEATURE; case VP8E_SET_CQ_LEVEL: return vpx_codec_control(ctx, VP8E_SET_CQ_LEVEL, param); case VP8E_SET_MAX_INTRA_BITRATE_PCT: return vpx_codec_control(ctx, VP8E_SET_MAX_INTRA_BITRATE_PCT, param); + case VP9E_SET_MAX_INTER_BITRATE_PCT: + return vpx_codec_control(ctx, VP9E_SET_MAX_INTER_BITRATE_PCT, param); case VP8E_SET_GF_CBR_BOOST_PCT: return vpx_codec_control(ctx, VP8E_SET_GF_CBR_BOOST_PCT, param); case VP8E_SET_SCREEN_CONTENT_MODE: return vpx_codec_control(ctx, VP8E_SET_SCREEN_CONTENT_MODE, param); + case VP9E_SET_GF_CBR_BOOST_PCT: + return vpx_codec_control(ctx, VP9E_SET_GF_CBR_BOOST_PCT, param); + case VP9E_SET_LOSSLESS: + return vpx_codec_control(ctx, VP9E_SET_LOSSLESS, param); + case VP9E_SET_FRAME_PARALLEL_DECODING: + return vpx_codec_control(ctx, VP9E_SET_FRAME_PARALLEL_DECODING, param); + case VP9E_SET_AQ_MODE: + return vpx_codec_control(ctx, VP9E_SET_AQ_MODE, param); + case VP9E_SET_FRAME_PERIODIC_BOOST: + return vpx_codec_control(ctx, VP9E_SET_FRAME_PERIODIC_BOOST, param); + case VP9E_SET_NOISE_SENSITIVITY: + return vpx_codec_control(ctx, VP9E_SET_NOISE_SENSITIVITY, param); + case VP9E_SET_MIN_GF_INTERVAL: + return vpx_codec_control(ctx, VP9E_SET_MIN_GF_INTERVAL, param); + case VP9E_SET_MAX_GF_INTERVAL: + return vpx_codec_control(ctx, VP9E_SET_MAX_GF_INTERVAL, param); + case VP9E_SET_TARGET_LEVEL: + return vpx_codec_control(ctx, VP9E_SET_TARGET_LEVEL, param); + case VP9E_SET_ROW_MT: + return vpx_codec_control(ctx, VP9E_SET_ROW_MT, param); + case VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST: + return vpx_codec_control(ctx, VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, + param); + case VP9E_SET_SVC_INTER_LAYER_PRED: + return vpx_codec_control(ctx, VP9E_SET_SVC_INTER_LAYER_PRED, param); + case VP9E_SET_SVC_GF_TEMPORAL_REF: + return vpx_codec_control(ctx, VP9E_SET_SVC_GF_TEMPORAL_REF, param); + case VP9E_SET_POSTENCODE_DROP: + return vpx_codec_control(ctx, VP9E_SET_POSTENCODE_DROP, param); default: RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; } @@ -118,14 +146,41 @@ class LibvpxFacade : public LibvpxInterface { return vpx_codec_control(ctx, VP8E_SET_FRAME_FLAGS, param); case VP8E_SET_TEMPORAL_LAYER_ID: return vpx_codec_control(ctx, VP8E_SET_TEMPORAL_LAYER_ID, param); + case VP9E_SET_SVC: + return vpx_codec_control(ctx, VP9E_SET_SVC, param); case VP8E_SET_CPUUSED: return vpx_codec_control(ctx, VP8E_SET_CPUUSED, param); case VP8E_SET_TOKEN_PARTITIONS: return vpx_codec_control(ctx, VP8E_SET_TOKEN_PARTITIONS, param); case VP8E_SET_TUNING: return vpx_codec_control(ctx, VP8E_SET_TUNING, param); + case VP9E_SET_TILE_COLUMNS: + return vpx_codec_control(ctx, VP9E_SET_TILE_COLUMNS, param); + case VP9E_SET_TILE_ROWS: + return vpx_codec_control(ctx, VP9E_SET_TILE_ROWS, param); + case VP9E_SET_TPL: + return vpx_codec_control(ctx, VP9E_SET_TPL, param); + case VP9E_SET_ALT_REF_AQ: + return vpx_codec_control(ctx, VP9E_SET_ALT_REF_AQ, param); + case VP9E_SET_TUNE_CONTENT: + return vpx_codec_control(ctx, VP9E_SET_TUNE_CONTENT, param); + case VP9E_SET_COLOR_SPACE: + return vpx_codec_control(ctx, VP9E_SET_COLOR_SPACE, param); + case VP9E_SET_COLOR_RANGE: + return vpx_codec_control(ctx, VP9E_SET_COLOR_RANGE, param); + case VP9E_SET_DELTA_Q_UV: + return vpx_codec_control(ctx, VP9E_SET_DELTA_Q_UV, param); + case VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR: + return vpx_codec_control(ctx, VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, + param); + case VP9E_SET_DISABLE_LOOPFILTER: + return vpx_codec_control(ctx, VP9E_SET_DISABLE_LOOPFILTER, param); default: + if (param >= 0) { + // Might be intended for uint32_t but int literal used, try fallback. + return codec_control(ctx, ctrl_id, static_cast(param)); + } RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; } return VPX_CODEC_ERROR; @@ -139,6 +194,10 @@ class LibvpxFacade : public LibvpxInterface { return vpx_codec_control(ctx, VP8E_GET_LAST_QUANTIZER, param); case VP8E_GET_LAST_QUANTIZER_64: return vpx_codec_control(ctx, VP8E_GET_LAST_QUANTIZER_64, param); + case VP9E_SET_RENDER_SIZE: + return vpx_codec_control(ctx, VP9E_SET_RENDER_SIZE, param); + case VP9E_GET_LEVEL: + return vpx_codec_control(ctx, VP9E_GET_LEVEL, param); default: RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; } @@ -151,6 +210,8 @@ class LibvpxFacade : public LibvpxInterface { switch (ctrl_id) { case VP8E_SET_ROI_MAP: return vpx_codec_control(ctx, VP8E_SET_ROI_MAP, param); + case VP9E_SET_ROI_MAP: + return vpx_codec_control(ctx, VP9E_SET_ROI_MAP, param); default: RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; } @@ -163,6 +224,8 @@ class LibvpxFacade : public LibvpxInterface { switch (ctrl_id) { case VP8E_SET_ACTIVEMAP: return vpx_codec_control(ctx, VP8E_SET_ACTIVEMAP, param); + case VP9E_GET_ACTIVEMAP: + return vpx_codec_control(ctx, VP8E_SET_ACTIVEMAP, param); default: RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; } @@ -181,6 +244,98 @@ class LibvpxFacade : public LibvpxInterface { return VPX_CODEC_ERROR; } + vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_svc_extra_cfg_t* param) const override { + switch (ctrl_id) { + case VP9E_SET_SVC_PARAMETERS: + return vpx_codec_control_(ctx, VP9E_SET_SVC_PARAMETERS, param); + default: + RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; + } + return VPX_CODEC_ERROR; + } + + vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_svc_frame_drop_t* param) const override { + switch (ctrl_id) { + case VP9E_SET_SVC_FRAME_DROP_LAYER: + return vpx_codec_control_(ctx, VP9E_SET_SVC_FRAME_DROP_LAYER, param); + default: + RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; + } + return VPX_CODEC_ERROR; + } + + vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + void* param) const override { + switch (ctrl_id) { + case VP9E_SET_SVC_PARAMETERS: + return vpx_codec_control_(ctx, VP9E_SET_SVC_PARAMETERS, param); + case VP9E_REGISTER_CX_CALLBACK: + return vpx_codec_control_(ctx, VP9E_REGISTER_CX_CALLBACK, param); + default: + RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; + } + return VPX_CODEC_ERROR; + } + + vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_svc_layer_id_t* param) const override { + switch (ctrl_id) { + case VP9E_SET_SVC_LAYER_ID: + return vpx_codec_control_(ctx, VP9E_SET_SVC_LAYER_ID, param); + case VP9E_GET_SVC_LAYER_ID: + return vpx_codec_control_(ctx, VP9E_GET_SVC_LAYER_ID, param); + default: + RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; + } + return VPX_CODEC_ERROR; + } + + vpx_codec_err_t codec_control( + vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_svc_ref_frame_config_t* param) const override { + switch (ctrl_id) { + case VP9E_SET_SVC_REF_FRAME_CONFIG: + return vpx_codec_control_(ctx, VP9E_SET_SVC_REF_FRAME_CONFIG, param); + case VP9E_GET_SVC_REF_FRAME_CONFIG: + return vpx_codec_control_(ctx, VP9E_GET_SVC_REF_FRAME_CONFIG, param); + default: + RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; + } + return VPX_CODEC_ERROR; + } + + vpx_codec_err_t codec_control( + vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_svc_spatial_layer_sync_t* param) const override { + switch (ctrl_id) { + case VP9E_SET_SVC_SPATIAL_LAYER_SYNC: + return vpx_codec_control_(ctx, VP9E_SET_SVC_SPATIAL_LAYER_SYNC, param); + default: + RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; + } + return VPX_CODEC_ERROR; + } + + vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_rc_funcs_t* param) const override { + switch (ctrl_id) { + case VP9E_SET_EXTERNAL_RATE_CONTROL: + return vpx_codec_control_(ctx, VP9E_SET_EXTERNAL_RATE_CONTROL, param); + default: + RTC_NOTREACHED() << "Unsupported libvpx ctrl_id: " << ctrl_id; + } + return VPX_CODEC_ERROR; + } + vpx_codec_err_t codec_encode(vpx_codec_ctx_t* ctx, const vpx_image_t* img, vpx_codec_pts_t pts, @@ -199,6 +354,14 @@ class LibvpxFacade : public LibvpxInterface { const char* codec_error_detail(vpx_codec_ctx_t* ctx) const override { return ::vpx_codec_error_detail(ctx); } + + const char* codec_error(vpx_codec_ctx_t* ctx) const override { + return ::vpx_codec_error(ctx); + } + + const char* codec_err_to_string(vpx_codec_err_t err) const override { + return ::vpx_codec_err_to_string(err); + } }; } // namespace diff --git a/modules/video_coding/codecs/interface/libvpx_interface.h b/modules/video_coding/codecs/interface/libvpx_interface.h index f087ff383b..3dea24dd6d 100644 --- a/modules/video_coding/codecs/interface/libvpx_interface.h +++ b/modules/video_coding/codecs/interface/libvpx_interface.h @@ -81,7 +81,29 @@ class LibvpxInterface { virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, vp8e_enc_control_id ctrl_id, vpx_scaling_mode* param) const = 0; - + virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_svc_extra_cfg_t* param) const = 0; + virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_svc_frame_drop_t* param) const = 0; + virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + void* param) const = 0; + virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_svc_layer_id_t* param) const = 0; + virtual vpx_codec_err_t codec_control( + vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_svc_ref_frame_config_t* param) const = 0; + virtual vpx_codec_err_t codec_control( + vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_svc_spatial_layer_sync_t* param) const = 0; + virtual vpx_codec_err_t codec_control(vpx_codec_ctx_t* ctx, + vp8e_enc_control_id ctrl_id, + vpx_rc_funcs_t* param) const = 0; virtual vpx_codec_err_t codec_encode(vpx_codec_ctx_t* ctx, const vpx_image_t* img, vpx_codec_pts_t pts, @@ -94,6 +116,8 @@ class LibvpxInterface { vpx_codec_iter_t* iter) const = 0; virtual const char* codec_error_detail(vpx_codec_ctx_t* ctx) const = 0; + virtual const char* codec_error(vpx_codec_ctx_t* ctx) const = 0; + virtual const char* codec_err_to_string(vpx_codec_err_t err) const = 0; // Returns interface wrapping the actual libvpx functions. static std::unique_ptr Create(); diff --git a/modules/video_coding/codecs/interface/mock_libvpx_interface.h b/modules/video_coding/codecs/interface/mock_libvpx_interface.h index 33681cb784..6dfe733dd0 100644 --- a/modules/video_coding/codecs/interface/mock_libvpx_interface.h +++ b/modules/video_coding/codecs/interface/mock_libvpx_interface.h @@ -86,6 +86,38 @@ class MockLibvpxInterface : public LibvpxInterface { codec_control, (vpx_codec_ctx_t*, vp8e_enc_control_id, vpx_scaling_mode*), (const, override)); + MOCK_METHOD(vpx_codec_err_t, + codec_control, + (vpx_codec_ctx_t*, vp8e_enc_control_id, vpx_svc_extra_cfg_t*), + (const, override)); + MOCK_METHOD(vpx_codec_err_t, + codec_control, + (vpx_codec_ctx_t*, vp8e_enc_control_id, vpx_svc_frame_drop_t*), + (const, override)); + MOCK_METHOD(vpx_codec_err_t, + codec_control, + (vpx_codec_ctx_t*, vp8e_enc_control_id, void*), + (const, override)); + MOCK_METHOD(vpx_codec_err_t, + codec_control, + (vpx_codec_ctx_t*, vp8e_enc_control_id, vpx_svc_layer_id_t*), + (const, override)); + MOCK_METHOD(vpx_codec_err_t, + codec_control, + (vpx_codec_ctx_t*, + vp8e_enc_control_id, + vpx_svc_ref_frame_config_t*), + (const, override)); + MOCK_METHOD(vpx_codec_err_t, + codec_control, + (vpx_codec_ctx_t*, + vp8e_enc_control_id, + vpx_svc_spatial_layer_sync_t*), + (const, override)); + MOCK_METHOD(vpx_codec_err_t, + codec_control, + (vpx_codec_ctx_t*, vp8e_enc_control_id, vpx_rc_funcs_t*), + (const, override)); MOCK_METHOD(vpx_codec_err_t, codec_encode, (vpx_codec_ctx_t*, @@ -103,6 +135,11 @@ class MockLibvpxInterface : public LibvpxInterface { codec_error_detail, (vpx_codec_ctx_t*), (const, override)); + MOCK_METHOD(const char*, codec_error, (vpx_codec_ctx_t*), (const, override)); + MOCK_METHOD(const char*, + codec_err_to_string, + (vpx_codec_err_t), + (const, override)); }; } // namespace webrtc diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc index 2f2fa6ccd2..0e3991bff8 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc @@ -257,7 +257,7 @@ int LibvpxVp9Encoder::Release() { if (encoder_ != nullptr) { if (inited_) { - if (vpx_codec_destroy(encoder_)) { + if (libvpx_->codec_destroy(encoder_)) { ret_val = WEBRTC_VIDEO_CODEC_MEMORY; } } @@ -269,7 +269,7 @@ int LibvpxVp9Encoder::Release() { config_ = nullptr; } if (raw_ != nullptr) { - vpx_img_free(raw_); + libvpx_->img_free(raw_); raw_ = nullptr; } inited_ = false; @@ -501,7 +501,7 @@ int LibvpxVp9Encoder::InitEncode(const VideoCodec* inst, is_svc_ = (num_spatial_layers_ > 1 || num_temporal_layers_ > 1); // Populate encoder configuration with default values. - if (vpx_codec_enc_config_default(vpx_codec_vp9_cx(), config_, 0)) { + if (libvpx_->codec_enc_config_default(vpx_codec_vp9_cx(), config_, 0)) { return WEBRTC_VIDEO_CODEC_ERROR; } @@ -532,8 +532,8 @@ int LibvpxVp9Encoder::InitEncode(const VideoCodec* inst, // Creating a wrapper to the image - setting image data to nullptr. Actual // pointer will be set in encode. Setting align to 1, as it is meaningless // (actual memory is not allocated). - raw_ = - vpx_img_wrap(nullptr, img_fmt, codec_.width, codec_.height, 1, nullptr); + raw_ = libvpx_->img_wrap(nullptr, img_fmt, codec_.width, codec_.height, 1, + nullptr); raw_->bit_depth = bits_for_storage; config_->g_w = codec_.width; @@ -728,11 +728,11 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) { return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } - const vpx_codec_err_t rv = vpx_codec_enc_init( + const vpx_codec_err_t rv = libvpx_->codec_enc_init( encoder_, vpx_codec_vp9_cx(), config_, config_->g_bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH); if (rv != VPX_CODEC_OK) { - RTC_LOG(LS_ERROR) << "Init error: " << vpx_codec_err_to_string(rv); + RTC_LOG(LS_ERROR) << "Init error: " << libvpx_->codec_err_to_string(rv); return WEBRTC_VIDEO_CODEC_UNINITIALIZED; } @@ -748,20 +748,20 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) { } } - vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT, - rc_max_intra_target_); - vpx_codec_control(encoder_, VP9E_SET_AQ_MODE, - inst->VP9().adaptiveQpMode ? 3 : 0); + libvpx_->codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT, + rc_max_intra_target_); + libvpx_->codec_control(encoder_, VP9E_SET_AQ_MODE, + inst->VP9().adaptiveQpMode ? 3 : 0); - vpx_codec_control(encoder_, VP9E_SET_FRAME_PARALLEL_DECODING, 0); - vpx_codec_control(encoder_, VP9E_SET_SVC_GF_TEMPORAL_REF, 0); + libvpx_->codec_control(encoder_, VP9E_SET_FRAME_PARALLEL_DECODING, 0); + libvpx_->codec_control(encoder_, VP9E_SET_SVC_GF_TEMPORAL_REF, 0); if (is_svc_) { - vpx_codec_control(encoder_, VP9E_SET_SVC, 1); - vpx_codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, &svc_params_); + libvpx_->codec_control(encoder_, VP9E_SET_SVC, 1); + libvpx_->codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, &svc_params_); } if (!performance_flags_.use_per_layer_speed) { - vpx_codec_control( + libvpx_->codec_control( encoder_, VP8E_SET_CPUUSED, performance_flags_by_spatial_index_.rbegin()->base_layer_speed); } @@ -769,13 +769,13 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) { if (num_spatial_layers_ > 1) { switch (inter_layer_pred_) { case InterLayerPredMode::kOn: - vpx_codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 0); + libvpx_->codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 0); break; case InterLayerPredMode::kOff: - vpx_codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 1); + libvpx_->codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 1); break; case InterLayerPredMode::kOnKeyPic: - vpx_codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 2); + libvpx_->codec_control(encoder_, VP9E_SET_SVC_INTER_LAYER_PRED, 2); break; default: RTC_NOTREACHED(); @@ -812,40 +812,41 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) { svc_drop_frame_.framedrop_thresh[i] = config_->rc_dropframe_thresh; } } - vpx_codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER, - &svc_drop_frame_); + libvpx_->codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER, + &svc_drop_frame_); } // Register callback for getting each spatial layer. vpx_codec_priv_output_cx_pkt_cb_pair_t cbp = { LibvpxVp9Encoder::EncoderOutputCodedPacketCallback, reinterpret_cast(this)}; - vpx_codec_control(encoder_, VP9E_REGISTER_CX_CALLBACK, - reinterpret_cast(&cbp)); + libvpx_->codec_control(encoder_, VP9E_REGISTER_CX_CALLBACK, + reinterpret_cast(&cbp)); // Control function to set the number of column tiles in encoding a frame, in // log2 unit: e.g., 0 = 1 tile column, 1 = 2 tile columns, 2 = 4 tile columns. // The number tile columns will be capped by the encoder based on image size // (minimum width of tile column is 256 pixels, maximum is 4096). - vpx_codec_control(encoder_, VP9E_SET_TILE_COLUMNS, (config_->g_threads >> 1)); + libvpx_->codec_control(encoder_, VP9E_SET_TILE_COLUMNS, + static_cast((config_->g_threads >> 1))); // Turn on row-based multithreading. - vpx_codec_control(encoder_, VP9E_SET_ROW_MT, 1); + libvpx_->codec_control(encoder_, VP9E_SET_ROW_MT, 1); #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \ !defined(ANDROID) // Do not enable the denoiser on ARM since optimization is pending. // Denoiser is on by default on other platforms. - vpx_codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY, - inst->VP9().denoisingOn ? 1 : 0); + libvpx_->codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY, + inst->VP9().denoisingOn ? 1 : 0); #endif if (codec_.mode == VideoCodecMode::kScreensharing) { // Adjust internal parameters to screen content. - vpx_codec_control(encoder_, VP9E_SET_TUNE_CONTENT, 1); + libvpx_->codec_control(encoder_, VP9E_SET_TUNE_CONTENT, 1); } // Enable encoder skip of static/low content blocks. - vpx_codec_control(encoder_, VP8E_SET_STATIC_THRESHOLD, 1); + libvpx_->codec_control(encoder_, VP8E_SET_STATIC_THRESHOLD, 1); inited_ = true; config_changed_ = true; return WEBRTC_VIDEO_CODEC_OK; @@ -992,20 +993,20 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, } } if (speed_updated) { - vpx_codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, &svc_params_); + libvpx_->codec_control(encoder_, VP9E_SET_SVC_PARAMETERS, &svc_params_); } } - vpx_codec_control(encoder_, VP9E_SET_SVC_LAYER_ID, &layer_id); + libvpx_->codec_control(encoder_, VP9E_SET_SVC_LAYER_ID, &layer_id); if (num_spatial_layers_ > 1) { // Update frame dropping settings as they may change on per-frame basis. - vpx_codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER, - &svc_drop_frame_); + libvpx_->codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER, + &svc_drop_frame_); } if (config_changed_) { - if (vpx_codec_enc_config_set(encoder_, config_)) { + if (libvpx_->codec_enc_config_set(encoder_, config_)) { return WEBRTC_VIDEO_CODEC_ERROR; } @@ -1022,7 +1023,7 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, std::prev(performance_flags_.settings_by_resolution.lower_bound( width * height)) ->second.base_layer_speed; - vpx_codec_control(encoder_, VP8E_SET_CPUUSED, speed); + libvpx_->codec_control(encoder_, VP8E_SET_CPUUSED, speed); break; } } @@ -1111,7 +1112,8 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, if (svc_controller_) { vpx_svc_ref_frame_config_t ref_config = Vp9References(layer_frames_); - vpx_codec_control(encoder_, VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_config); + libvpx_->codec_control(encoder_, VP9E_SET_SVC_REF_FRAME_CONFIG, + &ref_config); } else if (external_ref_control_) { vpx_svc_ref_frame_config_t ref_config = SetReferences(force_key_frame_, layer_id.spatial_layer_id); @@ -1124,7 +1126,8 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, } } - vpx_codec_control(encoder_, VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_config); + libvpx_->codec_control(encoder_, VP9E_SET_SVC_REF_FRAME_CONFIG, + &ref_config); } first_frame_in_picture_ = true; @@ -1144,14 +1147,14 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, .GetTargetRate()) : codec_.maxFramerate; uint32_t duration = static_cast(90000 / target_framerate_fps); - const vpx_codec_err_t rv = vpx_codec_encode(encoder_, raw_, timestamp_, - duration, flags, VPX_DL_REALTIME); + const vpx_codec_err_t rv = libvpx_->codec_encode( + encoder_, raw_, timestamp_, duration, flags, VPX_DL_REALTIME); if (rv != VPX_CODEC_OK) { - RTC_LOG(LS_ERROR) << "Encoding error: " << vpx_codec_err_to_string(rv) + RTC_LOG(LS_ERROR) << "Encoding error: " << libvpx_->codec_err_to_string(rv) << "\n" "Details: " - << vpx_codec_error(encoder_) << "\n" - << vpx_codec_error_detail(encoder_); + << libvpx_->codec_error(encoder_) << "\n" + << libvpx_->codec_error_detail(encoder_); return WEBRTC_VIDEO_CODEC_ERROR; } timestamp_ += duration; @@ -1182,7 +1185,7 @@ void LibvpxVp9Encoder::PopulateCodecSpecific(CodecSpecificInfo* codec_specific, } vpx_svc_layer_id_t layer_id = {0}; - vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); + libvpx_->codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); // Can't have keyframe with non-zero temporal layer. RTC_DCHECK(pics_since_key_ != 0 || layer_id.temporal_layer_id == 0); @@ -1310,7 +1313,7 @@ void LibvpxVp9Encoder::FillReferenceIndices(const vpx_codec_cx_pkt& pkt, const bool inter_layer_predicted, CodecSpecificInfoVP9* vp9_info) { vpx_svc_layer_id_t layer_id = {0}; - vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); + libvpx_->codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); const bool is_key_frame = (pkt.data.frame.flags & VPX_FRAME_IS_KEY) ? true : false; @@ -1319,7 +1322,8 @@ void LibvpxVp9Encoder::FillReferenceIndices(const vpx_codec_cx_pkt& pkt, if (is_svc_) { vpx_svc_ref_frame_config_t enc_layer_conf = {{0}}; - vpx_codec_control(encoder_, VP9E_GET_SVC_REF_FRAME_CONFIG, &enc_layer_conf); + libvpx_->codec_control(encoder_, VP9E_GET_SVC_REF_FRAME_CONFIG, + &enc_layer_conf); int ref_buf_flags = 0; if (enc_layer_conf.reference_last[layer_id.spatial_layer_id]) { @@ -1427,14 +1431,15 @@ void LibvpxVp9Encoder::FillReferenceIndices(const vpx_codec_cx_pkt& pkt, void LibvpxVp9Encoder::UpdateReferenceBuffers(const vpx_codec_cx_pkt& pkt, const size_t pic_num) { vpx_svc_layer_id_t layer_id = {0}; - vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); + libvpx_->codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); RefFrameBuffer frame_buf(pic_num, layer_id.spatial_layer_id, layer_id.temporal_layer_id); if (is_svc_) { vpx_svc_ref_frame_config_t enc_layer_conf = {{0}}; - vpx_codec_control(encoder_, VP9E_GET_SVC_REF_FRAME_CONFIG, &enc_layer_conf); + libvpx_->codec_control(encoder_, VP9E_GET_SVC_REF_FRAME_CONFIG, + &enc_layer_conf); const int update_buffer_slot = enc_layer_conf.update_buffer_slot[layer_id.spatial_layer_id]; @@ -1567,7 +1572,7 @@ int LibvpxVp9Encoder::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) { } vpx_svc_layer_id_t layer_id = {0}; - vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); + libvpx_->codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); if (layer_buffering_) { // Deliver buffered low spatial layer frame. @@ -1607,7 +1612,7 @@ int LibvpxVp9Encoder::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) { encoded_image_._encodedWidth = pkt->data.frame.width[layer_id.spatial_layer_id]; int qp = -1; - vpx_codec_control(encoder_, VP8E_GET_LAST_QUANTIZER, &qp); + libvpx_->codec_control(encoder_, VP8E_GET_LAST_QUANTIZER, &qp); encoded_image_.qp_ = qp; if (!layer_buffering_) { @@ -1863,12 +1868,14 @@ LibvpxVp9Encoder::GetDefaultPerformanceFlags() { void LibvpxVp9Encoder::MaybeRewrapRawWithFormat(const vpx_img_fmt fmt) { if (!raw_) { - raw_ = vpx_img_wrap(nullptr, fmt, codec_.width, codec_.height, 1, nullptr); + raw_ = libvpx_->img_wrap(nullptr, fmt, codec_.width, codec_.height, 1, + nullptr); } else if (raw_->fmt != fmt) { RTC_LOG(INFO) << "Switching VP9 encoder pixel format to " << (fmt == VPX_IMG_FMT_NV12 ? "NV12" : "I420"); - vpx_img_free(raw_); - raw_ = vpx_img_wrap(nullptr, fmt, codec_.width, codec_.height, 1, nullptr); + libvpx_->img_free(raw_); + raw_ = libvpx_->img_wrap(nullptr, fmt, codec_.width, codec_.height, 1, + nullptr); } // else no-op since the image is already in the right format. }