demux: use binary search for cache seek index

Not sure if this is bug-free. You _always_ make bugs when writing a
binary search from scratch (and such is the curse of C, though if I did
this in C++ it would probably end in blood). It seems to work though,
checking against the normal linear search.

It's slightly faster. Not much.

I wonder if the termination condition can be written in a nicer/elegant
way. I guess the fact that it's not a == predicate makes this slightly
messier?
This commit is contained in:
wm4 2019-06-02 23:29:40 +02:00
parent 1f13bd0942
commit 911718c413
1 changed files with 28 additions and 7 deletions

View File

@ -3098,18 +3098,39 @@ static void switch_current_range(struct demux_internal *in,
free_empty_cached_ranges(in);
}
// Search for the entry with the highest index with entry.pts <= pts true.
static struct demux_packet *search_index(struct demux_queue *queue, double pts)
{
size_t a = 0;
size_t b = queue->num_index;
while (a < b) {
size_t m = a + (b - a) / 2;
struct index_entry *e = &QUEUE_INDEX_ENTRY(queue, m);
bool m_ok = e->pts <= pts;
if (a + 1 == b)
return m_ok ? e->pkt : NULL;
if (m_ok) {
a = m;
} else {
b = m;
}
}
return NULL;
}
static struct demux_packet *find_seek_target(struct demux_queue *queue,
double pts, int flags)
{
pts -= queue->ds->sh->seek_preroll;
struct demux_packet *start = queue->head;
for (size_t n = 0; n < queue->num_index; n++) {
struct index_entry *e = &QUEUE_INDEX_ENTRY(queue, n);
if (e->pts > pts)
break;
start = e->pkt;
}
struct demux_packet *start = search_index(queue, pts);
if (!start)
start = queue->head;
struct demux_packet *target = NULL;
for (struct demux_packet *dp = start; dp; dp = dp->next) {