Remove malloc usage from x264/aom, reuse native picture buffers on x264/aom, handle chroma location in x264
This commit is contained in:
parent
194149963d
commit
8a77f16435
|
@ -21,13 +21,13 @@ import (
|
|||
)
|
||||
|
||||
type Encoder struct {
|
||||
w *obuwriter.Writer
|
||||
cleaned atomic.Bool
|
||||
cfg C.aom_codec_enc_cfg_t
|
||||
codec C.aom_codec_ctx_t
|
||||
raw *C.aom_image_t
|
||||
frames uint32
|
||||
pinner runtime.Pinner
|
||||
w *obuwriter.Writer
|
||||
cleaned atomic.Bool
|
||||
cfg C.aom_codec_enc_cfg_t
|
||||
codec C.aom_codec_ctx_t
|
||||
raw *C.aom_image_t
|
||||
frames uint32
|
||||
resourcePinner runtime.Pinner
|
||||
}
|
||||
|
||||
var libaomVersion = "libaom-av1 " + C.GoString(C.aom_codec_version_str())
|
||||
|
@ -106,9 +106,8 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
|
|||
flags |= C.AOM_CODEC_USE_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
if e.raw = (*C.aom_image_t)(C.malloc(C.size_t(unsafe.Sizeof(C.aom_image_t{})))); e.raw == nil {
|
||||
return nil, errors.New("error allocating memory")
|
||||
}
|
||||
e.raw = &C.aom_image_t{}
|
||||
e.resourcePinner.Pin(e.raw)
|
||||
if C.aom_img_alloc(e.raw, imageFormat, C.uint(properties.Width), C.uint(properties.Height), 1) == nil {
|
||||
return nil, errors.New("failed to allocate image")
|
||||
}
|
||||
|
@ -298,39 +297,25 @@ func (e *Encoder) EncodeStream(stream *frame.Stream) error {
|
|||
|
||||
func (e *Encoder) Encode(f frame.Frame) error {
|
||||
|
||||
var luma, cb, cr unsafe.Pointer
|
||||
|
||||
switch typedFrame := f.(type) {
|
||||
case frame.TypedFrame[uint8]:
|
||||
luma = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeLuma()))
|
||||
cb = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeCb()))
|
||||
cr = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeCr()))
|
||||
luma := typedFrame.GetNativeLuma()
|
||||
cb := typedFrame.GetNativeCb()
|
||||
cr := typedFrame.GetNativeCr()
|
||||
copy(unsafe.Slice((*byte)(e.raw.planes[0]), len(luma)), luma)
|
||||
copy(unsafe.Slice((*byte)(e.raw.planes[1]), len(cb)), cb)
|
||||
copy(unsafe.Slice((*byte)(e.raw.planes[2]), len(cr)), cr)
|
||||
case frame.TypedFrame[uint16]:
|
||||
luma = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeLuma()))
|
||||
cb = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeCb()))
|
||||
cr = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeCr()))
|
||||
luma := typedFrame.GetNativeLuma()
|
||||
cb := typedFrame.GetNativeCb()
|
||||
cr := typedFrame.GetNativeCr()
|
||||
copy(unsafe.Slice((*uint16)(unsafe.Pointer(e.raw.planes[0])), len(luma)), luma)
|
||||
copy(unsafe.Slice((*uint16)(unsafe.Pointer(e.raw.planes[1])), len(cb)), cb)
|
||||
copy(unsafe.Slice((*uint16)(unsafe.Pointer(e.raw.planes[2])), len(cr)), cr)
|
||||
default:
|
||||
return errors.New("unknown frame type")
|
||||
}
|
||||
|
||||
e.pinner.Pin(luma)
|
||||
e.pinner.Pin(cb)
|
||||
e.pinner.Pin(cr)
|
||||
|
||||
e.raw.planes[0] = (*C.uint8_t)(luma)
|
||||
e.raw.planes[1] = (*C.uint8_t)(cb)
|
||||
e.raw.planes[2] = (*C.uint8_t)(cr)
|
||||
|
||||
defer e.pinner.Unpin()
|
||||
|
||||
defer runtime.KeepAlive(f)
|
||||
//cleanup pointers
|
||||
defer func() {
|
||||
e.raw.planes[0] = nil
|
||||
e.raw.planes[1] = nil
|
||||
e.raw.planes[2] = nil
|
||||
}()
|
||||
|
||||
if _, err := e.encodeFrame(f.PTS(), e.raw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -397,10 +382,10 @@ func (e *Encoder) Close() {
|
|||
if e.cleaned.Swap(true) == false {
|
||||
if e.raw != nil {
|
||||
C.aom_img_free(e.raw)
|
||||
C.free(unsafe.Pointer(e.raw))
|
||||
e.raw = nil
|
||||
}
|
||||
C.aom_codec_destroy(&e.codec)
|
||||
e.resourcePinner.Unpin()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import "C"
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.gammaspectra.live/S.O.N.G/Ignite/color"
|
||||
"git.gammaspectra.live/S.O.N.G/Ignite/frame"
|
||||
"git.gammaspectra.live/S.O.N.G/Ignite/utilities"
|
||||
"io"
|
||||
|
@ -22,13 +23,13 @@ import (
|
|||
)
|
||||
|
||||
type Encoder struct {
|
||||
w io.Writer
|
||||
cleaned atomic.Bool
|
||||
params C.x264_param_t
|
||||
pictureIn *C.x264_picture_t
|
||||
pictureOut C.x264_picture_t
|
||||
h *C.x264_t
|
||||
pinner runtime.Pinner
|
||||
w io.Writer
|
||||
cleaned atomic.Bool
|
||||
params C.x264_param_t
|
||||
pictureIn *C.x264_picture_t
|
||||
pictureOut C.x264_picture_t
|
||||
h *C.x264_t
|
||||
resourcePinner runtime.Pinner
|
||||
}
|
||||
|
||||
var x264Version = fmt.Sprintf("x264 core:%d%s", C.X264_BUILD, C.GoString(C.Version()))
|
||||
|
@ -107,6 +108,23 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
|
|||
e.params.vui.b_fullrange = 0
|
||||
}
|
||||
|
||||
switch properties.ColorSpace.ChromaSamplePosition {
|
||||
case color.ChromaSamplePositionUnspecified:
|
||||
e.params.vui.i_chroma_loc = 0 //?
|
||||
case color.ChromaSamplePositionLeft:
|
||||
e.params.vui.i_chroma_loc = 0
|
||||
case color.ChromaSamplePositionCenter:
|
||||
e.params.vui.i_chroma_loc = 1
|
||||
case color.ChromaSamplePositionTopLeft:
|
||||
e.params.vui.i_chroma_loc = 2
|
||||
case color.ChromaSamplePositionTop:
|
||||
e.params.vui.i_chroma_loc = 3
|
||||
case color.ChromaSamplePositionBottomLeft:
|
||||
e.params.vui.i_chroma_loc = 4
|
||||
case color.ChromaSamplePositionBottom:
|
||||
e.params.vui.i_chroma_loc = 5
|
||||
}
|
||||
|
||||
for k, v := range settings {
|
||||
if k == "profile" || k == "preset" || k == "tune" {
|
||||
continue
|
||||
|
@ -161,9 +179,9 @@ func NewEncoder(w io.Writer, properties frame.StreamProperties, settings map[str
|
|||
encoder.Close()
|
||||
})
|
||||
|
||||
if e.pictureIn = (*C.x264_picture_t)(C.malloc(C.size_t(unsafe.Sizeof(C.x264_picture_t{})))); e.pictureIn == nil {
|
||||
return nil, errors.New("error allocating memory")
|
||||
}
|
||||
e.pictureIn = &C.x264_picture_t{}
|
||||
e.resourcePinner.Pin(e.pictureIn)
|
||||
|
||||
if C.x264_picture_alloc(e.pictureIn, e.params.i_csp, e.params.i_width, e.params.i_height) < 0 {
|
||||
return nil, errors.New("error allocating input picture")
|
||||
}
|
||||
|
@ -188,39 +206,25 @@ func (e *Encoder) EncodeStream(stream *frame.Stream) error {
|
|||
}
|
||||
|
||||
func (e *Encoder) Encode(f frame.Frame) error {
|
||||
var luma, cb, cr unsafe.Pointer
|
||||
|
||||
switch typedFrame := f.(type) {
|
||||
case frame.TypedFrame[uint8]:
|
||||
luma = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeLuma()))
|
||||
cb = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeCb()))
|
||||
cr = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeCr()))
|
||||
luma := typedFrame.GetNativeLuma()
|
||||
cb := typedFrame.GetNativeCb()
|
||||
cr := typedFrame.GetNativeCr()
|
||||
copy(unsafe.Slice((*byte)(e.pictureIn.img.plane[0]), len(luma)), luma)
|
||||
copy(unsafe.Slice((*byte)(e.pictureIn.img.plane[1]), len(cb)), cb)
|
||||
copy(unsafe.Slice((*byte)(e.pictureIn.img.plane[2]), len(cr)), cr)
|
||||
case frame.TypedFrame[uint16]:
|
||||
luma = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeLuma()))
|
||||
cb = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeCb()))
|
||||
cr = unsafe.Pointer(unsafe.SliceData(typedFrame.GetNativeCr()))
|
||||
luma := typedFrame.GetNativeLuma()
|
||||
cb := typedFrame.GetNativeCb()
|
||||
cr := typedFrame.GetNativeCr()
|
||||
copy(unsafe.Slice((*uint16)(unsafe.Pointer(e.pictureIn.img.plane[0])), len(luma)), luma)
|
||||
copy(unsafe.Slice((*uint16)(unsafe.Pointer(e.pictureIn.img.plane[1])), len(cb)), cb)
|
||||
copy(unsafe.Slice((*uint16)(unsafe.Pointer(e.pictureIn.img.plane[2])), len(cr)), cr)
|
||||
default:
|
||||
return errors.New("unknown frame type")
|
||||
}
|
||||
|
||||
e.pinner.Pin(luma)
|
||||
e.pinner.Pin(cb)
|
||||
e.pinner.Pin(cr)
|
||||
|
||||
e.pictureIn.img.plane[0] = (*C.uint8_t)(luma)
|
||||
e.pictureIn.img.plane[1] = (*C.uint8_t)(cb)
|
||||
e.pictureIn.img.plane[2] = (*C.uint8_t)(cr)
|
||||
|
||||
defer e.pinner.Unpin()
|
||||
|
||||
defer runtime.KeepAlive(f)
|
||||
//cleanup pointers
|
||||
defer func() {
|
||||
e.pictureIn.img.plane[0] = nil
|
||||
e.pictureIn.img.plane[1] = nil
|
||||
e.pictureIn.img.plane[2] = nil
|
||||
}()
|
||||
|
||||
e.pictureIn.i_pts = C.int64_t(f.PTS())
|
||||
|
||||
return e.encoderEncode(e.pictureIn)
|
||||
|
@ -291,13 +295,13 @@ func (e *Encoder) Close() {
|
|||
}
|
||||
if e.pictureIn != nil {
|
||||
C.x264_picture_clean(e.pictureIn)
|
||||
C.free(unsafe.Pointer(e.pictureIn))
|
||||
e.pictureIn = nil
|
||||
}
|
||||
if e.params.p_log_private != nil {
|
||||
(cgo.Handle)(e.params.p_log_private).Delete()
|
||||
e.params.p_log_private = nil
|
||||
}
|
||||
e.resourcePinner.Unpin()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue