Cleanup/add parameters on libaom
This commit is contained in:
parent
c52fabeae9
commit
a81bae6524
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue