Opened 4 weeks ago

Last modified 4 weeks ago

#6974 new defect

Improve handling of AAC PCE audio channels with segmented MPEG-TS

Reported by: redmcg Owned by:
Priority: important Component: undetermined
Version: git-master Keywords: aac regression
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no


Summary of the bug:
I had been happily transcoding from AC3 (5.1 side) to AAC with HLS muxing. But after a recompile from 'master' I discovered audio had stopped working.

A 'git bisect' indicated that this stopped working with commit fc9dcfe7d50d7f1b38fb287b4d92b5f3fc4bfb05.

This commit marked '5.1 side' as not "normal" for AAC and thus a PCE entry was now required.

The PCE entry seems to work fine for the first segment of a segmented MPEG-TS, but subsequent MPEG-TS files don't appear to have an ASC (AudioSpecificConfig? data structure).

Running ffprobe against the first segment (for example 'ffprobe hls0.ts') works fine and returns:

Input #0, mpegts, from 'hls0.ts':
  Duration: 00:00:02.01, start: 1.400000, bitrate: 382 kb/s
  Program 1 
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100](eng): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, 6 channels, fltp, 378 kb/s

But running it on the second segment (for example 'ffprobe hls1.ts') returns:

[mpegts @ 0x1476040] decoding for stream 0 failed
[mpegts @ 0x1476040] Could not find codec parameters for stream 0 (Audio: aac (LC) ([15][0][0][0] / 0x000F), 0 channels, fltp, 426 kb/s): unspecified sample rate
Consider increasing the value for the 'analyzeduration' and 'probesize' options
hls1.ts: End of file

I discovered the failure occurs at libavcodec/aacdec_template.c:3126 - which has this check:

        if (!avctx->channels && elem_type != TYPE_PCE) {
            err = AVERROR_INVALIDDATA;
            goto fail;

because avctx->channels == 0 and elem_type == TYPE_CPE.

I'm not sure of the solution though. I figure either:
a) Add the ASC to beginning of each TS segment (if possible);
b) Encode each AAC frame with a TYPE_CPE (if possible);
c) Have HLS default to fMP4 when an AAC CPE is in use (for which CPE seems to work); or
d) Produce a warning

Although I think option 'b)' breaks compatibility with older decoders (if it is even possible to do).

How to reproduce:

% ffmpeg -loglevel info -i in.ts -map 0:a -c:0 aac -f hls hls.m3u8
% ffprobe hls0.ts # works
% ffprobe hls1.ts # doesn't

ffprobe version N-89870-gbda5ad3 Copyright (c) 2007-2018 the FFmpeg developers

Change History (2)

comment:1 Changed 4 weeks ago by cehoyos

  • Keywords regression added; hls adts pce removed
  • Priority changed from normal to important
  • Type changed from enhancement to defect

See also #6965.

comment:2 Changed 4 weeks ago by heleppkes

This appears to be caused by the ADTS muxer which is used when muxing MPEG-TS. ADTS streams with PCE require the PCE to be in-band as TYPE_PCE elements, and the ADTS muxer does insert the PCE as an in-band element - except, it only does it once at the beginning - hence the first segment works, and any further segments do not.

For a fully compliant ADTS stream in MPEG-TS, the PCE should probably be repeated on regular intervals. How often this should happen I do not know, I'm sure there is some specification that defines such intervals. Perhaps even in every audio frame?

Note: See TracTickets for help on using tickets.