Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bit rate for MP4 audio tracks #414

Closed
gino0631 opened this issue Apr 3, 2023 · 3 comments
Closed

Bit rate for MP4 audio tracks #414

gino0631 opened this issue Apr 3, 2023 · 3 comments

Comments

@gino0631
Copy link

gino0631 commented Apr 3, 2023

I have noticed that getID3 does not output bit rate for MP4 audio, while other tools, like MediaInfo and ffprobe, do that. This can be seen with the sample provided for #413. It would be nice to have this feature in getID3 too.

Technically, it is possible to extract the bit rate from esds extension atom.

Sound Sample Descriptions may contain extensions which are made using atoms. MPEG-4 Elementary Stream Descriptor Atom ('esds') contains Elementary Stream Descriptor as defined in the MPEG-4 specification ISO/IEC 14496, which in turn contains DecoderConfigDescriptor with maxBitrate and avgBitrate fields.

To read this information, the following logic can be used:

  1. Determine if there is some additional data after Sound Sample Description. Size of the description depends on its version, so version field has to be read and analyzed first (while it is documented that "extensions were first added with sound sample description v1", the sample in question has version 0 but nevertheless does contain an extension). It is also worth mentioning that the current code in getID3 ignores the version and always reads version 0 description, which means the values will be incorrect in case of version 2.
  2. If there is additional data, read the atoms.
  3. If esds atom is found, parse it. For example, the sample in question contains the following atom:
    00000033 65736473 00000000 03 80808022 0002 00 04 80808014 40 15 000000 0004e211 0004e211 05 80808002 1190 06 80808001 02
    with header:
    00000033 - size 51 bytes
    65736473 - esds
    00000000 - version (0)
    and Elementary Stream Descriptor (see ISO/IEC 14496-1:2010 7.2.6.5 and 7.2.6.6):
    03 - ES_DescrTag
    80808022 - size 34 bytes
    0002 - ES_ID
    00 - flags
    -----
    04 - DecoderConfigDescrTag
    80808014 - size 20 bytes
    40 - objectTypeIndication ("Audio ISO/IEC 14496-3")
    15 - streamType plus flags ("AudioStream")
    000000 - bufferSizeDB
    0004e211 - maxBitrate (320017)
    0004e211 - avgBitrate (320017)
    05 - DecSpecificInfoTag
    80808002 - size 2 bytes
    1190 - DecoderSpecificInfo
    -----
    06 - SLConfigDescrTag
    80808001 - size 1 byte
    02 - SLConfigDescriptor ("Reserved for use in MP4 files")

An example of parsing can also be found here.

JamesHeinrich added a commit that referenced this issue Apr 5, 2023
@JamesHeinrich
Copy link
Owner

Thank you for the detailed breakdown, and links to the Chromium example, that was helpful.
I've implemented it at ce4a159
Please feel free to suggest any changes or improvements, PRs (very) welcome.

JamesHeinrich added a commit that referenced this issue Apr 5, 2023
Fix wrong variable name in ce4a159
@gino0631
Copy link
Author

gino0631 commented Apr 5, 2023

Thanks for the implementation, I am so glad the references were helpful!

It is difficult with PRs without knowing the code well enough. As for the improvements, I think you already had a function to read the sizes - quicktime_read_mp4_descr_length() is quite similar to quicktime_readESsize().

@JamesHeinrich
Copy link
Owner

Sometimes I don't know the code that well myself -- most of getID3 was written 20 years ago...

You're right, quicktime_read_mp4_descr_length is a better implementation, I have removed quicktime_readESsize.

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

No branches or pull requests

2 participants