aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-07-06 21:52:07 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-07-06 22:27:35 +0200
commit8ca5d277d8a8e31365b0e9609114738db26bbc6a (patch)
treeea102d2f4743acff257da8099fed2fb245df341e
parentd64f3b72e0eaec2933b5283b676272c678b28e79 (diff)
downloadffmpeg-8ca5d277d8a8e31365b0e9609114738db26bbc6a.tar.gz
avformat/utils: factor ff_find_last_ts() out of ff_gen_search()
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavformat/internal.h3
-rw-r--r--libavformat/utils.c63
2 files changed, 42 insertions, 24 deletions
diff --git a/libavformat/internal.h b/libavformat/internal.h
index ee66e8c04e..1f74069bcc 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -242,6 +242,9 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index,
*/
void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
+int ff_find_last_ts(AVFormatContext *s, int stream_index, int64_t *ts, int64_t *pos,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ));
+
/**
* Perform a binary search using read_timestamp().
*
diff --git a/libavformat/utils.c b/libavformat/utils.c
index f7822eeec7..6acc7c848c 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1745,14 +1745,50 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
return 0;
}
+int ff_find_last_ts(AVFormatContext *s, int stream_index, int64_t *ts, int64_t *pos,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
+{
+ int64_t step= 1024;
+ int64_t limit, ts_max;
+ int64_t filesize = avio_size(s->pb);
+ int64_t pos_max = filesize - 1;
+ do{
+ limit = pos_max;
+ pos_max = FFMAX(0, (pos_max) - step);
+ ts_max = ff_read_timestamp(s, stream_index, &pos_max, limit, read_timestamp);
+ step += step;
+ }while(ts_max == AV_NOPTS_VALUE && 2*limit > step);
+ if (ts_max == AV_NOPTS_VALUE)
+ return -1;
+
+ for(;;){
+ int64_t tmp_pos = pos_max + 1;
+ int64_t tmp_ts = ff_read_timestamp(s, stream_index, &tmp_pos, INT64_MAX, read_timestamp);
+ if(tmp_ts == AV_NOPTS_VALUE)
+ break;
+ ts_max = tmp_ts;
+ pos_max = tmp_pos;
+ if(tmp_pos >= filesize)
+ break;
+ }
+
+ if (ts)
+ *ts = ts_max;
+ if (pos)
+ *pos = pos_max;
+
+ return 0;
+}
+
int64_t ff_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;
+ int64_t start_pos;
int no_change;
+ int ret;
av_dlog(s, "gen_seek: %d %s\n", stream_index, av_ts2str(target_ts));
@@ -1769,29 +1805,8 @@ int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
}
if(ts_max == AV_NOPTS_VALUE){
- int64_t step= 1024;
- int64_t limit;
- filesize = avio_size(s->pb);
- pos_max = filesize - 1;
- do{
- limit = pos_max;
- pos_max = FFMAX(0, pos_max - step);
- ts_max = ff_read_timestamp(s, stream_index, &pos_max, limit, read_timestamp);
- step += step;
- }while(ts_max == AV_NOPTS_VALUE && 2*limit > step);
- if (ts_max == AV_NOPTS_VALUE)
- return -1;
-
- for(;;){
- int64_t tmp_pos= pos_max + 1;
- int64_t tmp_ts= ff_read_timestamp(s, stream_index, &tmp_pos, INT64_MAX, read_timestamp);
- if(tmp_ts == AV_NOPTS_VALUE)
- break;
- ts_max= tmp_ts;
- pos_max= tmp_pos;
- if(tmp_pos >= filesize)
- break;
- }
+ if ((ret = ff_find_last_ts(s, stream_index, &ts_max, &pos_max, read_timestamp)) < 0)
+ return ret;
pos_limit= pos_max;
}