static void check_index_entries ( // Creates the index_entries prior to seeking if needbe. The usage of // av_read_frame is just going to cycle back to ogg_read_packet and so // av_read_frame could be changed to ogg_read_packet which would be more // appropriate. I use this same code at a higher level and reason for // av_read_frame - don moir. AVFormatContext *pFmtCtx, uint32_t streamIndex, int64_t timestamp) { AVPacket packet; AVStream* pStream; if (pFmtCtx == NULL || streamIndex >= pFmtCtx->nb_streams) return; pStream = pFmtCtx->streams [streamIndex]; if (pStream->nb_index_entries) { int64_t lastKnownTime = pStream->index_entries [pStream->nb_index_entries - 1].timestamp; if (lastKnownTime >= timestamp) return; // I am assuming we don't need to seek to the lastKnownTime to start reading because // the file position will be before here or past it. If it is past it then the entry // would have already been created and we would not be here :) This may require a // little more thought but this doesn't hurt anything. } for (;;) { if (av_read_frame (pFmtCtx,&packet)) break; if (packet.stream_index == streamIndex) { int64_t pts = packet.dts == AV_NOPTS_VALUE ? packet.pts : packet.dts; if (pts >= timestamp) { av_free_packet (&packet); break; } } av_free_packet (&packet); } } static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { struct ogg *ogg = s->priv_data; struct ogg_stream *os = ogg->streams + stream_index; int ret; // added check for index_entries - this is normal for most decoders - don moir if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO && !((flags & AVSEEK_FLAG_FRAME) || (flags & AVSEEK_FLAG_BYTE))) check_index_entries (s,(uint32_t)stream_index,timestamp); // Try seeking to a keyframe first. If this fails (very possible), // av_seek_frame will fall back to ignoring keyframes if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO && !(flags & AVSEEK_FLAG_ANY)) os->keyframe_seek = 1; ret = ff_seek_frame_binary(s, stream_index, timestamp, flags); os = ogg->streams + stream_index; if (ret < 0) os->keyframe_seek = 0; else // added - don moir { // clear the lastpts and lastdts for all ogg streams. This seems to be // the most appropriate thing to do since the seek effects all streams. // Could be need to do this even if ret < 0. int i; for (i = 0; i < ogg->nstreams; i++) ogg->streams[i].lastpts = ogg->streams[i].lastdts = AV_NOPTS_VALUE; } return ret; }