347 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			347 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package fmp4io
 | |
| 
 | |
| import "git.r-2.top/kunmeng/vdk/utils/bits/pio"
 | |
| 
 | |
| const AVC1 = Tag(0x61766331)
 | |
| 
 | |
| type AVC1Desc struct {
 | |
| 	DataRefIdx           int16
 | |
| 	Version              int16
 | |
| 	Revision             int16
 | |
| 	Vendor               int32
 | |
| 	TemporalQuality      int32
 | |
| 	SpatialQuality       int32
 | |
| 	Width                int16
 | |
| 	Height               int16
 | |
| 	HorizontalResolution float64
 | |
| 	VorizontalResolution float64
 | |
| 	FrameCount           int16
 | |
| 	CompressorName       [32]byte
 | |
| 	Depth                int16
 | |
| 	ColorTableId         int16
 | |
| 	Conf                 *AVC1Conf
 | |
| 	PixelAspect          *PixelAspect
 | |
| 	Unknowns             []Atom
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a AVC1Desc) Tag() Tag {
 | |
| 	return AVC1
 | |
| }
 | |
| 
 | |
| func (a AVC1Desc) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(AVC1))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a AVC1Desc) marshal(b []byte) (n int) {
 | |
| 	n += 6
 | |
| 	pio.PutI16BE(b[n:], a.DataRefIdx)
 | |
| 	n += 2
 | |
| 	pio.PutI16BE(b[n:], a.Version)
 | |
| 	n += 2
 | |
| 	pio.PutI16BE(b[n:], a.Revision)
 | |
| 	n += 2
 | |
| 	pio.PutI32BE(b[n:], a.Vendor)
 | |
| 	n += 4
 | |
| 	pio.PutI32BE(b[n:], a.TemporalQuality)
 | |
| 	n += 4
 | |
| 	pio.PutI32BE(b[n:], a.SpatialQuality)
 | |
| 	n += 4
 | |
| 	pio.PutI16BE(b[n:], a.Width)
 | |
| 	n += 2
 | |
| 	pio.PutI16BE(b[n:], a.Height)
 | |
| 	n += 2
 | |
| 	PutFixed32(b[n:], a.HorizontalResolution)
 | |
| 	n += 4
 | |
| 	PutFixed32(b[n:], a.VorizontalResolution)
 | |
| 	n += 4
 | |
| 	n += 4
 | |
| 	pio.PutI16BE(b[n:], a.FrameCount)
 | |
| 	n += 2
 | |
| 	copy(b[n:], a.CompressorName[:])
 | |
| 	n += len(a.CompressorName[:])
 | |
| 	pio.PutI16BE(b[n:], a.Depth)
 | |
| 	n += 2
 | |
| 	pio.PutI16BE(b[n:], a.ColorTableId)
 | |
| 	n += 2
 | |
| 	if a.Conf != nil {
 | |
| 		n += a.Conf.Marshal(b[n:])
 | |
| 	}
 | |
| 	if a.PixelAspect != nil {
 | |
| 		n += a.PixelAspect.Marshal(b[n:])
 | |
| 	}
 | |
| 	for _, atom := range a.Unknowns {
 | |
| 		n += atom.Marshal(b[n:])
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a AVC1Desc) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += 6
 | |
| 	n += 2
 | |
| 	n += 2
 | |
| 	n += 2
 | |
| 	n += 4
 | |
| 	n += 4
 | |
| 	n += 4
 | |
| 	n += 2
 | |
| 	n += 2
 | |
| 	n += 4
 | |
| 	n += 4
 | |
| 	n += 4
 | |
| 	n += 2
 | |
| 	n += len(a.CompressorName[:])
 | |
| 	n += 2
 | |
| 	n += 2
 | |
| 	if a.Conf != nil {
 | |
| 		n += a.Conf.Len()
 | |
| 	}
 | |
| 	if a.PixelAspect != nil {
 | |
| 		n += a.PixelAspect.Len()
 | |
| 	}
 | |
| 	for _, atom := range a.Unknowns {
 | |
| 		n += atom.Len()
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *AVC1Desc) Unmarshal(b []byte, offset int) (n int, err error) {
 | |
| 	a.AtomPos.setPos(offset, len(b))
 | |
| 	n += 8
 | |
| 	n += 6
 | |
| 	if len(b) < n+2 {
 | |
| 		err = parseErr("DataRefIdx", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.DataRefIdx = pio.I16BE(b[n:])
 | |
| 	n += 2
 | |
| 	if len(b) < n+2 {
 | |
| 		err = parseErr("Version", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Version = pio.I16BE(b[n:])
 | |
| 	n += 2
 | |
| 	if len(b) < n+2 {
 | |
| 		err = parseErr("Revision", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Revision = pio.I16BE(b[n:])
 | |
| 	n += 2
 | |
| 	if len(b) < n+4 {
 | |
| 		err = parseErr("Vendor", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Vendor = pio.I32BE(b[n:])
 | |
| 	n += 4
 | |
| 	if len(b) < n+4 {
 | |
| 		err = parseErr("TemporalQuality", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.TemporalQuality = pio.I32BE(b[n:])
 | |
| 	n += 4
 | |
| 	if len(b) < n+4 {
 | |
| 		err = parseErr("SpatialQuality", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.SpatialQuality = pio.I32BE(b[n:])
 | |
| 	n += 4
 | |
| 	if len(b) < n+2 {
 | |
| 		err = parseErr("Width", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Width = pio.I16BE(b[n:])
 | |
| 	n += 2
 | |
| 	if len(b) < n+2 {
 | |
| 		err = parseErr("Height", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Height = pio.I16BE(b[n:])
 | |
| 	n += 2
 | |
| 	if len(b) < n+4 {
 | |
| 		err = parseErr("HorizontalResolution", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.HorizontalResolution = GetFixed32(b[n:])
 | |
| 	n += 4
 | |
| 	if len(b) < n+4 {
 | |
| 		err = parseErr("VorizontalResolution", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.VorizontalResolution = GetFixed32(b[n:])
 | |
| 	n += 4
 | |
| 	n += 4
 | |
| 	if len(b) < n+2 {
 | |
| 		err = parseErr("FrameCount", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.FrameCount = pio.I16BE(b[n:])
 | |
| 	n += 2
 | |
| 	if len(b) < n+len(a.CompressorName) {
 | |
| 		err = parseErr("CompressorName", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	copy(a.CompressorName[:], b[n:])
 | |
| 	n += len(a.CompressorName)
 | |
| 	if len(b) < n+2 {
 | |
| 		err = parseErr("Depth", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.Depth = pio.I16BE(b[n:])
 | |
| 	n += 2
 | |
| 	if len(b) < n+2 {
 | |
| 		err = parseErr("ColorTableId", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.ColorTableId = pio.I16BE(b[n:])
 | |
| 	n += 2
 | |
| 	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 AVCC:
 | |
| 			{
 | |
| 				atom := &AVC1Conf{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("avcC", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.Conf = atom
 | |
| 			}
 | |
| 		case PASP:
 | |
| 			{
 | |
| 				atom := &PixelAspect{}
 | |
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil {
 | |
| 					err = parseErr("pasp", n+offset, err)
 | |
| 					return
 | |
| 				}
 | |
| 				a.PixelAspect = 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 AVC1Desc) Children() (r []Atom) {
 | |
| 	if a.Conf != nil {
 | |
| 		r = append(r, a.Conf)
 | |
| 	}
 | |
| 	if a.PixelAspect != nil {
 | |
| 		r = append(r, a.PixelAspect)
 | |
| 	}
 | |
| 	r = append(r, a.Unknowns...)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| const AVCC = Tag(0x61766343)
 | |
| 
 | |
| type AVC1Conf struct {
 | |
| 	Data []byte
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a AVC1Conf) Tag() Tag {
 | |
| 	return AVCC
 | |
| }
 | |
| 
 | |
| func (a AVC1Conf) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(AVCC))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a AVC1Conf) marshal(b []byte) (n int) {
 | |
| 	copy(b[n:], a.Data[:])
 | |
| 	n += len(a.Data[:])
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a AVC1Conf) Len() (n int) {
 | |
| 	n += 8
 | |
| 	n += len(a.Data[:])
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *AVC1Conf) Unmarshal(b []byte, offset int) (n int, err error) {
 | |
| 	a.AtomPos.setPos(offset, len(b))
 | |
| 	n += 8
 | |
| 	a.Data = b[n:]
 | |
| 	n += len(b[n:])
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a AVC1Conf) Children() (r []Atom) {
 | |
| 	return
 | |
| }
 | |
| 
 | |
| const PASP = Tag(0x70617370)
 | |
| 
 | |
| type PixelAspect struct {
 | |
| 	HorizontalSpacing uint32
 | |
| 	VerticalSpacing   uint32
 | |
| 	AtomPos
 | |
| }
 | |
| 
 | |
| func (a PixelAspect) Tag() Tag {
 | |
| 	return PASP
 | |
| }
 | |
| 
 | |
| func (a PixelAspect) Marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[4:], uint32(PASP))
 | |
| 	n += a.marshal(b[8:]) + 8
 | |
| 	pio.PutU32BE(b[0:], uint32(n))
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a PixelAspect) marshal(b []byte) (n int) {
 | |
| 	pio.PutU32BE(b[n:], a.HorizontalSpacing)
 | |
| 	n += 4
 | |
| 	pio.PutU32BE(b[n:], a.VerticalSpacing)
 | |
| 	n += 4
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a PixelAspect) Len() (n int) {
 | |
| 	return 8 + 8
 | |
| }
 | |
| 
 | |
| func (a *PixelAspect) Unmarshal(b []byte, offset int) (n int, err error) {
 | |
| 	a.AtomPos.setPos(offset, len(b))
 | |
| 	n += 8
 | |
| 	if len(b) < n+4 {
 | |
| 		err = parseErr("HorizontalSpacing", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.HorizontalSpacing = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	if len(b) < n+4 {
 | |
| 		err = parseErr("VerticalSpacing", n+offset, err)
 | |
| 		return
 | |
| 	}
 | |
| 	a.VerticalSpacing = pio.U32BE(b[n:])
 | |
| 	n += 4
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (a *PixelAspect) Children() (r []Atom) {
 | |
| 	return nil
 | |
| }
 | 
