mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-29 19:02:21 +00:00
Preallocate index entries in mov demuxer, huge speedup
Originally committed as revision 22363 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
1307463d52
commit
987e857f63
@ -1462,6 +1462,13 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
|
|||||||
|
|
||||||
current_dts -= sc->dts_shift;
|
current_dts -= sc->dts_shift;
|
||||||
|
|
||||||
|
if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries))
|
||||||
|
return;
|
||||||
|
st->index_entries = av_malloc(sc->sample_count*sizeof(*st->index_entries));
|
||||||
|
if (!st->index_entries)
|
||||||
|
return;
|
||||||
|
st->index_entries_allocated_size = sc->sample_count*sizeof(*st->index_entries);
|
||||||
|
|
||||||
for (i = 0; i < sc->chunk_count; i++) {
|
for (i = 0; i < sc->chunk_count; i++) {
|
||||||
current_offset = sc->chunk_offsets[i];
|
current_offset = sc->chunk_offsets[i];
|
||||||
if (stsc_index + 1 < sc->stsc_count &&
|
if (stsc_index + 1 < sc->stsc_count &&
|
||||||
@ -1488,8 +1495,12 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
|
|||||||
sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
|
sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
|
||||||
if(sc->pseudo_stream_id == -1 ||
|
if(sc->pseudo_stream_id == -1 ||
|
||||||
sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
|
sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
|
||||||
av_add_index_entry(st, current_offset, current_dts, sample_size, distance,
|
AVIndexEntry *e = &st->index_entries[st->nb_index_entries++];
|
||||||
keyframe ? AVINDEX_KEYFRAME : 0);
|
e->pos = current_offset;
|
||||||
|
e->timestamp = current_dts;
|
||||||
|
e->size = sample_size;
|
||||||
|
e->min_distance = distance;
|
||||||
|
e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
|
||||||
dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
|
dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
|
||||||
"size %d, distance %d, keyframe %d\n", st->index, current_sample,
|
"size %d, distance %d, keyframe %d\n", st->index, current_sample,
|
||||||
current_offset, current_dts, sample_size, distance, keyframe);
|
current_offset, current_dts, sample_size, distance, keyframe);
|
||||||
@ -1510,21 +1521,52 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
|
|||||||
if (st->duration > 0)
|
if (st->duration > 0)
|
||||||
st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration;
|
st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration;
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < sc->chunk_count; i++) {
|
unsigned chunk_samples, total = 0;
|
||||||
unsigned chunk_samples;
|
|
||||||
|
|
||||||
|
// compute total chunk count
|
||||||
|
for (i = 0; i < sc->stsc_count; i++) {
|
||||||
|
unsigned count, chunk_count;
|
||||||
|
|
||||||
|
chunk_samples = sc->stsc_data[i].count;
|
||||||
|
if (sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
|
||||||
|
av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sc->samples_per_frame >= 160) { // gsm
|
||||||
|
count = chunk_samples / sc->samples_per_frame;
|
||||||
|
} else if (sc->samples_per_frame > 1) {
|
||||||
|
unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
|
||||||
|
count = (chunk_samples+samples-1) / samples;
|
||||||
|
} else {
|
||||||
|
count = (chunk_samples+1023) / 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < sc->stsc_count - 1)
|
||||||
|
chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
|
||||||
|
else
|
||||||
|
chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
|
||||||
|
total += chunk_count * count;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf(mov->fc, "chunk count %d\n", total);
|
||||||
|
if (total >= UINT_MAX / sizeof(*st->index_entries))
|
||||||
|
return;
|
||||||
|
st->index_entries = av_malloc(total*sizeof(*st->index_entries));
|
||||||
|
if (!st->index_entries)
|
||||||
|
return;
|
||||||
|
st->index_entries_allocated_size = total*sizeof(*st->index_entries);
|
||||||
|
|
||||||
|
// populate index
|
||||||
|
for (i = 0; i < sc->chunk_count; i++) {
|
||||||
current_offset = sc->chunk_offsets[i];
|
current_offset = sc->chunk_offsets[i];
|
||||||
if (stsc_index + 1 < sc->stsc_count &&
|
if (stsc_index + 1 < sc->stsc_count &&
|
||||||
i + 1 == sc->stsc_data[stsc_index + 1].first)
|
i + 1 == sc->stsc_data[stsc_index + 1].first)
|
||||||
stsc_index++;
|
stsc_index++;
|
||||||
chunk_samples = sc->stsc_data[stsc_index].count;
|
chunk_samples = sc->stsc_data[stsc_index].count;
|
||||||
|
|
||||||
if (sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
|
|
||||||
av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (chunk_samples > 0) {
|
while (chunk_samples > 0) {
|
||||||
|
AVIndexEntry *e;
|
||||||
unsigned size, samples;
|
unsigned size, samples;
|
||||||
|
|
||||||
if (sc->samples_per_frame >= 160) { // gsm
|
if (sc->samples_per_frame >= 160) { // gsm
|
||||||
@ -1541,7 +1583,16 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
av_add_index_entry(st, current_offset, current_dts, size, 0, AVINDEX_KEYFRAME);
|
if (st->nb_index_entries >= total) {
|
||||||
|
av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %d\n", total);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e = &st->index_entries[st->nb_index_entries++];
|
||||||
|
e->pos = current_offset;
|
||||||
|
e->timestamp = current_dts;
|
||||||
|
e->size = size;
|
||||||
|
e->min_distance = 0;
|
||||||
|
e->flags = AVINDEX_KEYFRAME;
|
||||||
dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", "
|
dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", "
|
||||||
"size %d, duration %d\n", st->index, i, current_offset, current_dts,
|
"size %d, duration %d\n", st->index, i, current_offset, current_dts,
|
||||||
size, samples);
|
size, samples);
|
||||||
|
Loading…
Reference in New Issue
Block a user