[FFmpeg-soc] [soc]: r5826 - in seek2010: . seek2010.patch
Michael Chinen
mchinen at gmail.com
Wed Jun 16 22:50:06 CEST 2010
On Wed, Jun 16, 2010 at 10:07 PM, Michael Niedermayer <michaelni at gmx.at> wrote:
> On Wed, Jun 09, 2010 at 03:42:09PM +0200, mchinen wrote:
>> Author: mchinen
>> Date: Wed Jun 9 15:42:08 2010
>> New Revision: 5826
>>
>> Log:
>> creating seek2010 dir for my soc proj and adding current patch
> [...]
>
>> +Index: libavformat/avformat.h
>> +===================================================================
>> +--- libavformat/avformat.h (revision 23548)
>> ++++ libavformat/avformat.h (working copy)
>> +@@ -390,6 +390,21 @@
>> + int min_distance; /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */
>> + } AVIndexEntry;
>> +
>> ++#define AV_SEEKTABLE_BUILDING 0x0001
>> ++#define AV_SEEKTABLE_CBR 0x0002
>> ++#define AV_SEEKTABLE_FINISHED 0x0004
>> ++#define AV_SEEKTABLE_COPIED 0x0008
>
> missing documentation
>
>
> [...]
>
>> +@@ -531,6 +546,9 @@
>> + * Number of frames that have been demuxed during av_find_stream_info()
>> + */
>> + int codec_info_nb_frames;
>> ++
>> ++ /* new av_seek_frame() support */
>> ++ AVSeekTable seek_table;
>> + } AVStream;
>
> we alraedy have a table for seeking, that is AVStream.index_entries
> why do you add a second table?
This one is a complete index table that will be saved/loaded/built on
a different thread during decoding. I made a new one mostly to make
sure I didn't cause regression bugs. Also currently lots of demuxers
change the state of that index table during normal read/parse. Once
the complete table is built, the idea is to stop using the old
index_entries one and use the complete table for seeking. Is this
okay?
>
>
> [...]
>> +Index: libavformat/utils.c
>> +===================================================================
>> +--- libavformat/utils.c (revision 23548)
>> ++++ libavformat/utils.c (working copy)
>> +@@ -1001,7 +1001,38 @@
>> + pkt->convergence_duration = pc->convergence_duration;
>> + }
>> +
>> ++static int av_add_table_entry(AVStream *st,
>> ++ int64_t pos, int64_t timestamp, int size, int distance, int flags)
>> ++{
>> ++ AVIndexEntry *entries, *ie;
>> ++ int index;
>> +
>> ++ if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
>> ++ return -1;
>> ++
>> ++ entries = av_fast_realloc(st->seek_table.index_entries,
>> ++ &st->seek_table.index_entries_allocated_size,
>> ++ (st->seek_table.nb_index_entries + 1) *
>> ++ sizeof(AVIndexEntry));
>> ++ if(!entries)
>> ++ return -1;
>> ++
>> ++ st->seek_table.index_entries= entries;
>> ++
>> ++ /* we assume the indecies are placed in order */
>> ++ ie = &st->seek_table.index_entries[st->seek_table.nb_index_entries++];
>> ++ assert(index==0 || ie[-1].timestamp < timestamp);
>> ++
>> ++ ie->pos = pos;
>> ++ ie->timestamp = timestamp;
>> ++ ie->min_distance= distance;
>> ++ ie->size= size;
>> ++ ie->flags = flags;
>> ++
>> ++ return st->seek_table.nb_index_entries;
>> ++}
>> ++
>> ++
>> + static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
>> + {
>> + AVStream *st;
>> +@@ -1359,6 +1390,7 @@
>> + int a, b, m;
>> + int64_t timestamp;
>> +
>> ++
>> + a = - 1;
>> + b = nb_entries;
>> +
>> +@@ -1675,6 +1707,11 @@
>> + timestamp = av_rescale(timestamp, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);
>> + }
>> +
>> ++ /* if we've built a seek table, use it. */
>> ++ st = s->streams[stream_index];
>> ++ if (st->seek_table.flags & AV_SEEKTABLE_FINISHED)
>> ++ return av_seek_frame_table(s, stream_index, timestamp, flags);
>> ++
>> + /* first, we try the format specific seek */
>> + if (s->iformat->read_seek)
>> + ret = s->iformat->read_seek(s, stream_index, timestamp, flags);
>> +@@ -1712,9 +1749,367 @@
>> + // try some generic seek like av_seek_frame_generic() but with new ts semantics
>> + }
>> +
>> ++
>> + /*******************************************************/
>> ++int av_table_search_timestamp(AVStream *st, int64_t wanted_timestamp,
>> ++ int flags)
>> ++{
>> ++ AVIndexEntry *entries= st->seek_table.index_entries;
>> ++ int nb_entries= st->seek_table.nb_index_entries;
>> ++ int a, b, m;
>> ++ int64_t timestamp;
>> +
>> ++ a = - 1;
>> ++ b = nb_entries;
>> ++
>> ++ //optimize appending index entries at the end
>> ++ if(b && entries[b-1].timestamp < wanted_timestamp)
>> ++ a= b-1;
>> ++
>> ++ while (b - a > 1) {
>> ++ //TODO: since we have a lot of contiguous entries in the table, we can use something more
>> ++ //like dictionary search, which will speed things up quite a bit.
>> ++ m = (a + b) >> 1;
>> ++ timestamp = entries[m].timestamp;
>> ++ if(timestamp >= wanted_timestamp)
>> ++ b = m;
>> ++ if(timestamp <= wanted_timestamp)
>> ++ a = m;
>> ++ }
>> ++ 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)
>> ++ return -1;
>> ++ return m;
>> ++}
>> ++
> [...]
>> ++static int av_fill_table_internal(AVFormatContext *s, AVPacket *pkt, ByteIOContext *pb)
>
> lots of code duplication
yes, these are working stubs based on the calls to modify the old
index_entries, but I will optimize them to be a special case for
complete index table.
Michael
More information about the FFmpeg-soc
mailing list