diff --git a/CHANGELOG.md b/CHANGELOG.md index 106584db..073b63c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet + +### Added + +- New TryDecodeMfro function + +### Fixed + +- More robust check for mfro at the end of file ## [0.43.0] - 2024-04-04 diff --git a/mp4/file.go b/mp4/file.go index 7a55141d..75173940 100644 --- a/mp4/file.go +++ b/mp4/file.go @@ -346,24 +346,18 @@ func (f *File) findAndReadMfra(r io.Reader) error { if err != nil { return fmt.Errorf("could not seek %d bytes from end: %w", mfroSize, err) } - b, err := DecodeBox(uint64(pos), rs) // mfro + mfro, err := TryDecodeMfro(uint64(pos), rs) // mfro if err != nil { // Not an mfro box here, just reset and return _, err = rs.Seek(0, io.SeekStart) return err } - mfro, ok := b.(*MfroBox) - if !ok { - // Not an mfro box here, just reset and return - _, err = rs.Seek(0, io.SeekStart) - return err - } mfraSize := int64(mfro.ParentSize) pos, err = rs.Seek(-mfraSize, io.SeekEnd) if err != nil { return fmt.Errorf("could not seek %d bytes from end: %w", mfraSize, err) } - b, err = DecodeBox(uint64(pos), rs) // mfra + b, err := DecodeBox(uint64(pos), rs) // mfra if err != nil { return fmt.Errorf("could not decode mfra box: %w", err) } diff --git a/mp4/mfro.go b/mp4/mfro.go index 0933cd34..53ad11b4 100644 --- a/mp4/mfro.go +++ b/mp4/mfro.go @@ -1,6 +1,7 @@ package mp4 import ( + "fmt" "io" "github.com/Eyevinn/mp4ff/bits" @@ -14,6 +15,23 @@ type MfroBox struct { ParentSize uint32 } +// TryDecodeMfro only decode an MfroBox and return it. +// If it is not an MfroBox, it returns nil and an error. +func TryDecodeMfro(startPos uint64, r io.Reader) (*MfroBox, error) { + hdr, err := DecodeHeader(r) + if err != nil { + return nil, err + } + if hdr.Name != "mfro" { + return nil, fmt.Errorf("not an mfro box") + } + box, err := DecodeMfro(hdr, startPos, r) + if err != nil { + return nil, err + } + return box.(*MfroBox), nil +} + // DecodeMfro - box-specific decode func DecodeMfro(hdr BoxHeader, startPos uint64, r io.Reader) (Box, error) { data, err := readBoxBody(r, hdr)