-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #142 from aler9/patch-opus
add Opus boxes
- Loading branch information
Showing
2 changed files
with
129 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package mp4 | ||
|
||
/*************************** Opus ****************************/ | ||
|
||
// https://opus-codec.org/docs/opus_in_isobmff.html | ||
|
||
func BoxTypeOpus() BoxType { return StrToBoxType("Opus") } | ||
|
||
func init() { | ||
AddAnyTypeBoxDef(&AudioSampleEntry{}, BoxTypeOpus()) | ||
} | ||
|
||
/*************************** dOps ****************************/ | ||
|
||
// https://opus-codec.org/docs/opus_in_isobmff.html | ||
|
||
func BoxTypeDOps() BoxType { return StrToBoxType("dOps") } | ||
|
||
func init() { | ||
AddBoxDef(&DOps{}) | ||
} | ||
|
||
type DOps struct { | ||
Box | ||
Version uint8 `mp4:"0,size=8"` | ||
OutputChannelCount uint8 `mp4:"1,size=8"` | ||
PreSkip uint16 `mp4:"2,size=16"` | ||
InputSampleRate uint32 `mp4:"3,size=32"` | ||
OutputGain int16 `mp4:"4,size=16"` | ||
ChannelMappingFamily uint8 `mp4:"5,size=8"` | ||
StreamCount uint8 `mp4:"6,opt=dynamic,size=8"` | ||
CoupledCount uint8 `mp4:"7,opt=dynamic,size=8"` | ||
ChannelMapping []uint8 `mp4:"8,opt=dynamic,size=8,len=dynamic"` | ||
} | ||
|
||
func (DOps) GetType() BoxType { | ||
return BoxTypeDOps() | ||
} | ||
|
||
func (dops DOps) IsOptFieldEnabled(name string, ctx Context) bool { | ||
switch name { | ||
case "StreamCount", "CoupledCount", "ChannelMapping": | ||
return dops.ChannelMappingFamily != 0 | ||
} | ||
return false | ||
} | ||
|
||
func (ops DOps) GetFieldLength(name string, ctx Context) uint { | ||
switch name { | ||
case "ChannelMapping": | ||
return uint(ops.OutputChannelCount) | ||
} | ||
return 0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package mp4 | ||
|
||
import ( | ||
"bytes" | ||
"io" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestBoxTypesOpus(t *testing.T) { | ||
testCases := []struct { | ||
name string | ||
src IImmutableBox | ||
dst IBox | ||
bin []byte | ||
str string | ||
ctx Context | ||
}{ | ||
{ | ||
name: "dOps", | ||
src: &DOps{ | ||
OutputChannelCount: 2, | ||
PreSkip: 312, | ||
InputSampleRate: 48000, | ||
OutputGain: 0, | ||
ChannelMappingFamily: 2, | ||
StreamCount: 1, | ||
CoupledCount: 1, | ||
ChannelMapping: []uint8{1, 2}, | ||
}, | ||
dst: &DOps{}, | ||
bin: []byte{ | ||
0x00, 0x02, 0x01, 0x38, 0x00, 0x00, 0xbb, 0x80, | ||
0x00, 0x00, 0x02, 0x01, 0x01, 0x01, 0x02, | ||
}, | ||
str: `Version=0 OutputChannelCount=0x2 PreSkip=312 InputSampleRate=48000 OutputGain=0 ChannelMappingFamily=0x2 StreamCount=0x1 CoupledCount=0x1 ChannelMapping=[0x1, 0x2]`, | ||
}, | ||
} | ||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
// Marshal | ||
buf := bytes.NewBuffer(nil) | ||
n, err := Marshal(buf, tc.src, tc.ctx) | ||
require.NoError(t, err) | ||
assert.Equal(t, uint64(len(tc.bin)), n) | ||
assert.Equal(t, tc.bin, buf.Bytes()) | ||
|
||
// Unmarshal | ||
r := bytes.NewReader(tc.bin) | ||
n, err = Unmarshal(r, uint64(len(tc.bin)), tc.dst, tc.ctx) | ||
require.NoError(t, err) | ||
assert.Equal(t, uint64(buf.Len()), n) | ||
assert.Equal(t, tc.src, tc.dst) | ||
s, err := r.Seek(0, io.SeekCurrent) | ||
require.NoError(t, err) | ||
assert.Equal(t, int64(buf.Len()), s) | ||
|
||
// UnmarshalAny | ||
dst, n, err := UnmarshalAny(bytes.NewReader(tc.bin), tc.src.GetType(), uint64(len(tc.bin)), tc.ctx) | ||
require.NoError(t, err) | ||
assert.Equal(t, uint64(buf.Len()), n) | ||
assert.Equal(t, tc.src, dst) | ||
s, err = r.Seek(0, io.SeekCurrent) | ||
require.NoError(t, err) | ||
assert.Equal(t, int64(buf.Len()), s) | ||
|
||
// Stringify | ||
str, err := Stringify(tc.src, tc.ctx) | ||
require.NoError(t, err) | ||
assert.Equal(t, tc.str, str) | ||
}) | ||
} | ||
} |