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