diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f78ea9..2728659 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Allow missing optional DecoderSpecificInfo + - Nothing yet ## [0.46.0] - 2024-08-08 diff --git a/mp4/descriptors.go b/mp4/descriptors.go index 01205b9..bf42bd3 100644 --- a/mp4/descriptors.go +++ b/mp4/descriptors.go @@ -228,7 +228,9 @@ func (e *ESDescriptor) Size() uint64 { if ocrStreamFlag == 1 { size += 2 } - size += e.DecConfigDescriptor.SizeSize() + if e.DecConfigDescriptor != nil { + size += e.DecConfigDescriptor.SizeSize() + } if e.SLConfigDescriptor != nil { size += e.SLConfigDescriptor.SizeSize() } @@ -379,14 +381,17 @@ func DecodeDecoderConfigDescriptor(tag byte, sr bits.SliceReader, maxNrBytes int currPos := sr.GetPos() nrBytesLeft := int(size) - (currPos - dataStart) + if nrBytesLeft == 0 { + return &dd, nil + } desc, err := DecodeDescriptor(sr, nrBytesLeft) if err != nil { - return nil, fmt.Errorf("failed to decode DecSpecificInfoDescriptor: %w", err) + return nil, fmt.Errorf("failed to decode descriptor: %w", err) } var ok bool dd.DecSpecificInfo, ok = desc.(*DecSpecificInfoDescriptor) - if !ok { - return nil, fmt.Errorf("expected DecSpecificInfoDescriptor") + if !ok { // The optional decoderSpeicificInfo is not present + dd.OtherDescriptors = append(dd.OtherDescriptors, desc) } for { currPos := sr.GetPos() @@ -417,7 +422,10 @@ func (d *DecoderConfigDescriptor) Type() string { } func (d *DecoderConfigDescriptor) Size() uint64 { - size := 13 + d.DecSpecificInfo.SizeSize() + size := uint64(13) + if d.DecSpecificInfo != nil { + size += d.DecSpecificInfo.SizeSize() + } for _, od := range d.OtherDescriptors { size += od.SizeSize() } @@ -437,12 +445,14 @@ func (d *DecoderConfigDescriptor) EncodeSW(sw bits.SliceWriter) error { sw.WriteUint32(streamTypeAndBufferSizeDB) sw.WriteUint32(d.MaxBitrate) sw.WriteUint32(d.AvgBitrate) - err := d.DecSpecificInfo.EncodeSW(sw) - if err != nil { - return err + if d.DecSpecificInfo != nil { + err := d.DecSpecificInfo.EncodeSW(sw) + if err != nil { + return err + } } for _, desc := range d.OtherDescriptors { - err = desc.EncodeSW(sw) + err := desc.EncodeSW(sw) if err != nil { return err } @@ -463,12 +473,14 @@ func (d *DecoderConfigDescriptor) Info(w io.Writer, specificLevels, indent, inde bd.write(" - BufferSizeDB: %d", d.BufferSizeDB) bd.write(" - MaxBitrate: %d", d.MaxBitrate) bd.write(" - AvgBitrate: %d", d.AvgBitrate) - err := d.DecSpecificInfo.Info(w, specificLevels, indent+indentStep, indentStep) - if err != nil { - return err + if d.DecSpecificInfo != nil { + err := d.DecSpecificInfo.Info(w, specificLevels, indent+indentStep, indentStep) + if err != nil { + return err + } } for _, od := range d.OtherDescriptors { - err = od.Info(w, specificLevels, indent+indentStep, indentStep) + err := od.Info(w, specificLevels, indent+indentStep, indentStep) if err != nil { return err } diff --git a/mp4/descriptors_test.go b/mp4/descriptors_test.go index 8fb3f90..a6ec46f 100644 --- a/mp4/descriptors_test.go +++ b/mp4/descriptors_test.go @@ -12,6 +12,7 @@ import ( const badSizeDescriptor = `031900010004134015000000000000000001f40005021190060102` const missingSLConfig = `031600010004114015000000000000000001d40005021190` const partOfEsdsProgIn = `03808080250002000480808017401500000000010d88000003f80580808005128856e500068080800102` +const missingDecSpecificInfo = `0315000100040d4015000000000000000001d400060102` func TestDecodeDescriptor(t *testing.T) { cases := []struct { @@ -21,6 +22,7 @@ func TestDecodeDescriptor(t *testing.T) { {"badSizeDescriptor", badSizeDescriptor}, {"missingSLConfig", missingSLConfig}, {"partOfEsdsProgIn", partOfEsdsProgIn}, + {"missingDecSpecificInfo", missingDecSpecificInfo}, } for _, c := range cases { t.Run(c.desc, func(t *testing.T) { @@ -92,6 +94,22 @@ func TestDescriptorInfo(t *testing.T) { - DecConfig (2B): 1190 - Missing SLConfigDescriptor `}, + {"missingDecSpecificInfo", missingDecSpecificInfo, + `Descriptor "tag=3 ES" size=2+21 + - EsID: 1 + - DependsOnEsID: 0 + - OCResID: 0 + - FlagsAndPriority: 0 + - URLString: + Descriptor "tag=4 DecoderConfig" size=2+13 + - ObjectType: 64 + - StreamType: 21 + - BufferSizeDB: 0 + - MaxBitrate: 0 + - AvgBitrate: 119808 + Descriptor "tag=6 SLConfig" size=2+1 + - ConfigValue: 2 + `}, } for _, c := range cases { t.Run(c.desc, func(t *testing.T) {