766 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			766 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package fmp4io
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 
 | |
| 	"git.r-2.top/kunmeng/vdk/utils/bits/pio"
 | |
| )
 | |
| 
 | |
| const MOOF = Tag(0x6d6f6f66)
 | |
| 
 | |
| type MovieFrag struct {
 | |
| 	Header   *MovieFragHeader
 | |
| 	Tracks   []*TrackFrag
 | |
| 	Unknowns []Atom
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a MovieFrag) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(MOOF))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a MovieFrag) marshal(b []byte) (n int) {
 | |
| 	if a.Header != nil {
 | |
| 		n += a.Header.Marshal(b[n:])
 | |
| 	}
 | |
| 	for _, atom := range a.Tracks {
 | |
| 		n += atom.Marshal(b[n:])
 | |
| 	}
 | |
| 	for _, atom := range a.Unknowns {
 | |
| 		n += atom.Marshal(b[n:])
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a MovieFrag) Len() (n int) {
 | |
| 	n += 8
 | |
| 	if a.Header != nil {
 | |
| 		n += a.Header.Len()
 | |
| 	}
 | |
| 	for _, atom := range a.Tracks {
 | |
| 		n += atom.Len()
 | |
| 	}
 | |
| 	for _, atom := range a.Unknowns {
 | |
| 		n += atom.Len()
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *MovieFrag) Unmarshal(b []byte, offset int) (n int, err error) {
 | |
| 	(&a.AtomPos).setPos(offset, len(b))
 | |
| 	n += 8
 | |
| 	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 MFHD:
 | |
| 			{
 | |
| 				atom := &MovieFragHeader{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("mfhd", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.Header = atom
 | |
| 			}
 | |
| 		case TRAF:
 | |
| 			{
 | |
| 				atom := &TrackFrag{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("traf", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.Tracks = append(a.Tracks, atom)
 | |
| 			}
 | |
| 		default:
 | |
| 			{
 | |
| 				atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.Unknowns = append(a.Unknowns, atom)
 | |
| 			}
 | |
| 		}
 | |
| 		n += size
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a MovieFrag) Children() (r []Atom) {
 | |
| 	if a.Header != nil {
 | |
| 		r = append(r, a.Header)
 | |
| 	}
 | |
| 	for _, atom := range a.Tracks {
 | |
| 		r = append(r, atom)
 | |
| 	}
 | |
| 	r = append(r, a.Unknowns...)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a MovieFrag) Tag() Tag {
 | |
| 	return MOOF
 | |
| }
 | |
| 
 | |
| const MFHD = Tag(0x6d666864)
 | |
| 
 | |
| type MovieFragHeader struct {
 | |
| 	Version uint8
 | |
| 	Flags   uint32
 | |
| 	Seqnum  uint32
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a MovieFragHeader) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(MFHD))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a MovieFragHeader) 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.Seqnum)
 | |
| 	n += 4
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a MovieFragHeader) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *MovieFragHeader) 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("Seqnum", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Seqnum = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a MovieFragHeader) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a MovieFragHeader) Tag() Tag {
 | |
| 	return MFHD
 | |
| }
 | |
| 
 | |
| // TRUN is the atom type for TrackFragRun
 | |
| const TRUN = Tag(0x7472756e)
 | |
| 
 | |
| // TrackFragRun atom
 | |
| type TrackFragRun struct {
 | |
| 	Version          uint8
 | |
| 	Flags            TrackRunFlags
 | |
| 	DataOffset       uint32
 | |
| 	FirstSampleFlags SampleFlags
 | |
| 	Entries          []TrackFragRunEntry
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| // TrackRunFlags is the type of TrackFragRun's Flags
 | |
| type TrackRunFlags uint32
 | |
| 
 | |
| // Defined flags for TrackFragRun
 | |
| const (
 | |
| 	TrackRunDataOffset       TrackRunFlags = 0x01
 | |
| 	TrackRunFirstSampleFlags TrackRunFlags = 0x04
 | |
| 	TrackRunSampleDuration   TrackRunFlags = 0x100
 | |
| 	TrackRunSampleSize       TrackRunFlags = 0x200
 | |
| 	TrackRunSampleFlags      TrackRunFlags = 0x400
 | |
| 	TrackRunSampleCTS        TrackRunFlags = 0x800
 | |
| )
 | |
| 
 | |
| func (a TrackFragRun) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(TRUN))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFragRun) marshal(b []byte) (n int) {
 | |
| 	pio.PutU8(b[n:], a.Version)
 | |
| 	n += 1
 | |
| 	pio.PutU24BE(b[n:], uint32(a.Flags))
 | |
| 	n += 3
 | |
| 	pio.PutU32BE(b[n:], uint32(len(a.Entries)))
 | |
| 	n += 4
 | |
| 	if a.Flags&TrackRunDataOffset != 0 {
 | |
| 		{
 | |
| 			pio.PutU32BE(b[n:], a.DataOffset)
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackRunFirstSampleFlags != 0 {
 | |
| 		{
 | |
| 			pio.PutU32BE(b[n:], uint32(a.FirstSampleFlags))
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	for _, entry := range a.Entries {
 | |
| 		if a.Flags&TrackRunSampleDuration != 0 {
 | |
| 			pio.PutU32BE(b[n:], entry.Duration)
 | |
| 			n += 4
 | |
| 		}
 | |
| 		if a.Flags&TrackRunSampleSize != 0 {
 | |
| 			pio.PutU32BE(b[n:], entry.Size)
 | |
| 			n += 4
 | |
| 		}
 | |
| 		if a.Flags&TrackRunSampleFlags != 0 {
 | |
| 			pio.PutU32BE(b[n:], uint32(entry.Flags))
 | |
| 			n += 4
 | |
| 		}
 | |
| 		if a.Flags&TrackRunSampleCTS != 0 {
 | |
| 			if a.Version > 0 {
 | |
| 				pio.PutI32BE(b[:n], int32(entry.CTS))
 | |
| 			} else {
 | |
| 				pio.PutU32BE(b[n:], uint32(entry.CTS))
 | |
| 			}
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFragRun) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	if a.Flags&TrackRunDataOffset != 0 {
 | |
| 		{
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackRunFirstSampleFlags != 0 {
 | |
| 		{
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	for range a.Entries {
 | |
| 		if a.Flags&TrackRunSampleDuration != 0 {
 | |
| 			n += 4
 | |
| 		}
 | |
| 		if a.Flags&TrackRunSampleSize != 0 {
 | |
| 			n += 4
 | |
| 		}
 | |
| 		if a.Flags&TrackRunSampleFlags != 0 {
 | |
| 			n += 4
 | |
| 		}
 | |
| 		if a.Flags&TrackRunSampleCTS != 0 {
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *TrackFragRun) 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 = TrackRunFlags(pio.U24BE(b[n:]))
 | |
| 	n += 3
 | |
| 	var _len_Entries uint32
 | |
| 	_len_Entries = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	a.Entries = make([]TrackFragRunEntry, _len_Entries)
 | |
| 	if a.Flags&TrackRunDataOffset != 0 {
 | |
| 		{
 | |
| 			if len(b) < n+4 {
 | |
| 				err = parseErr("DataOffset", n+offset, err)
 | |
| 				return
 | |
| 			}
 | |
| 			a.DataOffset = pio.U32BE(b[n:])
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackRunFirstSampleFlags != 0 {
 | |
| 		{
 | |
| 			if len(b) < n+4 {
 | |
| 				err = parseErr("FirstSampleFlags", n+offset, err)
 | |
| 				return
 | |
| 			}
 | |
| 			a.FirstSampleFlags = SampleFlags(pio.U32BE(b[n:]))
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	for i := 0; i < int(_len_Entries); i++ {
 | |
| 		entry := &a.Entries[i]
 | |
| 		if a.Flags&TrackRunSampleDuration != 0 {
 | |
| 			entry.Duration = pio.U32BE(b[n:])
 | |
| 			n += 4
 | |
| 		}
 | |
| 		if a.Flags&TrackRunSampleSize != 0 {
 | |
| 			entry.Size = pio.U32BE(b[n:])
 | |
| 			n += 4
 | |
| 		}
 | |
| 		if a.Flags&TrackRunSampleFlags != 0 {
 | |
| 			entry.Flags = SampleFlags(pio.U32BE(b[n:]))
 | |
| 			n += 4
 | |
| 		}
 | |
| 		if a.Flags&TrackRunSampleCTS != 0 {
 | |
| 			if a.Version > 0 {
 | |
| 				entry.CTS = int32(pio.I32BE(b[n:]))
 | |
| 			} else {
 | |
| 				entry.CTS = int32(pio.U32BE(b[n:]))
 | |
| 			}
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFragRun) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| type TrackFragRunEntry struct {
 | |
| 	Duration uint32
 | |
| 	Size     uint32
 | |
| 	Flags    SampleFlags
 | |
| 	CTS      int32
 | |
| }
 | |
| 
 | |
| func (a TrackFragRun) Tag() Tag {
 | |
| 	return TRUN
 | |
| }
 | |
| 
 | |
| const TFDT = Tag(0x74666474)
 | |
| 
 | |
| type TrackFragDecodeTime struct {
 | |
| 	Version uint8
 | |
| 	Flags   uint32
 | |
| 	Time    uint64
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a TrackFragDecodeTime) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(TFDT))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFragDecodeTime) marshal(b []byte) (n int) {
 | |
| 	pio.PutU8(b[n:], a.Version)
 | |
| 	n += 1
 | |
| 	pio.PutU24BE(b[n:], a.Flags)
 | |
| 	n += 3
 | |
| 	if a.Version != 0 {
 | |
| 		pio.PutU64BE(b[n:], a.Time)
 | |
| 		n += 8
 | |
| 	} else {
 | |
| 		pio.PutU32BE(b[n:], uint32(a.Time))
 | |
| 		n += 4
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFragDecodeTime) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	if a.Version != 0 {
 | |
| 		n += 8
 | |
| 	} else {
 | |
| 
 | |
| 		n += 4
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *TrackFragDecodeTime) 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 a.Version != 0 {
 | |
| 		a.Time = pio.U64BE(b[n:])
 | |
| 		n += 8
 | |
| 	} else {
 | |
| 		a.Time = uint64(pio.U32BE(b[n:]))
 | |
| 		n += 4
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFragDecodeTime) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFragDecodeTime) Tag() Tag {
 | |
| 	return TFDT
 | |
| }
 | |
| 
 | |
| const TRAF = Tag(0x74726166)
 | |
| 
 | |
| type TrackFrag struct {
 | |
| 	Header     *TrackFragHeader
 | |
| 	DecodeTime *TrackFragDecodeTime
 | |
| 	Run        *TrackFragRun
 | |
| 	Unknowns   []Atom
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a TrackFrag) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(TRAF))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFrag) marshal(b []byte) (n int) {
 | |
| 	if a.Header != nil {
 | |
| 		n += a.Header.Marshal(b[n:])
 | |
| 	}
 | |
| 	if a.DecodeTime != nil {
 | |
| 		n += a.DecodeTime.Marshal(b[n:])
 | |
| 	}
 | |
| 	if a.Run != nil {
 | |
| 		n += a.Run.Marshal(b[n:])
 | |
| 	}
 | |
| 	for _, atom := range a.Unknowns {
 | |
| 		n += atom.Marshal(b[n:])
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFrag) Len() (n int) {
 | |
| 	n += 8
 | |
| 	if a.Header != nil {
 | |
| 		n += a.Header.Len()
 | |
| 	}
 | |
| 	if a.DecodeTime != nil {
 | |
| 		n += a.DecodeTime.Len()
 | |
| 	}
 | |
| 	if a.Run != nil {
 | |
| 		n += a.Run.Len()
 | |
| 	}
 | |
| 	for _, atom := range a.Unknowns {
 | |
| 		n += atom.Len()
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *TrackFrag) Unmarshal(b []byte, offset int) (n int, err error) {
 | |
| 	(&a.AtomPos).setPos(offset, len(b))
 | |
| 	n += 8
 | |
| 	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 TFHD:
 | |
| 			{
 | |
| 				atom := &TrackFragHeader{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("tfhd", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.Header = atom
 | |
| 			}
 | |
| 		case TFDT:
 | |
| 			{
 | |
| 				atom := &TrackFragDecodeTime{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("tfdt", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.DecodeTime = atom
 | |
| 			}
 | |
| 		case TRUN:
 | |
| 			{
 | |
| 				atom := &TrackFragRun{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("trun", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.Run = atom
 | |
| 			}
 | |
| 		default:
 | |
| 			{
 | |
| 				atom := &Dummy{Tag_: tag, Data: b[n : n+size]}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.Unknowns = append(a.Unknowns, atom)
 | |
| 			}
 | |
| 		}
 | |
| 		n += size
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFrag) Children() (r []Atom) {
 | |
| 	if a.Header != nil {
 | |
| 		r = append(r, a.Header)
 | |
| 	}
 | |
| 	if a.DecodeTime != nil {
 | |
| 		r = append(r, a.DecodeTime)
 | |
| 	}
 | |
| 	if a.Run != nil {
 | |
| 		r = append(r, a.Run)
 | |
| 	}
 | |
| 	r = append(r, a.Unknowns...)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFrag) Tag() Tag {
 | |
| 	return TRAF
 | |
| }
 | |
| 
 | |
| func (a TrackFragRun) String() string {
 | |
| 	return fmt.Sprintf("dataoffset=%d", a.DataOffset)
 | |
| }
 | |
| 
 | |
| // TFHD is the atom type for TrackFragHeader
 | |
| const TFHD = Tag(0x74666864)
 | |
| 
 | |
| // TrackFragHeader atom
 | |
| type TrackFragHeader struct {
 | |
| 	Version         uint8
 | |
| 	Flags           TrackFragFlags
 | |
| 	TrackID         uint32
 | |
| 	BaseDataOffset  uint64
 | |
| 	StsdID          uint32
 | |
| 	DefaultDuration uint32
 | |
| 	DefaultSize     uint32
 | |
| 	DefaultFlags    SampleFlags
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| // TrackFragFlags is the type of TrackFragHeader's Flags
 | |
| type TrackFragFlags uint32
 | |
| 
 | |
| // Defined flags for TrackFragHeader
 | |
| const (
 | |
| 	TrackFragBaseDataOffset    TrackFragFlags = 0x01
 | |
| 	TrackFragStsdID            TrackFragFlags = 0x02
 | |
| 	TrackFragDefaultDuration   TrackFragFlags = 0x08
 | |
| 	TrackFragDefaultSize       TrackFragFlags = 0x10
 | |
| 	TrackFragDefaultFlags      TrackFragFlags = 0x20
 | |
| 	TrackFragDurationIsEmpty   TrackFragFlags = 0x010000
 | |
| 	TrackFragDefaultBaseIsMOOF TrackFragFlags = 0x020000
 | |
| )
 | |
| 
 | |
| func (a TrackFragHeader) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(TFHD))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFragHeader) marshal(b []byte) (n int) {
 | |
| 	pio.PutU8(b[n:], a.Version)
 | |
| 	n += 1
 | |
| 	pio.PutU24BE(b[n:], uint32(a.Flags))
 | |
| 	n += 3
 | |
| 	pio.PutU32BE(b[n:], a.TrackID)
 | |
| 	n += 4
 | |
| 	if a.Flags&TrackFragBaseDataOffset != 0 {
 | |
| 		{
 | |
| 			pio.PutU64BE(b[n:], a.BaseDataOffset)
 | |
| 			n += 8
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragStsdID != 0 {
 | |
| 		{
 | |
| 			pio.PutU32BE(b[n:], a.StsdID)
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragDefaultDuration != 0 {
 | |
| 		{
 | |
| 			pio.PutU32BE(b[n:], a.DefaultDuration)
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragDefaultSize != 0 {
 | |
| 		{
 | |
| 			pio.PutU32BE(b[n:], a.DefaultSize)
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragDefaultFlags != 0 {
 | |
| 		{
 | |
| 			pio.PutU32BE(b[n:], uint32(a.DefaultFlags))
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFragHeader) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	if a.Flags&TrackFragBaseDataOffset != 0 {
 | |
| 		{
 | |
| 			n += 8
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragStsdID != 0 {
 | |
| 		{
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragDefaultDuration != 0 {
 | |
| 		{
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragDefaultSize != 0 {
 | |
| 		{
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragDefaultFlags != 0 {
 | |
| 		{
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *TrackFragHeader) 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 = TrackFragFlags(pio.U24BE(b[n:]))
 | |
| 	n += 3
 | |
| 	if len(b) < n+4 {
 | |
| 		err = parseErr("TrackID", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.TrackID = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	if a.Flags&TrackFragBaseDataOffset != 0 {
 | |
| 		{
 | |
| 			if len(b) < n+8 {
 | |
| 				err = parseErr("BaseDataOffset", n+offset, err)
 | |
| 				return
 | |
| 			}
 | |
| 			a.BaseDataOffset = pio.U64BE(b[n:])
 | |
| 			n += 8
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragStsdID != 0 {
 | |
| 		{
 | |
| 			if len(b) < n+4 {
 | |
| 				err = parseErr("StsdId", n+offset, err)
 | |
| 				return
 | |
| 			}
 | |
| 			a.StsdID = pio.U32BE(b[n:])
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragDefaultDuration != 0 {
 | |
| 		{
 | |
| 			if len(b) < n+4 {
 | |
| 				err = parseErr("DefaultDuration", n+offset, err)
 | |
| 				return
 | |
| 			}
 | |
| 			a.DefaultDuration = pio.U32BE(b[n:])
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragDefaultSize != 0 {
 | |
| 		{
 | |
| 			if len(b) < n+4 {
 | |
| 				err = parseErr("DefaultSize", n+offset, err)
 | |
| 				return
 | |
| 			}
 | |
| 			a.DefaultSize = pio.U32BE(b[n:])
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	if a.Flags&TrackFragDefaultFlags != 0 {
 | |
| 		{
 | |
| 			if len(b) < n+4 {
 | |
| 				err = parseErr("DefaultFlags", n+offset, err)
 | |
| 				return
 | |
| 			}
 | |
| 			a.DefaultFlags = SampleFlags(pio.U32BE(b[n:]))
 | |
| 			n += 4
 | |
| 		}
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFragHeader) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TrackFragHeader) Tag() Tag {
 | |
| 	return TFHD
 | |
| }
 | |
| 
 | |
| func (a TrackFragHeader) String() string {
 | |
| 	return fmt.Sprintf("basedataoffset=%d", a.BaseDataOffset)
 | |
| }
 | 
