[FFmpeg-trac] #9621(avcodec:new): flac parser sync heuristics issue

FFmpeg trac at avcodec.org
Mon Jan 31 16:46:25 EET 2022


#9621: flac parser sync heuristics issue
-------------------------------------+-------------------------------------
             Reporter:  Mattias      |                     Type:  defect
  Wadman                             |
               Status:  new          |                 Priority:  normal
            Component:  avcodec      |                  Version:  git-
                                     |  master
             Keywords:  flac         |               Blocked By:
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
 Summary of the bug:

 Here is a flac file that decodes fine with the flac referenced decoder but
 fails with CRC error with ffmpeg. Unfortunately i can't share the whole
 original file but i've managed to cut out the first 27 frames and manually
 corrected CRCs and MD5 checksums and it fails in the same way.

 How to reproduce:
 {{{
 $ flac -t flac_validate_bug.flac

 flac 1.3.3
 Copyright (C) 2000-2009  Josh Coalson, 2011-2016  Xiph.Org Foundation
 flac comes with ABSOLUTELY NO WARRANTY.  This is free software, and you
 are
 welcome to redistribute it under certain conditions.  Type `flac' for
 details.

 flac_validate_bug.flac: ok

 ffmpeg master 2020-01-31:

 $ ./ffmpeg -v trace -i flac_validate_bug.flac -f null -
 ffmpeg version N-105439-g1530b3f566 Copyright (c) 2000-2022 the FFmpeg
 developers
   built with Apple clang version 13.0.0 (clang-1300.0.29.30)
   configuration:
   libavutil      57. 19.100 / 57. 19.100
   libavcodec     59. 20.100 / 59. 20.100
   libavformat    59. 17.101 / 59. 17.101
   libavdevice    59.  5.100 / 59.  5.100
   libavfilter     8. 26.101 /  8. 26.101
   libswscale      6.  5.100 /  6.  5.100
   libswresample   4.  4.100 /  4.  4.100
 Splitting the commandline.
 Reading option '-v' ... matched as option 'v' (set logging level) with
 argument 'trace'.
 Reading option '-i' ... matched as input url with argument
 'flac_validate_bug.flac'.
 Reading option '-f' ... matched as option 'f' (force format) with argument
 'null'.
 Reading option '-' ... matched as output url.
 Finished splitting the commandline.
 Parsing a group of options: global .
 Applying option v (set logging level) with argument trace.
 Successfully parsed a group of options.
 Parsing a group of options: input url flac_validate_bug.flac.
 Successfully parsed a group of options.
 Opening an input file: flac_validate_bug.flac.
 [NULL @ 0x7feb7b804080] Opening 'flac_validate_bug.flac' for reading
 [file @ 0x7feb7b804880] Setting default whitelist 'file,crypto,data'
 Probing flac score:100 size:2048
 [flac @ 0x7feb7b804080] Format flac probed with size=2048 and score=100
 [flac @ 0x7feb7b804080] Before avformat_find_stream_info() pos: 8238 bytes
 read:20879 seeks:0 nb_streams:1
 [flac @ 0x7feb7b804080] All info found
 [flac @ 0x7feb7b804080] stream 0: start_time: 0 duration: 2.60063
 [flac @ 0x7feb7b804080] format: start_time: 0 duration: 2.60064 (estimate
 from stream) bitrate=64 kb/s
 [flac @ 0x7feb7b804080] After avformat_find_stream_info() pos: 10286 bytes
 read:20879 seeks:0 frames:1
 Input #0, flac, from 'flac_validate_bug.flac':
   Duration: 00:00:02.60, start: 0.000000, bitrate: 64 kb/s
   Stream #0:0, 1, 1/44100: Audio: flac, 44100 Hz, stereo, s16
 Successfully opened the file.
 Parsing a group of options: output url -.
 Applying option f (force format) with argument null.
 Successfully parsed a group of options.
 Opening an output file: -.
 Successfully opened the file.
 detected 4 logical cores
 Stream mapping:
   Stream #0:0 -> #0:0 (flac (native) -> pcm_s16le (native))
 Press [q] to stop, [?] for help
 cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless
 if it occurs once at the start per stream)
     Last message repeated 4 times
 [graph_0_in_0_0 @ 0x7feb7b905b40] Setting 'time_base' to value '1/44100'
 [graph_0_in_0_0 @ 0x7feb7b905b40] Setting 'sample_rate' to value '44100'
 [graph_0_in_0_0 @ 0x7feb7b905b40] Setting 'sample_fmt' to value 's16'
 [graph_0_in_0_0 @ 0x7feb7b905b40] Setting 'channel_layout' to value '0x3'
 [graph_0_in_0_0 @ 0x7feb7b905b40] tb:1/44100 samplefmt:s16
 samplerate:44100 chlayout:0x3
 [format_out_0_0 @ 0x7feb7b9060c0] Setting 'sample_fmts' to value 's16'
 [AVFilterGraph @ 0x7feb7bb09f00] query_formats: 4 queried, 9 merged, 0
 already done, 0 delayed
 Output #0, null, to 'pipe:':
   Metadata:
     encoder         : Lavf59.17.101
   Stream #0:0, 0, 1/44100: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411
 kb/s
     Metadata:
       encoder         : Lavc59.20.100 pcm_s16le
 [NULL @ 0x7feb7b9051c0] sample/frame number mismatch in adjacent frames
 [NULL @ 0x7feb7b9051c0] crc check failed from offset 0 (frame 27) to 2027
 (frame 27)
 [flac @ 0x7feb7bb07bc0] illegal residual coding method 2
 [flac @ 0x7feb7bb07bc0] decode_frame() failed
 [flac @ 0x7feb7bb07300] invalid residual
 [flac @ 0x7feb7bb07300] decode_frame() failed
 Error while decoding stream #0:0: Invalid data found when processing input
     Last message repeated 1 times
 [null @ 0x7feb7bb04540] Application provided invalid, non monotonically
 increasing dts to muxer in stream 0: 102400 >= 32256
 [out_0_0 @ 0x7feb7b905f00] EOF on sink link out_0_0:default.
 No more output streams to write to, finishing.
 size=N/A time=00:00:02.41 bitrate=N/A speed=1.31e+03x
 video:0kB audio:432kB subtitle:0kB other streams:0kB global headers:0kB
 muxing overhead: unknown
 Input file #0 (flac_validate_bug.flac):
   Input stream #0:0 (audio): 29 packets read (12641 bytes); 27 frames
 decoded (110592 samples);
   Total: 29 packets (12641 bytes) demuxed
 Output file #0 (pipe:):
   Output stream #0:0 (audio): 27 frames encoded (110592 samples); 27
 packets muxed (442368 bytes);
   Total: 27 packets (442368 bytes) muxed
 27 frames successfully decoded, 2 decoding errors
 [AVIOContext @ 0x7feb7b804a00] Statistics: 20879 bytes read, 0 seeks
 }}}

 I think the issue is that the flac parser falsely finds a frame header
 inside the samples data of frame 26. If i use fq (disclaimer im the author
 of the tool) i can see that inside frame 26 at byte 2603 there is a bunch
 of bytes that very much looks like a flac header and seems to fool all
 current validation code checks in
 frame_header_is_valid/ff_flac_decode_frame_header and also even happens to
 have end of header bits indicating it is frame number 27.

 Here i run fq to show the header of frame 26 and also show the header when
 decoding byte 2603 and forward of frame 266 as a flac frame. I also see
 that "illegal residual coding method 2" seems to match.

 {{{
 $ fq -o line_bytes=10 '.frames[26] | ., (tobytesrange[2603:] | flac_frame)
 | (.header | d), .subframes[1].residual_coding_method'
 flac_validate_bug.flac
       │00 01 02 03 04 05 06 07 08 09│0123456789│.frames[26].header{}:
 0x2b52│            ff f8            │    ..    │  sync: 0b11111111111110
 (valid)
 0x2b52│               f8            │     .    │  reserved0: 0 (valid)
 0x2b52│               f8            │     .    │  blocking_strategy:
 "fixed" (0)
 0x2b52│                  c9         │      .   │  block_size: 4096
 (0b1100)
 0x2b52│                  c9         │      .   │  sample_rate: 44100
 (0b1001)
 0x2b52│                     18      │       .  │  channel_assignment: 2
 (1) (lr)
 0x2b52│                     18      │       .  │  sample_size: 16 (0b100)
 0x2b52│                     18      │       .  │  reserved1: 0 (valid)
       │                             │          │  end_of_header{}:
 0x2b52│                        1a   │        . │    frame_number: 26
 0x2b52│                           84│         .│  crc: 0x84 (valid)
       │00 01 02 03 04 05 06 07 08 09│0123456789│
 0x3476│   86                        │ .
 │.frames[26].subframes[1].residual_coding_method: 4 (0) (rice)
       │00 01 02 03 04 05 06 07 08 09│0123456789│.header{}:
 0x357a│                     ff f8   │       .. │  sync: 0b11111111111110
 (valid)
 0x357a│                        f8   │        . │  reserved0: 0 (valid)
 0x357a│                        f8   │        . │  blocking_strategy:
 "fixed" (0)
 0x357a│                           39│         9│  block_size: 1152 (0b11)
 0x357a│                           39│         9│  sample_rate: 44100
 (0b1001)
 0x3584│88                           │.         │  channel_assignment: 2
 (8) (left/side stereo)
       │                             │          │  side_channel_index: 1
 0x3584│88                           │.         │  sample_size: 16 (0b100)
 0x3584│88                           │.         │  reserved1: 0 (valid)
       │                             │          │  end_of_header{}:
 0x3584│   1b                        │ .        │    frame_number: 27
 0x3584│      0e                     │  .       │  crc: 0xe (valid)
       │00 01 02 03 04 05 06 07 08 09│0123456789│
 0x3944│      b1 2e                  │  ..
 │.subframes[1].residual_coding_method: 2
 }}}

 I reported and fixed a similar issue some month ago
 https://trac.ffmpeg.org/ticket/9185 but this time I haven't yet been able
 to figure what more heuristic that could be added.

 An alternative to ever increasing number of heuristics might be to
 optionally allow the flac parser and flac decoder to use
 AV_CODEC_CAP_SUBFRAMES somehow? I've done some failed attempt at bypassing
 the flac parser and let the decoder read frame by frame.
-- 
Ticket URL: <https://trac.ffmpeg.org/ticket/9621>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list