package mp4 import ( "errors" "io" "math" "github.com/abema/go-mp4/bitio" ) const LengthUnlimited = math.MaxUint32 type ICustomFieldObject interface { // GetFieldSize returns size of dynamic field GetFieldSize(name string, ctx Context) uint // GetFieldLength returns length of dynamic field GetFieldLength(name string, ctx Context) uint // IsOptFieldEnabled check whether if the optional field is enabled IsOptFieldEnabled(name string, ctx Context) bool // StringifyField returns field value as string StringifyField(name string, indent string, depth int, ctx Context) (string, bool) IsPString(name string, bytes []byte, remainingSize uint64, ctx Context) bool BeforeUnmarshal(r io.ReadSeeker, size uint64, ctx Context) (n uint64, override bool, err error) OnReadField(name string, r bitio.ReadSeeker, leftBits uint64, ctx Context) (rbits uint64, override bool, err error) OnWriteField(name string, w bitio.Writer, ctx Context) (wbits uint64, override bool, err error) } type BaseCustomFieldObject struct { } // GetFieldSize returns size of dynamic field func (box *BaseCustomFieldObject) GetFieldSize(string, Context) uint { panic(errors.New("GetFieldSize not implemented")) } // GetFieldLength returns length of dynamic field func (box *BaseCustomFieldObject) GetFieldLength(string, Context) uint { panic(errors.New("GetFieldLength not implemented")) } // IsOptFieldEnabled check whether if the optional field is enabled func (box *BaseCustomFieldObject) IsOptFieldEnabled(string, Context) bool { return false } // StringifyField returns field value as string func (box *BaseCustomFieldObject) StringifyField(string, string, int, Context) (string, bool) { return "", false } func (*BaseCustomFieldObject) IsPString(name string, bytes []byte, remainingSize uint64, ctx Context) bool { return true } func (*BaseCustomFieldObject) BeforeUnmarshal(io.ReadSeeker, uint64, Context) (uint64, bool, error) { return 0, false, nil } func (*BaseCustomFieldObject) OnReadField(string, bitio.ReadSeeker, uint64, Context) (uint64, bool, error) { return 0, false, nil } func (*BaseCustomFieldObject) OnWriteField(string, bitio.Writer, Context) (uint64, bool, error) { return 0, false, nil } // IImmutableBox is common interface of box type IImmutableBox interface { ICustomFieldObject // GetVersion returns the box version GetVersion() uint8 // GetFlags returns the flags GetFlags() uint32 // CheckFlag checks the flag status CheckFlag(uint32) bool // GetType returns the BoxType GetType() BoxType } // IBox is common interface of box type IBox interface { IImmutableBox // SetVersion sets the box version SetVersion(uint8) // SetFlags sets the flags SetFlags(uint32) // AddFlag adds the flag AddFlag(uint32) // RemoveFlag removes the flag RemoveFlag(uint32) } type Box struct { BaseCustomFieldObject } // GetVersion returns the box version func (box *Box) GetVersion() uint8 { return 0 } // SetVersion sets the box version func (box *Box) SetVersion(uint8) { } // GetFlags returns the flags func (box *Box) GetFlags() uint32 { return 0x000000 } // CheckFlag checks the flag status func (box *Box) CheckFlag(flag uint32) bool { return true } // SetFlags sets the flags func (box *Box) SetFlags(uint32) { } // AddFlag adds the flag func (box *Box) AddFlag(flag uint32) { } // RemoveFlag removes the flag func (box *Box) RemoveFlag(flag uint32) { } // FullBox is ISOBMFF FullBox type FullBox struct { BaseCustomFieldObject Version uint8 `mp4:"0,size=8"` Flags [3]byte `mp4:"1,size=8"` } // GetVersion returns the box version func (box *FullBox) GetVersion() uint8 { return box.Version } // SetVersion sets the box version func (box *FullBox) SetVersion(version uint8) { box.Version = version } // GetFlags returns the flags func (box *FullBox) GetFlags() uint32 { flag := uint32(box.Flags[0]) << 16 flag ^= uint32(box.Flags[1]) << 8 flag ^= uint32(box.Flags[2]) return flag } // CheckFlag checks the flag status func (box *FullBox) CheckFlag(flag uint32) bool { return box.GetFlags()&flag != 0 } // SetFlags sets the flags func (box *FullBox) SetFlags(flags uint32) { box.Flags[0] = byte(flags >> 16) box.Flags[1] = byte(flags >> 8) box.Flags[2] = byte(flags) } // AddFlag adds the flag func (box *FullBox) AddFlag(flag uint32) { box.SetFlags(box.GetFlags() | flag) } // RemoveFlag removes the flag func (box *FullBox) RemoveFlag(flag uint32) { box.SetFlags(box.GetFlags() & (^flag)) }