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

mpe2aac: ADTS frame length validation #36

Open
mrwish7 opened this issue Apr 2, 2020 · 2 comments · May be fixed by #40
Open

mpe2aac: ADTS frame length validation #36

mrwish7 opened this issue Apr 2, 2020 · 2 comments · May be fixed by #40

Comments

@mrwish7
Copy link
Contributor

mrwish7 commented Apr 2, 2020

This seems to apply to the Spanish PRISA radio stations on Hispasat 30°W (12518H and also the Catalan language versions on 12519H).

As the audio level on these feeds can be really inconsistent (I think they're processed by the local studios of each of the stations before being broadcast on FM), I use a script to feed them through FFMPEG and level the audio using the 'dynaudnorm' filter.

With the raw output from mpe2aac, FFMPEG stops after a certain amount of time, complaining that the AAC audio data is invalid.

I investigated this, and it turns out that certain ADTS AAC frames in the stream don't seem to be valid, with a really long length set (longer than the amount of data in the UDP frame). I used this guide to get the ADTS frame length from the audio data packet - https://wiki.multimedia.cx/index.php/ADTS

These frames still start 0xFF 0xF1 or 0xFF 0xF9, so the mpe2aac tool counts them as valid and passes them through. I think because the amount of data in the UDP packet is less than the reported AAC frame length, FFMPEG treats it as corrupted.

I'm not a C programmer, so this code may not be the best, but I added a check to test if the length of the UDP data matches the length reported by the AAC packet itself. The packets only then get output if the length matches -

/* when aac located successfully */
    if (len_udp > 8) {
        /* get AAC frame length as reported by the ADTS packet itself */
        int aac_frame_len = ((payload[3] & 0x3) << 11) | ((payload[4] << 3) | (payload[5] >> 5));

        /* Only output AAC frames with matching length in ADTS packet to avoid FFMPEG errors */
        if (len_udp == aac_frame_len)
            fwrite(payload, 1, len_udp, stdout);
    }

The resulting output seems to play OK still is counted as valid by FFMPEG instead of stopping after several minutes.

I don't know enough about AAC/ADTS to know what these other frames are, and if they're necessary for anything. Removing them seems to work in any case!

@newspaperman
Copy link
Contributor

Thx for your investigation. Which file did You edit and which line? There are similar problems on 23.5° E 12642v 280 3/4

@mrwish7
Copy link
Contributor Author

mrwish7 commented Oct 25, 2020

Thx for your investigation. Which file did You edit and which line? There are similar problems on 23.5° E 12642v 280 3/4

File mpe2aac.c on lines 308-310, replaced with the code I've pasted above.

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 a pull request may close this issue.

2 participants