252 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			252 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package fmp4io
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 
 | |
| 	"git.r-2.top/kunmeng/vdk/utils/bits/pio"
 | |
| )
 | |
| 
 | |
| const DREF = Tag(0x64726566)
 | |
| 
 | |
| type DataRefer struct {
 | |
| 	Version uint8
 | |
| 	Flags   uint32
 | |
| 	Url     *DataReferUrl
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a DataRefer) Tag() Tag {
 | |
| 	return DREF
 | |
| }
 | |
| 
 | |
| func (a DataRefer) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(DREF))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a DataRefer) marshal(b []byte) (n int) {
 | |
| 	pio.PutU8(b[n:], a.Version)
 | |
| 	n += 1
 | |
| 	pio.PutU24BE(b[n:], a.Flags)
 | |
| 	n += 3
 | |
| 	_childrenNR := 0
 | |
| 	if a.Url != nil {
 | |
| 		_childrenNR++
 | |
| 	}
 | |
| 	pio.PutI32BE(b[n:], int32(_childrenNR))
 | |
| 	n += 4
 | |
| 	if a.Url != nil {
 | |
| 		n += a.Url.Marshal(b[n:])
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a DataRefer) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	if a.Url != nil {
 | |
| 		n += a.Url.Len()
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *DataRefer) Unmarshal(b []byte, offset int) (n int, err error) {
 | |
| 	(&a.AtomPos).setPos(offset, len(b))
 | |
| 	n += 8
 | |
| 	if len(b) < n+1 {
 | |
| 		err = parseErr("Version", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Version = pio.U8(b[n:])
 | |
| 	n += 1
 | |
| 	if len(b) < n+3 {
 | |
| 		err = parseErr("Flags", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Flags = pio.U24BE(b[n:])
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	for n+8 < len(b) {
 | |
| 		tag := Tag(pio.U32BE(b[n+4:]))
 | |
| 		size := int(pio.U32BE(b[n:]))
 | |
| 		if len(b) < n+size {
 | |
| 			err = parseErr("TagSizeInvalid", n+offset, err)
 | |
| 			return
 | |
| 		}
 | |
| 		switch tag {
 | |
| 		case URL:
 | |
| 			{
 | |
| 				atom := &DataReferUrl{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("url ", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.Url = atom
 | |
| 			}
 | |
| 		}
 | |
| 		n += size
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a DataRefer) Children() (r []Atom) {
 | |
| 	if a.Url != nil {
 | |
| 		r = append(r, a.Url)
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| const URL = Tag(0x75726c20)
 | |
| 
 | |
| type DataReferUrl struct {
 | |
| 	Version uint8
 | |
| 	Flags   uint32
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a DataReferUrl) Tag() Tag {
 | |
| 	return URL
 | |
| }
 | |
| 
 | |
| func (a DataReferUrl) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(URL))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a DataReferUrl) marshal(b []byte) (n int) {
 | |
| 	pio.PutU8(b[n:], a.Version)
 | |
| 	n += 1
 | |
| 	pio.PutU24BE(b[n:], a.Flags)
 | |
| 	n += 3
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a DataReferUrl) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *DataReferUrl) Unmarshal(b []byte, offset int) (n int, err error) {
 | |
| 	(&a.AtomPos).setPos(offset, len(b))
 | |
| 	n += 8
 | |
| 	if len(b) < n+1 {
 | |
| 		err = parseErr("Version", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Version = pio.U8(b[n:])
 | |
| 	n += 1
 | |
| 	if len(b) < n+3 {
 | |
| 		err = parseErr("Flags", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Flags = pio.U24BE(b[n:])
 | |
| 	n += 3
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a DataReferUrl) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| const HDLR = Tag(0x68646c72)
 | |
| 
 | |
| type HandlerRefer struct {
 | |
| 	Version    uint8
 | |
| 	Flags      uint32
 | |
| 	Predefined uint32
 | |
| 	Type       uint32
 | |
| 	Reserved   [3]uint32
 | |
| 	Name       string
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| const (
 | |
| 	VideoHandler = 0x76696465 // vide
 | |
| 	SoundHandler = 0x736f756e // soun
 | |
| )
 | |
| 
 | |
| func (a HandlerRefer) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(HDLR))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a HandlerRefer) marshal(b []byte) (n int) {
 | |
| 	pio.PutU8(b[n:], a.Version)
 | |
| 	n += 1
 | |
| 	pio.PutU24BE(b[n:], a.Flags)
 | |
| 	n += 3
 | |
| 	pio.PutU32BE(b[n:], a.Predefined)
 | |
| 	n += 4
 | |
| 	pio.PutU32BE(b[n:], a.Type)
 | |
| 	n += 4
 | |
| 	n += 3 * 4
 | |
| 	copy(b[n:], a.Name)
 | |
| 	n += len(a.Name) + 1
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a HandlerRefer) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	n += 4
 | |
| 	n += 3 * 4
 | |
| 	n += len(a.Name) + 1
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *HandlerRefer) Unmarshal(b []byte, offset int) (n int, err error) {
 | |
| 	(&a.AtomPos).setPos(offset, len(b))
 | |
| 	n += 8
 | |
| 	if len(b) < n+1 {
 | |
| 		err = parseErr("Version", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Version = pio.U8(b[n:])
 | |
| 	n += 1
 | |
| 	if len(b) < n+3 {
 | |
| 		err = parseErr("Flags", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Flags = pio.U24BE(b[n:])
 | |
| 	n += 3
 | |
| 	if len(b) < n+4 {
 | |
| 		err = parseErr("Predefined", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Predefined = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	if len(b) < n+4 {
 | |
| 		err = parseErr("Type", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Type = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	n += 3 * 4
 | |
| 	i := bytes.IndexByte(b[n:], 0)
 | |
| 	if i > 0 {
 | |
| 		a.Name = string(b[n : n+i])
 | |
| 		n += i + 1
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a HandlerRefer) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a HandlerRefer) Tag() Tag {
 | |
| 	return HDLR
 | |
| }
 | 
