Skip duplicate chunks in stsc box writing

Earlier muxer wrote a different entry for every chunk but as
per the spec (ISO 14496-12) exact same chunks can be combined
and only the first chunk number can be written.

PiperOrigin-RevId: 714154531
This commit is contained in:
sheenachhabra 2025-01-10 13:23:38 -08:00 committed by Copybara-Service
parent 28027c64fd
commit 36be62ee8c
3 changed files with 28 additions and 8 deletions

View File

@ -1065,21 +1065,28 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
ByteBuffer.allocate(writtenChunkSampleCounts.size() * 12 + MAX_FIXED_LEAF_BOX_SIZE);
contents.putInt(0x0); // version and flags
contents.putInt(writtenChunkSampleCounts.size()); // entry_count
int totalEntryCountIndex = contents.position();
contents.putInt(0); // entry_count
int currentChunk = 1;
int prevChunkSampleCount = -1;
int totalEntryCount = 0;
// TODO: b/270583563 - Consider optimizing for consecutive chunks having same number of samples.
for (int i = 0; i < writtenChunkSampleCounts.size(); i++) {
int samplesInChunk = writtenChunkSampleCounts.get(i);
contents.putInt(currentChunk); // first_chunk
contents.putInt(samplesInChunk); // samples_per_chunk
// sample_description_index: there is only one sample description in each track.
contents.putInt(1);
// For exact same chunks, add only first chunk number.
if (samplesInChunk != prevChunkSampleCount) {
contents.putInt(currentChunk); // first_chunk
contents.putInt(samplesInChunk); // samples_per_chunk
// sample_description_index: there is only one sample description in each track.
contents.putInt(1);
totalEntryCount++;
prevChunkSampleCount = samplesInChunk;
}
currentChunk += 1;
}
contents.putInt(totalEntryCountIndex, totalEntryCount);
contents.flip();
return BoxUtils.wrapIntoBox("stsc", contents);
}

View File

@ -735,7 +735,7 @@ public class BoxesTest {
}
@Test
public void createStscBox_matchesExpected() throws IOException {
public void createStscBox_withDifferentChunks_matchesExpected() throws IOException {
ImmutableList<Integer> chunkSampleCounts = ImmutableList.of(100, 500, 200, 100);
ByteBuffer stscBox = Boxes.stsc(chunkSampleCounts);
@ -745,6 +745,17 @@ public class BoxesTest {
context, dumpableBox, MuxerTestUtil.getExpectedDumpFilePath("stsc_box"));
}
@Test
public void createStscBox_withSameChunks_matchesExpected() throws IOException {
ImmutableList<Integer> chunkSampleCounts = ImmutableList.of(100, 100, 100, 100);
ByteBuffer stscBox = Boxes.stsc(chunkSampleCounts);
DumpableMp4Box dumpableBox = new DumpableMp4Box(stscBox);
DumpFileAsserts.assertOutput(
context, dumpableBox, MuxerTestUtil.getExpectedDumpFilePath("stsc_box_with_same_chunks"));
}
@Test
public void createStcoBox_matchesExpected() throws IOException {
ImmutableList<Long> chunkOffsets = ImmutableList.of(1_000L, 5_000L, 7_000L, 10_000L);

View File

@ -0,0 +1,2 @@
stsc (28 bytes):
Data = length 20, hash 94E19968