|
|
|
@ -1462,6 +1462,13 @@ static void mov_build_index(MOVContext *mov, AVStream *st) |
|
|
|
|
|
|
|
|
|
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++) { |
|
|
|
|
current_offset = sc->chunk_offsets[i]; |
|
|
|
|
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]; |
|
|
|
|
if(sc->pseudo_stream_id == -1 || |
|
|
|
|
sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { |
|
|
|
|
av_add_index_entry(st, current_offset, current_dts, sample_size, distance, |
|
|
|
|
keyframe ? AVINDEX_KEYFRAME : 0); |
|
|
|
|
AVIndexEntry *e = &st->index_entries[st->nb_index_entries++]; |
|
|
|
|
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", " |
|
|
|
|
"size %d, distance %d, keyframe %d\n", st->index, current_sample, |
|
|
|
|
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) |
|
|
|
|
st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration; |
|
|
|
|
} else { |
|
|
|
|
for (i = 0; i < sc->chunk_count; i++) { |
|
|
|
|
unsigned chunk_samples; |
|
|
|
|
unsigned chunk_samples, total = 0; |
|
|
|
|
|
|
|
|
|
current_offset = sc->chunk_offsets[i]; |
|
|
|
|
if (stsc_index + 1 < sc->stsc_count && |
|
|
|
|
i + 1 == sc->stsc_data[stsc_index + 1].first) |
|
|
|
|
stsc_index++; |
|
|
|
|
chunk_samples = sc->stsc_data[stsc_index].count; |
|
|
|
|
// 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]; |
|
|
|
|
if (stsc_index + 1 < sc->stsc_count && |
|
|
|
|
i + 1 == sc->stsc_data[stsc_index + 1].first) |
|
|
|
|
stsc_index++; |
|
|
|
|
chunk_samples = sc->stsc_data[stsc_index].count; |
|
|
|
|
|
|
|
|
|
while (chunk_samples > 0) { |
|
|
|
|
AVIndexEntry *e; |
|
|
|
|
unsigned size, samples; |
|
|
|
|
|
|
|
|
|
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", " |
|
|
|
|
"size %d, duration %d\n", st->index, i, current_offset, current_dts, |
|
|
|
|
size, samples); |
|
|
|
|