88 lines
2.4 KiB
Go
88 lines
2.4 KiB
Go
package frame
|
|
|
|
import (
|
|
"errors"
|
|
"runtime"
|
|
"unsafe"
|
|
)
|
|
|
|
type FrameUint16 struct {
|
|
properties Properties
|
|
Pts int64
|
|
Y []uint16
|
|
Cb []uint16
|
|
Cr []uint16
|
|
}
|
|
|
|
func NewUint16FrameFromBytes(properties Properties, pts int64, data []byte) (*FrameUint16, error) {
|
|
if frameLength, _ := properties.ColorSpace.FrameSize(properties.Width, properties.Height); frameLength != len(data) {
|
|
return nil, errors.New("wrong length of data")
|
|
}
|
|
|
|
if properties.ColorSpace.BitDepth >= 16 {
|
|
return nil, errors.New("wrong bit depth")
|
|
}
|
|
|
|
buf := make([]uint16, len(data)/2)
|
|
copy(buf, unsafe.Slice((*uint16)(unsafe.Pointer(&data[0])), len(data)/2))
|
|
runtime.KeepAlive(data)
|
|
|
|
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)
|
|
|
|
return &FrameUint16{
|
|
properties: properties,
|
|
Y: buf[:iY],
|
|
Cb: buf[iY : iY+iCb],
|
|
Cr: buf[iY+iCb : iY+iCb+iCr],
|
|
Pts: pts,
|
|
}, nil
|
|
}
|
|
|
|
func (i *FrameUint16) Get16(x, y int) (Y uint16, Cb uint16, Cr uint16) {
|
|
cy, cb, cr := i.GetNative(x, y)
|
|
|
|
return cy << (16 - i.properties.ColorSpace.BitDepth), cb << (16 - i.properties.ColorSpace.BitDepth), cr << (16 - i.properties.ColorSpace.BitDepth)
|
|
}
|
|
|
|
func (i *FrameUint16) Get8(x, y int) (Y uint8, Cb uint8, Cr uint8) {
|
|
cy, cb, cr := i.GetNative(x, y)
|
|
|
|
return uint8(cy >> (i.properties.ColorSpace.BitDepth - 8)), uint8(cb >> (i.properties.ColorSpace.BitDepth - 8)), uint8(cr >> (i.properties.ColorSpace.BitDepth - 8))
|
|
}
|
|
|
|
func (i *FrameUint16) Properties() Properties {
|
|
return i.properties
|
|
}
|
|
|
|
func (i *FrameUint16) PTS() int64 {
|
|
return i.Pts
|
|
}
|
|
|
|
func (i *FrameUint16) GetNative(x, y int) (Y uint16, Cb uint16, Cr uint16) {
|
|
Yindex := x + y*i.properties.Width
|
|
|
|
Cwidth := (i.properties.Width * int(i.properties.ColorSpace.ChromaSampling.A)) / int(i.properties.ColorSpace.ChromaSampling.J)
|
|
if i.properties.ColorSpace.ChromaSampling.B == 0 {
|
|
y /= 2
|
|
}
|
|
Cindex := (x*int(i.properties.ColorSpace.ChromaSampling.A))/int(i.properties.ColorSpace.ChromaSampling.J) + y*Cwidth
|
|
Y = i.Y[Yindex]
|
|
Cb = i.Cb[Cindex]
|
|
Cr = i.Cr[Cindex]
|
|
return
|
|
}
|
|
|
|
func (i *FrameUint16) GetNativeLuma() []uint16 {
|
|
return i.Y
|
|
}
|
|
|
|
func (i *FrameUint16) GetNativeCb() []uint16 {
|
|
return i.Cb
|
|
}
|
|
|
|
func (i *FrameUint16) GetNativeCr() []uint16 {
|
|
return i.Cr
|
|
}
|