Commit 89ddd2a9 authored by Michael Niedermayer's avatar Michael Niedermayer

split av_seek_frame_binary() so the code becomes idependant of AVInputFormat and AVIndex

Originally committed as revision 7035 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 2ce92289
...@@ -445,6 +445,7 @@ int av_add_index_entry(AVStream *st, ...@@ -445,6 +445,7 @@ int av_add_index_entry(AVStream *st,
int64_t pos, int64_t timestamp, int size, int distance, int flags); int64_t pos, int64_t timestamp, int size, int distance, int flags);
int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags); int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags);
void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp); void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ));
/* media file output */ /* media file output */
int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap); int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);
......
...@@ -1163,8 +1163,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts ...@@ -1163,8 +1163,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
AVInputFormat *avif= s->iformat; AVInputFormat *avif= s->iformat;
int64_t pos_min, pos_max, pos, pos_limit; int64_t pos_min, pos_max, pos, pos_limit;
int64_t ts_min, ts_max, ts; int64_t ts_min, ts_max, ts;
int64_t start_pos, filesize; int index;
int index, no_change;
AVStream *st; AVStream *st;
if (stream_index < 0) if (stream_index < 0)
...@@ -1212,9 +1211,36 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts ...@@ -1212,9 +1211,36 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
} }
} }
pos= av_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp);
if(pos<0)
return -1;
/* do the seek */
url_fseek(&s->pb, pos, SEEK_SET);
av_update_cur_dts(s, st, ts);
return 0;
}
/**
* Does a binary search using read_timestamp().
* this isnt supposed to be called directly by a user application, but by demuxers
* @param target_ts target timestamp in the time base of the given stream
* @param stream_index stream number
*/
int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )){
int64_t pos, ts;
int64_t start_pos, filesize;
int no_change;
#ifdef DEBUG_SEEK
av_log(s, AV_LOG_DEBUG, "gen_seek: %d %"PRId64"\n", stream_index, target_ts);
#endif
if(ts_min == AV_NOPTS_VALUE){ if(ts_min == AV_NOPTS_VALUE){
pos_min = s->data_offset; pos_min = s->data_offset;
ts_min = avif->read_timestamp(s, stream_index, &pos_min, INT64_MAX); ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
if (ts_min == AV_NOPTS_VALUE) if (ts_min == AV_NOPTS_VALUE)
return -1; return -1;
} }
...@@ -1225,7 +1251,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts ...@@ -1225,7 +1251,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
pos_max = filesize - 1; pos_max = filesize - 1;
do{ do{
pos_max -= step; pos_max -= step;
ts_max = avif->read_timestamp(s, stream_index, &pos_max, pos_max + step); ts_max = read_timestamp(s, stream_index, &pos_max, pos_max + step);
step += step; step += step;
}while(ts_max == AV_NOPTS_VALUE && pos_max >= step); }while(ts_max == AV_NOPTS_VALUE && pos_max >= step);
if (ts_max == AV_NOPTS_VALUE) if (ts_max == AV_NOPTS_VALUE)
...@@ -1233,7 +1259,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts ...@@ -1233,7 +1259,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
for(;;){ for(;;){
int64_t tmp_pos= pos_max + 1; int64_t tmp_pos= pos_max + 1;
int64_t tmp_ts= avif->read_timestamp(s, stream_index, &tmp_pos, INT64_MAX); int64_t tmp_ts= read_timestamp(s, stream_index, &tmp_pos, INT64_MAX);
if(tmp_ts == AV_NOPTS_VALUE) if(tmp_ts == AV_NOPTS_VALUE)
break; break;
ts_max= tmp_ts; ts_max= tmp_ts;
...@@ -1277,7 +1303,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts ...@@ -1277,7 +1303,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
pos= pos_limit; pos= pos_limit;
start_pos= pos; start_pos= pos;
ts = avif->read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1 ts = read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1
if(pos == pos_max) if(pos == pos_max)
no_change++; no_change++;
else else
...@@ -1301,18 +1327,14 @@ av_log(s, AV_LOG_DEBUG, "%"PRId64" %"PRId64" %"PRId64" / %"PRId64" %"PRId64" %"P ...@@ -1301,18 +1327,14 @@ av_log(s, AV_LOG_DEBUG, "%"PRId64" %"PRId64" %"PRId64" / %"PRId64" %"PRId64" %"P
ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max; ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max;
#ifdef DEBUG_SEEK #ifdef DEBUG_SEEK
pos_min = pos; pos_min = pos;
ts_min = avif->read_timestamp(s, stream_index, &pos_min, INT64_MAX); ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
pos_min++; pos_min++;
ts_max = avif->read_timestamp(s, stream_index, &pos_min, INT64_MAX); ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n", av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n",
pos, ts_min, target_ts, ts_max); pos, ts_min, target_ts, ts_max);
#endif #endif
/* do the seek */ *ts_ret= ts;
url_fseek(&s->pb, pos, SEEK_SET); return pos;
av_update_cur_dts(s, st, ts);
return 0;
} }
static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){ static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment