diff --git a/CHANGELOG.md b/CHANGELOG.md index 508de1c1..2741c806 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet +### Added + +- Loudness boxes `ludt`, `tlou`, and `alou` +- Description boxes `desc`, `©cpy`, `©nam`, `©ART` boxes +- `GenericContainerBox` struct + +### Changed + +- Made `©too` use `GenericContainerBox` ## [0.37.0] - 2023-08-14 diff --git a/mp4/box.go b/mp4/box.go index f4c0c55c..f5ffbdaa 100644 --- a/mp4/box.go +++ b/mp4/box.go @@ -36,6 +36,7 @@ func init() { "dac3": DecodeDac3, "data": DecodeData, "dec3": DecodeDec3, + "desc": DecodeGenericContainerBox, "dinf": DecodeDinf, "dpnd": DecodeTrefType, "dref": DecodeDref, @@ -135,7 +136,10 @@ func init() { "vttC": DecodeVttC, "vtte": DecodeVtte, "wvtt": DecodeWvtt, - "\xa9too": DecodeCToo, + "\xa9cpy": DecodeGenericContainerBox, + "\xa9nam": DecodeGenericContainerBox, + "\xa9too": DecodeGenericContainerBox, + "\xa9ART": DecodeGenericContainerBox, } } diff --git a/mp4/boxsr.go b/mp4/boxsr.go index ec6a349c..c3375596 100644 --- a/mp4/boxsr.go +++ b/mp4/boxsr.go @@ -27,6 +27,7 @@ func init() { "dac3": DecodeDac3SR, "data": DecodeDataSR, "dec3": DecodeDec3SR, + "desc": DecodeGenericContainerBoxSR, "dinf": DecodeDinfSR, "dpnd": DecodeTrefTypeSR, "dref": DecodeDrefSR, @@ -126,7 +127,10 @@ func init() { "vttC": DecodeVttCSR, "vtte": DecodeVtteSR, "wvtt": DecodeWvttSR, - "\xa9too": DecodeCTooSR, + "\xa9cpy": DecodeGenericContainerBoxSR, + "\xa9nam": DecodeGenericContainerBoxSR, + "\xa9too": DecodeGenericContainerBoxSR, + "\xa9ART": DecodeGenericContainerBoxSR, } } diff --git a/mp4/container.go b/mp4/container.go index c954602b..ce82d5dd 100644 --- a/mp4/container.go +++ b/mp4/container.go @@ -17,6 +17,75 @@ type ContainerBox interface { Info(w io.Writer, specificBoxLevels, indent, indentStep string) error } +// GenericContainerBox is a generic container box with no special child pointers +type GenericContainerBox struct { + name string + Children []Box +} + +func NewGenericContainerBox(name string) *GenericContainerBox { + return &GenericContainerBox{name: name} +} + +func (b *GenericContainerBox) Type() string { + return b.name +} + +func (b *GenericContainerBox) Size() uint64 { + return containerSize(b.Children) +} + +// Encode - write GenericContainerBox to w +func (b *GenericContainerBox) Encode(w io.Writer) error { + return EncodeContainer(b, w) +} + +// Encode - write minf container to sw +func (b *GenericContainerBox) EncodeSW(sw bits.SliceWriter) error { + return EncodeContainerSW(b, sw) +} + +// Info - write box-specific information +func (b *GenericContainerBox) Info(w io.Writer, specificBoxLevels, indent, indentStep string) error { + return ContainerInfo(b, w, specificBoxLevels, indent, indentStep) +} + +// GetChildren - list of child boxes +func (b *GenericContainerBox) GetChildren() []Box { + return b.Children +} + +// DecodeGenericContainerBox - box-specific decode +func DecodeGenericContainerBox(hdr BoxHeader, startPos uint64, r io.Reader) (Box, error) { + children, err := DecodeContainerChildren(hdr, startPos+8, startPos+hdr.Size, r) + if err != nil { + return nil, err + } + m := NewGenericContainerBox(hdr.Name) + for _, c := range children { + m.AddChild(c) + } + return m, nil +} + +// DecodeGenericContainerBoxSR - box-specific decode +func DecodeGenericContainerBoxSR(hdr BoxHeader, startPos uint64, sr bits.SliceReader) (Box, error) { + children, err := DecodeContainerChildrenSR(hdr, startPos+8, startPos+hdr.Size, sr) + if err != nil { + return nil, err + } + m := NewGenericContainerBox(hdr.Name) + for _, c := range children { + m.AddChild(c) + } + return m, nil +} + +// AddChild - Add a child box +func (b *GenericContainerBox) AddChild(child Box) { + b.Children = append(b.Children, child) +} + func containerSize(children []Box) uint64 { var contentSize uint64 = 0 for _, child := range children { diff --git a/mp4/ffmpeg.go b/mp4/ffmpeg.go index edae772b..fb4bfcc7 100644 --- a/mp4/ffmpeg.go +++ b/mp4/ffmpeg.go @@ -12,67 +12,6 @@ type CTooBox struct { Children []Box } -// DecodeCToo - box-specific decode -func DecodeCToo(hdr BoxHeader, startPos uint64, r io.Reader) (Box, error) { - children, err := DecodeContainerChildren(hdr, startPos+8, startPos+hdr.Size, r) - if err != nil { - return nil, err - } - b := &CTooBox{} - for _, c := range children { - b.AddChild(c) - } - return b, nil -} - -// DecodeCTooSR - box-specific decode -func DecodeCTooSR(hdr BoxHeader, startPos uint64, sr bits.SliceReader) (Box, error) { - children, err := DecodeContainerChildrenSR(hdr, startPos+8, startPos+hdr.Size, sr) - if err != nil { - return nil, err - } - b := &CTooBox{} - for _, c := range children { - b.AddChild(c) - } - return b, nil -} - -// AddChild - Add a child box and update SampleCount -func (b *CTooBox) AddChild(child Box) { - b.Children = append(b.Children, child) -} - -// Type - box type -func (b *CTooBox) Type() string { - return "\xa9too" -} - -// Size - calculated size of box -func (b *CTooBox) Size() uint64 { - return containerSize(b.Children) -} - -// GetChildren - list of child boxes -func (b *CTooBox) GetChildren() []Box { - return b.Children -} - -// Encode - write minf container to w -func (b *CTooBox) Encode(w io.Writer) error { - return EncodeContainer(b, w) -} - -// Encode - write minf container to sw -func (b *CTooBox) EncodeSW(sw bits.SliceWriter) error { - return EncodeContainerSW(b, sw) -} - -// Info - box-specific Info -func (b *CTooBox) Info(w io.Writer, specificBoxLevels, indent, indentStep string) error { - return ContainerInfo(b, w, specificBoxLevels, indent, indentStep) -} - // DataBox - data box used by ffmpeg for providing information. type DataBox struct { Data []byte