work HEVC in progress
This commit is contained in:
		| @@ -1,7 +1,10 @@ | ||||
| package mp4io | ||||
|  | ||||
| import "github.com/deepch/vdk/utils/bits/pio" | ||||
| import "time" | ||||
| import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/deepch/vdk/utils/bits/pio" | ||||
| ) | ||||
|  | ||||
| const MOOF = Tag(0x6d6f6f66) | ||||
|  | ||||
| @@ -21,6 +24,17 @@ func (self AVC1Desc) Tag() Tag { | ||||
| 	return AVC1 | ||||
| } | ||||
|  | ||||
| //0x31766568 | ||||
| const HEV1 = Tag(0x68766331) | ||||
|  | ||||
| func (self HV1Desc) Tag() Tag { | ||||
| 	return HEV1 | ||||
| } | ||||
|  | ||||
| //const HVC1 = Tag(0x68766331) | ||||
| //func (self HVC1Desc) Tag() Tag { | ||||
| //	return HVC1 | ||||
| //} | ||||
| const URL = Tag(0x75726c20) | ||||
|  | ||||
| func (self DataReferUrl) Tag() Tag { | ||||
| @@ -153,6 +167,12 @@ func (self AVC1Conf) Tag() Tag { | ||||
| 	return AVCC | ||||
| } | ||||
|  | ||||
| const HVCC = Tag(0x68766343) | ||||
|  | ||||
| func (self HV1Conf) Tag() Tag { | ||||
| 	return HVCC | ||||
| } | ||||
|  | ||||
| const TFDT = Tag(0x74666474) | ||||
|  | ||||
| func (self TrackFragDecodeTime) Tag() Tag { | ||||
| @@ -1682,6 +1702,7 @@ func (self SampleTable) Children() (r []Atom) { | ||||
| type SampleDesc struct { | ||||
| 	Version  uint8 | ||||
| 	AVC1Desc *AVC1Desc | ||||
| 	HV1Desc  *HV1Desc | ||||
| 	MP4ADesc *MP4ADesc | ||||
| 	Unknowns []Atom | ||||
| 	AtomPos | ||||
| @@ -1701,6 +1722,9 @@ func (self SampleDesc) marshal(b []byte) (n int) { | ||||
| 	if self.AVC1Desc != nil { | ||||
| 		_childrenNR++ | ||||
| 	} | ||||
| 	if self.HV1Desc != nil { | ||||
| 		_childrenNR++ | ||||
| 	} | ||||
| 	if self.MP4ADesc != nil { | ||||
| 		_childrenNR++ | ||||
| 	} | ||||
| @@ -1710,6 +1734,9 @@ func (self SampleDesc) marshal(b []byte) (n int) { | ||||
| 	if self.AVC1Desc != nil { | ||||
| 		n += self.AVC1Desc.Marshal(b[n:]) | ||||
| 	} | ||||
| 	if self.HV1Desc != nil { | ||||
| 		n += self.HV1Desc.Marshal(b[n:]) | ||||
| 	} | ||||
| 	if self.MP4ADesc != nil { | ||||
| 		n += self.MP4ADesc.Marshal(b[n:]) | ||||
| 	} | ||||
| @@ -1726,6 +1753,9 @@ func (self SampleDesc) Len() (n int) { | ||||
| 	if self.AVC1Desc != nil { | ||||
| 		n += self.AVC1Desc.Len() | ||||
| 	} | ||||
| 	if self.HV1Desc != nil { | ||||
| 		n += self.HV1Desc.Len() | ||||
| 	} | ||||
| 	if self.MP4ADesc != nil { | ||||
| 		n += self.MP4ADesc.Len() | ||||
| 	} | ||||
| @@ -1762,6 +1792,15 @@ func (self *SampleDesc) Unmarshal(b []byte, offset int) (n int, err error) { | ||||
| 				} | ||||
| 				self.AVC1Desc = atom | ||||
| 			} | ||||
| 		case HEV1: | ||||
| 			{ | ||||
| 				atom := &HV1Desc{} | ||||
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { | ||||
| 					err = parseErr("hec1", n+offset, err) | ||||
| 					return | ||||
| 				} | ||||
| 				self.HV1Desc = atom | ||||
| 			} | ||||
| 		case MP4A: | ||||
| 			{ | ||||
| 				atom := &MP4ADesc{} | ||||
| @@ -1789,6 +1828,9 @@ func (self SampleDesc) Children() (r []Atom) { | ||||
| 	if self.AVC1Desc != nil { | ||||
| 		r = append(r, self.AVC1Desc) | ||||
| 	} | ||||
| 	if self.HV1Desc != nil { | ||||
| 		r = append(r, self.HV1Desc) | ||||
| 	} | ||||
| 	if self.MP4ADesc != nil { | ||||
| 		r = append(r, self.MP4ADesc) | ||||
| 	} | ||||
| @@ -1955,6 +1997,25 @@ func (self MP4ADesc) Children() (r []Atom) { | ||||
| 	return | ||||
| } | ||||
|  | ||||
| type HV1Desc 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                 *HV1Conf | ||||
| 	Unknowns             []Atom | ||||
| 	AtomPos | ||||
| } | ||||
| type AVC1Desc struct { | ||||
| 	DataRefIdx           int16 | ||||
| 	Version              int16 | ||||
| @@ -1981,6 +2042,12 @@ func (self AVC1Desc) Marshal(b []byte) (n int) { | ||||
| 	pio.PutU32BE(b[0:], uint32(n)) | ||||
| 	return | ||||
| } | ||||
| func (self HV1Desc) Marshal(b []byte) (n int) { | ||||
| 	pio.PutU32BE(b[4:], uint32(HEV1)) | ||||
| 	n += self.marshal(b[8:]) + 8 | ||||
| 	pio.PutU32BE(b[0:], uint32(n)) | ||||
| 	return | ||||
| } | ||||
| func (self AVC1Desc) marshal(b []byte) (n int) { | ||||
| 	n += 6 | ||||
| 	pio.PutI16BE(b[n:], self.DataRefIdx) | ||||
| @@ -2020,6 +2087,45 @@ func (self AVC1Desc) marshal(b []byte) (n int) { | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| func (self HV1Desc) marshal(b []byte) (n int) { | ||||
| 	n += 6 | ||||
| 	pio.PutI16BE(b[n:], self.DataRefIdx) | ||||
| 	n += 2 | ||||
| 	pio.PutI16BE(b[n:], self.Version) | ||||
| 	n += 2 | ||||
| 	pio.PutI16BE(b[n:], self.Revision) | ||||
| 	n += 2 | ||||
| 	pio.PutI32BE(b[n:], self.Vendor) | ||||
| 	n += 4 | ||||
| 	pio.PutI32BE(b[n:], self.TemporalQuality) | ||||
| 	n += 4 | ||||
| 	pio.PutI32BE(b[n:], self.SpatialQuality) | ||||
| 	n += 4 | ||||
| 	pio.PutI16BE(b[n:], self.Width) | ||||
| 	n += 2 | ||||
| 	pio.PutI16BE(b[n:], self.Height) | ||||
| 	n += 2 | ||||
| 	PutFixed32(b[n:], self.HorizontalResolution) | ||||
| 	n += 4 | ||||
| 	PutFixed32(b[n:], self.VorizontalResolution) | ||||
| 	n += 4 | ||||
| 	n += 4 | ||||
| 	pio.PutI16BE(b[n:], self.FrameCount) | ||||
| 	n += 2 | ||||
| 	copy(b[n:], self.CompressorName[:]) | ||||
| 	n += len(self.CompressorName[:]) | ||||
| 	pio.PutI16BE(b[n:], self.Depth) | ||||
| 	n += 2 | ||||
| 	pio.PutI16BE(b[n:], self.ColorTableId) | ||||
| 	n += 2 | ||||
| 	if self.Conf != nil { | ||||
| 		n += self.Conf.Marshal(b[n:]) | ||||
| 	} | ||||
| 	for _, atom := range self.Unknowns { | ||||
| 		n += atom.Marshal(b[n:]) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| func (self AVC1Desc) Len() (n int) { | ||||
| 	n += 8 | ||||
| 	n += 6 | ||||
| @@ -2046,6 +2152,32 @@ func (self AVC1Desc) Len() (n int) { | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| func (self HV1Desc) 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(self.CompressorName[:]) | ||||
| 	n += 2 | ||||
| 	n += 2 | ||||
| 	if self.Conf != nil { | ||||
| 		n += self.Conf.Len() | ||||
| 	} | ||||
| 	for _, atom := range self.Unknowns { | ||||
| 		n += atom.Len() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| func (self *AVC1Desc) Unmarshal(b []byte, offset int) (n int, err error) { | ||||
| 	(&self.AtomPos).setPos(offset, len(b)) | ||||
| 	n += 8 | ||||
| @@ -2166,6 +2298,126 @@ func (self *AVC1Desc) Unmarshal(b []byte, offset int) (n int, err error) { | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| func (self *HV1Desc) Unmarshal(b []byte, offset int) (n int, err error) { | ||||
| 	(&self.AtomPos).setPos(offset, len(b)) | ||||
| 	n += 8 | ||||
| 	n += 6 | ||||
| 	if len(b) < n+2 { | ||||
| 		err = parseErr("DataRefIdx", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.DataRefIdx = pio.I16BE(b[n:]) | ||||
| 	n += 2 | ||||
| 	if len(b) < n+2 { | ||||
| 		err = parseErr("Version", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.Version = pio.I16BE(b[n:]) | ||||
| 	n += 2 | ||||
| 	if len(b) < n+2 { | ||||
| 		err = parseErr("Revision", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.Revision = pio.I16BE(b[n:]) | ||||
| 	n += 2 | ||||
| 	if len(b) < n+4 { | ||||
| 		err = parseErr("Vendor", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.Vendor = pio.I32BE(b[n:]) | ||||
| 	n += 4 | ||||
| 	if len(b) < n+4 { | ||||
| 		err = parseErr("TemporalQuality", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.TemporalQuality = pio.I32BE(b[n:]) | ||||
| 	n += 4 | ||||
| 	if len(b) < n+4 { | ||||
| 		err = parseErr("SpatialQuality", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.SpatialQuality = pio.I32BE(b[n:]) | ||||
| 	n += 4 | ||||
| 	if len(b) < n+2 { | ||||
| 		err = parseErr("Width", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.Width = pio.I16BE(b[n:]) | ||||
| 	n += 2 | ||||
| 	if len(b) < n+2 { | ||||
| 		err = parseErr("Height", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.Height = pio.I16BE(b[n:]) | ||||
| 	n += 2 | ||||
| 	if len(b) < n+4 { | ||||
| 		err = parseErr("HorizontalResolution", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.HorizontalResolution = GetFixed32(b[n:]) | ||||
| 	n += 4 | ||||
| 	if len(b) < n+4 { | ||||
| 		err = parseErr("VorizontalResolution", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.VorizontalResolution = GetFixed32(b[n:]) | ||||
| 	n += 4 | ||||
| 	n += 4 | ||||
| 	if len(b) < n+2 { | ||||
| 		err = parseErr("FrameCount", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.FrameCount = pio.I16BE(b[n:]) | ||||
| 	n += 2 | ||||
| 	if len(b) < n+len(self.CompressorName) { | ||||
| 		err = parseErr("CompressorName", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	copy(self.CompressorName[:], b[n:]) | ||||
| 	n += len(self.CompressorName) | ||||
| 	if len(b) < n+2 { | ||||
| 		err = parseErr("Depth", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.Depth = pio.I16BE(b[n:]) | ||||
| 	n += 2 | ||||
| 	if len(b) < n+2 { | ||||
| 		err = parseErr("ColorTableId", n+offset, err) | ||||
| 		return | ||||
| 	} | ||||
| 	self.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 HVCC: | ||||
| 			{ | ||||
| 				atom := &HV1Conf{} | ||||
| 				if _, err = atom.Unmarshal(b[n:n+size], offset+n); err != nil { | ||||
| 					err = parseErr("hvcC", n+offset, err) | ||||
| 					return | ||||
| 				} | ||||
| 				self.Conf = 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 | ||||
| 				} | ||||
| 				self.Unknowns = append(self.Unknowns, atom) | ||||
| 			} | ||||
| 		} | ||||
| 		n += size | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| func (self AVC1Desc) Children() (r []Atom) { | ||||
| 	if self.Conf != nil { | ||||
| 		r = append(r, self.Conf) | ||||
| @@ -2173,12 +2425,24 @@ func (self AVC1Desc) Children() (r []Atom) { | ||||
| 	r = append(r, self.Unknowns...) | ||||
| 	return | ||||
| } | ||||
| func (self HV1Desc) Children() (r []Atom) { | ||||
| 	if self.Conf != nil { | ||||
| 		r = append(r, self.Conf) | ||||
| 	} | ||||
| 	r = append(r, self.Unknowns...) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| type AVC1Conf struct { | ||||
| 	Data []byte | ||||
| 	AtomPos | ||||
| } | ||||
|  | ||||
| type HV1Conf struct { | ||||
| 	Data []byte | ||||
| 	AtomPos | ||||
| } | ||||
|  | ||||
| func (self AVC1Conf) Marshal(b []byte) (n int) { | ||||
| 	pio.PutU32BE(b[4:], uint32(AVCC)) | ||||
| 	n += self.marshal(b[8:]) + 8 | ||||
| @@ -2206,6 +2470,36 @@ func (self AVC1Conf) Children() (r []Atom) { | ||||
| 	return | ||||
| } | ||||
|  | ||||
| /* | ||||
| HVEC | ||||
| */ | ||||
| func (self HV1Conf) Marshal(b []byte) (n int) { | ||||
| 	pio.PutU32BE(b[4:], uint32(HVCC)) | ||||
| 	n += self.marshal(b[8:]) + 8 | ||||
| 	pio.PutU32BE(b[0:], uint32(n)) | ||||
| 	return | ||||
| } | ||||
| func (self HV1Conf) marshal(b []byte) (n int) { | ||||
| 	copy(b[n:], self.Data[:]) | ||||
| 	n += len(self.Data[:]) | ||||
| 	return | ||||
| } | ||||
| func (self HV1Conf) Len() (n int) { | ||||
| 	n += 8 | ||||
| 	n += len(self.Data[:]) | ||||
| 	return | ||||
| } | ||||
| func (self *HV1Conf) Unmarshal(b []byte, offset int) (n int, err error) { | ||||
| 	(&self.AtomPos).setPos(offset, len(b)) | ||||
| 	n += 8 | ||||
| 	self.Data = b[n:] | ||||
| 	n += len(b[n:]) | ||||
| 	return | ||||
| } | ||||
| func (self HV1Conf) Children() (r []Atom) { | ||||
| 	return | ||||
| } | ||||
|  | ||||
| type TimeToSample struct { | ||||
| 	Version uint8 | ||||
| 	Flags   uint32 | ||||
|   | ||||
| @@ -29,7 +29,7 @@ func NewMuxer(w io.WriteSeeker) *Muxer { | ||||
|  | ||||
| func (self *Muxer) newStream(codec av.CodecData) (err error) { | ||||
| 	switch codec.Type() { | ||||
| 	case av.H264, av.AAC: | ||||
| 	case av.H264, av.H265, av.AAC: | ||||
|  | ||||
| 	default: | ||||
| 		err = fmt.Errorf("mp4: codec type=%v is not supported", codec.Type()) | ||||
| @@ -82,6 +82,8 @@ func (self *Muxer) newStream(codec av.CodecData) (err error) { | ||||
| 	switch codec.Type() { | ||||
| 	case av.H264: | ||||
| 		stream.sample.SyncSample = &mp4io.SyncSample{} | ||||
| 	case av.H265: | ||||
| 		stream.sample.SyncSample = &mp4io.SyncSample{} | ||||
| 	} | ||||
|  | ||||
| 	stream.timeScale = 90000 | ||||
| @@ -94,7 +96,6 @@ func (self *Muxer) newStream(codec av.CodecData) (err error) { | ||||
| func (self *Stream) fillTrackAtom() (err error) { | ||||
| 	self.trackAtom.Media.Header.TimeScale = int32(self.timeScale) | ||||
| 	self.trackAtom.Media.Header.Duration = int32(self.duration) | ||||
|  | ||||
| 	if self.Type() == av.H264 { | ||||
| 		codec := self.CodecData.(h264parser.CodecData) | ||||
| 		width, height := codec.Width(), codec.Height() | ||||
| @@ -118,7 +119,29 @@ func (self *Stream) fillTrackAtom() (err error) { | ||||
| 		} | ||||
| 		self.trackAtom.Header.TrackWidth = float64(width) | ||||
| 		self.trackAtom.Header.TrackHeight = float64(height) | ||||
|  | ||||
| 	} else if self.Type() == av.H265 { | ||||
| 		codec := self.CodecData.(h264parser.CodecData) | ||||
| 		width, height := codec.Width(), codec.Height() | ||||
| 		self.sample.SampleDesc.HV1Desc = &mp4io.HV1Desc{ | ||||
| 			DataRefIdx:           1, | ||||
| 			HorizontalResolution: 72, | ||||
| 			VorizontalResolution: 72, | ||||
| 			Width:                int16(width), | ||||
| 			Height:               int16(height), | ||||
| 			FrameCount:           1, | ||||
| 			Depth:                24, | ||||
| 			ColorTableId:         -1, | ||||
| 			Conf:                 &mp4io.HV1Conf{Data: codec.AVCDecoderConfRecordBytes()}, | ||||
| 		} | ||||
| 		self.trackAtom.Media.Handler = &mp4io.HandlerRefer{ | ||||
| 			SubType: [4]byte{'v', 'i', 'd', 'e'}, | ||||
| 			Name:    []byte("Video Media Handler"), | ||||
| 		} | ||||
| 		self.trackAtom.Media.Info.Video = &mp4io.VideoMediaInfo{ | ||||
| 			Flags: 0x000001, | ||||
| 		} | ||||
| 		self.trackAtom.Header.TrackWidth = float64(width) | ||||
| 		self.trackAtom.Header.TrackHeight = float64(height) | ||||
| 	} else if self.Type() == av.AAC { | ||||
| 		codec := self.CodecData.(aacparser.CodecData) | ||||
| 		self.sample.SampleDesc.MP4ADesc = &mp4io.MP4ADesc{ | ||||
|   | ||||
| @@ -34,7 +34,7 @@ func (self *Muxer) SetMaxFrames(count int) { | ||||
| } | ||||
| func (self *Muxer) newStream(codec av.CodecData) (err error) { | ||||
| 	switch codec.Type() { | ||||
| 	case av.H264, av.AAC: | ||||
| 	case av.H264, av.H265, av.AAC: | ||||
| 	default: | ||||
| 		err = fmt.Errorf("fmp4: codec type=%v is not supported", codec.Type()) | ||||
| 		return | ||||
| @@ -78,6 +78,9 @@ func (self *Muxer) newStream(codec av.CodecData) (err error) { | ||||
| 	case av.H264: | ||||
| 		stream.sample.SyncSample = &mp4io.SyncSample{} | ||||
| 		stream.timeScale = 90000 | ||||
| 	case av.H265: | ||||
| 		stream.sample.SyncSample = &mp4io.SyncSample{} | ||||
| 		stream.timeScale = 90000 | ||||
| 	case av.AAC: | ||||
| 		stream.timeScale = int64(codec.(av.AudioCodecData).SampleRate()) | ||||
| 	} | ||||
| @@ -174,6 +177,28 @@ func (self *Stream) fillTrackAtom() (err error) { | ||||
| 			Flags: 0x000001, | ||||
| 		} | ||||
| 		self.codecString = fmt.Sprintf("avc1.%02X%02X%02X", codec.RecordInfo.AVCProfileIndication, codec.RecordInfo.ProfileCompatibility, codec.RecordInfo.AVCLevelIndication) | ||||
| 	} else if self.Type() == av.H265 { | ||||
| 		codec := self.CodecData.(h264parser.CodecData) | ||||
| 		width, height := codec.Width(), codec.Height() | ||||
| 		self.sample.SampleDesc.HV1Desc = &mp4io.HV1Desc{ | ||||
| 			DataRefIdx:           1, | ||||
| 			HorizontalResolution: 72, | ||||
| 			VorizontalResolution: 72, | ||||
| 			Width:                int16(width), | ||||
| 			Height:               int16(height), | ||||
| 			FrameCount:           1, | ||||
| 			Depth:                24, | ||||
| 			ColorTableId:         -1, | ||||
| 			Conf:                 &mp4io.HV1Conf{Data: codec.AVCDecoderConfRecordBytes()}, | ||||
| 		} | ||||
| 		self.trackAtom.Media.Handler = &mp4io.HandlerRefer{ | ||||
| 			SubType: [4]byte{'v', 'i', 'd', 'e'}, | ||||
| 			Name:    []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'G', 'G', 0, 0, 0}, | ||||
| 		} | ||||
| 		self.trackAtom.Media.Info.Video = &mp4io.VideoMediaInfo{ | ||||
| 			Flags: 0x000001, | ||||
| 		} | ||||
| 		self.codecString = fmt.Sprintf("hvc1.%02X%02X%02X", codec.RecordInfo.AVCProfileIndication, codec.RecordInfo.ProfileCompatibility, codec.RecordInfo.AVCLevelIndication) | ||||
| 	} else if self.Type() == av.AAC { | ||||
| 		codec := self.CodecData.(aacparser.CodecData) | ||||
| 		self.sample.SampleDesc.MP4ADesc = &mp4io.MP4ADesc{ | ||||
| @@ -183,8 +208,7 @@ func (self *Stream) fillTrackAtom() (err error) { | ||||
| 			SampleRate:       float64(codec.SampleRate()), | ||||
| 			Unknowns:         []mp4io.Atom{self.buildEsds(codec.MPEG4AudioConfigBytes())}, | ||||
| 		} | ||||
| 		//log.Fatalln(codec.MPEG4AudioConfigBytes()) | ||||
| 		//log.Fatalln(codec.SampleFormat().BytesPerSample()) | ||||
|  | ||||
| 		self.trackAtom.Header.Volume = 1 | ||||
| 		self.trackAtom.Header.AlternateGroup = 1 | ||||
| 		self.trackAtom.Header.Duration = 0 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Andrey Semochkin
					Andrey Semochkin