From 8ca5d277d8a8e31365b0e9609114738db26bbc6a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 6 Jul 2013 21:52:07 +0200 Subject: [PATCH] avformat/utils: factor ff_find_last_ts() out of ff_gen_search() Signed-off-by: Michael Niedermayer --- libavformat/internal.h | 3 ++ libavformat/utils.c | 63 ++++++++++++++++++++++++++---------------- 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; }