Opened 5 years ago

Last modified 5 years ago

#2282 open defect

Failed seeks lead to undefined behavior

Reported by: gjdfgh Owned by:
Priority: normal Component: avformat
Version: git-master Keywords: flac
Cc: onemda@gmail.com Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: no

Description

Play a .flac file with ffplay. Right at the start, hit the cursor-right and cursor-down key multiple times. Then ffplay prints some error messages, and the printed playback position doesn't actually match what you hear.

Specifically, it prints decoder errors after an (obviously) failed seek. This indicates a problem with demuxer behavior and/or the seek API. (And if not, it's a ffplay bug.)

On IRC, it was said that failed seeks leave the demuxer in an undefined state.

$ ffplay test.flac 
ffplay version 1.0.3 Copyright (c) 2003-2012 the FFmpeg developers
  built on Jan 24 2013 14:52:18 with gcc 4.7 (Debian 4.7.2-5)
  configuration: --prefix=/usr --extra-cflags='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security ' --extra-ldflags='-Wl,-z,relro' --cc='ccache cc' --enable-shared --enable-libmp3lame --enable-gpl --enable-nonfree --enable-libvorbis --enable-pthreads --enable-libfaac --enable-libxvid --enable-postproc --enable-x11grab --enable-libgsm --enable-libtheora --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libx264 --enable-libspeex --enable-nonfree --disable-stripping --enable-libvpx --enable-libschroedinger --disable-encoder=libschroedinger --enable-version3 --enable-libopenjpeg --enable-librtmp --enable-avfilter --enable-libfreetype --enable-libvo-aacenc --disable-decoder=amrnb --enable-libvo-amrwbenc --enable-libaacplus --libdir=/usr/lib/i386-linux-gnu --disable-vda --enable-libbluray --enable-libcdio --enable-gnutls --enable-frei0r --enable-openssl --enable-libass --enable-libopus --enable-fontconfig --enable-libdc1394 --disable-altivec --disable-armv5te --disable  libavutil      51. 73.101 / 51. 73.101
  libavcodec     54. 59.100 / 54. 59.100
  libavformat    54. 29.104 / 54. 29.104
  libavdevice    54.  2.101 / 54.  2.101
  libavfilter     3. 17.100 /  3. 17.100
  libswscale      2.  1.101 /  2.  1.101
  libswresample   0. 15.100 /  0. 15.100
  libpostproc    52.  0.100 / 52.  0.100
[flac @ 0x80e0620] max_analyze_duration 5000000 reached at 5015510
Input #0, flac, from 'test.flac':
  Metadata:
    ENCODER         : Lavf54.29.104
  Duration: 00:10:01.48, bitrate: 1186 kb/s
    Stream #0:0: Audio: flac, 44100 Hz, stereo, s16
test.flac: error while seeking=   47KB vq=    0KB sq=    0B f=0/0   
[flac @ 0x80e8a80] invalid sync codeKB vq=    0KB sq=    0B f=0/0   
[flac @ 0x80e8a80] invalid frame header
[flac @ 0x80e8a80] decode_frame() failed
[flac @ 0x80e8a80] invalid sync codeKB vq=    0KB sq=    0B f=0/0   
[flac @ 0x80e8a80] invalid frame header
[flac @ 0x80e8a80] decode_frame() failed

Change History (12)

comment:1 Changed 5 years ago by cehoyos

  • Keywords flac added

Please test current git head and please provide (or point to) a sample.

comment:2 Changed 5 years ago by gjdfgh

Current git is affected too.

You can generate a sample yourself with ffmpeg. The output I posted also indicates that it was a sample generated by ffmpeg, but I tested it with other files as well. It probably happens with all flacs.

What's worse is that ffmpeg doesn't support multiple seek commands during transcoding, making creating reproducible test cases a pain.

comment:3 Changed 5 years ago by richardpl

  • Component changed from undetermined to avformat
  • Status changed from new to open
  • Version changed from unspecified to git-master

comment:4 Changed 5 years ago by richardpl

  • Analyzed by developer set
  • Reproduced by developer set

comment:5 Changed 5 years ago by richardpl

  • Cc onemda@gmail.com added

comment:6 Changed 5 years ago by cehoyos

  • Analyzed by developer unset

comment:7 Changed 5 years ago by DonMoir

I see the same thing with an mp3 file. Also got error while seeking with flac using ffplay. In my own app both seem fine but using older build for that.

Here's result of mp3 and banging on the right arrow.

ffplay d:\flashfiles\audio\rabbit.mp3
ffplay version N-50911-g9efcfbe Copyright (c) 2003-2013 the FFmpeg developers
  built on Mar 13 2013 21:29:22 with gcc 4.7.2 (GCC)
  configuration: --disable-static --enable-shared --enable-gpl --enable-version3
 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --ena
ble-frei0r --enable-gnutls --enable-libass --enable-libbluray --enable-libcaca -
-enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmp3lame --enabl
e-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-lib
opus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspee
x --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-am
rwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --en
able-libxvid --enable-zlib
  libavutil      52. 19.100 / 52. 19.100
  libavcodec     55.  0.100 / 55.  0.100
  libavformat    55.  0.100 / 55.  0.100
  libavdevice    54.  4.100 / 54.  4.100
  libavfilter     3. 45.103 /  3. 45.103
  libswscale      2.  2.100 /  2.  2.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
[mp3 @ 00b45720] max_analyze_duration 5000000 reached at 5015510 microseconds
[mp3 @ 00b45720] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from 'd:\flashfiles\audio\rabbit.mp3':
  Metadata:
    track           : 10
    TLEN            : 153106
    artist          : jefferson airplane
    album           : surrealistic pillow
    title           : white rabbit
    date            : 1967
  Duration: 00:02:33.05, start: 0.000000, bitrate: 256 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 256 kb/s
d:\flashfiles\audio\rabbit.mp3: error while seekingq=    0B f=0/0
    d:\nanf lA-ashfV:i  l0.es\audio\rabbit.mp3: error while seeking000 fd
d:\flashfiles\audio\rabbit.mp3: error while seekingq=    0B f=0/0
    nan A-V:  0.000 fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0

comment:8 follow-up: Changed 5 years ago by richardpl

  • Analyzed by developer set

comment:9 in reply to: ↑ 8 Changed 5 years ago by Cigaes

Replying to richardpl:

Analyzed by developer set

Care to elaborate? Do you intend to fix the bug and submit a patch? To publish this developer's analysis?

comment:10 Changed 5 years ago by richardpl

Analysis results: implementation is flawed. Ask on irc for extremely boring elaboration.

comment:11 Changed 5 years ago by cehoyos

  • Analyzed by developer unset

comment:12 Changed 5 years ago by gjdfgh

MiNi? said himself that the state after seeking failure is undefined. That was a month ago.

By the way, I suggest the following semantics for seeking failure:

  • If the seek is to a position before the start of a file, do not return failure, and seek to the start of the file. The new (defined) state is that the demuxer returns packets from begin of the file normally. Note that seeks can be quite imprecise, and the new position you get is not always the position you requested, so this won't be an API change.
  • If the seek is to a position past the end of the file, do not return failure. Instead, behave as if the end of the file has been reached. I think this simply means returning no packets for the next av_read_frame().
  • If the seek actually fails (seek index broken, I/O errors), return failure, but do not change the state. Continue to demux from the old position. This means the application won't resets its decoders and can continue to play the file normally.
  • This means the application has to reset its decoders if seeking returns success, but shouldn't do it if seeking fails.

Alternatively, return exact error codes that identify all these cases. But only if it actually works with all demuxers.

Note: See TracTickets for help on using tickets.