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.

Just to restate this. Early seek times are going to succeed because there are some initial AVStream.index_entries in place at start up. It's all about when you try to seek past the last entry in the index_entries table which have not been created but should be in the ogg_read_seek function. So the seek failure is all about ogg_read_seek's failure to create the index_entries. If I go ahead and make sure the index_entries are created prior to calling avformat_seek_file, then seeking works fine outside of the additional clean up notes mentioned in item 2) above. Also I remap my timestamp to the one returned by av_index_search_timestamp so I make sure I know I am at the place I need to be without second quessing.

Attempting to seek inbetween one of these index_entries could possibly be the reason an incomplete frame is being produced for ticket #438 but there is probably more to this. With my own current code setup I don't see any incomplete frames, but there is still some other odd behavior with some ogg files.

Most of the decoders either create these index_entries in their read_seek function or they don't need to because they may be stored in the file. Without these index_entries seeking is going to be bad for ogg files.

I mentioned I had some other odd behavior with some ogg files. For my app this showed up as frames not displaying for some time after a seek. In other apps you will see other odd behavior like incomplete frames, audio out of sync, or just weirdness.

os->keyframe_seek needs to be set back to 0 regardless of the return value. After I changed this all the remaining problems went away and I can now seek perfect on all the ogg files I have.

In summary 3 things need to be fixed for ogg_read_seek:

1) create the index entries prior to seeking - without this seeking will be bad - hopefully someone will come up with a more efficient solution then the solution I am using.

2) make sure os->keyframe_seek is set back to 0 always and don't depend on any return value. This fixed all the remaining weirdness.

3) call ogg_reset after the seek - this is not perfect and there is something more with this but without this - the first packet read will contain stale information as mentioned above. You will still get AV_NOPTS_VALUE on the first read which is not right either. I think calling ogg_reset and setting the lastpts and lastdts in the ogg_stream may do it.

Note: I removed the code that was setting pOggStream->key_frame to 1 from the check_index_entries function above. I noticed a little strange behavior with this and it works fine without it, but check_index_entries should be optimized for ogg.

the index_entries table which have not been created but should be in the ogg_read_seek function

This is nonsense, there is no need for any index entries at that point, and your method of creating them has O(n) performance.
What happens is that FFmpeg falls back to seeking via read_timestamp, which can seek without index with O(log(n)) performance.
The problem however is that read_timestamp randomly fails due to a bug:

[ogg @ 0003B000] read_timestamp() failed in the middle

This can cause all kinds of issues like seeking completely failing or degrading to O(n*n) performance.
Worse, that bug can even for a single byte of corruption cause the Ogg demuxer to suddenly start discarding all following data from a stream for no good reason at all.
Patch to fix this bug is on the ffmpeg-devel list ([PATCH] Fix potential infinite discard loop.).

reimar, not nonsense when you have to have something that works. I had to prevent it from ever getting to read_timestamp and creating the index entries in the read_seek function follows the model of the matroska decoder. I mentioned that my method was not optimal and hopefully someone would fix it for real, but it works and thats what I needed to do to get a demo out that worked.

Hopefully, items 2) and 3) in summary for comment #5 above will be addressed as well because those are just as important epecially item 2)

I said nonsense to one specific statement, and that was claiming that index entries should be created in that function.
That is just not correct and will just cause confusion and misunderstanding about what the intention of the code is.
As to 2) and 3) they are separate issues and would be better to be reported as such.
However as far as I can tell for 2) the current code does exactly what it should and you did not say what issue you had with that.
For 3) as far as I call tell ogg_reset is always called at least when there is no index, though there might be one missing for the case where the index we look for is already in the index.

No problem reimar. I was just following the model of matroskadec.c matroska_read_seek which does create it's seek index prior to continuing. Since I am not as familiar with the code as you are, I just have to do what I can, but digging into these problems is definitely getting me more familiar :) matroska_read_seek creates it's index efficiently as far as I can tell though.

matroska_read_seek creates it's index efficiently as far as I can tell though.

It just reads the index from the file. For real-world cases that is the most efficient way (though from a pure theory standpoint it is still O(n) unless the writing application automatically culls the index which has its own issues and is generally not allowed).
I saw that your files use Ogg skeleton v4, which means that they probably contain an index, too, so you should be able to implement the same approach - however it would be a good amount of work I expect.