Skip to content

mp4a: find esds inside the QuickTime wave box#170

Merged
bradh merged 1 commit into
kixelated:mainfrom
AdrianEddy:fix-quicktime-wave-esds
Jul 12, 2026
Merged

mp4a: find esds inside the QuickTime wave box#170
bradh merged 1 commit into
kixelated:mainfrom
AdrianEddy:fix-quicktime-wave-esds

Conversation

@AdrianEddy

Copy link
Copy Markdown
Contributor

Problem

Mp4a::decode_body has a comment saying "Find esds in mp4a or wave", but it never actually descends into the QuickTime wave box — it only iterates the direct children of mp4a. When the esds is nested inside a wave (siDecompressionParam) box, the loop sees wave as an unknown atom, skips it via decode_unknown, and then returns Error::MissingBox(esds), failing the whole moov decode.

This is a very common layout: FFmpeg's mov muxer and many camera apps (e.g. MotionCam) emit AAC-in-MOV with the esds inside wave:

mp4a
  wave                       // siDecompressionParam
    frma  'mp4a'
    mp4a  (4-byte stub)      // NOT a valid AudioSampleEntry
    esds
    0000  (all-zero terminator)

Such files currently fail to parse entirely with missing box: esds.

Fix

Descend into the wave box and scan its children by header for esds (and btrt), which is what the existing comment already promised. Every other child — frma, the nested mp4a terminator stub, the trailing zero box — is skipped by size and deliberately not typed-decoded: the nested mp4a is a 4-byte stub that is not a valid audio sample entry, so decoding it as one would error.

The change is additive and does not affect the ISO-BMFF path (esds as a direct child of mp4a). Re-encoding normalises to the ISO layout, as before.

Test

Adds test_mp4a_quicktime_wave, which builds the QuickTime mp4a → wave → { frma, mp4a-stub, esds, terminator } layout and asserts Mp4a::decode recovers the esds. Full suite passes (227 tests).

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Updated Mp4a::decode_body to handle QuickTime wave containers. A new helper scans nested atoms, decoding esds and btrt entries while stopping on invalid sizes. Added a test helper and unit test covering nested AAC atoms and validating the decoded audio fields.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: finding esds inside QuickTime wave boxes.
Description check ✅ Passed The description is directly related to the change and clearly explains the problem, fix, and test coverage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/moov/trak/mdia/minf/stbl/stsd/mp4a/mod.rs`:
- Around line 134-198: In test_mp4a_quicktime_wave, move audio_bytes directly
into mp4a_body instead of cloning it. Also extend the wave fixture with a btrt
child and assert the decoded result preserves the expected bitrate data,
covering decode_wave’s btrt handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bfb205fa-6378-42ed-b8cb-ad7562b048d2

📥 Commits

Reviewing files that changed from the base of the PR and between 3241814 and 11ad4b7.

📒 Files selected for processing (1)
  • src/moov/trak/mdia/minf/stbl/stsd/mp4a/mod.rs

Comment thread src/moov/trak/mdia/minf/stbl/stsd/mp4a/mod.rs
@AdrianEddy AdrianEddy force-pushed the fix-quicktime-wave-esds branch from 11ad4b7 to 2547b0e Compare July 11, 2026 13:32
FFmpeg and camera muxers (MotionCam, etc.) emit AAC-in-MOV with the
esds nested inside a QuickTime `wave` (siDecompressionParam) box rather
than as a direct child of `mp4a`. The decode loop already claimed to
"find esds in mp4a or wave" but only ever saw `wave` as an unknown atom
and skipped it, so Mp4a::decode_body returned MissingBox(esds) and the
whole moov decode failed.

Descend into the wave box, scanning its children by header for esds/btrt
only. Other children (frma, a nested mp4a terminator stub, the trailing
zero box) are skipped by size and never typed-decoded — the nested mp4a
stub is 4 bytes and is not a valid audio sample entry.
@AdrianEddy AdrianEddy force-pushed the fix-quicktime-wave-esds branch from 2547b0e to d073717 Compare July 11, 2026 13:36
@bradh

bradh commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/moov/trak/mdia/minf/stbl/stsd/mp4a/mod.rs`:
- Around line 68-85: Update the size guard in decode_wave so only child sizes
greater than zero and within wave.remaining() are accepted. Treat Some(0) like
other invalid or over-long sizes by breaking the scan, ensuring
wave.advance(size) always makes progress.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2bf5cc98-1306-46d0-be12-31e7ca41de8f

📥 Commits

Reviewing files that changed from the base of the PR and between 3241814 and d073717.

📒 Files selected for processing (1)
  • src/moov/trak/mdia/minf/stbl/stsd/mp4a/mod.rs

Comment thread src/moov/trak/mdia/minf/stbl/stsd/mp4a/mod.rs
@bradh bradh merged commit f6192b7 into kixelated:main Jul 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants