Properly close dav1d decoder, clone settings map on aom
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
b08b662354
commit
c54e961aee
|
@ -8,7 +8,7 @@
|
|||
|
||||
void set_threading(Dav1dSettings* s, int threads) {
|
||||
#if DAV1D_VERSION_AT_LEAST(6,0)
|
||||
|
||||
s->n_threads = threads;
|
||||
#else
|
||||
s->n_tile_threads = MIN(floor(sqrt(threads)), DAV1D_MAX_TILE_THREADS);
|
||||
s->n_frame_threads = MIN(ceil(threads / s->n_tile_threads), DAV1D_MAX_FRAME_THREADS);
|
||||
|
|
|
@ -15,8 +15,10 @@ import (
|
|||
"git.gammaspectra.live/S.O.N.G/Ignite/frame"
|
||||
"git.gammaspectra.live/S.O.N.G/Ignite/utilities"
|
||||
"git.gammaspectra.live/S.O.N.G/Ignite/utilities/ivfreader"
|
||||
"golang.org/x/exp/constraints"
|
||||
"io"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
|
@ -35,6 +37,8 @@ type Decoder struct {
|
|||
picture C.Dav1dPicture
|
||||
data C.Dav1dData
|
||||
|
||||
closer sync.Once
|
||||
|
||||
bufPool sync.Pool
|
||||
}
|
||||
|
||||
|
@ -57,12 +61,20 @@ func NewDecoder(r io.Reader, settings map[string]any) (d *Decoder, err error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
maxThreads := int(getSettingUnsigned[uint64](settings, "threads", 0))
|
||||
if maxThreads == 0 {
|
||||
maxThreads = runtime.NumCPU()
|
||||
}
|
||||
|
||||
//TODO settings: apply_grain, output_invisible_frames, decode_frame_type, inloop_filters
|
||||
|
||||
C.dav1d_default_settings(&d.settings)
|
||||
C.set_threading(&d.settings, C.int(runtime.NumCPU()))
|
||||
C.set_threading(&d.settings, C.int(maxThreads))
|
||||
if ret := C.dav1d_open(&d.ctx, &d.settings); ret != 0 {
|
||||
return nil, fmt.Errorf("error %d", ret)
|
||||
}
|
||||
if d.firstFrame, err = d.Decode(); err != nil {
|
||||
d.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -146,11 +158,14 @@ func (d *Decoder) flushPicture() C.int {
|
|||
}
|
||||
|
||||
func (d *Decoder) Close() {
|
||||
if d.data.sz > 0 {
|
||||
C.dav1d_data_unref(&d.data)
|
||||
}
|
||||
//TODO: close other context
|
||||
|
||||
d.closer.Do(func() {
|
||||
if d.data.sz > 0 {
|
||||
C.dav1d_data_unref(&d.data)
|
||||
}
|
||||
if d.ctx != nil {
|
||||
C.dav1d_close(&d.ctx)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -196,12 +211,8 @@ func (d *Decoder) pictureToFrame() (frame.Frame, error) {
|
|||
}
|
||||
|
||||
properties.ColorSpace.BitDepth = byte(bitDepth)
|
||||
properties.FullColorRange = false
|
||||
|
||||
if d.picture.seq_hdr.color_range == 1 {
|
||||
//TODO check
|
||||
properties.FullColorRange = true
|
||||
}
|
||||
//TODO check
|
||||
properties.FullColorRange = d.picture.seq_hdr.color_range == 1
|
||||
|
||||
properties.ColorSpace.ChromaSamplePosition = color.ChromaSamplePositionUnspecified
|
||||
if d.picture.seq_hdr.chr == C.DAV1D_CHR_UNKNOWN {
|
||||
|
@ -316,3 +327,65 @@ func (d *Decoder) Decode() (frame.Frame, error) {
|
|||
func (d *Decoder) Version() string {
|
||||
return Version()
|
||||
}
|
||||
|
||||
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.ParseUint(val, 10, 0); err != nil {
|
||||
delete(m, name)
|
||||
return T(intVal)
|
||||
} else {
|
||||
return fallback
|
||||
}
|
||||
}
|
||||
if val, ok := v.(int); ok {
|
||||
return T(val)
|
||||
}
|
||||
if val, ok := v.(int64); ok {
|
||||
return T(val)
|
||||
}
|
||||
if val, ok := v.(uint); ok {
|
||||
return T(val)
|
||||
}
|
||||
if val, ok := v.(uint64); ok {
|
||||
return T(val)
|
||||
}
|
||||
if val, ok := v.(C.int); ok {
|
||||
return T(val)
|
||||
}
|
||||
if val, ok := v.(C.uint); ok {
|
||||
return T(val)
|
||||
}
|
||||
if val, ok := v.(bool); ok {
|
||||
if val {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
if val, ok := v.(uint); ok {
|
||||
return val != 0
|
||||
}
|
||||
if val, ok := v.(uint64); ok {
|
||||
return val != 0
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"git.gammaspectra.live/S.O.N.G/Ignite/utilities/obuwriter"
|
||||
"golang.org/x/exp/constraints"
|
||||
"io"
|
||||
"maps"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync/atomic"
|
||||
|
@ -45,6 +46,8 @@ const (
|
|||
func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[string]any) (*Encoder, error) {
|
||||
e := &Encoder{}
|
||||
|
||||
clonedSettings := maps.Clone(settings)
|
||||
|
||||
var aomErr C.aom_codec_err_t
|
||||
|
||||
encoder := C.aom_codec_av1_cx()
|
||||
|
@ -52,15 +55,15 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
|
|||
return nil, errors.New("unsupported codec")
|
||||
}
|
||||
|
||||
e.cfg.g_usage = C.uint(getSettingUnsigned(settings, "usage", uint(UsageGoodQuality)))
|
||||
e.cfg.g_usage = C.uint(getSettingUnsigned(clonedSettings, "usage", uint(UsageGoodQuality)))
|
||||
|
||||
if getSettingBool(settings, "good", false) {
|
||||
if getSettingBool(clonedSettings, "good", false) {
|
||||
e.cfg.g_usage = UsageGoodQuality
|
||||
}
|
||||
if getSettingBool(settings, "rt", false) {
|
||||
if getSettingBool(clonedSettings, "rt", false) {
|
||||
e.cfg.g_usage = UsageRealtime
|
||||
}
|
||||
if getSettingBool(settings, "allintra", false) {
|
||||
if getSettingBool(clonedSettings, "allintra", false) {
|
||||
e.cfg.g_usage = UsageAllIntra
|
||||
}
|
||||
|
||||
|
@ -138,17 +141,17 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
|
|||
|
||||
// boolean settings
|
||||
|
||||
if getSettingBool(settings, "large-scale-tile", e.cfg.large_scale_tile != 0) {
|
||||
if getSettingBool(clonedSettings, "large-scale-tile", e.cfg.large_scale_tile != 0) {
|
||||
e.cfg.large_scale_tile = 1
|
||||
}
|
||||
if getSettingBool(settings, "monochrome", e.cfg.monochrome != 0) {
|
||||
if getSettingBool(clonedSettings, "monochrome", e.cfg.monochrome != 0) {
|
||||
e.cfg.monochrome = 1
|
||||
}
|
||||
if getSettingBool(settings, "enable-fwd-kf", e.cfg.fwd_kf_enabled != 0) {
|
||||
if getSettingBool(clonedSettings, "enable-fwd-kf", e.cfg.fwd_kf_enabled != 0) {
|
||||
e.cfg.fwd_kf_enabled = 1
|
||||
}
|
||||
|
||||
if getSettingBool(settings, "kf-disabled", false) {
|
||||
if getSettingBool(clonedSettings, "kf-disabled", false) {
|
||||
e.cfg.kf_mode = C.AOM_KF_DISABLED
|
||||
}
|
||||
|
||||
|
@ -198,12 +201,12 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
|
|||
{&e.cfg.sframe_mode, "sframe-mode"},
|
||||
} {
|
||||
//todo: unset setting from map
|
||||
*s.p = C.uint(getSettingUnsigned(settings, s.n, uint(*s.p)))
|
||||
*s.p = C.uint(getSettingUnsigned(clonedSettings, s.n, uint(*s.p)))
|
||||
}
|
||||
|
||||
// string/enum settings
|
||||
|
||||
endUsage := getSettingString(settings, "end-usage", "vbr")
|
||||
endUsage := getSettingString(clonedSettings, "end-usage", "vbr")
|
||||
|
||||
switch endUsage {
|
||||
case "vbr":
|
||||
|
@ -234,7 +237,7 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
|
|||
}
|
||||
}
|
||||
|
||||
for k, v := range settings {
|
||||
for k, v := range clonedSettings {
|
||||
if err := func() error {
|
||||
var strVal *C.char
|
||||
if val, ok := v.(string); ok {
|
||||
|
|
Loading…
Reference in a new issue