Skip to content

Commit 3677740

Browse files
committed
feat: support for weird dac3 reported in Issue #395
1 parent e8067d2 commit 3677740

File tree

3 files changed

+38
-14
lines changed

3 files changed

+38
-14
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
### Added
1717

1818
- mp4.SetUUID() can take base64 string as well as hex-encoded.
19+
- Support for weird dac3 box with initial 4 zero bytes (Issue #395)
1920

2021
### Fixed
2122

mp4/dac3.go

+29-12
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,16 @@ var AC3BitrateCodesKbps = []uint16{
5050
}
5151

5252
// Dac3Box - AC3SpecificBox from ETSI TS 102 366 V1.4.1 F.4 (2017)
53+
// Extra b
5354
type Dac3Box struct {
54-
FSCod byte
55-
BSID byte
56-
BSMod byte
57-
ACMod byte
58-
LFEOn byte
59-
BitRateCode byte
55+
FSCod byte
56+
BSID byte
57+
BSMod byte
58+
ACMod byte
59+
LFEOn byte
60+
BitRateCode byte
61+
Reserved byte
62+
InitialZeroes byte // Should be zero
6063
}
6164

6265
// DecodeDac3 - box-specific decode
@@ -78,20 +81,25 @@ func DecodeDac3SR(hdr BoxHeader, startPos uint64, sr bits.SliceReader) (Box, err
7881
}
7982

8083
func decodeDac3FromData(data []byte) (Box, error) {
81-
if len(data) != 3 {
82-
return nil, fmt.Errorf("not 3 bytes payload in dac3 box")
84+
b := Dac3Box{}
85+
if len(data) > 3 {
86+
b.InitialZeroes = byte(len(data) - 3)
8387
}
8488
buf := bytes.NewBuffer(data)
8589
br := bits.NewReader(buf)
86-
b := Dac3Box{}
90+
for i := 0; i < int(b.InitialZeroes); i++ {
91+
if zero := br.Read(8); zero != 0 {
92+
return nil, fmt.Errorf("dac3 box, extra initial bytes are not zero")
93+
}
94+
}
8795
b.FSCod = byte(br.Read(2))
8896
b.BSID = byte(br.Read(5))
8997
b.BSMod = byte(br.Read(3))
9098
b.ACMod = byte(br.Read(3))
9199
b.LFEOn = byte(br.Read(1))
92100
b.BitRateCode = byte(br.Read(5))
93101
// 5 bits reserved follows
94-
_ = br.Read(5)
102+
b.Reserved = byte(br.Read(5))
95103
return &b, nil
96104
}
97105

@@ -102,7 +110,7 @@ func (b *Dac3Box) Type() string {
102110

103111
// Size - calculated size of box
104112
func (b *Dac3Box) Size() uint64 {
105-
return uint64(boxHeaderSize + 3)
113+
return uint64(boxHeaderSize + 3 + uint(b.InitialZeroes))
106114
}
107115

108116
// Encode - write box to w
@@ -122,13 +130,16 @@ func (b *Dac3Box) EncodeSW(sw bits.SliceWriter) error {
122130
if err != nil {
123131
return err
124132
}
133+
for i := 0; i < int(b.InitialZeroes); i++ {
134+
sw.WriteBits(0, 8)
135+
}
125136
sw.WriteBits(uint(b.FSCod), 2)
126137
sw.WriteBits(uint(b.BSID), 5)
127138
sw.WriteBits(uint(b.BSMod), 3)
128139
sw.WriteBits(uint(b.ACMod), 3)
129140
sw.WriteBits(uint(b.LFEOn), 1)
130141
sw.WriteBits(uint(b.BitRateCode), 5)
131-
sw.WriteBits(0, 5) // 5-bits padding
142+
sw.WriteBits(uint(b.Reserved), 5) // 5-bits reserved
132143
return sw.AccError()
133144
}
134145

@@ -154,6 +165,12 @@ func (b *Dac3Box) Info(w io.Writer, specificBoxLevels, indent, indentStep string
154165
bd.write(" - bitRateCode=%d => bitrate=%dkbps", b.BitRateCode, AC3BitrateCodesKbps[b.BitRateCode])
155166
nrChannels, chanmap := b.ChannelInfo()
156167
bd.write(" - nrChannels=%d, chanmap=%04x", nrChannels, chanmap)
168+
if b.Reserved != 0 {
169+
bd.write(" - reserved=%d", b.Reserved)
170+
}
171+
if b.InitialZeroes > 0 {
172+
bd.write(" - weird initial zero bytes=%d", b.InitialZeroes)
173+
}
157174
return bd.err
158175
}
159176

mp4/dac3_test.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@ import (
88
)
99

1010
func TestEncodeDedodeAC3(t *testing.T) {
11-
dac3 := &Dac3Box{FSCod: 1, BSID: 2, ACMod: 3, LFEOn: 1, BitRateCode: 7}
12-
boxDiffAfterEncodeAndDecode(t, dac3)
11+
t.Run("normal-dac3", func(t *testing.T) {
12+
dac3 := &Dac3Box{FSCod: 1, BSID: 2, ACMod: 3, LFEOn: 1, BitRateCode: 7}
13+
boxDiffAfterEncodeAndDecode(t, dac3)
14+
})
15+
t.Run("weird-dac3", func(t *testing.T) {
16+
dac3 := &Dac3Box{FSCod: 1, BSID: 2, ACMod: 3, LFEOn: 1, BitRateCode: 7, InitialZeroes: 4}
17+
boxDiffAfterEncodeAndDecode(t, dac3)
18+
})
1319
}
1420

1521
func TestGetChannelInfo(t *testing.T) {

0 commit comments

Comments
 (0)