From 322e4466d1dedfc210f3f671f9a3411da69c5dad Mon Sep 17 00:00:00 2001 From: WeebDataHoarder <57538841+WeebDataHoarder@users.noreply.github.com> Date: Fri, 11 Nov 2022 13:46:27 +0100 Subject: [PATCH] libdav1d: optimize allocations with a sync.Pool --- decoder/libdav1d/libdav1d.go | 40 ++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/decoder/libdav1d/libdav1d.go b/decoder/libdav1d/libdav1d.go index 1df5234..2d33349 100644 --- a/decoder/libdav1d/libdav1d.go +++ b/decoder/libdav1d/libdav1d.go @@ -13,6 +13,8 @@ import ( "git.gammaspectra.live/S.O.N.G/Ignite/utilities" "git.gammaspectra.live/S.O.N.G/Ignite/utilities/ivfreader" "io" + "runtime" + "sync" "sync/atomic" "unsafe" ) @@ -29,6 +31,8 @@ type Decoder struct { ctx *C.Dav1dContext picture C.Dav1dPicture data C.Dav1dData + + bufPool sync.Pool } var dav1dVersion = fmt.Sprintf("dav1d %s", C.GoString(C.dav1d_version())) @@ -208,12 +212,25 @@ func (d *Decoder) pictureToFrame() (frame.Frame, error) { } - buf := make([]byte, len(yData)+len(uData)+len(vData)) + n := len(yData) + len(uData) + len(vData) + + var buf []byte + if b := d.bufPool.Get(); b != nil && len(b.([]byte)) == n { + buf = b.([]byte) + } else { + buf = make([]byte, n) + } + copy(buf, yData) copy(buf[len(yData):], uData) copy(buf[len(yData)+len(uData):], vData) - return frame.NewUint16FrameFromBytes(properties, int64(d.picture.m.timestamp), buf) + if f, err := frame.NewUint16FrameFromBytes(properties, int64(d.picture.m.timestamp), buf); err != nil { + return nil, err + } else { + d.bufPool.Put(buf) + return f, nil + } } else { yData := unsafe.Slice((*byte)(d.picture.data[planeY]), properties.Height*properties.Width) var uData, vData []byte @@ -223,12 +240,27 @@ func (d *Decoder) pictureToFrame() (frame.Frame, error) { vData = unsafe.Slice((*byte)(d.picture.data[planeV]), chromaHeight*chromaWidth) } - buf := make([]byte, len(yData)+len(uData)+len(vData)) + n := len(yData) + len(uData) + len(vData) + + var buf []byte + if b := d.bufPool.Get(); b != nil && len(b.([]byte)) == n { + buf = b.([]byte) + } else { + buf = make([]byte, n) + } + copy(buf, yData) copy(buf[len(yData):], uData) copy(buf[len(yData)+len(uData):], vData) - return frame.NewUint8FrameFromBytes(properties, int64(d.picture.m.timestamp), buf) + if f, err := frame.NewUint8FrameFromBytes(properties, int64(d.picture.m.timestamp), buf); err != nil { + return nil, err + } else { + runtime.SetFinalizer(f, func(frameUint8 *frame.FrameUint8) { + d.bufPool.Put(buf) + }) + return f, nil + } } }