[FFmpeg-trac] #941(avformat:new): Seek problems with ogg decoder

FFmpeg trac at avcodec.org
Thu Jan 26 23:05:08 CET 2012


#941: Seek problems with ogg decoder
----------------------------------+---------------------------------------
             Reporter:  DonMoir   |                     Type:  defect
               Status:  new       |                 Priority:  normal
            Component:  avformat  |                  Version:  unspecified
             Keywords:            |               Blocked By:
             Blocking:            |  Reproduced by developer:  0
Analyzed by developer:  0         |
----------------------------------+---------------------------------------
 ffmpeg-git-14d94a1
   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

 There seems to be several problems with seeking in the ogg decoder
 (libavformat/oggdec.c)

 This file can be used to identify some of the key problems:

 http://sms.pangolin.com/temp/bad_seek_ogg_BuckBunny.zip (46 mb)

 There are no issues with playback of this file and only seeking is a
 problem. Fails to seek properly with SMPlayer, ffplay, and anything else
 using ffmpeg unless special handling is applied.

 In reference to the function ogg_read_seek in file oggdec.c.

 1) I see it makes no attempt to create (if needbe) the AVIndexEntry table
 for the stream which is pretty much required to make seeking work. Most of
 the other formats do this when you call it's read_seek function. So I find
 that I need to create this table prior to calling avformat_seek_file for
 ogg files. This table can be created by calling av_read_packet until the
 timestamp of interest is reached. This is pretty quick but it should only
 be done when needbe. Other formats have other and quicker means to do
 this, but the read packet method works well enough if nothing else is
 available. For ogg files, once I know that the index_entries have been
 created as best they are going to be, I then call
 av_index_search_timestamp(pStream,timestamp,AVSEEK_FLAG_BACKWARD) and I
 use the timestamp associated with the returned index for my seek time. The
 AVSEEK_FLAG_BACKWARD flag makes sure the returned timestamp will be less
 than or equal to my requested timestamp. If -1 is returned form
 av_index_search_timestamp I deal with it but this should not happen if the
 index_entries have been built and all else is good. Now we can call
 avformat_seek_file with the modified timestamp and expect reasonable
 results. If you don't do this read_timestamp will fail in
 ff_seek_frame_binary which is called from ogg_read_seek. Note that
 av_index_search_timestamp is also pretty much worthless for ogg files if
 the index_entries have not been created.

 2) ogg_read_seek does not do the proper cleanup after a seek. That is,
 there is stale information left that was in place prior to a seek. The ogg
 decoder uses private data that it places in AVFormatContext.priv_data.
 This is known to ogg as struct ogg*. Within this structure, ogg also has
 information for each stream. This is known to ogg as struct ogg_stream*.
 The stale information that I know about within the ogg_stream is lastpts
 and lastdts. These are not modified by a seek and whatever was in there
 before the seek will be used after a seek and these values will be used by
 the next av_read_packet. After a seek, I am having to call ogg_reset (also
 in oggdec.c) but this is clearly not the right thing to do. This ogg_reset
 is not available to higher level code but I have it hacked in for the
 present. The packet now will contain AV_NOPTS_VALUE for the pts and dts
 and this is not right either, but at least I can deal with it. Additional
 packet reads straighten this out. The lastdts and lastpts should of course
 reflect the next packet that is read. Not really sure how to clean it all
 up after a seek to make sure all is normal for ogg files. All the other
 decoders I have tested do this correctly. I think more needs to be cleaned
 up in addition to lastpts and lastdts but not sure.

 With the above changes, I can now seek into the buckbunny sample
 perfectly. Would be great if someone would revisit the seek code in the
 oggdec.c file and make sure it does the right thing.

 There are some other problems with ogg but the above 2 things goes a long
 way in fixing some of them. For the most part, most of my ogg files work
 fine after the above changes, but there are still some anoying problems
 with some files. It's like the audio packets are being used to create
 index_entries for a video stream for some files and not video packets and
 so this will throw the index_entries off. So while the seek works fine, it
 may be some time before the next video frame is available but audio is
 dead on. Not sure about this one and this is just for some ogg files.

 I can provide more information and code samples if required.

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


More information about the FFmpeg-trac mailing list