libaom: improved settings
This commit is contained in:
parent
86a7d25bcd
commit
c804c2e337
|
@ -32,6 +32,12 @@ func Version() string {
|
|||
return libaomVersion
|
||||
}
|
||||
|
||||
const (
|
||||
UsageGoodQuality = C.AOM_USAGE_GOOD_QUALITY
|
||||
UsageRealtime = C.AOM_USAGE_REALTIME
|
||||
UsageAllIntra = C.AOM_USAGE_ALL_INTRA
|
||||
)
|
||||
|
||||
func NewEncoder(w io.Writer, stream *y4m.Stream, settings map[string]any) (*Encoder, error) {
|
||||
e := &Encoder{
|
||||
w: w,
|
||||
|
@ -44,13 +50,29 @@ func NewEncoder(w io.Writer, stream *y4m.Stream, settings map[string]any) (*Enco
|
|||
return nil, errors.New("unsupported codec")
|
||||
}
|
||||
|
||||
var usage C.uint = C.AOM_USAGE_GOOD_QUALITY
|
||||
var speed C.int = 8
|
||||
var bitrate C.uint = 800
|
||||
globalConfig := struct {
|
||||
usage C.uint
|
||||
speed C.int
|
||||
}{
|
||||
usage: UsageGoodQuality,
|
||||
}
|
||||
|
||||
globalConfig.usage = C.uint(getSettingInt(settings, "usage", int(globalConfig.usage)))
|
||||
if getSettingBool(settings, "good", false) {
|
||||
globalConfig.usage = UsageGoodQuality
|
||||
}
|
||||
if getSettingBool(settings, "rt", false) {
|
||||
globalConfig.usage = UsageRealtime
|
||||
}
|
||||
if getSettingBool(settings, "allintra", false) {
|
||||
globalConfig.usage = UsageAllIntra
|
||||
}
|
||||
|
||||
globalConfig.speed = C.int(getSettingInt(settings, "cpu-used", int(globalConfig.speed)))
|
||||
|
||||
var imageFormat C.aom_img_fmt_t
|
||||
|
||||
if aomErr = C.aom_codec_enc_config_default(encoder, &e.cfg, usage); aomErr != 0 {
|
||||
if aomErr = C.aom_codec_enc_config_default(encoder, &e.cfg, globalConfig.usage); aomErr != 0 {
|
||||
return nil, errors.New("failed to get default codec config")
|
||||
}
|
||||
|
||||
|
@ -98,14 +120,64 @@ func NewEncoder(w io.Writer, stream *y4m.Stream, settings map[string]any) (*Enco
|
|||
e.cfg.g_h = C.uint(height)
|
||||
e.cfg.g_timebase.num = C.int(stream.FrameRate().Denominator)
|
||||
e.cfg.g_timebase.den = C.int(stream.FrameRate().Numerator)
|
||||
e.cfg.rc_target_bitrate = bitrate
|
||||
|
||||
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)))
|
||||
if getSettingBool(settings, "large-scale-tile", e.cfg.large_scale_tile != 0) {
|
||||
e.cfg.large_scale_tile = 1
|
||||
}
|
||||
if getSettingBool(settings, "monochrome", e.cfg.monochrome != 0) {
|
||||
e.cfg.monochrome = 1
|
||||
}
|
||||
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)))
|
||||
|
||||
//TODO: find all settings not set on AV1 encoder and place them on e.cfg
|
||||
|
||||
if aomErr = C.aom_codec_enc_init_ver(&e.codec, encoder, &e.cfg, 0, C.AOM_ENCODER_ABI_VERSION); aomErr != 0 {
|
||||
return nil, fmt.Errorf("failed to initialize encoder: %s", C.GoString(e.codec.err_detail))
|
||||
}
|
||||
|
||||
if aomErr = C.aom_codec_control_int(&e.codec, C.AOME_SET_CPUUSED, speed); aomErr != 0 {
|
||||
return nil, errors.New("failed to set cpu-used")
|
||||
for k, v := range settings {
|
||||
if err := func() error {
|
||||
var strVal *C.char
|
||||
if val, ok := v.(string); ok {
|
||||
strVal = C.CString(val)
|
||||
} else if val, ok := v.(int); ok {
|
||||
strVal = C.CString(strconv.Itoa(val))
|
||||
} else if val, ok := v.(int64); ok {
|
||||
strVal = C.CString(strconv.Itoa(int(val)))
|
||||
}
|
||||
|
||||
if strVal != nil {
|
||||
defer C.free(unsafe.Pointer(strVal))
|
||||
} else {
|
||||
return fmt.Errorf("could not get parameter %s", k)
|
||||
}
|
||||
strKey := C.CString(k)
|
||||
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)))
|
||||
} 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 {
|
||||
return fmt.Errorf("error setting parameter %s: %s", k, C.GoString(C.aom_codec_error_detail(&e.codec)))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := binary.Write(e.w, binary.LittleEndian, struct {
|
||||
|
@ -246,6 +318,23 @@ func (e *Encoder) Version() string {
|
|||
return Version()
|
||||
}
|
||||
|
||||
func getSettingBool(m map[string]any, name string, fallback bool) bool {
|
||||
if v, ok := m[name]; ok {
|
||||
if val, ok := v.(string); ok {
|
||||
return val == "false" || val == "f" || val == "n"
|
||||
}
|
||||
if val, ok := v.(int); ok {
|
||||
return val != 0
|
||||
}
|
||||
if val, ok := v.(int64); ok {
|
||||
return val != 0
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func getSettingString(m map[string]any, name string, fallback string) string {
|
||||
if v, ok := m[name]; ok {
|
||||
if val, ok := v.(string); ok {
|
||||
|
@ -260,3 +349,34 @@ func getSettingString(m map[string]any, name string, fallback string) string {
|
|||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func getSettingInt(m map[string]any, name string, fallback int) int {
|
||||
if v, ok := m[name]; ok {
|
||||
if val, ok := v.(string); ok {
|
||||
if intVal, err := strconv.Atoi(val); err != nil {
|
||||
return intVal
|
||||
} else {
|
||||
return fallback
|
||||
}
|
||||
}
|
||||
if val, ok := v.(int); ok {
|
||||
return val
|
||||
}
|
||||
if val, ok := v.(int64); ok {
|
||||
return int(val)
|
||||
}
|
||||
if val, ok := v.(uint); ok {
|
||||
return int(val)
|
||||
}
|
||||
if val, ok := v.(uint64); ok {
|
||||
return int(val)
|
||||
}
|
||||
if val, ok := v.(C.int); ok {
|
||||
return int(val)
|
||||
}
|
||||
if val, ok := v.(C.uint); ok {
|
||||
return int(val)
|
||||
}
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue