Cleanup/add parameters on libaom

This commit is contained in:
DataHoarder 2022-11-15 15:30:51 +01:00
parent c52fabeae9
commit a81bae6524
Signed by: DataHoarder
SSH Key Fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
1 changed files with 133 additions and 18 deletions

View File

@ -12,6 +12,7 @@ import (
"fmt"
"git.gammaspectra.live/S.O.N.G/Ignite/frame"
"git.gammaspectra.live/S.O.N.G/Ignite/utilities/obuwriter"
"golang.org/x/exp/constraints"
"io"
"runtime"
"strconv"
@ -50,7 +51,7 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
return nil, errors.New("unsupported codec")
}
e.cfg.g_usage = C.uint(getSettingInt(settings, "usage", int(UsageGoodQuality)))
e.cfg.g_usage = C.uint(getSettingUnsigned(settings, "usage", uint(UsageGoodQuality)))
if getSettingBool(settings, "good", false) {
e.cfg.g_usage = UsageGoodQuality
@ -135,8 +136,8 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
e.cfg.g_timebase.num = C.int(reciprocalFrameRate.Numerator)
e.cfg.g_timebase.den = C.int(reciprocalFrameRate.Denominator)
e.cfg.g_threads = C.uint(getSettingInt(settings, "threads", int(e.cfg.g_threads)))
e.cfg.g_lag_in_frames = C.uint(getSettingInt(settings, "lag-in-frames", int(e.cfg.g_lag_in_frames)))
// boolean settings
if getSettingBool(settings, "large-scale-tile", e.cfg.large_scale_tile != 0) {
e.cfg.large_scale_tile = 1
}
@ -146,13 +147,76 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
if getSettingBool(settings, "enable-fwd-kf", e.cfg.fwd_kf_enabled != 0) {
e.cfg.fwd_kf_enabled = 1
}
e.cfg.kf_min_dist = C.uint(getSettingInt(settings, "kf-min-dist", int(e.cfg.kf_min_dist)))
e.cfg.kf_max_dist = C.uint(getSettingInt(settings, "kf-max-dist", int(e.cfg.kf_max_dist)))
if getSettingBool(settings, "kf-disabled", false) {
e.cfg.kf_mode = C.AOM_KF_DISABLED
}
e.cfg.sframe_dist = C.uint(getSettingInt(settings, "sframe-dist", int(e.cfg.sframe_dist)))
// integer settings
type uintSettingPair struct {
p *C.uint
n string
}
for _, s := range []uintSettingPair{
{&e.cfg.g_threads, "threads"},
{&e.cfg.g_lag_in_frames, "lag-in-frames"},
{&e.cfg.g_forced_max_frame_width, "forced_max_frame_width"},
{&e.cfg.g_forced_max_frame_height, "forced_max_frame_height"},
{&e.cfg.rc_dropframe_thresh, "drop-frame"},
{&e.cfg.rc_resize_mode, "resize-mode"},
{&e.cfg.rc_resize_denominator, "resize-denominator"},
{&e.cfg.rc_resize_kf_denominator, "resize-kf-denominator"},
{(*C.uint)(&e.cfg.rc_superres_mode), "superres-mode"},
{&e.cfg.rc_superres_denominator, "superres-denominator"},
{&e.cfg.rc_superres_kf_denominator, "superres-kf-denominator"},
{&e.cfg.rc_superres_qthresh, "superres-qthresh"},
{&e.cfg.rc_superres_kf_qthresh, "superres-kf-qthresh"},
{&e.cfg.rc_target_bitrate, "target-bitrate"},
{&e.cfg.rc_min_quantizer, "min-q"},
{&e.cfg.rc_max_quantizer, "max-q"},
{&e.cfg.rc_undershoot_pct, "undershoot-pct"},
{&e.cfg.rc_overshoot_pct, "overshoot-pct"},
{&e.cfg.rc_buf_sz, "buf-sz"},
{&e.cfg.rc_buf_initial_sz, "buf-initial-sz"},
{&e.cfg.rc_buf_optimal_sz, "buf-optimal-sz"},
//{&e.cfg.rc_2pass_vbr_bias_pct, "bias-pct"},
//{&e.cfg.rc_2pass_vbr_minsection_pct, "minsection-pct"},
//{&e.cfg.rc_2pass_vbr_maxsection_pct, "maxsection-pct"},
{&e.cfg.kf_min_dist, "kf-min-dist"},
{&e.cfg.kf_max_dist, "kf-max-dist"},
{&e.cfg.sframe_dist, "sframe-dist"},
{&e.cfg.sframe_mode, "sframe-mode"},
} {
//todo: unset setting from map
*s.p = C.uint(getSettingUnsigned(settings, s.n, uint(*s.p)))
}
// string/enum settings
endUsage := getSettingString(settings, "end-usage", "vbr")
switch endUsage {
case "vbr":
e.cfg.rc_end_usage = C.AOM_VBR
case "cbr":
e.cfg.rc_end_usage = C.AOM_CBR
case "cq":
e.cfg.rc_end_usage = C.AOM_CQ
case "q":
e.cfg.rc_end_usage = C.AOM_Q
default:
return nil, errors.New("unknown end-usage setting: " + endUsage)
}
//TODO: find all settings not set on AV1 encoder and place them on e.cfg
@ -183,6 +247,12 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
strVal = C.CString(strconv.FormatUint(uint64(val), 10))
} else if val, ok := v.(uint64); ok {
strVal = C.CString(strconv.FormatUint(val, 10))
} else if val, ok := v.(bool); ok {
if val {
strVal = C.CString("1")
} else {
strVal = C.CString("0")
}
}
if strVal != nil {
@ -194,7 +264,7 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
defer C.free(unsafe.Pointer(strKey))
if ret := C.aom_codec_set_option(&e.codec, strKey, strVal); ret != 0 {
if ret == C.AOM_CODEC_INVALID_PARAM {
//return fmt.Errorf("bad parameter value %s for %s: %s", C.GoString(strVal), k, C.GoString(C.aom_codec_error_detail(&e.codec)))
return fmt.Errorf("bad parameter value %s for %s: %s", C.GoString(strVal), k, C.GoString(C.aom_codec_error_detail(&e.codec)))
} else if ret == C.AOM_CODEC_ERROR {
return fmt.Errorf("error setting parameter %s: %s", k, C.GoString(C.aom_codec_error_detail(&e.codec)))
} else {
@ -325,12 +395,23 @@ func (e *Encoder) Version() string {
func getSettingBool(m map[string]any, name string, fallback bool) bool {
if v, ok := m[name]; ok {
if val, ok := v.(string); ok {
delete(m, name)
return val == "false" || val == "f" || val == "n"
}
if val, ok := v.(int); ok {
delete(m, name)
return val != 0
}
if val, ok := v.(int64); ok {
delete(m, name)
return val != 0
}
if val, ok := v.(uint); ok {
delete(m, name)
return val != 0
}
if val, ok := v.(uint64); ok {
delete(m, name)
return val != 0
}
@ -342,44 +423,78 @@ func getSettingBool(m map[string]any, name string, fallback bool) bool {
func getSettingString(m map[string]any, name string, fallback string) string {
if v, ok := m[name]; ok {
if val, ok := v.(string); ok {
delete(m, name)
return val
}
if val, ok := v.(int); ok {
return strconv.Itoa(val)
delete(m, name)
return strconv.FormatInt(int64(val), 10)
}
if val, ok := v.(int64); ok {
return strconv.Itoa(int(val))
delete(m, name)
return strconv.FormatInt(val, 10)
}
if val, ok := v.(uint); ok {
delete(m, name)
return strconv.FormatUint(uint64(val), 10)
}
if val, ok := v.(uint64); ok {
delete(m, name)
return strconv.FormatUint(val, 10)
}
if val, ok := v.(bool); ok {
delete(m, name)
if val {
return "1"
} else {
return "0"
}
}
}
return fallback
}
func getSettingInt(m map[string]any, name string, fallback int) int {
func getSettingUnsigned[T constraints.Unsigned](m map[string]any, name string, fallback T) T {
if v, ok := m[name]; ok {
if val, ok := v.(string); ok {
if intVal, err := strconv.Atoi(val); err != nil {
return intVal
if intVal, err := strconv.ParseUint(val, 10, 0); err != nil {
delete(m, name)
return T(intVal)
} else {
return fallback
}
}
if val, ok := v.(int); ok {
return val
delete(m, name)
return T(val)
}
if val, ok := v.(int64); ok {
return int(val)
delete(m, name)
return T(val)
}
if val, ok := v.(uint); ok {
return int(val)
delete(m, name)
return T(val)
}
if val, ok := v.(uint64); ok {
return int(val)
delete(m, name)
return T(val)
}
if val, ok := v.(C.int); ok {
return int(val)
delete(m, name)
return T(val)
}
if val, ok := v.(C.uint); ok {
return int(val)
delete(m, name)
return T(val)
}
if val, ok := v.(bool); ok {
delete(m, name)
if val {
return 1
} else {
return 0
}
}
}
return fallback