@@ -60,6 +60,7 @@ use mp4parse::MediaContext;
60
60
use mp4parse:: MediaScaledTime ;
61
61
use mp4parse:: MediaTimeScale ;
62
62
use mp4parse:: SampleEntry ;
63
+ use mp4parse:: ToUsize ;
63
64
use mp4parse:: Track ;
64
65
use mp4parse:: TrackScaledTime ;
65
66
use mp4parse:: TrackTimeScale ;
@@ -1385,6 +1386,18 @@ impl<'a> TimeToSampleIterator<'a> {
1385
1386
// For example:
1386
1387
// (1, 5), (5, 10), (9, 2) => (1, 5), (2, 5), (3, 5), (4, 5), (5, 10), (6, 10),
1387
1388
// (7, 10), (8, 10), (9, 2)
1389
+ fn sample_to_chunk_iter < ' a > (
1390
+ stsc_samples : & ' a TryVec < mp4parse:: SampleToChunk > ,
1391
+ stco_offsets : & ' a TryVec < u64 > ,
1392
+ ) -> SampleToChunkIterator < ' a > {
1393
+ SampleToChunkIterator {
1394
+ chunks : ( 0 ..0 ) ,
1395
+ sample_count : 0 ,
1396
+ stsc_peek_iter : stsc_samples. as_slice ( ) . iter ( ) . peekable ( ) ,
1397
+ remain_chunk_count : stco_offsets. len ( ) as u32 ,
1398
+ }
1399
+ }
1400
+
1388
1401
struct SampleToChunkIterator < ' a > {
1389
1402
chunks : std:: ops:: Range < u32 > ,
1390
1403
sample_count : u32 ,
@@ -1460,19 +1473,20 @@ fn create_sample_table(
1460
1473
_ => false ,
1461
1474
} ;
1462
1475
1463
- let mut sample_table = TryVec :: new ( ) ;
1464
1476
let mut sample_size_iter = stsz. sample_sizes . iter ( ) ;
1465
1477
1466
1478
// Get 'stsc' iterator for (chunk_id, chunk_sample_count) and calculate the sample
1467
1479
// offset address.
1468
- let stsc_iter = SampleToChunkIterator {
1469
- chunks : ( 0 ..0 ) ,
1470
- sample_count : 0 ,
1471
- stsc_peek_iter : stsc. samples . as_slice ( ) . iter ( ) . peekable ( ) ,
1472
- remain_chunk_count : stco. offsets . len ( ) as u32 ,
1473
- } ;
1474
1480
1475
- for i in stsc_iter {
1481
+ // With large numbers of samples, the cost of many allocations dominates,
1482
+ // so it's worth iterating twice to allocate sample_table just once.
1483
+ let total_sample_count = sample_to_chunk_iter ( & stsc. samples , & stco. offsets )
1484
+ . by_ref ( )
1485
+ . map ( |( _, sample_counts) | sample_counts. to_usize ( ) )
1486
+ . sum ( ) ;
1487
+ let mut sample_table = TryVec :: with_capacity ( total_sample_count) . ok ( ) ?;
1488
+
1489
+ for i in sample_to_chunk_iter ( & stsc. samples , & stco. offsets ) {
1476
1490
let chunk_id = i. 0 as usize ;
1477
1491
let sample_counts = i. 1 ;
1478
1492
let mut cur_position = match stco. offsets . get ( chunk_id) {
@@ -1565,7 +1579,8 @@ fn create_sample_table(
1565
1579
// calculate to correct the composition end time.
1566
1580
if !sample_table. is_empty ( ) {
1567
1581
// Create an index table refers to sample_table and sorted by start_composisiton time.
1568
- let mut sort_table = TryVec :: new ( ) ;
1582
+ let mut sort_table = TryVec :: with_capacity ( sample_table. len ( ) ) . ok ( ) ?;
1583
+
1569
1584
for i in 0 ..sample_table. len ( ) {
1570
1585
sort_table. push ( i) . ok ( ) ?;
1571
1586
}
0 commit comments