Extend LibvpxInterface with VP9 support and use it from LibvpxVp9Encoder
Bug: webrtc:12274 Change-Id: I7a66a91f6a21ba482347af3c8af53544f9eb2269 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/196900 Commit-Queue: Erik Språng <sprang@webrtc.org> Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32822}
This commit is contained in:
@ -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<uint32_t>(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
|
||||
|
@ -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<LibvpxInterface> Create();
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
libvpx_->codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
||||
rc_max_intra_target_);
|
||||
vpx_codec_control(encoder_, VP9E_SET_AQ_MODE,
|
||||
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,7 +812,7 @@ 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,
|
||||
libvpx_->codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER,
|
||||
&svc_drop_frame_);
|
||||
}
|
||||
|
||||
@ -820,32 +820,33 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) {
|
||||
vpx_codec_priv_output_cx_pkt_cb_pair_t cbp = {
|
||||
LibvpxVp9Encoder::EncoderOutputCodedPacketCallback,
|
||||
reinterpret_cast<void*>(this)};
|
||||
vpx_codec_control(encoder_, VP9E_REGISTER_CX_CALLBACK,
|
||||
libvpx_->codec_control(encoder_, VP9E_REGISTER_CX_CALLBACK,
|
||||
reinterpret_cast<void*>(&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<int>((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,
|
||||
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,
|
||||
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<uint32_t>(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.
|
||||
}
|
||||
|
Reference in New Issue
Block a user