Mercurial > libavformat.hg
comparison mov.c @ 5788:8539cb618ae7 libavformat
Preallocate index entries in mov demuxer, huge speedup
author | bcoudurier |
---|---|
date | Tue, 09 Mar 2010 00:46:26 +0000 |
parents | adf1ad73c63e |
children | dba191dda275 |
comparison
equal
deleted
inserted
replaced
5787:667736f463b3 | 5788:8539cb618ae7 |
---|---|
1460 unsigned int distance = 0; | 1460 unsigned int distance = 0; |
1461 int key_off = sc->keyframes && sc->keyframes[0] == 1; | 1461 int key_off = sc->keyframes && sc->keyframes[0] == 1; |
1462 | 1462 |
1463 current_dts -= sc->dts_shift; | 1463 current_dts -= sc->dts_shift; |
1464 | 1464 |
1465 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries)) | |
1466 return; | |
1467 st->index_entries = av_malloc(sc->sample_count*sizeof(*st->index_entries)); | |
1468 if (!st->index_entries) | |
1469 return; | |
1470 st->index_entries_allocated_size = sc->sample_count*sizeof(*st->index_entries); | |
1471 | |
1465 for (i = 0; i < sc->chunk_count; i++) { | 1472 for (i = 0; i < sc->chunk_count; i++) { |
1466 current_offset = sc->chunk_offsets[i]; | 1473 current_offset = sc->chunk_offsets[i]; |
1467 if (stsc_index + 1 < sc->stsc_count && | 1474 if (stsc_index + 1 < sc->stsc_count && |
1468 i + 1 == sc->stsc_data[stsc_index + 1].first) | 1475 i + 1 == sc->stsc_data[stsc_index + 1].first) |
1469 stsc_index++; | 1476 stsc_index++; |
1486 if (keyframe) | 1493 if (keyframe) |
1487 distance = 0; | 1494 distance = 0; |
1488 sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample]; | 1495 sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample]; |
1489 if(sc->pseudo_stream_id == -1 || | 1496 if(sc->pseudo_stream_id == -1 || |
1490 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { | 1497 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { |
1491 av_add_index_entry(st, current_offset, current_dts, sample_size, distance, | 1498 AVIndexEntry *e = &st->index_entries[st->nb_index_entries++]; |
1492 keyframe ? AVINDEX_KEYFRAME : 0); | 1499 e->pos = current_offset; |
1500 e->timestamp = current_dts; | |
1501 e->size = sample_size; | |
1502 e->min_distance = distance; | |
1503 e->flags = keyframe ? AVINDEX_KEYFRAME : 0; | |
1493 dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " | 1504 dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " |
1494 "size %d, distance %d, keyframe %d\n", st->index, current_sample, | 1505 "size %d, distance %d, keyframe %d\n", st->index, current_sample, |
1495 current_offset, current_dts, sample_size, distance, keyframe); | 1506 current_offset, current_dts, sample_size, distance, keyframe); |
1496 } | 1507 } |
1497 | 1508 |
1508 } | 1519 } |
1509 } | 1520 } |
1510 if (st->duration > 0) | 1521 if (st->duration > 0) |
1511 st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration; | 1522 st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration; |
1512 } else { | 1523 } else { |
1524 unsigned chunk_samples, total = 0; | |
1525 | |
1526 // compute total chunk count | |
1527 for (i = 0; i < sc->stsc_count; i++) { | |
1528 unsigned count, chunk_count; | |
1529 | |
1530 chunk_samples = sc->stsc_data[i].count; | |
1531 if (sc->samples_per_frame && chunk_samples % sc->samples_per_frame) { | |
1532 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n"); | |
1533 return; | |
1534 } | |
1535 | |
1536 if (sc->samples_per_frame >= 160) { // gsm | |
1537 count = chunk_samples / sc->samples_per_frame; | |
1538 } else if (sc->samples_per_frame > 1) { | |
1539 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame; | |
1540 count = (chunk_samples+samples-1) / samples; | |
1541 } else { | |
1542 count = (chunk_samples+1023) / 1024; | |
1543 } | |
1544 | |
1545 if (i < sc->stsc_count - 1) | |
1546 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first; | |
1547 else | |
1548 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1); | |
1549 total += chunk_count * count; | |
1550 } | |
1551 | |
1552 dprintf(mov->fc, "chunk count %d\n", total); | |
1553 if (total >= UINT_MAX / sizeof(*st->index_entries)) | |
1554 return; | |
1555 st->index_entries = av_malloc(total*sizeof(*st->index_entries)); | |
1556 if (!st->index_entries) | |
1557 return; | |
1558 st->index_entries_allocated_size = total*sizeof(*st->index_entries); | |
1559 | |
1560 // populate index | |
1513 for (i = 0; i < sc->chunk_count; i++) { | 1561 for (i = 0; i < sc->chunk_count; i++) { |
1514 unsigned chunk_samples; | |
1515 | |
1516 current_offset = sc->chunk_offsets[i]; | 1562 current_offset = sc->chunk_offsets[i]; |
1517 if (stsc_index + 1 < sc->stsc_count && | 1563 if (stsc_index + 1 < sc->stsc_count && |
1518 i + 1 == sc->stsc_data[stsc_index + 1].first) | 1564 i + 1 == sc->stsc_data[stsc_index + 1].first) |
1519 stsc_index++; | 1565 stsc_index++; |
1520 chunk_samples = sc->stsc_data[stsc_index].count; | 1566 chunk_samples = sc->stsc_data[stsc_index].count; |
1521 | 1567 |
1522 if (sc->samples_per_frame && chunk_samples % sc->samples_per_frame) { | |
1523 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n"); | |
1524 return; | |
1525 } | |
1526 | |
1527 while (chunk_samples > 0) { | 1568 while (chunk_samples > 0) { |
1569 AVIndexEntry *e; | |
1528 unsigned size, samples; | 1570 unsigned size, samples; |
1529 | 1571 |
1530 if (sc->samples_per_frame >= 160) { // gsm | 1572 if (sc->samples_per_frame >= 160) { // gsm |
1531 samples = sc->samples_per_frame; | 1573 samples = sc->samples_per_frame; |
1532 size = sc->bytes_per_frame; | 1574 size = sc->bytes_per_frame; |
1539 samples = FFMIN(1024, chunk_samples); | 1581 samples = FFMIN(1024, chunk_samples); |
1540 size = samples * sc->sample_size; | 1582 size = samples * sc->sample_size; |
1541 } | 1583 } |
1542 } | 1584 } |
1543 | 1585 |
1544 av_add_index_entry(st, current_offset, current_dts, size, 0, AVINDEX_KEYFRAME); | 1586 if (st->nb_index_entries >= total) { |
1587 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %d\n", total); | |
1588 return; | |
1589 } | |
1590 e = &st->index_entries[st->nb_index_entries++]; | |
1591 e->pos = current_offset; | |
1592 e->timestamp = current_dts; | |
1593 e->size = size; | |
1594 e->min_distance = 0; | |
1595 e->flags = AVINDEX_KEYFRAME; | |
1545 dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", " | 1596 dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", " |
1546 "size %d, duration %d\n", st->index, i, current_offset, current_dts, | 1597 "size %d, duration %d\n", st->index, i, current_offset, current_dts, |
1547 size, samples); | 1598 size, samples); |
1548 | 1599 |
1549 current_offset += size; | 1600 current_offset += size; |