Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#7335 closed defect (invalid)

Low-level error in DCA XLL decode becomes ignored in dcadec.c then SWResample crashes NPX

Reported by: Heinrich Tegethoff Owned by:
Priority: normal Component: avcodec
Version: git-master Keywords: DCA
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no


Summary of the bug:

  • Input: (dca) DTS 48000 Hz, 8 ch 7.1 (s32p)
  • Call: API avcodec_receive_frame(), after avcodec_send_packet()

-> libavcodec/dca_xll.c/parse_band_data() produces and logs error "Invalid NAVI position\n"

-> parse_band_data returns AVERROR_INVALIDDATA

  • Up-stack: Caller libavcodec/dcadec.c/dcadec_decode_frame().ff_dca_xll_parse() handles AVERROR(EAGAIN), AVERROR(ENOMEM) and AV_EF_EXPLODE but ignores AVERROR_INVALIDDATA
  • Crash: 2 out of 8 planes (the XLL channels) of the "successfully" decoded frame are unassigned => the next unit in flow, the SWResampler, crashes with NPX.

ffmpeg version 4.0

built with gcc 7.3.0 (GCC)
configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --enable-sdl2 --enable-bzlib --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth
libavutil 56. 14.100 / 56. 14.100
libavcodec 58. 18.100 / 58. 18.100
libswscale 5. 1.100 / 5. 1.100
libswresample 3. 1.100 / 3. 1.100

How to reproduce:

  • own Java/JNI i/f to libavcodec et al with elementary DTS MA stream of copyrighted material
  • [SWR] FC: FL:0.160189 FR:0.160189 FC:0.226541 LFE:0.000000 BL:0.113270 BR:0.113270 SL:0.113270 SR:0.113270
    send 6760 B                   <<< pre avcodec_receive_frame 
    swr  1 1 1 1 1 1 1 1 ok       <<< SWR input planes ok/NULL
    send 4116 B                   
    #>> E  Invalid NAVI position  <<< av_log (from BUG HUNTING)
    swr  1 1 1 1 1 1 -99 -99 #    <<< ok ok ok ok ok ok NULL NULL
    # A fatal error has been detected by the Java Runtime Environment:
    #  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007fffb3ec0feb, pid=13912, tid=0x0000000000003e94
    # JRE version: Java(TM) SE Runtime Environment (8.0_162-b12) (build 1.8.0_162-b12)
    # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.162-b12 mixed mode windows-amd64 compressed oops)
    # Problematic frame:
    # C  [swresample-3.dll+0x10feb]

Patches should be submitted to the ffmpeg-devel mailing list and not this bug tracker.

Attachments (1)

DUMP.dts (1.5 MB ) - added by Heinrich Tegethoff 3 years ago.
DTS HD MA - final 4116 bytes packet fails DCA XLL

Download all attachments as: .zip

Change History (8)

comment:1 by Carl Eugen Hoyos, 3 years ago

Keywords: XLL SWResampler AVERROR_INVALIDDATA Invalid NAVI position removed

Please provide the input sample and explain how we can reproduce the issue.

by Heinrich Tegethoff, 3 years ago

Attachment: DUMP.dts added

DTS HD MA - final 4116 bytes packet fails DCA XLL

comment:2 by Heinrich Tegethoff, 3 years ago


  • Using doc/examples/decode_audio.c as starting point
    • Read attached erroneous sample (DUMP.dts)
    • av_parser_parse2 --> encoded packets with 1 DTS HD frame each
    • avcodec_send_packet --> plain send + receive mechanism
    • avcodec_receive_frame
  • Using doc/examples/resampling_audio.c for SWResampler code, which fails, but due to an unhandled error code in dcadec.c
    • av_samples_alloc (ONCE!)
    • swr_convert
  • The last packet in the attached sample audio (4116 bytes) raises dcaxll error by log message, returns error code, dcadec does not handle it, channel planes 7+8 are still NULL => SWR crashes accessing the planes.

comment:3 by Hendrik, 3 years ago

A brief look at the code suggests that the decoder properly falls back to 5.1 core decoding if the XLL layer fails to decode.

Maybe your code does not handle on-the-fly channel configuration changes? Please do verify that frame->channels or avctx->channels actually mis-matches the number of allocated channel buffer. Only then would it actually be an error.

comment:4 by Heinrich Tegethoff, 3 years ago

Yeah, my AVEncoder wrapper handles channel changes properly (TV recordings change often on movie/commercials), but my SWResampler feeder handles initial "changes" only.

frame->channels changes from 8 to 6 => I will handle it.

Suggestion: Please close ticket.

Thank you!

comment:5 by Carl Eugen Hoyos, 3 years ago

Resolution: invalid
Status: newclosed

comment:6 by Heinrich Tegethoff, 3 years ago


On the other hand ...
From a higher viewpoint the Java part handles the on-the-fly channel configuration changes well, with the assumption that a packet identified by metadata as 7.1 (et al) decodes to 8 channels, which isn't true: a channel config change for a single frame with opposite metadata is misleading; and a frame drop, replacing it with silence, is clean (the Java corrects drop errors). This would require the expected error return code.

PS: The application on top is a tool similar to Cuttermaran, based on an entirely refactored ProjectX, and handles the entire flow from media input to intro-PDF with cast&crew and cover etc.
Cuttermaran handles SD (DVD/TV) very well, while Java + FFmpeg offers HD level (BD/HDTV). Audio transcoding is required for the cutter's "preview", video transcoding for the video fragments joiner. Designed for GIANT video material backbone :-)

comment:7 by Hendrik, 3 years ago

If you don't want fallback to core decoding with DTS, you can set the explode error flag, and it'll instead return you the INVALID_DATA error.

A user might prefer hearing some audio though instead of nothing, and if you don't want to reconfigure your entire audio chain you could just add silent channels to make up for the difference.

Last edited 3 years ago by Hendrik (previous) (diff)
Note: See TracTickets for help on using tickets.