make esds tag calc result same as libav

This commit is contained in:
nareix 2016-04-01 18:19:08 +08:00
parent f00dbdeb24
commit 662146e1dc
2 changed files with 69 additions and 48 deletions

View File

@ -15,6 +15,9 @@ const (
MP4DecSpecificDescrTag = 5
)
var debugReader = false
var debugWriter = false
// copied from libavcodec/mpeg4audio.h
const (
AOT_AAC_MAIN = 1 + iota ///< Y Main
@ -270,15 +273,13 @@ func writeDesc(w io.Writer, tag uint, data []byte) (err error) {
return
}
length := uint(len(data))
for length > 0 {
val := length & 0x7f
if length >= 0x80 {
val |= 0x80
}
if err = bits.WriteUIntBE(w, val, 8); err != nil {
for i := 3; i > 0; i-- {
if err = bits.WriteUIntBE(w, (length>>uint(7*i))&0x7f|0x80, 8); err != nil {
return
}
length >>= 7
}
if err = bits.WriteUIntBE(w, length&0x7f, 8); err != nil {
return
}
if _, err = w.Write(data); err != nil {
return
@ -287,8 +288,9 @@ func writeDesc(w io.Writer, tag uint, data []byte) (err error) {
}
func readESDesc(r io.Reader) (err error) {
var ES_ID uint
// ES_ID
if _, err = bits.ReadUIntBE(r, 16); err != nil {
if ES_ID, err = bits.ReadUIntBE(r, 16); err != nil {
return
}
var flags uint
@ -317,12 +319,15 @@ func readESDesc(r io.Reader) (err error) {
return
}
}
if debugReader {
println("readESDesc:", ES_ID, flags)
}
return
}
func writeESDesc(w io.Writer) (err error) {
func writeESDesc(w io.Writer, ES_ID uint) (err error) {
// ES_ID
if err = bits.WriteUIntBE(w, 0, 16); err != nil {
if err = bits.WriteUIntBE(w, ES_ID, 16); err != nil {
return
}
// flags
@ -332,6 +337,28 @@ func writeESDesc(w io.Writer) (err error) {
return
}
func readDescByTag(r io.Reader, targetTag uint) (data []byte, err error) {
var found bool
for {
if tag, _data, err := readDesc(r); err != nil {
break
} else {
if tag == targetTag {
data = _data
found = true
}
if debugReader {
println("readDescByTag:", tag, len(_data))
}
}
}
if !found {
err = fmt.Errorf("tag not found")
return
}
return
}
// copied from libavformat/isom.c ff_mp4_read_dec_config_descr()
func readDecConfDesc(r io.Reader) (decConfig []byte, err error) {
var objectId uint
@ -361,20 +388,13 @@ func readDecConfDesc(r io.Reader) (decConfig []byte, err error) {
return
}
if false {
println("readDecConfDesc", objectId, streamType, bufSize, maxBitrate, avgBitrate)
if debugReader {
println("readDecConfDesc:", objectId, streamType, bufSize, maxBitrate, avgBitrate)
}
var tag uint
var data []byte
if tag, data, err = readDesc(r); err != nil {
if decConfig, err = readDescByTag(r, MP4DecSpecificDescrTag); err != nil {
return
}
if tag != MP4DecSpecificDescrTag {
err = fmt.Errorf("MP4DecSpecificDescrTag not found")
return
}
decConfig = data
return
}
@ -393,7 +413,7 @@ func writeDecConfDesc(w io.Writer, objectId uint, streamType uint, decConfig []b
return
}
// max bitrate
if err = bits.WriteUIntBE(w, 0, 32); err != nil {
if err = bits.WriteUIntBE(w, 200000, 32); err != nil {
return
}
// avg bitrate
@ -408,13 +428,12 @@ func writeDecConfDesc(w io.Writer, objectId uint, streamType uint, decConfig []b
// copied from libavformat/mov.c ff_mov_read_esds()
func ReadElemStreamDesc(r io.Reader) (decConfig []byte, err error) {
var tag uint
var data []byte
if tag, data, err = readDesc(r); err != nil {
return
if debugReader {
println("ReadElemStreamDesc: start")
}
if tag != MP4ESDescrTag {
err = fmt.Errorf("MP4ESDescrTag not found")
var data []byte
if data, err = readDescByTag(r, MP4ESDescrTag); err != nil {
return
}
r = bytes.NewReader(data)
@ -422,11 +441,8 @@ func ReadElemStreamDesc(r io.Reader) (decConfig []byte, err error) {
if err = readESDesc(r); err != nil {
return
}
if tag, data, err = readDesc(r); err != nil {
return
}
if tag != MP4DecConfigDescrTag {
err = fmt.Errorf("MP4DecSpecificDescrTag not found")
if data, err = readDescByTag(r, MP4DecConfigDescrTag); err != nil {
return
}
r = bytes.NewReader(data)
@ -434,6 +450,10 @@ func ReadElemStreamDesc(r io.Reader) (decConfig []byte, err error) {
if decConfig, err = readDecConfDesc(r); err != nil {
return
}
if debugReader {
println("ReadElemStreamDesc: end")
}
return
}
@ -442,13 +462,16 @@ func ReadElemStreamDescAAC(r io.Reader) (config MPEG4AudioConfig, err error) {
if data, err = ReadElemStreamDesc(r); err != nil {
return
}
if debugReader {
println("decConfig: ", len(data))
}
if config, err = ReadMPEG4AudioConfig(bytes.NewReader(data)); err != nil {
return
}
return
}
func WriteElemStreamDescAAC(w io.Writer, config MPEG4AudioConfig) (err error) {
func WriteElemStreamDescAAC(w io.Writer, config MPEG4AudioConfig, trackId uint) (err error) {
// MP4ESDescrTag(ESDesc MP4DecConfigDescrTag(objectId streamType bufSize avgBitrate MP4DecSpecificDescrTag(decConfig)))
buf := &bytes.Buffer{}
@ -462,21 +485,21 @@ func WriteElemStreamDescAAC(w io.Writer, config MPEG4AudioConfig) (err error) {
data = buf.Bytes()
buf = &bytes.Buffer{}
writeDesc(buf, MP4DecConfigDescrTag, data)
writeDesc(buf, MP4DecConfigDescrTag, data) // 4
data = buf.Bytes()
buf = &bytes.Buffer{}
writeESDesc(buf)
writeESDesc(buf, trackId)
buf.Write(data)
writeDesc(buf, 0x06, []byte{0x02})
data = buf.Bytes()
buf = &bytes.Buffer{}
writeDesc(buf, MP4ESDescrTag, data)
writeDesc(buf, MP4ESDescrTag, data) // 3
data = buf.Bytes()
if _, err = w.Write(data); err != nil {
return
}
return
}

View File

@ -7,19 +7,17 @@ import (
)
func TestReadElemStreamDesc(t *testing.T) {
var decConfig []byte
debugReader = true
debugWriter = true
var err error
data, _ := hex.DecodeString("03808080220002000480808014401500000000030d400000000005808080021210068080800102")
t.Logf("elemDesc=%x", data)
t.Logf("length=%d", len(data))
if decConfig, err = ReadElemStreamDesc(bytes.NewReader(data)); err != nil {
t.Error(err)
}
t.Logf("decConfig=%x", decConfig)
var aconfig MPEG4AudioConfig
if aconfig, err = ReadMPEG4AudioConfig(bytes.NewReader(decConfig)); err != nil {
if aconfig, err = ReadElemStreamDescAAC(bytes.NewReader(data)); err != nil {
t.Error(err)
}
aconfig = aconfig.Complete()
@ -27,17 +25,17 @@ func TestReadElemStreamDesc(t *testing.T) {
bw := &bytes.Buffer{}
WriteMPEG4AudioConfig(bw, aconfig)
t.Logf("decConfig=%x", bw.Bytes())
bw = &bytes.Buffer{}
WriteElemStreamDescAAC(bw, aconfig)
WriteElemStreamDescAAC(bw, aconfig, 2)
t.Logf("elemDesc=%x", bw.Bytes())
data = bw.Bytes()
t.Logf("length=%d", len(data))
if decConfig, err = ReadElemStreamDesc(bytes.NewReader(data)); err != nil {
if aconfig, err = ReadElemStreamDescAAC(bytes.NewReader(data)); err != nil {
t.Error(err)
}
t.Logf("decConfig=%x", decConfig)
t.Logf("aconfig=%x", aconfig.Complete())
//00000000 ff f1 50 80 04 3f fc de 04 00 00 6c 69 62 66 61 |..P..?.....libfa|
//00000010 61 63 20 31 2e 32 38 00 00 42 40 93 20 04 32 00 |ac 1.28..B@. .2.|