Commit 27a5fe5f authored by Michael Niedermayer's avatar Michael Niedermayer

keyframe & non keyframe index fixes

Originally committed as revision 4034 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent fcc87242
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
extern "C" { extern "C" {
#endif #endif
#define LIBAVFORMAT_BUILD 4621 #define LIBAVFORMAT_BUILD 4622
#define LIBAVFORMAT_VERSION_INT FFMPEG_VERSION_INT #define LIBAVFORMAT_VERSION_INT FFMPEG_VERSION_INT
#define LIBAVFORMAT_VERSION FFMPEG_VERSION #define LIBAVFORMAT_VERSION FFMPEG_VERSION
...@@ -584,6 +584,7 @@ void av_set_pts_info(AVStream *s, int pts_wrap_bits, ...@@ -584,6 +584,7 @@ void av_set_pts_info(AVStream *s, int pts_wrap_bits,
#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward #define AVSEEK_FLAG_BACKWARD 1 ///< seek backward
#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes #define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes
#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non keyframes
int av_find_default_stream_index(AVFormatContext *s); int av_find_default_stream_index(AVFormatContext *s);
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
......
...@@ -1482,7 +1482,7 @@ static int mpegps_read_pes_header(AVFormatContext *s, ...@@ -1482,7 +1482,7 @@ static int mpegps_read_pes_header(AVFormatContext *s,
int i; int i;
for(i=0; i<s->nb_streams; i++){ for(i=0; i<s->nb_streams; i++){
if(startcode == s->streams[i]->id) { if(startcode == s->streams[i]->id) {
av_add_index_entry(s->streams[i], *ppos, dts, 0, 0 /* FIXME keyframe? */); av_add_index_entry(s->streams[i], *ppos, dts, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */);
} }
} }
} }
......
...@@ -1024,7 +1024,7 @@ int av_add_index_entry(AVStream *st, ...@@ -1024,7 +1024,7 @@ int av_add_index_entry(AVStream *st,
st->index_entries= entries; st->index_entries= entries;
index= av_index_search_timestamp(st, timestamp, 0); index= av_index_search_timestamp(st, timestamp, AVSEEK_FLAG_ANY);
if(index<0){ if(index<0){
index= st->nb_index_entries++; index= st->nb_index_entries++;
...@@ -1090,13 +1090,14 @@ static int is_raw_stream(AVFormatContext *s) ...@@ -1090,13 +1090,14 @@ static int is_raw_stream(AVFormatContext *s)
/** /**
* gets the index for a specific timestamp. * gets the index for a specific timestamp.
* @param backward if non zero then the returned index will correspond to * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond to
* the timestamp which is <= the requested one, if backward is 0 * the timestamp which is <= the requested one, if backward is 0
* then it will be >= * then it will be >=
* if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise
* @return < 0 if no such timestamp could be found * @return < 0 if no such timestamp could be found
*/ */
int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp,
int backward) int flags)
{ {
AVIndexEntry *entries= st->index_entries; AVIndexEntry *entries= st->index_entries;
int nb_entries= st->nb_index_entries; int nb_entries= st->nb_index_entries;
...@@ -1114,7 +1115,13 @@ int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, ...@@ -1114,7 +1115,13 @@ int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp,
if(timestamp <= wanted_timestamp) if(timestamp <= wanted_timestamp)
a = m; a = m;
} }
m= backward ? a : b; m= (flags & AVSEEK_FLAG_BACKWARD) ? a : b;
if(!(flags & AVSEEK_FLAG_ANY)){
while(m>=0 && m<nb_entries && !(entries[m].flags & AVINDEX_KEYFRAME)){
m += (flags & AVSEEK_FLAG_BACKWARD) ? -1 : 1;
}
}
if(m == nb_entries) if(m == nb_entries)
return -1; return -1;
...@@ -1152,7 +1159,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts ...@@ -1152,7 +1159,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
if(st->index_entries){ if(st->index_entries){
AVIndexEntry *e; AVIndexEntry *e;
index= av_index_search_timestamp(st, target_ts, 1); index= av_index_search_timestamp(st, target_ts, flags | AVSEEK_FLAG_BACKWARD); //FIXME whole func must be checked for non keyframe entries in index case, especially read_timestamp()
index= FFMAX(index, 0); index= FFMAX(index, 0);
e= &st->index_entries[index]; e= &st->index_entries[index];
...@@ -1166,8 +1173,10 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts ...@@ -1166,8 +1173,10 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
}else{ }else{
assert(index==0); assert(index==0);
} }
index++;
if(index < st->nb_index_entries){ index= av_index_search_timestamp(st, target_ts, flags & ~AVSEEK_FLAG_BACKWARD);
assert(index < st->nb_index_entries);
if(index >= 0){
e= &st->index_entries[index]; e= &st->index_entries[index];
assert(e->timestamp >= target_ts); assert(e->timestamp >= target_ts);
pos_max= e->pos; pos_max= e->pos;
...@@ -1316,7 +1325,7 @@ static int av_seek_frame_generic(AVFormatContext *s, ...@@ -1316,7 +1325,7 @@ static int av_seek_frame_generic(AVFormatContext *s,
} }
st = s->streams[stream_index]; st = s->streams[stream_index];
index = av_index_search_timestamp(st, timestamp, flags & AVSEEK_FLAG_BACKWARD); index = av_index_search_timestamp(st, timestamp, flags);
if (index < 0) if (index < 0)
return -1; return -1;
......
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