898 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			898 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package fmp4io
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 
 | |
| 	"git.r-2.top/kunmeng/vdk/utils/bits/pio"
 | |
| )
 | |
| 
 | |
| const STBL = Tag(0x7374626c)
 | |
| 
 | |
| type SampleTable struct {
 | |
| 	SampleDesc        *SampleDesc
 | |
| 	TimeToSample      *TimeToSample
 | |
| 	CompositionOffset *CompositionOffset
 | |
| 	SampleToChunk     *SampleToChunk
 | |
| 	SyncSample        *SyncSample
 | |
| 	ChunkOffset       *ChunkOffset
 | |
| 	SampleSize        *SampleSize
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a SampleTable) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(STBL))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleTable) marshal(b []byte) (n int) {
 | |
| 	if a.SampleDesc != nil {
 | |
| 		n += a.SampleDesc.Marshal(b[n:])
 | |
| 	}
 | |
| 	if a.TimeToSample != nil {
 | |
| 		n += a.TimeToSample.Marshal(b[n:])
 | |
| 	}
 | |
| 	if a.CompositionOffset != nil {
 | |
| 		n += a.CompositionOffset.Marshal(b[n:])
 | |
| 	}
 | |
| 	if a.SampleToChunk != nil {
 | |
| 		n += a.SampleToChunk.Marshal(b[n:])
 | |
| 	}
 | |
| 	if a.SyncSample != nil {
 | |
| 		n += a.SyncSample.Marshal(b[n:])
 | |
| 	}
 | |
| 	if a.SampleSize != nil {
 | |
| 		n += a.SampleSize.Marshal(b[n:])
 | |
| 	}
 | |
| 	if a.ChunkOffset != nil {
 | |
| 		n += a.ChunkOffset.Marshal(b[n:])
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleTable) Len() (n int) {
 | |
| 	n += 8
 | |
| 	if a.SampleDesc != nil {
 | |
| 		n += a.SampleDesc.Len()
 | |
| 	}
 | |
| 	if a.TimeToSample != nil {
 | |
| 		n += a.TimeToSample.Len()
 | |
| 	}
 | |
| 	if a.CompositionOffset != nil {
 | |
| 		n += a.CompositionOffset.Len()
 | |
| 	}
 | |
| 	if a.SampleToChunk != nil {
 | |
| 		n += a.SampleToChunk.Len()
 | |
| 	}
 | |
| 	if a.SyncSample != nil {
 | |
| 		n += a.SyncSample.Len()
 | |
| 	}
 | |
| 	if a.ChunkOffset != nil {
 | |
| 		n += a.ChunkOffset.Len()
 | |
| 	}
 | |
| 	if a.SampleSize != nil {
 | |
| 		n += a.SampleSize.Len()
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *SampleTable) 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 STSD:
 | |
| 			{
 | |
| 				atom := &SampleDesc{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("stsd", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.SampleDesc = atom
 | |
| 			}
 | |
| 		case STTS:
 | |
| 			{
 | |
| 				atom := &TimeToSample{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("stts", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.TimeToSample = atom
 | |
| 			}
 | |
| 		case CTTS:
 | |
| 			{
 | |
| 				atom := &CompositionOffset{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("ctts", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.CompositionOffset = atom
 | |
| 			}
 | |
| 		case STSC:
 | |
| 			{
 | |
| 				atom := &SampleToChunk{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("stsc", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.SampleToChunk = atom
 | |
| 			}
 | |
| 		case STSS:
 | |
| 			{
 | |
| 				atom := &SyncSample{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("stss", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.SyncSample = atom
 | |
| 			}
 | |
| 		case STCO:
 | |
| 			{
 | |
| 				atom := &ChunkOffset{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("stco", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.ChunkOffset = atom
 | |
| 			}
 | |
| 		case STSZ:
 | |
| 			{
 | |
| 				atom := &SampleSize{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("stsz", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.SampleSize = atom
 | |
| 			}
 | |
| 		}
 | |
| 		n += size
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleTable) Children() (r []Atom) {
 | |
| 	if a.SampleDesc != nil {
 | |
| 		r = append(r, a.SampleDesc)
 | |
| 	}
 | |
| 	if a.TimeToSample != nil {
 | |
| 		r = append(r, a.TimeToSample)
 | |
| 	}
 | |
| 	if a.CompositionOffset != nil {
 | |
| 		r = append(r, a.CompositionOffset)
 | |
| 	}
 | |
| 	if a.SampleToChunk != nil {
 | |
| 		r = append(r, a.SampleToChunk)
 | |
| 	}
 | |
| 	if a.SyncSample != nil {
 | |
| 		r = append(r, a.SyncSample)
 | |
| 	}
 | |
| 	if a.ChunkOffset != nil {
 | |
| 		r = append(r, a.ChunkOffset)
 | |
| 	}
 | |
| 	if a.SampleSize != nil {
 | |
| 		r = append(r, a.SampleSize)
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleTable) Tag() Tag {
 | |
| 	return STBL
 | |
| }
 | |
| 
 | |
| const STSD = Tag(0x73747364)
 | |
| 
 | |
| type SampleDesc struct {
 | |
| 	Version  uint8
 | |
| 	AVC1Desc *AVC1Desc
 | |
| 	MP4ADesc *MP4ADesc
 | |
| 	OpusDesc *OpusSampleEntry
 | |
| 	Unknowns []Atom
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a SampleDesc) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(STSD))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleDesc) marshal(b []byte) (n int) {
 | |
| 	pio.PutU8(b[n:], a.Version)
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	_childrenNR := 0
 | |
| 	if a.AVC1Desc != nil {
 | |
| 		_childrenNR++
 | |
| 	}
 | |
| 	if a.MP4ADesc != nil {
 | |
| 		_childrenNR++
 | |
| 	}
 | |
| 	if a.OpusDesc != nil {
 | |
| 		_childrenNR++
 | |
| 	}
 | |
| 	_childrenNR += len(a.Unknowns)
 | |
| 	pio.PutI32BE(b[n:], int32(_childrenNR))
 | |
| 	n += 4
 | |
| 	if a.AVC1Desc != nil {
 | |
| 		n += a.AVC1Desc.Marshal(b[n:])
 | |
| 	}
 | |
| 	if a.MP4ADesc != nil {
 | |
| 		n += a.MP4ADesc.Marshal(b[n:])
 | |
| 	}
 | |
| 	if a.OpusDesc != nil {
 | |
| 		n += a.OpusDesc.Marshal(b[n:])
 | |
| 	}
 | |
| 	for _, atom := range a.Unknowns {
 | |
| 		n += atom.Marshal(b[n:])
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleDesc) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	if a.AVC1Desc != nil {
 | |
| 		n += a.AVC1Desc.Len()
 | |
| 	}
 | |
| 	if a.MP4ADesc != nil {
 | |
| 		n += a.MP4ADesc.Len()
 | |
| 	}
 | |
| 	if a.OpusDesc != nil {
 | |
| 		n += a.OpusDesc.Len()
 | |
| 	}
 | |
| 	for _, atom := range a.Unknowns {
 | |
| 		n += atom.Len()
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *SampleDesc) 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
 | |
| 	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 AVC1:
 | |
| 			{
 | |
| 				atom := &AVC1Desc{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("avc1", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.AVC1Desc = atom
 | |
| 			}
 | |
| 		case MP4A:
 | |
| 			{
 | |
| 				atom := &MP4ADesc{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("mp4a", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.MP4ADesc = atom
 | |
| 			}
 | |
| 		case OPUS:
 | |
| 			{
 | |
| 				atom := &OpusSampleEntry{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("OPUS", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 			}
 | |
| 		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 SampleDesc) Children() (r []Atom) {
 | |
| 	if a.AVC1Desc != nil {
 | |
| 		r = append(r, a.AVC1Desc)
 | |
| 	}
 | |
| 	if a.MP4ADesc != nil {
 | |
| 		r = append(r, a.MP4ADesc)
 | |
| 	}
 | |
| 	if a.OpusDesc != nil {
 | |
| 		r = append(r, a.OpusDesc)
 | |
| 	}
 | |
| 	r = append(r, a.Unknowns...)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleDesc) Tag() Tag {
 | |
| 	return STSD
 | |
| }
 | |
| 
 | |
| const STTS = Tag(0x73747473)
 | |
| 
 | |
| type TimeToSample struct {
 | |
| 	Version uint8
 | |
| 	Flags   uint32
 | |
| 	Entries []TimeToSampleEntry
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a TimeToSample) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(STTS))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TimeToSample) 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:], uint32(len(a.Entries)))
 | |
| 	n += 4
 | |
| 	for _, entry := range a.Entries {
 | |
| 		putTimeToSampleEntry(b[n:], entry)
 | |
| 		n += lenTimeToSampleEntry
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TimeToSample) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	n += lenTimeToSampleEntry * len(a.Entries)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *TimeToSample) 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
 | |
| 	var _len_Entries uint32
 | |
| 	_len_Entries = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	a.Entries = make([]TimeToSampleEntry, _len_Entries)
 | |
| 	if len(b) < n+lenTimeToSampleEntry*len(a.Entries) {
 | |
| 		err = parseErr("TimeToSampleEntry", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	for i := range a.Entries {
 | |
| 		a.Entries[i] = getTimeToSampleEntry(b[n:])
 | |
| 		n += lenTimeToSampleEntry
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TimeToSample) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a TimeToSample) String() string {
 | |
| 	return fmt.Sprintf("entries=%d", len(a.Entries))
 | |
| }
 | |
| 
 | |
| type TimeToSampleEntry struct {
 | |
| 	Count    uint32
 | |
| 	Duration uint32
 | |
| }
 | |
| 
 | |
| func getTimeToSampleEntry(b []byte) (a TimeToSampleEntry) {
 | |
| 	a.Count = pio.U32BE(b[0:])
 | |
| 	a.Duration = pio.U32BE(b[4:])
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func putTimeToSampleEntry(b []byte, a TimeToSampleEntry) {
 | |
| 	pio.PutU32BE(b[0:], a.Count)
 | |
| 	pio.PutU32BE(b[4:], a.Duration)
 | |
| }
 | |
| 
 | |
| const lenTimeToSampleEntry = 8
 | |
| 
 | |
| func (a TimeToSample) Tag() Tag {
 | |
| 	return STTS
 | |
| }
 | |
| 
 | |
| const STSC = Tag(0x73747363)
 | |
| 
 | |
| type SampleToChunk struct {
 | |
| 	Version uint8
 | |
| 	Flags   uint32
 | |
| 	Entries []SampleToChunkEntry
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a SampleToChunk) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(STSC))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleToChunk) 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:], uint32(len(a.Entries)))
 | |
| 	n += 4
 | |
| 	for _, entry := range a.Entries {
 | |
| 		putSampleToChunkEntry(b[n:], entry)
 | |
| 		n += lenSampleToChunkEntry
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleToChunk) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	n += lenSampleToChunkEntry * len(a.Entries)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *SampleToChunk) 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
 | |
| 	var _len_Entries uint32
 | |
| 	_len_Entries = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	a.Entries = make([]SampleToChunkEntry, _len_Entries)
 | |
| 	if len(b) < n+lenSampleToChunkEntry*len(a.Entries) {
 | |
| 		err = parseErr("SampleToChunkEntry", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	for i := range a.Entries {
 | |
| 		a.Entries[i] = getSampleToChunkEntry(b[n:])
 | |
| 		n += lenSampleToChunkEntry
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleToChunk) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleToChunk) String() string {
 | |
| 	return fmt.Sprintf("entries=%d", len(a.Entries))
 | |
| }
 | |
| 
 | |
| type SampleToChunkEntry struct {
 | |
| 	FirstChunk      uint32
 | |
| 	SamplesPerChunk uint32
 | |
| 	SampleDescId    uint32
 | |
| }
 | |
| 
 | |
| func getSampleToChunkEntry(b []byte) (a SampleToChunkEntry) {
 | |
| 	a.FirstChunk = pio.U32BE(b[0:])
 | |
| 	a.SamplesPerChunk = pio.U32BE(b[4:])
 | |
| 	a.SampleDescId = pio.U32BE(b[8:])
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func putSampleToChunkEntry(b []byte, a SampleToChunkEntry) {
 | |
| 	pio.PutU32BE(b[0:], a.FirstChunk)
 | |
| 	pio.PutU32BE(b[4:], a.SamplesPerChunk)
 | |
| 	pio.PutU32BE(b[8:], a.SampleDescId)
 | |
| }
 | |
| 
 | |
| const lenSampleToChunkEntry = 12
 | |
| 
 | |
| func (a SampleToChunk) Tag() Tag {
 | |
| 	return STSC
 | |
| }
 | |
| 
 | |
| const CTTS = Tag(0x63747473)
 | |
| 
 | |
| type CompositionOffset struct {
 | |
| 	Version uint8
 | |
| 	Flags   uint32
 | |
| 	Entries []CompositionOffsetEntry
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a CompositionOffset) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(CTTS))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a CompositionOffset) 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:], uint32(len(a.Entries)))
 | |
| 	n += 4
 | |
| 	for _, entry := range a.Entries {
 | |
| 		putCompositionOffsetEntry(b[n:], entry)
 | |
| 		n += lenCompositionOffsetEntry
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a CompositionOffset) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	n += lenCompositionOffsetEntry * len(a.Entries)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *CompositionOffset) 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
 | |
| 	var _len_Entries uint32
 | |
| 	_len_Entries = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	a.Entries = make([]CompositionOffsetEntry, _len_Entries)
 | |
| 	if len(b) < n+lenCompositionOffsetEntry*len(a.Entries) {
 | |
| 		err = parseErr("CompositionOffsetEntry", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	for i := range a.Entries {
 | |
| 		a.Entries[i] = getCompositionOffsetEntry(b[n:])
 | |
| 		n += lenCompositionOffsetEntry
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a CompositionOffset) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a CompositionOffset) String() string {
 | |
| 	return fmt.Sprintf("entries=%d", len(a.Entries))
 | |
| }
 | |
| 
 | |
| type CompositionOffsetEntry struct {
 | |
| 	Count  uint32
 | |
| 	Offset uint32
 | |
| }
 | |
| 
 | |
| func getCompositionOffsetEntry(b []byte) (a CompositionOffsetEntry) {
 | |
| 	a.Count = pio.U32BE(b[0:])
 | |
| 	a.Offset = pio.U32BE(b[4:])
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func putCompositionOffsetEntry(b []byte, a CompositionOffsetEntry) {
 | |
| 	pio.PutU32BE(b[0:], a.Count)
 | |
| 	pio.PutU32BE(b[4:], a.Offset)
 | |
| }
 | |
| 
 | |
| const lenCompositionOffsetEntry = 8
 | |
| 
 | |
| func (a CompositionOffset) Tag() Tag {
 | |
| 	return CTTS
 | |
| }
 | |
| 
 | |
| const STSS = Tag(0x73747373)
 | |
| 
 | |
| type SyncSample struct {
 | |
| 	Version uint8
 | |
| 	Flags   uint32
 | |
| 	Entries []uint32
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a SyncSample) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(STSS))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SyncSample) 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:], uint32(len(a.Entries)))
 | |
| 	n += 4
 | |
| 	for _, entry := range a.Entries {
 | |
| 		pio.PutU32BE(b[n:], entry)
 | |
| 		n += 4
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SyncSample) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	n += 4 * len(a.Entries)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *SyncSample) 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
 | |
| 	var _len_Entries uint32
 | |
| 	_len_Entries = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	a.Entries = make([]uint32, _len_Entries)
 | |
| 	if len(b) < n+4*len(a.Entries) {
 | |
| 		err = parseErr("uint32", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	for i := range a.Entries {
 | |
| 		a.Entries[i] = pio.U32BE(b[n:])
 | |
| 		n += 4
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SyncSample) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SyncSample) Tag() Tag {
 | |
| 	return STSS
 | |
| }
 | |
| 
 | |
| func (a SyncSample) String() string {
 | |
| 	return fmt.Sprintf("entries=%d", len(a.Entries))
 | |
| }
 | |
| 
 | |
| const STCO = Tag(0x7374636f)
 | |
| 
 | |
| type ChunkOffset struct {
 | |
| 	Version uint8
 | |
| 	Flags   uint32
 | |
| 	Entries []uint32
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a ChunkOffset) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(STCO))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a ChunkOffset) 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:], uint32(len(a.Entries)))
 | |
| 	n += 4
 | |
| 	for _, entry := range a.Entries {
 | |
| 		pio.PutU32BE(b[n:], entry)
 | |
| 		n += 4
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a ChunkOffset) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	n += 4 * len(a.Entries)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *ChunkOffset) 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
 | |
| 	var _len_Entries uint32
 | |
| 	_len_Entries = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	a.Entries = make([]uint32, _len_Entries)
 | |
| 	if len(b) < n+4*len(a.Entries) {
 | |
| 		err = parseErr("uint32", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	for i := range a.Entries {
 | |
| 		a.Entries[i] = pio.U32BE(b[n:])
 | |
| 		n += 4
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a ChunkOffset) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a ChunkOffset) Tag() Tag {
 | |
| 	return STCO
 | |
| }
 | |
| 
 | |
| func (a ChunkOffset) String() string {
 | |
| 	return fmt.Sprintf("entries=%d", len(a.Entries))
 | |
| }
 | |
| 
 | |
| const STSZ = Tag(0x7374737a)
 | |
| 
 | |
| type SampleSize struct {
 | |
| 	Version    uint8
 | |
| 	Flags      uint32
 | |
| 	SampleSize uint32
 | |
| 	Entries    []uint32
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a SampleSize) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(STSZ))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleSize) 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.SampleSize)
 | |
| 	n += 4
 | |
| 	if a.SampleSize != 0 {
 | |
| 		return
 | |
| 	}
 | |
| 	pio.PutU32BE(b[n:], uint32(len(a.Entries)))
 | |
| 	n += 4
 | |
| 	for _, entry := range a.Entries {
 | |
| 		pio.PutU32BE(b[n:], entry)
 | |
| 		n += 4
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleSize) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 1
 | |
| 	n += 3
 | |
| 	n += 4
 | |
| 	if a.SampleSize != 0 {
 | |
| 		return
 | |
| 	}
 | |
| 	n += 4
 | |
| 	n += 4 * len(a.Entries)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *SampleSize) 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("SampleSize", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.SampleSize = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	if a.SampleSize != 0 {
 | |
| 		return
 | |
| 	}
 | |
| 	var _len_Entries uint32
 | |
| 	_len_Entries = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	a.Entries = make([]uint32, _len_Entries)
 | |
| 	if len(b) < n+4*len(a.Entries) {
 | |
| 		err = parseErr("uint32", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	for i := range a.Entries {
 | |
| 		a.Entries[i] = pio.U32BE(b[n:])
 | |
| 		n += 4
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleSize) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a SampleSize) Tag() Tag {
 | |
| 	return STSZ
 | |
| }
 | |
| 
 | |
| func (a SampleSize) String() string {
 | |
| 	return fmt.Sprintf("entries=%d", len(a.Entries))
 | |
| }
 | 
