use crate::{call_vpx, Error, Result};
#[derive(Clone, Debug)]
pub enum EncoderControlSet<'a> {
Vp8RoiMap(&'a vpx_sys::vpx_roi_map),
ActiveMap(&'a vpx_sys::vpx_active_map),
ScaleMode(vpx_sys::vpx_scaling_mode),
CpuUsed(i32),
EnableAutoAltRef(u32),
Vp8NoiseSensitivity(Vp8NoiseSensitivity),
Sharpness(u32),
StaticThreshold(u32),
Vp8TokenPartitions(vpx_sys::vp8e_token_partitions),
ARNRMaxFrames(u32),
ARNRStrength(u32),
Tuning(vpx_sys::vp8e_tuning),
CQLevel(u32),
MaxIntraBitratePct(u32),
Vp8FrameFlags(i32),
Vp9MaxInterBitratePct(u32),
Vp9GoldenFrameCBRBoostPct(u32),
Vp8TemporalLayerID(i32),
Vp8ScreenContentMode(Vp8ScreenContentMode),
Vp9CodingMode(Vp9CodingMode),
Vp9TileColumns(u32),
Vp9TileRows(u32),
Vp9FrameParallelDecoding(bool),
Vp9AQMode(Vp9AQMode),
Vp9FramePeriodicBoost(bool),
Vp9NoiseSensitivity(Vp9NoiseSensitivity),
Vp9Svc(bool),
Vp9RoiMap(Option<&'a vpx_sys::vpx_roi_map>),
Vp9TuneContent(Vp9TuneContent),
Vp9ColorSpace(vpx_sys::vpx_color_space),
Vp9MinGFInterval(u32),
Vp9MaxGFInterval(u32),
Vp9ColorRange(Vp9ColorRange),
Vp9SvcRefFrameConfig(&'a vpx_sys::vpx_svc_ref_frame_config),
Vp9RenderSize {
width: i32,
height: i32,
},
Vp9TargetLevel(u8),
Vp9RowMT(bool),
Vp9AltRefAQ(bool),
Vp8GoldenFrameCBRBoostPct(u32),
Vp9SvcInterLayerPred(Vp9SvcInterLayerPred),
Vp9SvcFrameDropLayer(vpx_sys::vpx_svc_frame_drop),
Vp9SvcGFTemporalRef(bool),
Vp9SvcSpatialLayerSync(vpx_sys::vpx_svc_spatial_layer_sync),
Vp9SetTPL(bool),
Vp9PostEncodeDrop(bool),
Vp9DeltaQUV(i32),
Vp9DisableOvershootMaxQCBR(bool),
Vp9Loopfilter(Vp9Loopfilter),
Vp9ExternalRateControl(&'a vpx_sys::vpx_rc_funcs),
Vp9SetQuantizerOnePass(i32),
}
impl EncoderControlSet<'_> {
pub(crate) fn set(&self, ctx: &mut vpx_sys::vpx_codec_ctx_t) -> Result<()> {
macro_rules! ctrl {
($ctx: expr, $ctrl_id: expr$(,)?) => {
call_vpx!(
vpx_sys::vpx_codec_control_($ctx, $ctrl_id as i32),
Error::CodecControlFailed,
)
};
($ctx: expr, $ctrl_id: expr, $arg: expr$(,)?) => {
call_vpx!(
vpx_sys::vpx_codec_control_($ctx, $ctrl_id as i32, $arg),
Error::CodecControlFailed,
)
};
}
use vpx_sys::vp8e_enc_control_id::*;
match self {
Self::Vp8RoiMap(map) => ctrl!(ctx, VP8E_SET_ROI_MAP, *map),
Self::ActiveMap(map) => ctrl!(ctx, VP8E_SET_ACTIVEMAP, *map),
Self::ScaleMode(mode) => ctrl!(ctx, VP8E_SET_SCALEMODE, mode),
Self::CpuUsed(cpu_used) => ctrl!(ctx, VP8E_SET_CPUUSED, cpu_used),
Self::EnableAutoAltRef(arf) => {
ctrl!(ctx, VP8E_SET_ENABLEAUTOALTREF, *arf)
}
Self::Vp8NoiseSensitivity(sens) => {
ctrl!(ctx, VP8E_SET_NOISE_SENSITIVITY, *sens)
}
Self::Sharpness(sharpness) => {
ctrl!(ctx, VP8E_SET_SHARPNESS, *sharpness)
}
Self::StaticThreshold(thresh) => {
ctrl!(ctx, VP8E_SET_STATIC_THRESHOLD, *thresh)
}
Self::Vp8TokenPartitions(part) => {
ctrl!(ctx, VP8E_SET_TOKEN_PARTITIONS, *part)
}
Self::ARNRMaxFrames(frames) => {
ctrl!(ctx, VP8E_SET_ARNR_MAXFRAMES, *frames)
}
Self::ARNRStrength(strength) => {
ctrl!(ctx, VP8E_SET_ARNR_STRENGTH, *strength)
}
Self::Tuning(tuning) => ctrl!(ctx, VP8E_SET_TUNING, *tuning),
Self::CQLevel(level) => ctrl!(ctx, VP8E_SET_CQ_LEVEL, *level),
Self::MaxIntraBitratePct(pct) => {
ctrl!(ctx, VP8E_SET_MAX_INTRA_BITRATE_PCT, *pct)
}
Self::Vp8FrameFlags(flags) => {
ctrl!(ctx, VP8E_SET_FRAME_FLAGS, *flags)
}
Self::Vp9MaxInterBitratePct(pct) => {
ctrl!(ctx, VP9E_SET_MAX_INTER_BITRATE_PCT, *pct)
}
Self::Vp9GoldenFrameCBRBoostPct(layer_id) => {
ctrl!(ctx, VP9E_SET_GF_CBR_BOOST_PCT, *layer_id)
}
Self::Vp8TemporalLayerID(pct) => {
ctrl!(ctx, VP8E_SET_TEMPORAL_LAYER_ID, *pct)
}
Self::Vp8ScreenContentMode(mode) => {
ctrl!(ctx, VP8E_SET_SCREEN_CONTENT_MODE, *mode)
}
Self::Vp9CodingMode(mode) => {
ctrl!(ctx, VP9E_SET_LOSSLESS, *mode as u32)
}
Self::Vp9TileColumns(cols) => {
ctrl!(ctx, VP9E_SET_TILE_COLUMNS, *cols)
}
Self::Vp9TileRows(cols) => ctrl!(ctx, VP9E_SET_TILE_ROWS, *cols),
Self::Vp9FrameParallelDecoding(flag) => {
ctrl!(ctx, VP9E_SET_FRAME_PARALLEL_DECODING, *flag as u32)
}
Self::Vp9AQMode(mode) => ctrl!(ctx, VP9E_SET_AQ_MODE, *mode),
Self::Vp9FramePeriodicBoost(flag) => {
ctrl!(ctx, VP9E_SET_FRAME_PERIODIC_BOOST, *flag as u32)
}
Self::Vp9NoiseSensitivity(sens) => {
ctrl!(ctx, VP9E_SET_NOISE_SENSITIVITY, *sens)
}
Self::Vp9Svc(flag) => ctrl!(ctx, VP9E_SET_SVC, *flag as i32),
Self::Vp9RoiMap(map) => {
ctrl!(
ctx,
VP9E_SET_ROI_MAP,
map.map_or(std::ptr::null(), |map| map as *const _)
)
}
Self::Vp9TuneContent(content) => {
ctrl!(ctx, VP9E_SET_TUNE_CONTENT, *content)
}
Self::Vp9ColorSpace(space) => {
ctrl!(ctx, VP9E_SET_COLOR_SPACE, *space as i32)
}
Self::Vp9MinGFInterval(intval) => {
ctrl!(ctx, VP9E_SET_MIN_GF_INTERVAL, *intval)
}
Self::Vp9MaxGFInterval(intval) => {
ctrl!(ctx, VP9E_SET_MAX_GF_INTERVAL, *intval)
}
Self::Vp9ColorRange(range) => {
ctrl!(ctx, VP9E_SET_COLOR_RANGE, *range)
}
Self::Vp9SvcRefFrameConfig(config) => {
ctrl!(ctx, VP9E_SET_SVC_REF_FRAME_CONFIG, *config)
}
Self::Vp9RenderSize { width, height } => {
ctrl!(ctx, VP9E_SET_RENDER_SIZE, &[width, height])
}
Self::Vp9TargetLevel(level) => {
ctrl!(ctx, VP9E_SET_TARGET_LEVEL, *level as i32)
}
Self::Vp9RowMT(flag) => ctrl!(ctx, VP9E_SET_ROW_MT, *flag as u32),
Self::Vp9AltRefAQ(aq) => {
ctrl!(ctx, VP9E_SET_ALT_REF_AQ, *aq as i32)
}
Self::Vp8GoldenFrameCBRBoostPct(pct) => {
ctrl!(ctx, VP8E_SET_GF_CBR_BOOST_PCT, *pct)
}
Self::Vp9SvcInterLayerPred(pred) => {
ctrl!(ctx, VP9E_SET_SVC_INTER_LAYER_PRED, *pred)
}
Self::Vp9SvcFrameDropLayer(drop) => {
ctrl!(ctx, VP9E_SET_SVC_FRAME_DROP_LAYER, drop)
}
Self::Vp9SvcGFTemporalRef(flag) => {
ctrl!(ctx, VP9E_SET_SVC_GF_TEMPORAL_REF, *flag as u32)
}
Self::Vp9SvcSpatialLayerSync(sync) => {
ctrl!(ctx, VP9E_SET_SVC_SPATIAL_LAYER_SYNC, sync)
}
Self::Vp9SetTPL(flag) => {
ctrl!(ctx, VP9E_SET_TPL, *flag as i32)
}
Self::Vp9PostEncodeDrop(flag) => {
ctrl!(ctx, VP9E_SET_POSTENCODE_DROP, *flag as i32)
}
Self::Vp9DeltaQUV(delta) => {
ctrl!(ctx, VP9E_SET_DELTA_Q_UV, *delta)
}
Self::Vp9DisableOvershootMaxQCBR(flag) => {
ctrl!(ctx, VP9E_SET_DELTA_Q_UV, !*flag as i32)
}
Self::Vp9Loopfilter(filter) => {
ctrl!(ctx, VP9E_SET_DISABLE_LOOPFILTER, *filter as i32)
}
Self::Vp9ExternalRateControl(rc_funcs) => {
ctrl!(ctx, VP9E_SET_EXTERNAL_RATE_CONTROL, *rc_funcs)
}
Self::Vp9SetQuantizerOnePass(qp) => {
ctrl!(ctx, VP9E_SET_QUANTIZER_ONE_PASS, *qp)
}
}
}
}
#[allow(missing_docs)]
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u32)]
pub enum Vp8NoiseSensitivity {
Off = 0,
OnYOnly = 1,
OnYuv = 2,
OnYuvAggressive = 3,
Adaptive = 4,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u32)]
pub enum Vp9NoiseSensitivity {
Off = 0,
OnYOnly = 1,
SvcOnly = 2,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u32)]
pub enum Vp8ScreenContentMode {
Off = 0,
On = 1,
OnWithAggressiveRC = 2,
}
#[allow(missing_docs)]
#[derive(Copy, Clone, Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u32)]
pub enum Vp9AQMode {
#[default]
No = vpx_sys::AQ_MODE::NO_AQ as u32,
Variance = vpx_sys::AQ_MODE::VARIANCE_AQ as u32,
Complexity = vpx_sys::AQ_MODE::COMPLEXITY_AQ as u32,
CyclicRefresh = vpx_sys::AQ_MODE::CYCLIC_REFRESH_AQ as u32,
Equator360 = vpx_sys::AQ_MODE::EQUATOR360_AQ as u32,
Lookahead = vpx_sys::AQ_MODE::LOOKAHEAD_AQ as u32,
}
#[derive(Copy, Clone, Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u32)]
pub enum Vp9TuneContent {
#[default]
Default = vpx_sys::vp9e_tune_content::VP9E_CONTENT_DEFAULT as u32,
Screen = vpx_sys::vp9e_tune_content::VP9E_CONTENT_SCREEN as u32,
Film = vpx_sys::vp9e_tune_content::VP9E_CONTENT_FILM as u32,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u32)]
#[allow(non_camel_case_types)]
pub enum Vp9ColorRange {
Limited = 0,
Full = 1,
}
#[allow(missing_docs)]
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u32)]
pub enum Vp9SvcInterLayerPred {
On = 0,
Off = 1,
OffOnlyOnNonKeyFrames = 2,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u32)]
pub enum Vp9Loopfilter {
EnableAll = 0,
DisableNonRef = 1,
DisableAll = 2,
}
#[derive(Copy, Clone, Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u32)]
pub enum Vp9CodingMode {
#[default]
Lossy = 0,
Lossless = 1,
}