DataHoarder
6ea3e971bb
All checks were successful
continuous-integration/drone/push Build is passing
103 lines
2.2 KiB
Go
103 lines
2.2 KiB
Go
package frame
|
|
|
|
import (
|
|
"errors"
|
|
"sync"
|
|
)
|
|
|
|
type Pool struct {
|
|
p sync.Pool
|
|
properties Properties
|
|
frameSize int
|
|
}
|
|
|
|
func NewPool(properties Properties) (*Pool, error) {
|
|
p := &Pool{
|
|
properties: properties,
|
|
}
|
|
|
|
if properties.ColorSpace.BitDepth > 16 || properties.ColorSpace.BitDepth <= 0 {
|
|
return nil, errors.New("unsupported bit depth")
|
|
}
|
|
|
|
frameSize, err := properties.ColorSpace.FrameSize(properties.Width, properties.Height)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
p.frameSize = frameSize
|
|
|
|
iY := properties.ColorSpace.ChromaSampling.PlaneLumaSamples(properties.Width, properties.Height)
|
|
iCb := properties.ColorSpace.ChromaSampling.PlaneCbSamples(properties.Width, properties.Height)
|
|
iCr := properties.ColorSpace.ChromaSampling.PlaneCrSamples(properties.Width, properties.Height)
|
|
|
|
// 16-bit frame
|
|
if properties.ColorSpace.BitDepth > 8 {
|
|
p.p.New = func() any {
|
|
buf := make([]uint16, p.frameSize/2)
|
|
return &fUint16{
|
|
ret: p.Put,
|
|
properties: properties,
|
|
Y: buf[:iY],
|
|
Cb: buf[iY : iY+iCb],
|
|
Cr: buf[iY+iCb : iY+iCb+iCr],
|
|
}
|
|
}
|
|
} else {
|
|
p.p.New = func() any {
|
|
buf := make([]uint8, p.frameSize)
|
|
return &fUint8{
|
|
ret: p.Put,
|
|
properties: properties,
|
|
Y: buf[:iY],
|
|
Cb: buf[iY : iY+iCb],
|
|
Cr: buf[iY+iCb : iY+iCb+iCr],
|
|
}
|
|
}
|
|
}
|
|
|
|
return p, nil
|
|
}
|
|
|
|
func (p *Pool) Properties() Properties {
|
|
return p.properties
|
|
}
|
|
|
|
func (p *Pool) Get(pts, nextPts int64) Frame {
|
|
switch tf := p.p.Get().(type) {
|
|
case *fUint16:
|
|
tf.Pts = pts
|
|
tf.NextPts = nextPts
|
|
return tf
|
|
case *fUint8:
|
|
tf.Pts = pts
|
|
tf.NextPts = nextPts
|
|
return tf
|
|
default:
|
|
panic("unsupported type")
|
|
}
|
|
}
|
|
|
|
func (p *Pool) Put(f Frame) {
|
|
switch tf := f.(type) {
|
|
case *fUint16:
|
|
if tf.properties != p.properties {
|
|
panic("unsupported properties")
|
|
}
|
|
if (len(tf.Y)+len(tf.Cb)+len(tf.Cr))*2 != p.frameSize {
|
|
panic("unsupported data size")
|
|
}
|
|
p.p.Put(tf)
|
|
case *fUint8:
|
|
if tf.properties != p.properties {
|
|
panic("unsupported properties")
|
|
}
|
|
if (len(tf.Y) + len(tf.Cb) + len(tf.Cr)) != p.frameSize {
|
|
panic("unsupported data size")
|
|
}
|
|
p.p.Put(tf)
|
|
default:
|
|
panic("unsupported type")
|
|
}
|
|
}
|