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") } }