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

View File

@ -7,19 +7,17 @@ import (
) )
func TestReadElemStreamDesc(t *testing.T) { func TestReadElemStreamDesc(t *testing.T) {
var decConfig []byte debugReader = true
debugWriter = true
var err error var err error
data, _ := hex.DecodeString("03808080220002000480808014401500000000030d400000000005808080021210068080800102") data, _ := hex.DecodeString("03808080220002000480808014401500000000030d400000000005808080021210068080800102")
t.Logf("elemDesc=%x", data)
t.Logf("length=%d", len(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 var aconfig MPEG4AudioConfig
if aconfig, err = ReadMPEG4AudioConfig(bytes.NewReader(decConfig)); err != nil { if aconfig, err = ReadElemStreamDescAAC(bytes.NewReader(data)); err != nil {
t.Error(err) t.Error(err)
} }
aconfig = aconfig.Complete() aconfig = aconfig.Complete()
@ -27,17 +25,17 @@ func TestReadElemStreamDesc(t *testing.T) {
bw := &bytes.Buffer{} bw := &bytes.Buffer{}
WriteMPEG4AudioConfig(bw, aconfig) WriteMPEG4AudioConfig(bw, aconfig)
t.Logf("decConfig=%x", bw.Bytes())
bw = &bytes.Buffer{} bw = &bytes.Buffer{}
WriteElemStreamDescAAC(bw, aconfig) WriteElemStreamDescAAC(bw, aconfig, 2)
t.Logf("elemDesc=%x", bw.Bytes()) t.Logf("elemDesc=%x", bw.Bytes())
data = 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.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| //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.| //00000010 61 63 20 31 2e 32 38 00 00 42 40 93 20 04 32 00 |ac 1.28..B@. .2.|