Opened 2 years ago

Last modified 2 years ago

#4904 new defect

Broken vp9 decoding after failed seek in webm file

Reported by: cehoyos Owned by:
Priority: normal Component: undetermined
Version: git-master Keywords: mkv vp9 seek
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

(Sample from videolan ticket 15433)
A vlc user has uploaded a webm vp9 sample that does not allow seeking with ffplay. If I try to seek forward ten seconds immediately after starting playback, the file continues to play for 66 seconds, then video gets broken and does not recover. I was unable to reproduce with ffmpeg.

$ ffplay TestClip\ webm.webm.webm
ffplay version N-75722-g32a6d37 Copyright (c) 2003-2015 the FFmpeg developers
  built with gcc 4.7 (SUSE Linux)
  configuration: --enable-gpl
  libavutil      55.  2.100 / 55.  2.100
  libavcodec     57.  4.101 / 57.  4.101
  libavformat    57.  2.102 / 57.  2.102
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6.  9.101 /  6.  9.101
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.100 /  2.  0.100
  libpostproc    54.  0.100 / 54.  0.100
Input #0, matroska,webm, from 'TestClip webm.webm.webm': 0B f=0/0
  Metadata:
    encoder         : Lavf56.40.101
  Duration: 00:03:01.29, start: 0.007000, bitrate: 1722 kb/s
    Stream #0:0: Video: vp9 (Profile 0), yuv420p(tv), 1920x1080, SAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn, 1k tbc (default)
    Stream #0:1(eng): Audio: opus, 48000 Hz, 5.1, fltp (default)
    Stream #0:2(eng): Subtitle: webvtt (default)
[matroska,webm @ 0x7fd45c000920] seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, 1002 non keyframes found
[matroska,webm @ 0x7fd45c000920] seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, 1002 non keyframes found
TestClip webm.webm.webm: error while seeking
  40.38 A-V:  0.006 fd=   1 aq= 3148KB vq=12213KB sq=    0B

The timecounter shows that FFplay seeks back after playing for 66 seconds which fails badly.

With a different configure line, the issue gets much easier to reproduce: Seeking forward produces nearly immediately broken video:

$ ffplay TestClip\ webm.webm.webm
ffplay version N-75722-g32a6d37 Copyright (c) 2003-2015 the FFmpeg developers
  built with gcc 4.7 (SUSE Linux)
  configuration: --disable-everything --disable-vdpau --disable-network --enable-protocol=file --enable-demuxer=matroska --enable-libopus --enable-decoder='vp9,opus' --enable-parser=vp9 --enable-filter=aresample
  libavutil      55.  2.100 / 55.  2.100
  libavcodec     57.  4.100 / 57.  4.100
  libavformat    57.  2.102 / 57.  2.102
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6.  9.101 /  6.  9.101
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.100 /  2.  0.100
Input #0, matroska,webm, from 'TestClip webm.webm.webm': 0B f=0/0
  Metadata:
    encoder         : Lavf56.40.101
  Duration: 00:03:01.29, start: 0.007000, bitrate: 1722 kb/s
    Stream #0:0: Video: vp9 (Profile 0), yuv420p(tv), 1920x1080, SAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn, 1k tbc (default)
    Stream #0:1(eng): Audio: opus, 48000 Hz, 5.1, fltp (default)
    Stream #0:2(eng): Subtitle: webvtt (default)
No codec could be found with id 96265
[matroska,webm @ 0x7fb258000920] seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, 1002 non keyframes found
[matroska,webm @ 0x7fb258000920] seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, 1002 non keyframes found
TestClip webm.webm.webm: error while seeking
  40.12 A-V: -0.001 fd=   1 aq=   69KB vq=  188KB sq=    0B

Change History (3)

comment:2 Changed 2 years ago by gjdfgh

What happens after a failed seek is essentially not defined in libavformat. I've complained a lot about this in the past. I suggest closing as WONTFIX.

comment:3 Changed 2 years ago by gjdfgh

Looking at this closer...

  • the file has only 1 index entry for video, pointing to the first packet
  • the video could indeed have only 1 keyframe (didn't check)
  • libavformat's demuxer "gives up" and does an *incorrect* seek (probably a fix for other broken files produced by lavf, I seem to remember a specific one)
  • the incorrect seek of course confuses the decoder, because the decoder only gets midstream packets
  • the correct behavior is seeking to the correct index entry, and decoding the video until the seek target is reached

The latter is confirmed to work with lavfilters and mpv.

Note: See TracTickets for help on using tickets.