[FFmpeg-soc] [soc]: r4315 - seek_api/mpeg.c
spyfeng
subversion at mplayerhq.hu
Tue May 26 18:56:30 CEST 2009
Author: spyfeng
Date: Tue May 26 18:56:29 2009
New Revision: 4315
Log:
use av_gen_search() to locate the seek position instead of reading key frame one by one.
Modified:
seek_api/mpeg.c
Modified: seek_api/mpeg.c
==============================================================================
--- seek_api/mpeg.c Tue May 26 16:25:35 2009 (r4314)
+++ seek_api/mpeg.c Tue May 26 18:56:29 2009 (r4315)
@@ -600,56 +600,55 @@ static int64_t mpegps_read_dts(AVFormatC
static int mpegps_read_seek(struct AVFormatContext *s, int stream_index,
int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
{
- AVStream *st = s->streams[stream_index];
- int ret, index;
- AVPacket pkt1, *pkt = &pkt1;
- AVIndexEntry *ie = st->index_entries;
- int64_t pos, pts, left_keyframe_ts, left_keyframe_pos;
+ AVStream *st;
+ int index;
+ int64_t pos, ret_ts, av_uninit(pos_min), av_uninit(pos_max), pos_limit;
- if (ts <min_ts || ts >max_ts) {
- av_log(s, AV_LOG_ERROR, "Wrong range set for target timestamp!\n");
- return -1;
- }
- if (ts < 0 || ts >= s->duration) {
- av_log(s, AV_LOG_ERROR, "Timestamp is out of bounds! timestamp=0x%"PRIx64" duration=0x%"PRIx64"\n", ts, s->duration);
- return -1;
+ if (stream_index < 0){
+ stream_index= av_find_default_stream_index(s);
+ if(stream_index < 0)
+ return -1;
}
+ st = s->streams[stream_index];
+ ts = av_rescale(ts, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);
+
if (st->discard >= AVDISCARD_ALL) {
av_log(s, AV_LOG_ERROR, "Not active stream!\n");
return -1;
}
- index = av_index_search_timestamp(st, ts, flags);
- if (index > 0) {
- if (ie[index].timestamp >= min_ts && ie[index].timestamp <= max_ts){
- url_fseek(s->pb, ie[index].pos, SEEK_SET);
- return 0;
+ if (st->nb_index_entries) {
+ index = av_index_search_timestamp(st, ts, flags);
+ if (index > 0) {
+ if (st->index_entries[index].timestamp >= min_ts && st->index_entries[index].timestamp <= max_ts){
+ url_fseek(s->pb, st->index_entries[index].pos, SEEK_SET);
+ return 0;
+ }
}
- }
- pos = url_ftell(s->pb);
- for(;;){
- ret = av_read_frame(s, pkt);
- if (ret < 0) {
- url_fseek(s->pb, pos, SEEK_SET);
- return -1;
+ index = av_index_search_timestamp(st, min_ts, 0);
+ if (index > 0) {
+ pos_min = st->index_entries[index].pos;
+ min_ts = st->index_entries[index].timestamp;
}
- pts = pkt->pts;
- av_free_packet(pkt);
-
- if (pkt->flags&PKT_FLAG_KEY) {
- if (pts < ts) {
- left_keyframe_ts = pts;
- left_keyframe_pos = pkt->pos;
- }
- else
- break;
+ index = av_index_search_timestamp(st, max_ts, AVSEEK_FLAG_BACKWARD);
+ if (index > 0) {
+ pos_max = st->index_entries[index].pos;
+ max_ts = st->index_entries[index].timestamp;
+ pos_limit = pos_max - st->index_entries[index].min_distance;
}
+ }else
+ {
+ min_ts =
+ max_ts = AV_NOPTS_VALUE;
}
- // check left_keyframe_ts and pts with ts_min and ts_max
- if (ts >= min_ts && ts <= max_ts && ts- left_keyframe_ts < pts - ts)
- url_fseek(s->pb, left_keyframe_pos, SEEK_SET);
+ pos= av_gen_search(s, stream_index, ts, pos_min, pos_max, pos_limit,
+ min_ts, max_ts, flags, &ret_ts, mpegps_read_dts);
+
+ // check return result
+ if (ret_ts >= min_ts && ret_ts <= max_ts)
+ url_fseek(s->pb, pos, SEEK_SET);
return 0;
}
More information about the FFmpeg-soc
mailing list