From 3fd2a25dc1171f8487836e37f2ec968c11fcf4ae Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Tue, 3 Jan 2023 19:22:10 +0100 Subject: [PATCH] improve tests --- internal/hls/client_downloader_primary.go | 10 +- internal/hls/fmp4/init.go | 123 +++- internal/hls/fmp4/init_test.go | 683 +++++++++++++++------- 3 files changed, 570 insertions(+), 246 deletions(-) diff --git a/internal/hls/client_downloader_primary.go b/internal/hls/client_downloader_primary.go index 730491d5..7128c5a3 100644 --- a/internal/hls/client_downloader_primary.go +++ b/internal/hls/client_downloader_primary.go @@ -271,19 +271,17 @@ func (d *clientDownloaderPrimary) run(ctx context.Context) error { for _, track := range tracks { switch ttrack := track.(type) { case *format.H264: - if videoTrack != nil { - return fmt.Errorf("multiple video tracks are not supported") - } videoTrack = ttrack case *format.MPEG4Audio: - if audioTrack != nil { - return fmt.Errorf("multiple audio tracks are not supported") - } audioTrack = ttrack } } + if videoTrack == nil && audioTrack == nil { + return fmt.Errorf("no supported tracks found") + } + err = d.onTracks(videoTrack, audioTrack) if err != nil { return err diff --git a/internal/hls/fmp4/init.go b/internal/hls/fmp4/init.go index 3f94007c..1ec9ba74 100644 --- a/internal/hls/fmp4/init.go +++ b/internal/hls/fmp4/init.go @@ -5,6 +5,7 @@ import ( "fmt" gomp4 "github.com/abema/go-mp4" + "github.com/aler9/gortsplib/v2/pkg/codecs/h265" "github.com/aler9/gortsplib/v2/pkg/codecs/mpeg4audio" "github.com/aler9/gortsplib/v2/pkg/format" ) @@ -23,8 +24,10 @@ func (i *Init) Unmarshal(byts []byte) error { waitingTkhd waitingMdhd waitingCodec - waitingAvcc + waitingAvcC + waitingHvcC waitingEsds + waitingDOps ) state := waitingTrak @@ -34,7 +37,7 @@ func (i *Init) Unmarshal(byts []byte) error { switch h.BoxInfo.Type.String() { case "trak": if state != waitingTrak { - return nil, fmt.Errorf("parse error") + return nil, fmt.Errorf("unexpected box 'trak'") } curTrack = &InitTrack{} @@ -43,7 +46,7 @@ func (i *Init) Unmarshal(byts []byte) error { case "tkhd": if state != waitingTkhd { - return nil, fmt.Errorf("parse error") + return nil, fmt.Errorf("unexpected box 'tkhd'") } box, _, err := h.ReadPayload() @@ -57,7 +60,7 @@ func (i *Init) Unmarshal(byts []byte) error { case "mdhd": if state != waitingMdhd { - return nil, fmt.Errorf("parse error") + return nil, fmt.Errorf("unexpected box 'mdhd'") } box, _, err := h.ReadPayload() @@ -71,38 +74,38 @@ func (i *Init) Unmarshal(byts []byte) error { case "avc1": if state != waitingCodec { - return nil, fmt.Errorf("parse error") + return nil, fmt.Errorf("unexpected box 'avc1'") } - state = waitingAvcc + state = waitingAvcC case "avcC": - if state != waitingAvcc { - return nil, fmt.Errorf("parse error") + if state != waitingAvcC { + return nil, fmt.Errorf("unexpected box 'avcC'") } box, _, err := h.ReadPayload() if err != nil { return nil, err } - conf := box.(*gomp4.AVCDecoderConfiguration) + avcc := box.(*gomp4.AVCDecoderConfiguration) - if len(conf.SequenceParameterSets) > 1 { + if len(avcc.SequenceParameterSets) > 1 { return nil, fmt.Errorf("multiple SPS are not supported") } var sps []byte - if len(conf.SequenceParameterSets) == 1 { - sps = conf.SequenceParameterSets[0].NALUnit + if len(avcc.SequenceParameterSets) == 1 { + sps = avcc.SequenceParameterSets[0].NALUnit } - if len(conf.PictureParameterSets) > 1 { + if len(avcc.PictureParameterSets) > 1 { return nil, fmt.Errorf("multiple PPS are not supported") } var pps []byte - if len(conf.PictureParameterSets) == 1 { - pps = conf.PictureParameterSets[0].NALUnit + if len(avcc.PictureParameterSets) == 1 { + pps = avcc.PictureParameterSets[0].NALUnit } curTrack.Format = &format.H264{ @@ -113,16 +116,76 @@ func (i *Init) Unmarshal(byts []byte) error { } state = waitingTrak - case "mp4a": + case "hev1": if state != waitingCodec { - return nil, fmt.Errorf("parse error") + return nil, fmt.Errorf("unexpected box 'hev1'") + } + state = waitingHvcC + + case "hvcC": + if state != waitingHvcC { + return nil, fmt.Errorf("unexpected box 'hvcC'") } + box, _, err := h.ReadPayload() + if err != nil { + return nil, err + } + hvcc := box.(*gomp4.HvcC) + + var vps []byte + var sps []byte + var pps []byte + + for _, arr := range hvcc.NaluArrays { + switch h265.NALUType(arr.NaluType) { + case h265.NALUType_VPS_NUT, h265.NALUType_SPS_NUT, h265.NALUType_PPS_NUT: + if arr.NumNalus != 1 { + return nil, fmt.Errorf("multiple VPS/SPS/PPS are not supported") + } + } + + switch h265.NALUType(arr.NaluType) { + case h265.NALUType_VPS_NUT: + vps = arr.Nalus[0].NALUnit + + case h265.NALUType_SPS_NUT: + sps = arr.Nalus[0].NALUnit + + case h265.NALUType_PPS_NUT: + pps = arr.Nalus[0].NALUnit + } + } + + if vps == nil { + return nil, fmt.Errorf("VPS not provided") + } + + if sps == nil { + return nil, fmt.Errorf("SPS not provided") + } + + if pps == nil { + return nil, fmt.Errorf("PPS not provided") + } + + curTrack.Format = &format.H265{ + PayloadTyp: 96, + VPS: vps, + SPS: sps, + PPS: pps, + } + state = waitingTrak + + case "mp4a": + if state != waitingCodec { + return nil, fmt.Errorf("unexpected box 'mp4a'") + } state = waitingEsds case "esds": if state != waitingEsds { - return nil, fmt.Errorf("parse error") + return nil, fmt.Errorf("unexpected box 'esds'") } box, _, err := h.ReadPayload() @@ -160,6 +223,30 @@ func (i *Init) Unmarshal(byts []byte) error { case "ac-3": return nil, fmt.Errorf("AC-3 codec is not supported (yet)") + + case "Opus": + if state != waitingCodec { + return nil, fmt.Errorf("unexpected box 'Opus'") + } + state = waitingDOps + + case "dOps": + if state != waitingDOps { + return nil, fmt.Errorf("unexpected box 'dOps'") + } + + box, _, err := h.ReadPayload() + if err != nil { + return nil, err + } + dops := box.(*DOps) + + curTrack.Format = &format.Opus{ + PayloadTyp: 96, + SampleRate: int(dops.InputSampleRate), + ChannelCount: int(dops.OutputChannelCount), + } + state = waitingTrak } return h.Expand() diff --git a/internal/hls/fmp4/init_test.go b/internal/hls/fmp4/init_test.go index 433e65f7..dadae46b 100644 --- a/internal/hls/fmp4/init_test.go +++ b/internal/hls/fmp4/init_test.go @@ -1,4 +1,3 @@ -//nolint:dupl package fmp4 import ( @@ -24,7 +23,7 @@ var testVideoTrack = &format.H264{ } var testAudioTrack = &format.MPEG4Audio{ - PayloadTyp: 97, + PayloadTyp: 96, Config: &mpeg4audio.Config{ Type: 2, SampleRate: 44100, @@ -35,203 +34,14 @@ var testAudioTrack = &format.MPEG4Audio{ IndexDeltaLength: 3, } -func TestInitMarshal(t *testing.T) { - t.Run("video + audio", func(t *testing.T) { - init := Init{ - Tracks: []*InitTrack{ - { - ID: 1, - TimeScale: 90000, - Format: testVideoTrack, - }, - { - ID: 2, - TimeScale: uint32(testAudioTrack.ClockRate()), - Format: testAudioTrack, - }, - }, - } - - byts, err := init.Marshal() - require.NoError(t, err) - - require.Equal(t, []byte{ - 0x00, 0x00, 0x00, 0x20, - 'f', 't', 'y', 'p', - 0x6d, 0x70, 0x34, 0x32, 0x00, 0x00, 0x00, 0x01, - 0x6d, 0x70, 0x34, 0x31, 0x6d, 0x70, 0x34, 0x32, - 0x69, 0x73, 0x6f, 0x6d, 0x68, 0x6c, 0x73, 0x66, - 0x00, 0x00, 0x04, 0x64, - 'm', 'o', 'o', 'v', - 0x00, 0x00, 0x00, 0x6c, - 'm', 'v', 'h', 'd', - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0xec, - 't', 'r', 'a', 'k', - 0x00, 0x00, 0x00, 0x5c, - 't', 'k', 'h', 'd', - 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x07, 0x80, 0x00, 0x00, 0x04, 0x38, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x88, 0x6d, 0x64, 0x69, 0x61, - 0x00, 0x00, 0x00, 0x20, - 'm', 'd', 'h', 'd', - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5f, 0x90, - 0x00, 0x00, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x68, 0x64, 0x6c, 0x72, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x76, 0x69, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, - 0x64, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x01, - 0x33, - 'm', 'i', 'n', 'f', - 0x00, 0x00, 0x00, 0x14, - 'v', 'm', 'h', 'd', - 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x24, 0x64, 0x69, 0x6e, - 0x66, 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, - 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, - 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xf3, 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, - 0xa7, 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x97, 0x61, 0x76, 0x63, 0x31, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x04, - 0x38, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x2d, 0x61, - 0x76, 0x63, 0x43, 0x01, 0x42, 0xc0, 0x28, 0x03, - 0x01, 0x00, 0x19, 0x67, 0x42, 0xc0, 0x28, 0xd9, - 0x00, 0x78, 0x02, 0x27, 0xe5, 0x84, 0x00, 0x00, - 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xf0, - 0x3c, 0x60, 0xc9, 0x20, 0x01, 0x00, 0x01, 0x08, - 0x00, 0x00, 0x00, 0x14, 0x62, 0x74, 0x72, 0x74, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, - 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x10, - 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x73, 0x74, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, - 0x73, 0x74, 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x63, 0x6f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0xbc, - 't', 'r', 'a', 'k', - 0x00, 0x00, 0x00, 0x5c, - 't', 'k', 'h', 'd', - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x58, - 0x6d, 0x64, 0x69, 0x61, 0x00, 0x00, 0x00, 0x20, - 'm', 'd', 'h', 'd', - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xac, 0x44, 0x00, 0x00, 0x00, 0x00, - 0x55, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, - 0x68, 0x64, 0x6c, 0x72, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x73, 0x6f, 0x75, 0x6e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x53, 0x6f, 0x75, 0x6e, - 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, - 0x00, 0x00, 0x00, 0x01, 0x03, 0x6d, 0x69, 0x6e, - 0x66, 0x00, 0x00, 0x00, 0x10, - 's', 'm', 'h', 'd', - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x24, 0x64, 0x69, 0x6e, - 0x66, 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, - 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, - 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xc7, 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, - 0x7b, 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x6b, 0x6d, 0x70, 0x34, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0xac, 0x44, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x33, 0x65, 0x73, 0x64, - 0x73, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x80, - 0x80, 0x22, 0x00, 0x02, 0x00, 0x04, 0x80, 0x80, - 0x80, 0x14, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x01, 0xf7, 0x39, 0x00, 0x01, 0xf7, 0x39, 0x05, - 0x80, 0x80, 0x80, 0x02, 0x12, 0x10, 0x06, 0x80, - 0x80, 0x80, 0x01, 0x02, 0x00, 0x00, 0x00, 0x14, - 0x62, 0x74, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0xf7, 0x39, 0x00, 0x01, 0xf7, 0x39, - 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x74, 0x73, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x73, 0x63, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x73, 0x74, 0x73, 0x7a, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x73, 0x74, 0x63, 0x6f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, - 0x6d, 0x76, 0x65, 0x78, 0x00, 0x00, 0x00, 0x20, - 0x74, 0x72, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, - 0x74, 0x72, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }, byts) - }) - - t.Run("video only", func(t *testing.T) { - init := Init{ - Tracks: []*InitTrack{ - { - ID: 1, - TimeScale: 90000, - Format: testVideoTrack, - }, - }, - } - - byts, err := init.Marshal() - require.NoError(t, err) - - require.Equal(t, []byte{ +var casesInit = []struct { + name string + enc []byte + dec Init +}{ + { + "h264", + []byte{ 0x00, 0x00, 0x00, 0x20, 'f', 't', 'y', 'p', 0x6d, 0x70, 0x34, 0x32, 0x00, 0x00, 0x00, 0x01, @@ -268,13 +78,15 @@ func TestInitMarshal(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x04, 0x38, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x88, 0x6d, 0x64, 0x69, 0x61, + 0x00, 0x00, 0x01, 0x88, + 'm', 'd', 'i', 'a', 0x00, 0x00, 0x00, 0x20, 'm', 'd', 'h', 'd', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2d, 0x68, 0x64, 0x6c, 0x72, + 0x00, 0x00, 0x00, 0x2d, + 'h', 'd', 'l', 'r', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -328,24 +140,140 @@ func TestInitMarshal(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }, byts) - }) - - t.Run("audio only", func(t *testing.T) { - init := &Init{ + }, + Init{ Tracks: []*InitTrack{ { ID: 1, - TimeScale: uint32(testAudioTrack.ClockRate()), - Format: testAudioTrack, + TimeScale: 90000, + Format: testVideoTrack, }, }, - } - - byts, err := init.Marshal() - require.NoError(t, err) - - require.Equal(t, []byte{ + }, + }, + { + "h265", + []byte{ + 0x00, 0x00, 0x00, 0x20, + 'f', 't', 'y', 'p', + 0x6d, 0x70, 0x34, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x6d, 0x70, 0x34, 0x31, 0x6d, 0x70, 0x34, 0x32, + 0x69, 0x73, 0x6f, 0x6d, 0x68, 0x6c, 0x73, 0x66, + 0x00, 0x00, 0x02, 0xb8, + 'm', 'o', 'o', 'v', + 0x00, 0x00, 0x00, 0x6c, + 'm', 'v', 'h', 'd', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x02, 0x1c, + 0x74, 0x72, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x5c, + 0x74, 0x6b, 0x68, 0x64, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x07, 0x80, 0x00, 0x00, 0x04, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xb8, 0x6d, 0x64, 0x69, 0x61, + 0x00, 0x00, 0x00, 0x20, 0x6d, 0x64, 0x68, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5f, 0x90, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x68, 0x64, 0x6c, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x76, 0x69, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x01, + 0x63, 0x6d, 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, + 0x14, 0x76, 0x6d, 0x68, 0x64, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x64, 0x69, 0x6e, + 0x66, 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, + 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x23, 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, + 0xd7, 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xc7, 0x68, 0x65, 0x76, 0x31, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x04, + 0x38, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x5d, 0x68, + 0x76, 0x63, 0x43, 0x01, 0x01, 0x60, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x90, 0x00, 0x00, 0x03, 0x78, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x03, 0x20, 0x00, 0x01, 0x00, 0x04, 0x01, + 0x02, 0x03, 0x04, 0x21, 0x00, 0x01, 0x00, 0x2a, + 0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03, + 0x00, 0x90, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, + 0x00, 0x78, 0xa0, 0x03, 0xc0, 0x80, 0x10, 0xe5, + 0x96, 0x66, 0x69, 0x24, 0xca, 0xe0, 0x10, 0x00, + 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x01, + 0xe0, 0x80, 0x22, 0x00, 0x01, 0x00, 0x01, 0x08, + 0x00, 0x00, 0x00, 0x14, 0x62, 0x74, 0x72, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, + 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x10, + 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x73, 0x74, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x73, 0x74, 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x63, 0x6f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x6d, 0x76, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x20, 0x74, 0x72, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + Init{ + Tracks: []*InitTrack{ + { + ID: 1, + TimeScale: 90000, + Format: &format.H265{ + PayloadTyp: 96, + VPS: []byte{0x01, 0x02, 0x03, 0x04}, + SPS: []byte{ + 0x42, 0x01, 0x01, 0x01, 0x60, 0x00, 0x00, 0x03, + 0x00, 0x90, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, + 0x00, 0x78, 0xa0, 0x03, 0xc0, 0x80, 0x10, 0xe5, + 0x96, 0x66, 0x69, 0x24, 0xca, 0xe0, 0x10, 0x00, + 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x01, + 0xe0, 0x80, + }, + PPS: []byte{0x08}, + }, + }, + }, + }, + }, + { + "mpeg4audio", + []byte{ 0x00, 0x00, 0x00, 0x20, 'f', 't', 'y', 'p', 0x6d, 0x70, 0x34, 0x32, 0x00, 0x00, 0x00, 0x01, @@ -444,12 +372,319 @@ func TestInitMarshal(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }, byts) - }) + }, + Init{ + Tracks: []*InitTrack{ + { + ID: 1, + TimeScale: uint32(testAudioTrack.ClockRate()), + Format: testAudioTrack, + }, + }, + }, + }, + { + "opus", + []byte{ + 0x00, 0x00, 0x00, 0x20, + 'f', 't', 'y', 'p', + 0x6d, 0x70, 0x34, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x6d, 0x70, 0x34, 0x31, 0x6d, 0x70, 0x34, 0x32, + 0x69, 0x73, 0x6f, 0x6d, 0x68, 0x6c, 0x73, 0x66, + 0x00, 0x00, 0x02, 0x38, + 'm', 'o', 'o', 'v', + 0x00, 0x00, 0x00, 0x6c, + 'm', 'v', 'h', 'd', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x9c, + 0x74, 0x72, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x5c, + 0x74, 0x6b, 0x68, 0x64, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x38, 0x6d, 0x64, 0x69, 0x61, + 0x00, 0x00, 0x00, 0x20, 0x6d, 0x64, 0x68, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0x68, 0x64, 0x6c, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x6f, 0x75, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, + 0xe3, 0x6d, 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, + 0x10, 0x73, 0x6d, 0x68, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x64, 0x69, 0x6e, 0x66, 0x00, 0x00, 0x00, + 0x1c, 0x64, 0x72, 0x65, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0c, 0x75, 0x72, 0x6c, 0x20, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xa7, 0x73, 0x74, 0x62, + 0x6c, 0x00, 0x00, 0x00, 0x5b, 0x73, 0x74, 0x73, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x4b, 0x4f, 0x70, 0x75, + 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0xbb, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x64, 0x4f, 0x70, 0x73, 0x00, 0x02, 0x01, + 0x38, 0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x14, 0x62, 0x74, 0x72, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf7, 0x39, + 0x00, 0x01, 0xf7, 0x39, 0x00, 0x00, 0x00, 0x10, + 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x73, 0x74, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x73, 0x74, 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x63, 0x6f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x6d, 0x76, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x20, 0x74, 0x72, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + Init{ + Tracks: []*InitTrack{ + { + ID: 1, + TimeScale: 48000, + Format: &format.Opus{ + PayloadTyp: 96, + SampleRate: 48000, + ChannelCount: 2, + }, + }, + }, + }, + }, + { + "h264 + mpeg4audio", + []byte{ + 0x00, 0x00, 0x00, 0x20, + 'f', 't', 'y', 'p', + 0x6d, 0x70, 0x34, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x6d, 0x70, 0x34, 0x31, 0x6d, 0x70, 0x34, 0x32, + 0x69, 0x73, 0x6f, 0x6d, 0x68, 0x6c, 0x73, 0x66, + 0x00, 0x00, 0x04, 0x64, + 'm', 'o', 'o', 'v', + 0x00, 0x00, 0x00, 0x6c, + 'm', 'v', 'h', 'd', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0xec, + 't', 'r', 'a', 'k', + 0x00, 0x00, 0x00, 0x5c, + 't', 'k', 'h', 'd', + 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x07, 0x80, 0x00, 0x00, 0x04, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x88, + 'm', 'd', 'i', 'a', + 0x00, 0x00, 0x00, 0x20, + 'm', 'd', 'h', 'd', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5f, 0x90, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, + 'h', 'd', 'l', 'r', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x76, 0x69, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x01, + 0x33, + 'm', 'i', 'n', 'f', + 0x00, 0x00, 0x00, 0x14, + 'v', 'm', 'h', 'd', + 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x64, 0x69, 0x6e, + 0x66, 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, + 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xf3, 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, + 0xa7, 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x97, 0x61, 0x76, 0x63, 0x31, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x04, + 0x38, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x2d, 0x61, + 0x76, 0x63, 0x43, 0x01, 0x42, 0xc0, 0x28, 0x03, + 0x01, 0x00, 0x19, 0x67, 0x42, 0xc0, 0x28, 0xd9, + 0x00, 0x78, 0x02, 0x27, 0xe5, 0x84, 0x00, 0x00, + 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xf0, + 0x3c, 0x60, 0xc9, 0x20, 0x01, 0x00, 0x01, 0x08, + 0x00, 0x00, 0x00, 0x14, 0x62, 0x74, 0x72, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, + 0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x10, + 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x73, 0x74, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x73, 0x74, 0x73, 0x7a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x63, 0x6f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xbc, + 't', 'r', 'a', 'k', + 0x00, 0x00, 0x00, 0x5c, + 't', 'k', 'h', 'd', + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x58, + 'm', 'd', 'i', 'a', + 0x00, 0x00, 0x00, 0x20, + 'm', 'd', 'h', 'd', + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xac, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x55, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 'h', 'd', 'l', 'r', + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x73, 0x6f, 0x75, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x6f, 0x75, 0x6e, + 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, + 0x00, 0x00, 0x00, 0x01, 0x03, 0x6d, 0x69, 0x6e, + 0x66, 0x00, 0x00, 0x00, 0x10, + 's', 'm', 'h', 'd', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x64, 0x69, 0x6e, + 0x66, 0x00, 0x00, 0x00, 0x1c, 0x64, 0x72, 0x65, + 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x75, 0x72, 0x6c, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xc7, 0x73, 0x74, 0x62, 0x6c, 0x00, 0x00, 0x00, + 0x7b, 0x73, 0x74, 0x73, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x6b, 0x6d, 0x70, 0x34, 0x61, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0xac, 0x44, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x33, 0x65, 0x73, 0x64, + 0x73, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x80, + 0x80, 0x22, 0x00, 0x02, 0x00, 0x04, 0x80, 0x80, + 0x80, 0x14, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xf7, 0x39, 0x00, 0x01, 0xf7, 0x39, 0x05, + 0x80, 0x80, 0x80, 0x02, 0x12, 0x10, 0x06, 0x80, + 0x80, 0x80, 0x01, 0x02, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x74, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xf7, 0x39, 0x00, 0x01, 0xf7, 0x39, + 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x74, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x14, 0x73, 0x74, 0x73, 0x7a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x73, 0x74, 0x63, 0x6f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x6d, 0x76, 0x65, 0x78, 0x00, 0x00, 0x00, 0x20, + 0x74, 0x72, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x74, 0x72, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }, + Init{ + Tracks: []*InitTrack{ + { + ID: 1, + TimeScale: 90000, + Format: testVideoTrack, + }, + { + ID: 2, + TimeScale: uint32(testAudioTrack.ClockRate()), + Format: testAudioTrack, + }, + }, + }, + }, +} + +func TestInitMarshal(t *testing.T) { + for _, ca := range casesInit { + t.Run(ca.name, func(t *testing.T) { + byts, err := ca.dec.Marshal() + require.NoError(t, err) + require.Equal(t, ca.enc, byts) + }) + } } func TestInitUnmarshal(t *testing.T) { - t.Run("video", func(t *testing.T) { + for _, ca := range casesInit { + t.Run(ca.name, func(t *testing.T) { + var init Init + err := init.Unmarshal(ca.enc) + require.NoError(t, err) + require.Equal(t, ca.dec, init) + }) + } +} + +func TestInitUnmarshalExternal(t *testing.T) { + t.Run("h264", func(t *testing.T) { byts := []byte{ 0x00, 0x00, 0x00, 0x1c, 'f', 't', 'y', 'p', @@ -487,13 +722,15 @@ func TestInitUnmarshal(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x92, - 0x6d, 0x64, 0x69, 0x61, 0x00, 0x00, 0x00, 0x20, + 'm', 'd', 'i', 'a', + 0x00, 0x00, 0x00, 0x20, 'm', 'd', 'h', 'd', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x96, 0x80, 0x00, 0x00, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, - 0x68, 0x64, 0x6c, 0x72, 0x00, 0x00, 0x00, 0x00, + 'h', 'd', 'l', 'r', + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x72, 0x6f, 0x61, @@ -575,7 +812,7 @@ func TestInitUnmarshal(t *testing.T) { }, init) }) - t.Run("audio", func(t *testing.T) { + t.Run("mpeg4audio", func(t *testing.T) { byts := []byte{ 0x00, 0x00, 0x00, 0x18, 'f', 't', 'y', 'p', @@ -612,13 +849,15 @@ func TestInitUnmarshal(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x43, 0x6d, 0x64, 0x69, 0x61, + 0x00, 0x00, 0x01, 0x43, + 'm', 'd', 'i', 'a', 0x00, 0x00, 0x00, 0x20, 'm', 'd', 'h', 'd', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x96, 0x80, 0x00, 0x00, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x68, 0x64, 0x6c, 0x72, + 0x00, 0x00, 0x00, 0x38, + 'h', 'd', 'l', 'r', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x6f, 0x75, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,