make esds tag calc result same as libav
This commit is contained in:
parent
f00dbdeb24
commit
662146e1dc
97
isom/isom.go
97
isom/isom.go
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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.|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user