diff mbox series

[FFmpeg-devel,277/281] ffmpeg: convert to new channel layout-API

Message ID 20220113020913.870-8-jamrial@gmail.com
State New
Headers show
Series New channel layout API
Related show

Commit Message

James Almer Jan. 13, 2022, 2:09 a.m. UTC
Signed-off-by: James Almer <jamrial@gmail.com>
---
 fftools/cmdutils.c            | 42 +++++++++++++++---------
 fftools/cmdutils.h            |  8 -----
 fftools/ffmpeg.c              | 47 ++++++++++++++++----------
 fftools/ffmpeg.h              |  7 ++--
 fftools/ffmpeg_filter.c       | 52 ++++++++++++++++++++++-------
 fftools/ffmpeg_opt.c          | 62 ++++++++++++++++++++++++++++++-----
 tests/fate/aac.mak            |  2 +-
 tests/fate/lavf-container.mak |  2 +-
 8 files changed, 155 insertions(+), 67 deletions(-)

Comments

Michael Niedermayer Jan. 13, 2022, 6:29 p.m. UTC | #1
On Wed, Jan 12, 2022 at 11:09:09PM -0300, James Almer wrote:
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  fftools/cmdutils.c            | 42 +++++++++++++++---------
>  fftools/cmdutils.h            |  8 -----
>  fftools/ffmpeg.c              | 47 ++++++++++++++++----------
>  fftools/ffmpeg.h              |  7 ++--
>  fftools/ffmpeg_filter.c       | 52 ++++++++++++++++++++++-------
>  fftools/ffmpeg_opt.c          | 62 ++++++++++++++++++++++++++++++-----
>  tests/fate/aac.mak            |  2 +-
>  tests/fate/lavf-container.mak |  2 +-
>  8 files changed, 155 insertions(+), 67 deletions(-)

This or a prior patch introduces crashes (it bisected to this but this is my
2nd testcase the first did not reproduce reliably at all)

Thread 1 "ffmpeg_g" received signal SIGSEGV, Segmentation fault.
0x00005555566ed811 in av_vlog (avcl=0x5555577400c0, level=24, fmt=0x5555568249e8 "%d frames left in the queue on closing\n", vl=0x7fffffffda50) at libavutil/log.c:428
428	    if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
(gdb) bt
#0  0x00005555566ed811 in av_vlog (avcl=0x5555577400c0, level=24, fmt=0x5555568249e8 "%d frames left in the queue on closing\n", vl=0x7fffffffda50) at libavutil/log.c:428
#1  0x00005555566ed6bd in av_log (avcl=0x5555577400c0, level=24, fmt=0x5555568249e8 "%d frames left in the queue on closing\n") at libavutil/log.c:411
#2  0x0000555555c320b9 in ff_af_queue_close (afq=0x5555576c47c8) at libavcodec/audio_frame_queue.c:39
#3  0x0000555555e84c06 in mp3lame_encode_close (avctx=0x5555576bf180) at libavcodec/libmp3lame.c:86
#4  0x0000555555c373f7 in avcodec_close (avctx=0x5555576bf180) at libavcodec/avcodec.c:489
#5  0x0000555555f7feab in avcodec_free_context (pavctx=0x5555576a8858) at libavcodec/options.c:163
#6  0x000055555569cfe3 in ffmpeg_cleanup (ret=1) at fftools/ffmpeg.c:608
#7  0x0000555555694817 in exit_program (ret=1) at fftools/cmdutils.c:131
#8  0x000055555569ef1f in do_audio_out (of=0x5555576ae2c0, ost=0x5555576a8800, frame=0x5555576bf580) at fftools/ffmpeg.c:1056
#9  0x00005555556a117a in reap_filters (flush=0) at fftools/ffmpeg.c:1546
#10 0x00005555556ad8e5 in transcode_step () at fftools/ffmpeg.c:4643
#11 0x00005555556ad9e7 in transcode () at fftools/ffmpeg.c:4687
#12 0x00005555556ae45c in main (argc=12, argv=0x7fffffffe1c8) at fftools/ffmpeg.c:4903
(gdb) print avc->version
Cannot access memory at address 0xc1528eb7c0ea0157

make -j32 && gdb --args ./ffmpeg_g -ss 8 -i NeroRecodeSample.mp4 -bitexact -t 3 -filter_complex '[0:2]scale=720:576[v];[v][0:5]overlay' -y file-whitesubs.avi

it appears this file is at:
https://samples.ffmpeg.org/MPEG-4/NeroRecodeSample-MP4/


Press [q] to stop, [?] for help
[aac @ 0x16fb3540] This stream seems to incorrectly report its last channel as SCE[1], mapping to LFE[0]
[aac @ 0x16fb3540] env_facs_q 253 is invalid
==21617==    at 0x12A09F8: VALGRIND_PRINTF_BACKTRACE (valgrind.h:6303)
==21617==    by 0x12A15B6: av_log_default_callback (log.c:397)
==21617==    by 0x12A185D: av_vlog (log.c:432)
==21617==    by 0x12A16BC: av_log (log.c:411)
==21617==    by 0xEED8B6: read_sbr_envelope (aacsbr_template.c:865)
==21617==    by 0xEEE22F: read_sbr_single_channel_element (aacsbr_template.c:983)
==21617==    by 0xEEE762: read_sbr_data (aacsbr_template.c:1055)
==21617==    by 0xEEEAFD: ff_decode_sbr_extension (aacsbr_template.c:1144)
==21617==    by 0xECD082: decode_extension_payload (aacdec_template.c:2582)
==21617==    by 0xED029B: aac_decode_frame_int (aacdec_template.c:3372)
==21617==    by 0xED0842: aac_decode_frame (aacdec_template.c:3500)
==21617==    by 0x8ABF66: decode_simple_internal (decode.c:329)
==21617==    by 0x8ACB62: decode_simple_receive_frame (decode.c:528)
==21617==    by 0x8ACC5C: decode_receive_frame_internal (decode.c:548)
==21617==    by 0x8ACF38: avcodec_send_packet (decode.c:615)
==21617==    by 0x258160: decode (ffmpeg.c:2276)
==21617==    by 0x258354: decode_audio (ffmpeg.c:2319)
==21617==    by 0x259949: process_input_packet (ffmpeg.c:2638)
==21617==    by 0x26138A: process_input (ffmpeg.c:4493)
==21617==    by 0x26187E: transcode_step (ffmpeg.c:4633)
[aac @ 0x16fb3540] env_facs_q 252 is invalid
==21617==    at 0x12A09F8: VALGRIND_PRINTF_BACKTRACE (valgrind.h:6303)
==21617==    by 0x12A15B6: av_log_default_callback (log.c:397)
==21617==    by 0x12A185D: av_vlog (log.c:432)
==21617==    by 0x12A16BC: av_log (log.c:411)
==21617==    by 0xEED8B6: read_sbr_envelope (aacsbr_template.c:865)
==21617==    by 0xEEE5AC: read_sbr_channel_pair_element (aacsbr_template.c:1028)
==21617==    by 0xEEE7A7: read_sbr_data (aacsbr_template.c:1060)
==21617==    by 0xEEEAFD: ff_decode_sbr_extension (aacsbr_template.c:1144)
==21617==    by 0xECD082: decode_extension_payload (aacdec_template.c:2582)
==21617==    by 0xED029B: aac_decode_frame_int (aacdec_template.c:3372)
==21617==    by 0xED0842: aac_decode_frame (aacdec_template.c:3500)
==21617==    by 0x8ABF66: decode_simple_internal (decode.c:329)
==21617==    by 0x8ACB62: decode_simple_receive_frame (decode.c:528)
==21617==    by 0x8ACC5C: decode_receive_frame_internal (decode.c:548)
==21617==    by 0x8ACF38: avcodec_send_packet (decode.c:615)
==21617==    by 0x258160: decode (ffmpeg.c:2276)
==21617==    by 0x258354: decode_audio (ffmpeg.c:2319)
==21617==    by 0x259949: process_input_packet (ffmpeg.c:2638)
==21617==    by 0x26138A: process_input (ffmpeg.c:4493)
==21617==    by 0x26187E: transcode_step (ffmpeg.c:4633)
[aac @ 0x16fb3540] noise_facs_q 255 is invalid
==21617==    at 0x12A09F8: VALGRIND_PRINTF_BACKTRACE (valgrind.h:6303)
==21617==    by 0x12A15B6: av_log_default_callback (log.c:397)
==21617==    by 0x12A185D: av_vlog (log.c:432)
==21617==    by 0x12A16BC: av_log (log.c:411)
==21617==    by 0xEEDE4D: read_sbr_noise (aacsbr_template.c:923)
==21617==    by 0xEEE615: read_sbr_channel_pair_element (aacsbr_template.c:1032)
==21617==    by 0xEEE7A7: read_sbr_data (aacsbr_template.c:1060)
==21617==    by 0xEEEAFD: ff_decode_sbr_extension (aacsbr_template.c:1144)
==21617==    by 0xECD082: decode_extension_payload (aacdec_template.c:2582)
==21617==    by 0xED029B: aac_decode_frame_int (aacdec_template.c:3372)
==21617==    by 0xED0842: aac_decode_frame (aacdec_template.c:3500)
==21617==    by 0x8ABF66: decode_simple_internal (decode.c:329)
==21617==    by 0x8ACB62: decode_simple_receive_frame (decode.c:528)
==21617==    by 0x8ACC5C: decode_receive_frame_internal (decode.c:548)
==21617==    by 0x8ACF38: avcodec_send_packet (decode.c:615)
==21617==    by 0x258160: decode (ffmpeg.c:2276)
==21617==    by 0x258354: decode_audio (ffmpeg.c:2319)
==21617==    by 0x259949: process_input_packet (ffmpeg.c:2638)
==21617==    by 0x26138A: process_input (ffmpeg.c:4493)
==21617==    by 0x26187E: transcode_step (ffmpeg.c:4633)
Audio encoding failed
==21617==    at 0x12A09F8: VALGRIND_PRINTF_BACKTRACE (valgrind.h:6303)
==21617==    by 0x12A15B6: av_log_default_callback (log.c:397)
==21617==    by 0x12A185D: av_vlog (log.c:432)
==21617==    by 0x12A16BC: av_log (log.c:411)
==21617==    by 0x252F14: do_audio_out (ffmpeg.c:1055)
==21617==    by 0x255179: reap_filters (ffmpeg.c:1546)
==21617==    by 0x2618E4: transcode_step (ffmpeg.c:4643)
==21617==    by 0x2619E6: transcode (ffmpeg.c:4687)
==21617==    by 0x26245B: main (ffmpeg.c:4903)
==21617== Invalid read of size 4
==21617==    at 0x12A1811: av_vlog (log.c:428)
==21617==    by 0x12A16BC: av_log (log.c:411)
==21617==    by 0x7E60B8: ff_af_queue_close (audio_frame_queue.c:39)
==21617==    by 0xA38C05: mp3lame_encode_close (libmp3lame.c:86)
==21617==    by 0x7EB3F6: avcodec_close (avcodec.c:489)
==21617==    by 0xB33EAA: avcodec_free_context (options.c:163)
==21617==    by 0x250FE2: ffmpeg_cleanup (ffmpeg.c:608)
==21617==    by 0x248816: exit_program (cmdutils.c:131)
==21617==    by 0x252F1E: do_audio_out (ffmpeg.c:1056)
==21617==    by 0x255179: reap_filters (ffmpeg.c:1546)
==21617==    by 0x2618E4: transcode_step (ffmpeg.c:4643)
==21617==    by 0x2619E6: transcode (ffmpeg.c:4687)
==21617==    by 0x26245B: main (ffmpeg.c:4903)
==21617==  Address 0xc1528eb7c0ea0157 is not stack'd, malloc'd or (recently) free'd
==21617== 
==21617== 
==21617== Process terminating with default action of signal 11 (SIGSEGV)
==21617==  General Protection Fault
==21617==    at 0x12A1811: av_vlog (log.c:428)
==21617==    by 0x12A16BC: av_log (log.c:411)
==21617==    by 0x7E60B8: ff_af_queue_close (audio_frame_queue.c:39)
==21617==    by 0xA38C05: mp3lame_encode_close (libmp3lame.c:86)
==21617==    by 0x7EB3F6: avcodec_close (avcodec.c:489)
==21617==    by 0xB33EAA: avcodec_free_context (options.c:163)
==21617==    by 0x250FE2: ffmpeg_cleanup (ffmpeg.c:608)
==21617==    by 0x248816: exit_program (cmdutils.c:131)
==21617==    by 0x252F1E: do_audio_out (ffmpeg.c:1056)
==21617==    by 0x255179: reap_filters (ffmpeg.c:1546)
==21617==    by 0x2618E4: transcode_step (ffmpeg.c:4643)
==21617==    by 0x2619E6: transcode (ffmpeg.c:4687)
==21617==    by 0x26245B: main (ffmpeg.c:4903)
==21617== 
==21617== HEAP SUMMARY:
==21617==     in use at exit: 3,463,746 bytes in 473 blocks
==21617==   total heap usage: 1,923 allocs, 1,450 frees, 9,590,510 bytes allocated
==21617== 
==21617== 5,888 bytes in 16 blocks are possibly lost in loss record 159 of 180
==21617==    at 0x4C33B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21617==    by 0x4013646: allocate_dtv (dl-tls.c:286)
==21617==    by 0x4013646: _dl_allocate_tls (dl-tls.c:530)
==21617==    by 0xCB4F227: allocate_stack (allocatestack.c:627)
==21617==    by 0xCB4F227: pthread_create@@GLIBC_2.2.5 (pthread_create.c:644)
==21617==    by 0xB6C3FB: init_thread (pthread_frame.c:842)
==21617==    by 0xB6C625: ff_frame_thread_init (pthread_frame.c:898)
==21617==    by 0xB69E97: ff_thread_init (pthread.c:81)
==21617==    by 0x7EAC52: avcodec_open2 (avcodec.c:330)
==21617==    by 0x25AA65: init_input_stream (ffmpeg.c:2922)
==21617==    by 0x25D48C: transcode_init (ffmpeg.c:3634)
==21617==    by 0x261924: transcode (ffmpeg.c:4658)
==21617==    by 0x26245B: main (ffmpeg.c:4903)
==21617== 
==21617== LEAK SUMMARY:
==21617==    definitely lost: 0 bytes in 0 blocks
==21617==    indirectly lost: 0 bytes in 0 blocks
==21617==      possibly lost: 5,888 bytes in 16 blocks
==21617==    still reachable: 3,457,858 bytes in 457 blocks
==21617==         suppressed: 0 bytes in 0 blocks
==21617== Reachable blocks (those to which a pointer was found) are not shown.
==21617== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==21617== 
==21617== For counts of detected and suppressed errors, rerun with: -v
==21617== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)


thx

[...]
James Almer Jan. 13, 2022, 6:40 p.m. UTC | #2
On 1/13/2022 3:29 PM, Michael Niedermayer wrote:
> On Wed, Jan 12, 2022 at 11:09:09PM -0300, James Almer wrote:
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>   fftools/cmdutils.c            | 42 +++++++++++++++---------
>>   fftools/cmdutils.h            |  8 -----
>>   fftools/ffmpeg.c              | 47 ++++++++++++++++----------
>>   fftools/ffmpeg.h              |  7 ++--
>>   fftools/ffmpeg_filter.c       | 52 ++++++++++++++++++++++-------
>>   fftools/ffmpeg_opt.c          | 62 ++++++++++++++++++++++++++++++-----
>>   tests/fate/aac.mak            |  2 +-
>>   tests/fate/lavf-container.mak |  2 +-
>>   8 files changed, 155 insertions(+), 67 deletions(-)
> 
> This or a prior patch introduces crashes (it bisected to this but this is my
> 2nd testcase the first did not reproduce reliably at all)
> 
> Thread 1 "ffmpeg_g" received signal SIGSEGV, Segmentation fault.
> 0x00005555566ed811 in av_vlog (avcl=0x5555577400c0, level=24, fmt=0x5555568249e8 "%d frames left in the queue on closing\n", vl=0x7fffffffda50) at libavutil/log.c:428

av_vlog() is where it crashes?

> 428	    if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
> (gdb) bt
> #0  0x00005555566ed811 in av_vlog (avcl=0x5555577400c0, level=24, fmt=0x5555568249e8 "%d frames left in the queue on closing\n", vl=0x7fffffffda50) at libavutil/log.c:428
> #1  0x00005555566ed6bd in av_log (avcl=0x5555577400c0, level=24, fmt=0x5555568249e8 "%d frames left in the queue on closing\n") at libavutil/log.c:411
> #2  0x0000555555c320b9 in ff_af_queue_close (afq=0x5555576c47c8) at libavcodec/audio_frame_queue.c:39
> #3  0x0000555555e84c06 in mp3lame_encode_close (avctx=0x5555576bf180) at libavcodec/libmp3lame.c:86
> #4  0x0000555555c373f7 in avcodec_close (avctx=0x5555576bf180) at libavcodec/avcodec.c:489
> #5  0x0000555555f7feab in avcodec_free_context (pavctx=0x5555576a8858) at libavcodec/options.c:163
> #6  0x000055555569cfe3 in ffmpeg_cleanup (ret=1) at fftools/ffmpeg.c:608
> #7  0x0000555555694817 in exit_program (ret=1) at fftools/cmdutils.c:131
> #8  0x000055555569ef1f in do_audio_out (of=0x5555576ae2c0, ost=0x5555576a8800, frame=0x5555576bf580) at fftools/ffmpeg.c:1056
> #9  0x00005555556a117a in reap_filters (flush=0) at fftools/ffmpeg.c:1546
> #10 0x00005555556ad8e5 in transcode_step () at fftools/ffmpeg.c:4643
> #11 0x00005555556ad9e7 in transcode () at fftools/ffmpeg.c:4687
> #12 0x00005555556ae45c in main (argc=12, argv=0x7fffffffe1c8) at fftools/ffmpeg.c:4903
> (gdb) print avc->version
> Cannot access memory at address 0xc1528eb7c0ea0157
> 
> make -j32 && gdb --args ./ffmpeg_g -ss 8 -i NeroRecodeSample.mp4 -bitexact -t 3 -filter_complex '[0:2]scale=720:576[v];[v][0:5]overlay' -y file-whitesubs.avi
> 
> it appears this file is at:
> https://samples.ffmpeg.org/MPEG-4/NeroRecodeSample-MP4/

I can't reproduce this on mingw64.
James Almer Jan. 13, 2022, 7:44 p.m. UTC | #3
On 1/13/2022 3:40 PM, James Almer wrote:
> On 1/13/2022 3:29 PM, Michael Niedermayer wrote:
>> On Wed, Jan 12, 2022 at 11:09:09PM -0300, James Almer wrote:
>>> Signed-off-by: James Almer <jamrial@gmail.com>
>>> ---
>>>   fftools/cmdutils.c            | 42 +++++++++++++++---------
>>>   fftools/cmdutils.h            |  8 -----
>>>   fftools/ffmpeg.c              | 47 ++++++++++++++++----------
>>>   fftools/ffmpeg.h              |  7 ++--
>>>   fftools/ffmpeg_filter.c       | 52 ++++++++++++++++++++++-------
>>>   fftools/ffmpeg_opt.c          | 62 ++++++++++++++++++++++++++++++-----
>>>   tests/fate/aac.mak            |  2 +-
>>>   tests/fate/lavf-container.mak |  2 +-
>>>   8 files changed, 155 insertions(+), 67 deletions(-)
>>
>> This or a prior patch introduces crashes (it bisected to this but this 
>> is my
>> 2nd testcase the first did not reproduce reliably at all)
>>
>> Thread 1 "ffmpeg_g" received signal SIGSEGV, Segmentation fault.
>> 0x00005555566ed811 in av_vlog (avcl=0x5555577400c0, level=24, 
>> fmt=0x5555568249e8 "%d frames left in the queue on closing\n", 
>> vl=0x7fffffffda50) at libavutil/log.c:428
> 
> av_vlog() is where it crashes?
> 
>> 428        if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
>> (gdb) bt
>> #0  0x00005555566ed811 in av_vlog (avcl=0x5555577400c0, level=24, 
>> fmt=0x5555568249e8 "%d frames left in the queue on closing\n", 
>> vl=0x7fffffffda50) at libavutil/log.c:428
>> #1  0x00005555566ed6bd in av_log (avcl=0x5555577400c0, level=24, 
>> fmt=0x5555568249e8 "%d frames left in the queue on closing\n") at 
>> libavutil/log.c:411
>> #2  0x0000555555c320b9 in ff_af_queue_close (afq=0x5555576c47c8) at 
>> libavcodec/audio_frame_queue.c:39
>> #3  0x0000555555e84c06 in mp3lame_encode_close (avctx=0x5555576bf180) 
>> at libavcodec/libmp3lame.c:86
>> #4  0x0000555555c373f7 in avcodec_close (avctx=0x5555576bf180) at 
>> libavcodec/avcodec.c:489
>> #5  0x0000555555f7feab in avcodec_free_context (pavctx=0x5555576a8858) 
>> at libavcodec/options.c:163
>> #6  0x000055555569cfe3 in ffmpeg_cleanup (ret=1) at fftools/ffmpeg.c:608
>> #7  0x0000555555694817 in exit_program (ret=1) at fftools/cmdutils.c:131
>> #8  0x000055555569ef1f in do_audio_out (of=0x5555576ae2c0, 
>> ost=0x5555576a8800, frame=0x5555576bf580) at fftools/ffmpeg.c:1056
>> #9  0x00005555556a117a in reap_filters (flush=0) at fftools/ffmpeg.c:1546
>> #10 0x00005555556ad8e5 in transcode_step () at fftools/ffmpeg.c:4643
>> #11 0x00005555556ad9e7 in transcode () at fftools/ffmpeg.c:4687
>> #12 0x00005555556ae45c in main (argc=12, argv=0x7fffffffe1c8) at 
>> fftools/ffmpeg.c:4903
>> (gdb) print avc->version
>> Cannot access memory at address 0xc1528eb7c0ea0157
>>
>> make -j32 && gdb --args ./ffmpeg_g -ss 8 -i NeroRecodeSample.mp4 
>> -bitexact -t 3 -filter_complex '[0:2]scale=720:576[v];[v][0:5]overlay' 
>> -y file-whitesubs.avi
>>
>> it appears this file is at:
>> https://samples.ffmpeg.org/MPEG-4/NeroRecodeSample-MP4/
> 
> I can't reproduce this on mingw64.

Does the following fix it for you?

> diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c
> index 36ae57eb83..728005b840 100644
> --- a/libavcodec/libmp3lame.c
> +++ b/libavcodec/libmp3lame.c
> @@ -344,9 +344,15 @@ const AVCodec ff_libmp3lame_encoder = {
>                                                               AV_SAMPLE_FMT_S16P,
>                                                               AV_SAMPLE_FMT_NONE },
>      .supported_samplerates = libmp3lame_sample_rates,
> +#if FF_API_OLD_CHANNEL_LAYOUT
>      .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
>                                                    AV_CH_LAYOUT_STEREO,
>                                                    0 },
> +#endif
> +    .ch_layouts            = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO,
> +                                                         AV_CHANNEL_LAYOUT_STEREO,
> +                                                         { 0 },
> +    },
>      .priv_class            = &libmp3lame_class,
>      .defaults              = libmp3lame_defaults,
>      .wrapper_name          = "libmp3lame",
Michael Niedermayer Jan. 15, 2022, 1:47 p.m. UTC | #4
On Thu, Jan 13, 2022 at 04:44:55PM -0300, James Almer wrote:
> 
> 
> On 1/13/2022 3:40 PM, James Almer wrote:
> > On 1/13/2022 3:29 PM, Michael Niedermayer wrote:
> > > On Wed, Jan 12, 2022 at 11:09:09PM -0300, James Almer wrote:
> > > > Signed-off-by: James Almer <jamrial@gmail.com>
> > > > ---
> > > >   fftools/cmdutils.c            | 42 +++++++++++++++---------
> > > >   fftools/cmdutils.h            |  8 -----
> > > >   fftools/ffmpeg.c              | 47 ++++++++++++++++----------
> > > >   fftools/ffmpeg.h              |  7 ++--
> > > >   fftools/ffmpeg_filter.c       | 52 ++++++++++++++++++++++-------
> > > >   fftools/ffmpeg_opt.c          | 62 ++++++++++++++++++++++++++++++-----
> > > >   tests/fate/aac.mak            |  2 +-
> > > >   tests/fate/lavf-container.mak |  2 +-
> > > >   8 files changed, 155 insertions(+), 67 deletions(-)
> > > 
> > > This or a prior patch introduces crashes (it bisected to this but
> > > this is my
> > > 2nd testcase the first did not reproduce reliably at all)
> > > 
> > > Thread 1 "ffmpeg_g" received signal SIGSEGV, Segmentation fault.
> > > 0x00005555566ed811 in av_vlog (avcl=0x5555577400c0, level=24,
> > > fmt=0x5555568249e8 "%d frames left in the queue on closing\n",
> > > vl=0x7fffffffda50) at libavutil/log.c:428
> > 
> > av_vlog() is where it crashes?
> > 
> > > 428        if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
> > > (gdb) bt
> > > #0  0x00005555566ed811 in av_vlog (avcl=0x5555577400c0, level=24,
> > > fmt=0x5555568249e8 "%d frames left in the queue on closing\n",
> > > vl=0x7fffffffda50) at libavutil/log.c:428
> > > #1  0x00005555566ed6bd in av_log (avcl=0x5555577400c0, level=24,
> > > fmt=0x5555568249e8 "%d frames left in the queue on closing\n") at
> > > libavutil/log.c:411
> > > #2  0x0000555555c320b9 in ff_af_queue_close (afq=0x5555576c47c8) at
> > > libavcodec/audio_frame_queue.c:39
> > > #3  0x0000555555e84c06 in mp3lame_encode_close
> > > (avctx=0x5555576bf180) at libavcodec/libmp3lame.c:86
> > > #4  0x0000555555c373f7 in avcodec_close (avctx=0x5555576bf180) at
> > > libavcodec/avcodec.c:489
> > > #5  0x0000555555f7feab in avcodec_free_context
> > > (pavctx=0x5555576a8858) at libavcodec/options.c:163
> > > #6  0x000055555569cfe3 in ffmpeg_cleanup (ret=1) at fftools/ffmpeg.c:608
> > > #7  0x0000555555694817 in exit_program (ret=1) at fftools/cmdutils.c:131
> > > #8  0x000055555569ef1f in do_audio_out (of=0x5555576ae2c0,
> > > ost=0x5555576a8800, frame=0x5555576bf580) at fftools/ffmpeg.c:1056
> > > #9  0x00005555556a117a in reap_filters (flush=0) at fftools/ffmpeg.c:1546
> > > #10 0x00005555556ad8e5 in transcode_step () at fftools/ffmpeg.c:4643
> > > #11 0x00005555556ad9e7 in transcode () at fftools/ffmpeg.c:4687
> > > #12 0x00005555556ae45c in main (argc=12, argv=0x7fffffffe1c8) at
> > > fftools/ffmpeg.c:4903
> > > (gdb) print avc->version
> > > Cannot access memory at address 0xc1528eb7c0ea0157
> > > 
> > > make -j32 && gdb --args ./ffmpeg_g -ss 8 -i NeroRecodeSample.mp4
> > > -bitexact -t 3 -filter_complex
> > > '[0:2]scale=720:576[v];[v][0:5]overlay' -y file-whitesubs.avi
> > > 
> > > it appears this file is at:
> > > https://samples.ffmpeg.org/MPEG-4/NeroRecodeSample-MP4/
> > 
> > I can't reproduce this on mingw64.
> 
> Does the following fix it for you?

jamrial/channel_layout4 seems not to crash anymore
but the output from
libswresample/tests/swresample

changes substantially with that branch merged
here a hunk showing that:

--- /tmp/old    2022-01-15 14:38:42.370067768 +0100
+++ /tmp/new    2022-01-15 14:37:58.265740924 +0100
@@ -3,14 +3,14 @@
 [e:0.037321 c:0.988153 max:0.208739] len:  968
 [e:0.037581 c:0.988035 max:0.208739] len:  968
 [e:0.040051 c:0.986398 max:0.208739] len:  968
-[e:0.042843 c:0.984417 max:0.215337] len:  968
-[e:0.038669 c:0.987065 max:0.208739] len:  968
+[e:0.238849 c:-nan max:0.990217] len:  968
+[e:0.236179 c:-nan max:0.990217] len:  968
 [e:0.000987 c:0.999985 max:0.003293] len:   16 F:  1
 [e:0.000131 c:0.999999 max:0.000438] len:   16 F:  1
 [e:0.000999 c:0.999985 max:0.003333] len:   16 F:  1
 [e:0.000084 c:1.000000 max:0.000280] len:   16 F:  1
-[e:0.000996 c:0.999985 max:0.003322] len:   16 F:  1
-[e:0.000027 c:1.000000 max:0.000089] len:   16 F:  1
+[e:0.181271 c:-nan max:0.297598] len:   16 F:  1
+[e:0.080519 c:-nan max:0.227637] len:   16 F:  1
 
 TEST: 3.0->7.1(wide-side), rate:16000->48000, fmt:dbl->dbl
 [e:0.039816 c:0.986742 max:0.283776] len:  968


 
[...]
James Almer Jan. 15, 2022, 4:04 p.m. UTC | #5
On 1/15/2022 10:47 AM, Michael Niedermayer wrote:
> On Thu, Jan 13, 2022 at 04:44:55PM -0300, James Almer wrote:
>>
>>
>> On 1/13/2022 3:40 PM, James Almer wrote:
>>> On 1/13/2022 3:29 PM, Michael Niedermayer wrote:
>>>> On Wed, Jan 12, 2022 at 11:09:09PM -0300, James Almer wrote:
>>>>> Signed-off-by: James Almer <jamrial@gmail.com>
>>>>> ---
>>>>>    fftools/cmdutils.c            | 42 +++++++++++++++---------
>>>>>    fftools/cmdutils.h            |  8 -----
>>>>>    fftools/ffmpeg.c              | 47 ++++++++++++++++----------
>>>>>    fftools/ffmpeg.h              |  7 ++--
>>>>>    fftools/ffmpeg_filter.c       | 52 ++++++++++++++++++++++-------
>>>>>    fftools/ffmpeg_opt.c          | 62 ++++++++++++++++++++++++++++++-----
>>>>>    tests/fate/aac.mak            |  2 +-
>>>>>    tests/fate/lavf-container.mak |  2 +-
>>>>>    8 files changed, 155 insertions(+), 67 deletions(-)
>>>>
>>>> This or a prior patch introduces crashes (it bisected to this but
>>>> this is my
>>>> 2nd testcase the first did not reproduce reliably at all)
>>>>
>>>> Thread 1 "ffmpeg_g" received signal SIGSEGV, Segmentation fault.
>>>> 0x00005555566ed811 in av_vlog (avcl=0x5555577400c0, level=24,
>>>> fmt=0x5555568249e8 "%d frames left in the queue on closing\n",
>>>> vl=0x7fffffffda50) at libavutil/log.c:428
>>>
>>> av_vlog() is where it crashes?
>>>
>>>> 428        if (avc && avc->version >= (50 << 16 | 15 << 8 | 2) &&
>>>> (gdb) bt
>>>> #0  0x00005555566ed811 in av_vlog (avcl=0x5555577400c0, level=24,
>>>> fmt=0x5555568249e8 "%d frames left in the queue on closing\n",
>>>> vl=0x7fffffffda50) at libavutil/log.c:428
>>>> #1  0x00005555566ed6bd in av_log (avcl=0x5555577400c0, level=24,
>>>> fmt=0x5555568249e8 "%d frames left in the queue on closing\n") at
>>>> libavutil/log.c:411
>>>> #2  0x0000555555c320b9 in ff_af_queue_close (afq=0x5555576c47c8) at
>>>> libavcodec/audio_frame_queue.c:39
>>>> #3  0x0000555555e84c06 in mp3lame_encode_close
>>>> (avctx=0x5555576bf180) at libavcodec/libmp3lame.c:86
>>>> #4  0x0000555555c373f7 in avcodec_close (avctx=0x5555576bf180) at
>>>> libavcodec/avcodec.c:489
>>>> #5  0x0000555555f7feab in avcodec_free_context
>>>> (pavctx=0x5555576a8858) at libavcodec/options.c:163
>>>> #6  0x000055555569cfe3 in ffmpeg_cleanup (ret=1) at fftools/ffmpeg.c:608
>>>> #7  0x0000555555694817 in exit_program (ret=1) at fftools/cmdutils.c:131
>>>> #8  0x000055555569ef1f in do_audio_out (of=0x5555576ae2c0,
>>>> ost=0x5555576a8800, frame=0x5555576bf580) at fftools/ffmpeg.c:1056
>>>> #9  0x00005555556a117a in reap_filters (flush=0) at fftools/ffmpeg.c:1546
>>>> #10 0x00005555556ad8e5 in transcode_step () at fftools/ffmpeg.c:4643
>>>> #11 0x00005555556ad9e7 in transcode () at fftools/ffmpeg.c:4687
>>>> #12 0x00005555556ae45c in main (argc=12, argv=0x7fffffffe1c8) at
>>>> fftools/ffmpeg.c:4903
>>>> (gdb) print avc->version
>>>> Cannot access memory at address 0xc1528eb7c0ea0157
>>>>
>>>> make -j32 && gdb --args ./ffmpeg_g -ss 8 -i NeroRecodeSample.mp4
>>>> -bitexact -t 3 -filter_complex
>>>> '[0:2]scale=720:576[v];[v][0:5]overlay' -y file-whitesubs.avi
>>>>
>>>> it appears this file is at:
>>>> https://samples.ffmpeg.org/MPEG-4/NeroRecodeSample-MP4/
>>>
>>> I can't reproduce this on mingw64.
>>
>> Does the following fix it for you?
> 
> jamrial/channel_layout4 seems not to crash anymore
> but the output from
> libswresample/tests/swresample
> 
> changes substantially with that branch merged
> here a hunk showing that:
> 
> --- /tmp/old    2022-01-15 14:38:42.370067768 +0100
> +++ /tmp/new    2022-01-15 14:37:58.265740924 +0100
> @@ -3,14 +3,14 @@
>   [e:0.037321 c:0.988153 max:0.208739] len:  968
>   [e:0.037581 c:0.988035 max:0.208739] len:  968
>   [e:0.040051 c:0.986398 max:0.208739] len:  968
> -[e:0.042843 c:0.984417 max:0.215337] len:  968
> -[e:0.038669 c:0.987065 max:0.208739] len:  968
> +[e:0.238849 c:-nan max:0.990217] len:  968
> +[e:0.236179 c:-nan max:0.990217] len:  968
>   [e:0.000987 c:0.999985 max:0.003293] len:   16 F:  1
>   [e:0.000131 c:0.999999 max:0.000438] len:   16 F:  1
>   [e:0.000999 c:0.999985 max:0.003333] len:   16 F:  1
>   [e:0.000084 c:1.000000 max:0.000280] len:   16 F:  1
> -[e:0.000996 c:0.999985 max:0.003322] len:   16 F:  1
> -[e:0.000027 c:1.000000 max:0.000089] len:   16 F:  1
> +[e:0.181271 c:-nan max:0.297598] len:   16 F:  1
> +[e:0.080519 c:-nan max:0.227637] len:   16 F:  1
>   
>   TEST: 3.0->7.1(wide-side), rate:16000->48000, fmt:dbl->dbl
>   [e:0.039816 c:0.986742 max:0.283776] len:  968

Should be fixed in the branch.
diff mbox series

Patch

diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 4b50e15eef..55cdbfb7a7 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -1470,8 +1470,19 @@  static void print_codec(const AVCodec *c)
                           GET_SAMPLE_RATE_NAME);
     PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample formats",
                           AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
-    PRINT_CODEC_SUPPORTED(c, channel_layouts, uint64_t, "channel layouts",
-                          0, GET_CH_LAYOUT_DESC);
+
+    if (c->ch_layouts) {
+        const AVChannelLayout *p = c->ch_layouts;
+
+        printf("    Supported channel layouts:");
+        while (p->nb_channels) {
+            char name[128];
+            av_channel_layout_describe(p, name, sizeof(name));
+            printf(" %s", name);
+            p++;
+        }
+        printf("\n");
+    }
 
     if (c->priv_class) {
         show_help_children(c->priv_class,
@@ -1784,29 +1795,30 @@  int show_pix_fmts(void *optctx, const char *opt, const char *arg)
 
 int show_layouts(void *optctx, const char *opt, const char *arg)
 {
+    const AVChannelLayout *ch_layout;
+    void *iter = NULL;
+    char buf[128], buf2[128];
     int i = 0;
-    uint64_t layout, j;
-    const char *name, *descr;
 
     printf("Individual channels:\n"
            "NAME           DESCRIPTION\n");
     for (i = 0; i < 63; i++) {
-        name = av_get_channel_name((uint64_t)1 << i);
-        if (!name)
+        av_channel_name(buf, sizeof(buf), i);
+        if (!strcmp(buf, "?"))
             continue;
-        descr = av_get_channel_description((uint64_t)1 << i);
-        printf("%-14s %s\n", name, descr);
+        av_channel_description(buf2, sizeof(buf2), i);
+        printf("%-14s %s\n", buf, buf2);
     }
     printf("\nStandard channel layouts:\n"
            "NAME           DECOMPOSITION\n");
-    for (i = 0; !av_get_standard_channel_layout(i, &layout, &name); i++) {
-        if (name) {
-            printf("%-14s ", name);
-            for (j = 1; j; j <<= 1)
-                if ((layout & j))
-                    printf("%s%s", (layout & (j - 1)) ? "+" : "", av_get_channel_name(j));
+    while (ch_layout = av_channel_layout_standard(&iter)) {
+            av_channel_layout_describe(ch_layout, buf, sizeof(buf));
+            av_channel_name(buf2, sizeof(buf2), i);
+            printf("%-14s ", buf);
+            for (i = 0; i < 63; i++)
+                if (av_channel_layout_index_from_channel(ch_layout, i) >= 0)
+                    printf("%s%s", i ? "+" : "", buf2);
             printf("\n");
-        }
     }
     return 0;
 }
diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h
index 50eed9b13a..274d2e5b14 100644
--- a/fftools/cmdutils.h
+++ b/fftools/cmdutils.h
@@ -663,14 +663,6 @@  void *allocate_array_elem(void *array, size_t elem_size, int *nb_elems);
     char name[16];\
     snprintf(name, sizeof(name), "%d", rate);
 
-#define GET_CH_LAYOUT_NAME(ch_layout)\
-    char name[16];\
-    snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout);
-
-#define GET_CH_LAYOUT_DESC(ch_layout)\
-    char name[128];\
-    av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
-
 double get_rotation(int32_t *displaymatrix);
 
 #endif /* FFTOOLS_CMDUTILS_H */
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 5d134b025f..22d6309f2a 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -555,6 +555,7 @@  static void ffmpeg_cleanup(int ret)
 
             avfilter_inout_free(&ofilter->out_tmp);
             av_freep(&ofilter->name);
+            av_channel_layout_uninit(&ofilter->ch_layout);
             av_freep(&fg->outputs[j]);
         }
         av_freep(&fg->outputs);
@@ -1537,7 +1538,7 @@  static int reap_filters(int flush)
                 break;
             case AVMEDIA_TYPE_AUDIO:
                 if (!(enc->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE) &&
-                    enc->channels != filtered_frame->channels) {
+                    enc->ch_layout.nb_channels != filtered_frame->ch_layout.nb_channels) {
                     av_log(NULL, AV_LOG_ERROR,
                            "Audio filter graph output is not normalized and encoder does not support parameter changes\n");
                     break;
@@ -1883,17 +1884,22 @@  static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
         print_final_stats(total_size);
 }
 
-static void ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
+static int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
 {
+    int ret;
+
     // We never got any input. Set a fake format, which will
     // come from libavformat.
     ifilter->format                 = par->format;
     ifilter->sample_rate            = par->sample_rate;
-    ifilter->channels               = par->channels;
-    ifilter->channel_layout         = par->channel_layout;
     ifilter->width                  = par->width;
     ifilter->height                 = par->height;
     ifilter->sample_aspect_ratio    = par->sample_aspect_ratio;
+    ret = av_channel_layout_copy(&ifilter->ch_layout, &par->ch_layout);
+    if (ret < 0)
+        return ret;
+
+    return 0;
 }
 
 static void flush_encoders(void)
@@ -1921,8 +1927,11 @@  static void flush_encoders(void)
                 int x;
                 for (x = 0; x < fg->nb_inputs; x++) {
                     InputFilter *ifilter = fg->inputs[x];
-                    if (ifilter->format < 0)
-                        ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
+                    if (ifilter->format < 0 &&
+                        ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar) < 0) {
+                        av_log(NULL, AV_LOG_ERROR, "Error copying paramerets from input stream\n");
+                        exit_program(1);
+                    }
                 }
 
                 if (!ifilter_has_all_input_formats(fg))
@@ -2098,16 +2107,15 @@  int guess_input_channel_layout(InputStream *ist)
 {
     AVCodecContext *dec = ist->dec_ctx;
 
-    if (!dec->channel_layout) {
+    if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
         char layout_name[256];
 
-        if (dec->channels > ist->guess_layout_max)
+        if (dec->ch_layout.nb_channels > ist->guess_layout_max)
             return 0;
-        dec->channel_layout = av_get_default_channel_layout(dec->channels);
-        if (!dec->channel_layout)
+        av_channel_layout_default(&dec->ch_layout, dec->ch_layout.nb_channels);
+        if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
             return 0;
-        av_get_channel_layout_string(layout_name, sizeof(layout_name),
-                                     dec->channels, dec->channel_layout);
+        av_channel_layout_describe(&dec->ch_layout, layout_name, sizeof(layout_name));
         av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Input Stream "
                "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
     }
@@ -2160,8 +2168,7 @@  static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_ref
     switch (ifilter->ist->st->codecpar->codec_type) {
     case AVMEDIA_TYPE_AUDIO:
         need_reinit |= ifilter->sample_rate    != frame->sample_rate ||
-                       ifilter->channels       != frame->channels ||
-                       ifilter->channel_layout != frame->channel_layout;
+                       av_channel_layout_compare(&ifilter->ch_layout, &frame->ch_layout);
         break;
     case AVMEDIA_TYPE_VIDEO:
         need_reinit |= ifilter->width  != frame->width ||
@@ -2241,8 +2248,11 @@  static int ifilter_send_eof(InputFilter *ifilter, int64_t pts)
             return ret;
     } else {
         // the filtergraph was never configured
-        if (ifilter->format < 0)
-            ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
+        if (ifilter->format < 0) {
+            ret = ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
+            if (ret < 0)
+                return ret;
+        }
         if (ifilter->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO)) {
             av_log(NULL, AV_LOG_ERROR, "Cannot determine format of input stream %d:%d after EOF\n", ifilter->ist->file_index, ifilter->ist->st->index);
             return AVERROR_INVALIDDATA;
@@ -3316,8 +3326,9 @@  static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
     case AVMEDIA_TYPE_AUDIO:
         enc_ctx->sample_fmt     = av_buffersink_get_format(ost->filter->filter);
         enc_ctx->sample_rate    = av_buffersink_get_sample_rate(ost->filter->filter);
-        enc_ctx->channel_layout = av_buffersink_get_channel_layout(ost->filter->filter);
-        enc_ctx->channels       = av_buffersink_get_channels(ost->filter->filter);
+        ret = av_buffersink_get_ch_layout(ost->filter->filter, &enc_ctx->ch_layout);
+        if (ret < 0)
+            return ret;
 
         if (ost->bits_per_raw_sample)
             enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample;
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 9b200b806a..75f6f9ef72 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -250,8 +250,7 @@  typedef struct InputFilter {
     AVRational sample_aspect_ratio;
 
     int sample_rate;
-    int channels;
-    uint64_t channel_layout;
+    AVChannelLayout ch_layout;
 
     AVBufferRef *hw_frames_ctx;
     int32_t *displaymatrix;
@@ -274,12 +273,12 @@  typedef struct OutputFilter {
     AVRational frame_rate;
     int format;
     int sample_rate;
-    uint64_t channel_layout;
+    AVChannelLayout ch_layout;
 
     // those are only set if no format is specified and the encoder gives us multiple options
     // They point directly to the relevant lists of the encoder.
     const int *formats;
-    const uint64_t *channel_layouts;
+    const AVChannelLayout *ch_layouts;
     const int *sample_rates;
 } OutputFilter;
 
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 1f6cba2c04..b096196135 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -153,8 +153,29 @@  DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
 DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
                   "%d", )
 
-DEF_CHOOSE_FORMAT(channel_layouts, uint64_t, channel_layout, channel_layouts, 0,
-                  "0x%"PRIx64, )
+static void choose_channel_layouts(OutputFilter *ofilter, AVBPrint *bprint)
+{
+    AVBPrint bp;
+
+    av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
+    if (av_channel_layout_check(&ofilter->ch_layout)) {
+        av_channel_layout_describe_bprint(&ofilter->ch_layout, &bp);
+        av_bprintf(bprint, "channel_layouts=%s", bp.str);
+    } else if (ofilter->ch_layouts) {
+        const AVChannelLayout *p;
+
+        av_bprintf(bprint, "channel_layouts=");
+        for (p = ofilter->ch_layouts; p->nb_channels; p++) {
+            av_channel_layout_describe_bprint(p, &bp);
+            av_bprintf(bprint, "%s|", bp.str);
+        }
+        if (bprint->len > 0)
+            bprint->str[--bprint->len] = '\0';
+    } else
+        return;
+    av_bprint_finalize(&bp, NULL);
+    av_bprint_chars(bprint, ':', 1);
+}
 
 int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
 {
@@ -541,9 +562,11 @@  static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
 } while (0)
     av_bprint_init(&args, 0, AV_BPRINT_SIZE_UNLIMITED);
     if (ost->audio_channels_mapped) {
+        AVChannelLayout mapped_layout = { 0 };
         int i;
-        av_bprintf(&args, "0x%"PRIx64,
-                   av_get_default_channel_layout(ost->audio_channels_mapped));
+        av_channel_layout_default(&mapped_layout, ost->audio_channels_mapped);
+        av_bprintf(&args, "0x%"PRIx64, mapped_layout.order == AV_CHANNEL_ORDER_NATIVE ?
+                                       mapped_layout.u.mask : 0);
         for (i = 0; i < ost->audio_channels_mapped; i++)
             if (ost->audio_channels_map[i] != -1)
                 av_bprintf(&args, "|c%d=c%d", i, ost->audio_channels_map[i]);
@@ -552,8 +575,8 @@  static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
         av_bprint_clear(&args);
     }
 
-    if (codec->channels && !codec->channel_layout)
-        codec->channel_layout = av_get_default_channel_layout(codec->channels);
+    if (codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
+        av_channel_layout_default(&codec->ch_layout, codec->ch_layout.nb_channels);
 
     choose_sample_fmts(ofilter,     &args);
     choose_sample_rates(ofilter,    &args);
@@ -832,11 +855,11 @@  static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
              1, ifilter->sample_rate,
              ifilter->sample_rate,
              av_get_sample_fmt_name(ifilter->format));
-    if (ifilter->channel_layout)
+    if (av_channel_layout_check(&ifilter->ch_layout) && ifilter->ch_layout.order == AV_CHANNEL_ORDER_NATIVE)
         av_bprintf(&args, ":channel_layout=0x%"PRIx64,
-                   ifilter->channel_layout);
+                   ifilter->ch_layout.u.mask);
     else
-        av_bprintf(&args, ":channels=%d", ifilter->channels);
+        av_bprintf(&args, ":channels=%d", ifilter->ch_layout.nb_channels);
     snprintf(name, sizeof(name), "graph_%d_in_%d_%d", fg->index,
              ist->file_index, ist->st->index);
 
@@ -1084,7 +1107,10 @@  int configure_filtergraph(FilterGraph *fg)
         ofilter->height = av_buffersink_get_h(sink);
 
         ofilter->sample_rate    = av_buffersink_get_sample_rate(sink);
-        ofilter->channel_layout = av_buffersink_get_channel_layout(sink);
+        av_channel_layout_uninit(&ofilter->ch_layout);
+        ret = av_buffersink_get_ch_layout(sink, &ofilter->ch_layout);
+        if (ret < 0)
+            goto fail;
     }
 
     fg->reconfiguration = 1;
@@ -1148,6 +1174,7 @@  fail:
 int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
 {
     AVFrameSideData *sd;
+    int ret;
 
     av_buffer_unref(&ifilter->hw_frames_ctx);
 
@@ -1158,8 +1185,9 @@  int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
     ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
 
     ifilter->sample_rate         = frame->sample_rate;
-    ifilter->channels            = frame->channels;
-    ifilter->channel_layout      = frame->channel_layout;
+    ret = av_channel_layout_copy(&ifilter->ch_layout, &frame->ch_layout);
+    if (ret < 0)
+        return ret;
 
     av_freep(&ifilter->displaymatrix);
     sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 9c820ab73f..0eb2c779f2 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -507,7 +507,7 @@  static int opt_map_channel(void *optctx, const char *opt, const char *arg)
     /* allow trailing ? to map_channel */
     if (allow_unused = strchr(mapchan, '?'))
         *allow_unused = 0;
-    if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->channels ||
+    if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->ch_layout.nb_channels ||
         input_streams[input_files[m->file_idx]->ist_index + m->stream_idx]->user_set_discard == AVDISCARD_ALL) {
         if (allow_unused) {
             av_log(NULL, AV_LOG_VERBOSE, "mapchan: invalid audio channel #%d.%d.%d\n",
@@ -1954,9 +1954,14 @@  static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, in
     MATCH_PER_STREAM_OPT(filters,        str, ost->filters,        oc, st);
 
     if (!ost->stream_copy) {
+        int channels = 0;
         char *sample_fmt = NULL;
 
-        MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
+        MATCH_PER_STREAM_OPT(audio_channels, i, channels, oc, st);
+        if (channels) {
+            audio_enc->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+            audio_enc->ch_layout.nb_channels = channels;
+        }
 
         MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
         if (sample_fmt &&
@@ -2378,7 +2383,7 @@  static int open_output_file(OptionsContext *o, const char *filename)
                 for (i = 0; i < ifile->nb_streams; i++) {
                     int score;
                     ist = input_streams[ifile->ist_index + i];
-                    score = ist->st->codecpar->channels
+                    score = ist->st->codecpar->ch_layout.nb_channels
                             + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
                             + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
                     if (ist->user_set_discard == AVDISCARD_ALL)
@@ -2651,10 +2656,10 @@  loop_end:
                 } else {
                     f->sample_rates = ost->enc->supported_samplerates;
                 }
-                if (ost->enc_ctx->channels) {
-                    f->channel_layout = av_get_default_channel_layout(ost->enc_ctx->channels);
-                } else {
-                    f->channel_layouts = ost->enc->channel_layouts;
+                if (ost->enc_ctx->ch_layout.nb_channels) {
+                    av_channel_layout_default(&f->ch_layout, ost->enc_ctx->ch_layout.nb_channels);
+                } else if (ost->enc->ch_layouts) {
+                    f->ch_layouts = ost->enc->ch_layouts;
                 }
                 break;
             }
@@ -3237,6 +3242,41 @@  static int opt_timecode(void *optctx, const char *opt, const char *arg)
     return ret;
 }
 
+static int opt_ch_layout(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    char layout_str[32];
+    char *stream_str;
+    char *ac_str;
+    int ret, ac_str_size;
+    AVChannelLayout layout = { 0 };
+
+    ret = av_channel_layout_from_string(&layout, arg);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
+        return AVERROR(EINVAL);
+    }
+    ret = opt_default_new(o, opt, arg);
+    if (ret < 0)
+        return ret;
+
+    /* set 'ac' option based on channel layout */
+    snprintf(layout_str, sizeof(layout_str), "%d", layout.nb_channels);
+    stream_str = strchr(opt, ':');
+    ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
+    ac_str = av_mallocz(ac_str_size);
+    if (!ac_str)
+        return AVERROR(ENOMEM);
+    av_strlcpy(ac_str, "ac", 3);
+    if (stream_str)
+        av_strlcat(ac_str, stream_str, ac_str_size);
+    ret = parse_option(o, ac_str, layout_str, options);
+    av_free(ac_str);
+
+    return ret;
+}
+
+#if FF_API_OLD_CHANNEL_LAYOUT
 static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
 {
     OptionsContext *o = optctx;
@@ -3272,6 +3312,7 @@  static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
 
     return ret;
 }
+#endif
 
 static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
 {
@@ -3818,9 +3859,14 @@  const OptionDef options[] = {
     { "sample_fmt",     OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC |
                         OPT_STRING | OPT_INPUT | OPT_OUTPUT,                       { .off = OFFSET(sample_fmts) },
         "set sample format", "format" },
+    { "ch_layout",      OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE |
+                        OPT_INPUT | OPT_OUTPUT,                                    { .func_arg = opt_ch_layout },
+        "set channel layout", "layout" },
+#if FF_API_OLD_CHANNEL_LAYOUT
     { "channel_layout", OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE |
                         OPT_INPUT | OPT_OUTPUT,                                    { .func_arg = opt_channel_layout },
-        "set channel layout", "layout" },
+        "deprecated, use -ch_layout", "layout" },
+#endif
     { "af",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_filters },
         "set audio filters", "filter_graph" },
     { "guess_layout_max", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC | OPT_EXPERT | OPT_INPUT, { .off = OFFSET(guess_layout_max) },
diff --git a/tests/fate/aac.mak b/tests/fate/aac.mak
index 1743428f54..d8750b093a 100644
--- a/tests/fate/aac.mak
+++ b/tests/fate/aac.mak
@@ -237,7 +237,7 @@  fate-aac-latm_000000001180bc60: CMD = pcm -i $(TARGET_SAMPLES)/aac/latm_00000000
 fate-aac-latm_000000001180bc60: REF = $(SAMPLES)/aac/latm_000000001180bc60.s16
 
 FATE_AAC_LATM += fate-aac-latm_stereo_to_51
-fate-aac-latm_stereo_to_51: CMD = pcm -i $(TARGET_SAMPLES)/aac/latm_stereo_to_51.ts -channel_layout 5.1
+fate-aac-latm_stereo_to_51: CMD = pcm -i $(TARGET_SAMPLES)/aac/latm_stereo_to_51.ts -ch_layout 5.1
 fate-aac-latm_stereo_to_51: REF = $(SAMPLES)/aac/latm_stereo_to_51_ref.s16
 
 fate-aac-autobsf-adtstoasc: CMD = transcode "aac" $(TARGET_SAMPLES)/audiomatch/tones_afconvert_16000_mono_aac_lc.adts \
diff --git a/tests/fate/lavf-container.mak b/tests/fate/lavf-container.mak
index 9e0eed4851..446a0cfbe2 100644
--- a/tests/fate/lavf-container.mak
+++ b/tests/fate/lavf-container.mak
@@ -26,7 +26,7 @@  $(FATE_LAVF_CONTAINER): $(AREF) $(VREF)
 
 fate-lavf-asf: CMD = lavf_container "" "-c:a mp2 -ar 44100" "-r 25"
 fate-lavf-avi fate-lavf-nut: CMD = lavf_container "" "-c:a mp2 -ar 44100 -threads 1"
-fate-lavf-dv:  CMD = lavf_container "-ar 48000 -channel_layout stereo" "-r 25 -s pal"
+fate-lavf-dv:  CMD = lavf_container "-ar 48000 -ch_layout stereo" "-r 25 -s pal"
 fate-lavf-dv_pal:  CMD = lavf_container_timecode_nodrop "-ar 48000 -r 25 -s pal -ac 2 -f dv"
 fate-lavf-dv_ntsc:  CMD = lavf_container_timecode_drop "-ar 48000 -pix_fmt yuv411p -s ntsc -ac 2 -f dv"
 fate-lavf-flv fate-lavf-swf: CMD = lavf_container "" "-an"