Ignite/utilities/obuwriter/writer.go

77 lines
1.8 KiB
Go

package obuwriter
import (
"encoding/binary"
"errors"
"git.gammaspectra.live/S.O.N.G/Ignite/utilities"
"io"
)
type Writer struct {
w io.Writer
}
func NewWriter(w io.Writer, width, height int, fourCC uint32, timeBase utilities.Ratio) (*Writer, error) {
if err := binary.Write(w, binary.LittleEndian, struct {
Magic [4]byte
Version uint16
HeaderSize uint16
FourCC uint32
Width uint16
Height uint16
Denominator uint32
Numerator uint32
Length uint32
Unused uint32
}{
Magic: [4]byte{'D', 'K', 'I', 'F'},
Version: 0,
HeaderSize: 32,
FourCC: fourCC,
Width: uint16(width),
Height: uint16(height),
Denominator: uint32(timeBase.Denominator),
Numerator: uint32(timeBase.Numerator),
Length: 0,
}); err != nil {
return nil, err
}
return &Writer{
w: w,
}, nil
}
func (w *Writer) WriteFrameBytes(pts uint64, data []byte) error {
if err := binary.Write(w.w, binary.LittleEndian, uint32(len(data))); err != nil {
return err
} else if err = binary.Write(w.w, binary.LittleEndian, pts); err != nil {
return err
} else if _, err = w.w.Write(data); err != nil {
return err
}
return nil
}
// WriteLength writes the Length field for number of frames, if writer was set to io.WriteSeeker
func (w *Writer) WriteLength(frames uint32) error {
if seeker, ok := w.w.(io.WriteSeeker); ok {
if currentIndex, err := seeker.Seek(0, io.SeekCurrent); err != nil {
return err
} else {
if _, err = seeker.Seek(4+2+2+4+2+2+4+4, io.SeekStart); err != nil {
return err
} else if err = binary.Write(w.w, binary.LittleEndian, frames); err != nil {
return err
} else if _, err = seeker.Seek(currentIndex, io.SeekStart); err != nil {
return err
}
return nil
}
} else {
return errors.New("writer is not io.WriteSeeker")
}
}