Read/Write AVCDecoderConfRecord
This commit is contained in:
parent
3f60565c66
commit
2ba72a94e8
@ -220,7 +220,7 @@ var atoms = {
|
|||||||
avc1Conf: {
|
avc1Conf: {
|
||||||
cc4: 'avcC',
|
cc4: 'avcC',
|
||||||
fields: [
|
fields: [
|
||||||
['data', '[]byte'],
|
['record', 'AVCDecoderConfRecord'],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2,52 +2,125 @@
|
|||||||
package atom
|
package atom
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_"io"
|
"io"
|
||||||
_"bytes"
|
"fmt"
|
||||||
_"log"
|
|
||||||
_"encoding/hex"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
type AVCDecoderConfRecord struct {
|
||||||
type VideoSampleDesc struct {
|
AVCProfileIndication int
|
||||||
VideoSampleDescHeader
|
ProfileCompatibility int
|
||||||
AVCDecoderConf []byte
|
AVCLevelIndication int
|
||||||
|
LengthSizeMinusOne int
|
||||||
|
SeqenceParamSet [][]byte
|
||||||
|
PictureParamSet [][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadVideoSampleDesc(r *io.LimitedReader) (res *VideoSampleDesc, err error) {
|
func CreateAVCDecoderConfRecord(
|
||||||
self := &VideoSampleDesc{}
|
SeqenceParamSet []byte,
|
||||||
|
PictureParamSet []byte,
|
||||||
if self.VideoSampleDescHeader, err = ReadVideoSampleDescHeader(r); err != nil {
|
) (self AVCDecoderConfRecord, err error) {
|
||||||
|
if len(SeqenceParamSet) < 4 {
|
||||||
|
err = fmt.Errorf("invalid SeqenceParamSet")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.AVCProfileIndication = int(SeqenceParamSet[1])
|
||||||
|
self.AVCLevelIndication = int(SeqenceParamSet[3])
|
||||||
|
self.LengthSizeMinusOne = 3
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for r.N > 0 {
|
func WriteAVCDecoderConfRecord(w io.Writer, self AVCDecoderConfRecord) (err error) {
|
||||||
var cc4 string
|
if err = WriteInt(w, 1, 1); err != nil {
|
||||||
var ar *io.LimitedReader
|
return
|
||||||
if ar, cc4, err = ReadAtomHeader(r, ""); err != nil {
|
}
|
||||||
|
if err = WriteInt(w, self.AVCProfileIndication, 1); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = WriteInt(w, self.ProfileCompatibility, 1); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = WriteInt(w, self.AVCLevelIndication, 1); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = WriteInt(w, self.LengthSizeMinusOne | 0xfc, 1); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if false {
|
if err = WriteInt(w, len(self.SeqenceParamSet) | 0xe0, 1); err != nil {
|
||||||
log.Println("VideoSampleDesc:", cc4, ar.N)
|
|
||||||
//log.Println("VideoSampleDesc:", "avcC", len(self.AVCDecoderConf))
|
|
||||||
}
|
|
||||||
|
|
||||||
switch cc4 {
|
|
||||||
case "avcC": {
|
|
||||||
if self.AVCDecoderConf, err = ReadBytes(ar, int(ar.N)); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
for _, data := range self.SeqenceParamSet {
|
||||||
|
if err = WriteInt(w, len(data), 2); err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
if err = WriteBytes(w, data, len(data)); err != nil {
|
||||||
|
|
||||||
if _, err = ReadDummy(ar, int(ar.N)); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = self
|
if err = WriteInt(w, len(self.PictureParamSet), 1); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, data := range self.PictureParamSet {
|
||||||
|
if err = WriteInt(w, len(data), 2); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = WriteBytes(w, data, len(data)); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadAVCDecoderConfRecord(r *io.LimitedReader) (self AVCDecoderConfRecord, err error) {
|
||||||
|
if _, err = ReadDummy(r, 1); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if self.AVCProfileIndication, err = ReadInt(r, 1); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if self.ProfileCompatibility, err = ReadInt(r, 1); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if self.AVCLevelIndication, err = ReadInt(r, 1); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if self.LengthSizeMinusOne, err = ReadInt(r, 1); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.LengthSizeMinusOne &= 0x03
|
||||||
|
|
||||||
|
var n, length int
|
||||||
|
var data []byte
|
||||||
|
|
||||||
|
if n, err = ReadInt(r, 1); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n &= 0x1f
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
if length, err = ReadInt(r, 2); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if data, err = ReadBytes(r, length); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.SeqenceParamSet = append(self.SeqenceParamSet, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n, err = ReadInt(r, 1); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
if length, err = ReadInt(r, 2); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if data, err = ReadBytes(r, length); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.PictureParamSet = append(self.PictureParamSet, data)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
@ -1292,13 +1292,13 @@ func WriteAvc1Desc(w io.WriteSeeker, self *Avc1Desc) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Avc1Conf struct {
|
type Avc1Conf struct {
|
||||||
Data []byte
|
Record AVCDecoderConfRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadAvc1Conf(r *io.LimitedReader) (res *Avc1Conf, err error) {
|
func ReadAvc1Conf(r *io.LimitedReader) (res *Avc1Conf, err error) {
|
||||||
|
|
||||||
self := &Avc1Conf{}
|
self := &Avc1Conf{}
|
||||||
if self.Data, err = ReadBytes(r, int(r.N)); err != nil {
|
if self.Record, err = ReadAVCDecoderConfRecord(r); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res = self
|
res = self
|
||||||
@ -1311,7 +1311,7 @@ func WriteAvc1Conf(w io.WriteSeeker, self *Avc1Conf) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
w = aw
|
w = aw
|
||||||
if err = WriteBytes(w, self.Data, len(self.Data)); err != nil {
|
if err = WriteAVCDecoderConfRecord(w, self.Record); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = aw.Close(); err != nil {
|
if err = aw.Close(); err != nil {
|
||||||
|
13
mp4.go
13
mp4.go
@ -106,8 +106,10 @@ func changeMoov(moov *atom.Movie) {
|
|||||||
if avc1Desc := desc.Avc1Desc; avc1Desc != nil {
|
if avc1Desc := desc.Avc1Desc; avc1Desc != nil {
|
||||||
if conf := avc1Desc.Conf; conf != nil {
|
if conf := avc1Desc.Conf; conf != nil {
|
||||||
if true {
|
if true {
|
||||||
log.Println("avc1", hex.Dump(conf.Data))
|
//log.Println("avc1", hex.Dump(conf.Data))
|
||||||
log.Println("avc1desc", avc1Desc)
|
log.Println("avc1desc", conf)
|
||||||
|
//avcconf, _ := atom.ReadAVCDecoderConfRecord(bytes.NewReader(conf.Data))
|
||||||
|
//log.Println("avcconf", avcconf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,6 +227,8 @@ func rewrite(moov *atom.Movie, mdat io.ReadSeeker, outfile io.WriteSeeker) (err
|
|||||||
sampleCh := make(chan Sample)
|
sampleCh := make(chan Sample)
|
||||||
go readSamples(vsample, mdat, sampleCh)
|
go readSamples(vsample, mdat, sampleCh)
|
||||||
|
|
||||||
|
log.Println("avc1Desc.conf", vsample.SampleDesc.Avc1Desc.Conf)
|
||||||
|
|
||||||
newsample := &atom.SampleTable{
|
newsample := &atom.SampleTable{
|
||||||
SampleDesc: &atom.SampleDesc{
|
SampleDesc: &atom.SampleDesc{
|
||||||
Avc1Desc: &atom.Avc1Desc{
|
Avc1Desc: &atom.Avc1Desc{
|
||||||
@ -311,8 +315,8 @@ func rewrite(moov *atom.Movie, mdat io.ReadSeeker, outfile io.WriteSeeker) (err
|
|||||||
Duration: vtrack.Header.Duration,
|
Duration: vtrack.Header.Duration,
|
||||||
Volume: vtrack.Header.Volume,
|
Volume: vtrack.Header.Volume,
|
||||||
Matrix: [9]int{0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0x40000000},
|
Matrix: [9]int{0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0x40000000},
|
||||||
TrackWidth: vtrack.Header.TrackWidth,
|
//TrackWidth: vtrack.Header.TrackWidth,
|
||||||
TrackHeight: vtrack.Header.TrackHeight,
|
//TrackHeight: vtrack.Header.TrackHeight,
|
||||||
TrackId: 1,
|
TrackId: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -401,7 +405,6 @@ func TestRewrite(filename string) (file *File, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestConvert(filename string) (file *File, err error) {
|
func TestConvert(filename string) (file *File, err error) {
|
||||||
var osfile *os.File
|
var osfile *os.File
|
||||||
if osfile, err = os.Open(filename); err != nil {
|
if osfile, err = os.Open(filename); err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user