[FFmpeg-trac] #958(avformat:new): matroska seek problem file (3 bugs)

FFmpeg trac at avcodec.org
Mon Jan 30 20:42:53 CET 2012


#958: matroska seek problem file (3 bugs)
----------------------------------+---------------------------------------
             Reporter:  DonMoir   |                     Type:  defect
               Status:  new       |                 Priority:  normal
            Component:  avformat  |                  Version:  unspecified
             Keywords:            |               Blocked By:
             Blocking:            |  Reproduced by developer:  0
Analyzed by developer:  0         |
----------------------------------+---------------------------------------
 In reference to libavformat/matroskadec.c

 Mostly, when you seek on a matroska file, matroska_read_seek will create
 an index table that is appropriate for seeking. With this particular file
 it does not create the index table.

 http://sms.pangolin.com/temp/bad_seek_h264_inf-rtwm_sample.zip

 Handling the creation of the seek index table is done with first 3 lines
 of code in matroska_read_seek (Parse the CUES). This is just done once on
 the first seek.


 {{{
 static int matroska_read_seek(AVFormatContext *s, int stream_index,
                               int64_t timestamp, int flags)
 {
     .....
     /* Parse the CUES now since we need the index data to seek. */
     if (matroska->cues_parsing_deferred) {
         matroska_parse_cues(matroska);
         matroska->cues_parsing_deferred = 0;
     }

     if (!st->nb_index_entries)
         return 0;
     ....
 }
 }}}

 matroska_parse_cues calls matroska_parse_seekhead_entry which ends up
 calling ebml_parse. ebml_parse calls ebml_read_num which fails because
 avio_r8(pb) returns 0.


 {{{
 static int ebml_read_num(MatroskaDemuxContext *matroska, AVIOContext *pb,
                          int max_size, uint64_t *number)
 {
     int read = 1, n = 1;
     uint64_t total = 0;

     ....

     /* The first byte tells us the length in bytes - avio_r8() can
 normally
      * return 0, but since that's not a valid first ebmlID byte, we can
      * use it safely here to catch EOS. */
     if (!(total = avio_r8(pb))) {
         /* we might encounter EOS here */
         if (!url_feof(pb)) {
             int64_t pos = avio_tell(pb);
             av_log(matroska->ctx, AV_LOG_ERROR,
                    "Read error at pos. %"PRIu64" (0x%"PRIx64")\n",
                    pos, pos);
         }
         return AVERROR(EIO); /* EOS or actual I/O error */
     }
     ....
 }
 }}}

 '''(bug 1)''' Since it thinks if failed, no index entries will be built,
 but 0 appears to be a valid return value for this particular file. If I
 just let it proceed with total == 0, it creates the index entries
 normally. So I believe this is a bug in the way it's checking for 0 here
 and failing because of it.

 Also note this code in matroska_read_seek:


 {{{
     if (!st->nb_index_entries)
         return 0;
 }}}


 '''(bug 2)''' If that code is executed, no seeking has been done, yet it
 returns 0 instead of -1. A 0 return value for read_seek means success and
 -1 means failure. I have not run into a case where this is a problem
 though because all the files I have, have a least one index_entry. But
 this is also a bug I believe.

 ffmpeg -ss gives no useful results. There are no errors reported. (It does
 get a read error at very end but it's not relevant to the problem)

 ffplay is the best way for you to see the problem because we know it
 doesn't do any special handling and just calls avformat_seek_file and uses
 the results of that.

 If you use:

 ffplay -ss 24 bad_seek_h264_inf-rtwm_sample.mkv

 You will notice it always starts from the beginning. This is because
 matroska_read_seek has failed to create the index entries for the above
 file.

 This is kind of a tough work around to deal with. I have to be able to
 recognize the problem and then create the index entries using a read
 packet method if the problem exist. You don't want to have to do this.
 It's a pain to recognize but mostly the read packet method is slower. If I
 do recognize there is a problem, 2 seeks may be required instead of one.

 Make sure you use ffplay to test it. Other programs may do some
 preprocessing and that will change the results.

 The following doesn't show much in the way of useful results. No errors
 etc. '''(bug 3)''' But you can see it has 5.1 audio and as a side note
 ffplay/SDL fails to play back the center speech channel on my machine.
 That is, it does not convert the 5.1 to stereo correctly.

 ffplay -ss 24 bad_seek_h264_inf-rtwm_sample.mkv

 ffplay version N-37063-g14d94a1 Copyright (c) 2003-2012 the FFmpeg
 developers
   built on Jan 23 2012 17:40:00 with gcc 4.6.2
   configuration:
   --disable-static --enable-shared --enable-gpl --enable-version3
   --disable-w32threads --enable-runtime-cpudetect --enable-avisynth
   --enable-bzlib --enable-frei0r --enable-libopencore-amrnb
   --enable-libopencore-amrwb --enable-libfreetype --enable-libgsm
   --enable-libmp3lame --enable-libopenjpeg --enable-librtmp
   --enable-libschroedinger --enable-libspeex --enable-libtheora
   --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis
   --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid
   --enable-zlib
   libavutil      51. 34.101 / 51. 34.101
   libavcodec     53. 57.105 / 53. 57.105
   libavformat    53. 30.100 / 53. 30.100
   libavdevice    53.  4.100 / 53.  4.100
   libavfilter     2. 59.101 /  2. 59.101
   libswscale      2.  1.100 /  2.  1.100
   libswresample   0.  6.100 /  0.  6.100
   libpostproc    52.  0.100 / 52.  0.100
 Input #0, matroska,webm, from 'c:\flashfiles\movies\bad_seek_h264_inf-
 rtwm_sample.mkv':
   Duration: 00:01:04.77, start: 0.000000, bitrate: 6406 kb/s
     Stream #0:0: Video: h264 (High), yuv420p, 1280x528, SAR 1:1 DAR 80:33,
 23.98
  fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
     Stream #0:1(eng): Audio: dts (DTS), 48000 Hz, 5.1(side), s16, 1536
 kb/s (default)
     Stream #0:2(eng): Subtitle: text (default)
   12.76 A-V: -0.001 fd=  44 aq=  320KB vq= 1058KB sq=    0B f=0/0   f=0/0

-- 
Ticket URL: <https://ffmpeg.org/trac/ffmpeg/ticket/958>
FFmpeg <http://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list