Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create stts box based on total duration of mediabox #1

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 7 additions & 29 deletions libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java
Original file line number Diff line number Diff line change
Expand Up @@ -655,40 +655,18 @@ public static List<Long> convertPresentationTimestampsToDurationsVu(
}

/** Generates the stts (decoding time to sample) box. */
public static ByteBuffer stts(List<Long> durationsVu) {
public static ByteBuffer stts(Long durationsVu,int writtenSampleSize) {
ByteBuffer contents =
ByteBuffer.allocate(durationsVu.size() * 8 + Mp4Utils.MAX_FIXED_LEAF_BOX_SIZE);
ByteBuffer.allocate(Long.BYTES + Mp4Utils.MAX_FIXED_LEAF_BOX_SIZE);

int sampleDelta = writtenSampleSize == 0 ? 0 : durationsVu.intValue()/writtenSampleSize;

contents.putInt(0x0); // version and flags.

// We will know total entry count only after processing all the sample durations, so put in a
// placeholder for total entry count and store its index.
int totalEntryCountIndex = contents.position();
contents.putInt(0x0); // entry_count.

int totalEntryCount = 0;
long lastDurationVu = -1L;
int lastSampleCountIndex = -1;

// Note that the framework MediaMuxer adjust time deltas within plus-minus 100 us, so that
// samples have repeating duration values. It saves few entries in the table.
for (int i = 0; i < durationsVu.size(); i++) {
long durationVu = durationsVu.get(i);
if (lastDurationVu != durationVu) {
lastDurationVu = durationVu;
lastSampleCountIndex = contents.position();

// sample_count; this will be updated instead of adding a new entry if the next sample has
// the same duration.
contents.putInt(1);
contents.putInt((int) durationVu); // sample_delta.
totalEntryCount++;
} else {
contents.putInt(lastSampleCountIndex, contents.getInt(lastSampleCountIndex) + 1);
}
}
contents.putInt(1); // entry_count.
contents.putInt(writtenSampleSize);
contents.putInt(sampleDelta);

contents.putInt(totalEntryCountIndex, totalEntryCount);

contents.flip();
return BoxUtils.wrapIntoBox("stts", contents);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public ByteBuffer moovMetadataHeader(
Mp4Utils.usFromVu(trackDurationInTrackUnitsVu, track.videoUnitTimebase());

@C.TrackType int trackType = MimeTypes.getTrackType(format.sampleMimeType);
ByteBuffer stts = Boxes.stts(sampleDurationsVu);
ByteBuffer stts = Boxes.stts(trackDurationInTrackUnitsVu,track.writtenSamples().size());
ByteBuffer stsz = Boxes.stsz(track.writtenSamples());
ByteBuffer stsc = Boxes.stsc(track.writtenChunkSampleCounts());
ByteBuffer chunkOffsetBox =
Expand Down
21 changes: 18 additions & 3 deletions libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,12 @@ public void createVideoSampleEntryBox_withUnknownVideoFormat_throws() {
public void createSttsBox_withSingleSampleDuration_matchesExpected() throws IOException {
ImmutableList<Long> sampleDurations = ImmutableList.of(500L);

ByteBuffer sttsBox = Boxes.stts(sampleDurations);
Long totalDuration = 0L;
for (int i = 0; i < sampleDurations.size(); i++) {
totalDuration += sampleDurations.get(i);
}
ByteBuffer sttsBox = Boxes.stts(totalDuration,sampleDurations.size());


DumpableMp4Box dumpableBox = new DumpableMp4Box(sttsBox);
DumpFileAsserts.assertOutput(
Expand All @@ -455,7 +460,12 @@ public void createSttsBox_withSingleSampleDuration_matchesExpected() throws IOEx
public void createSttsBox_withAllDifferentSampleDurations_matchesExpected() throws IOException {
ImmutableList<Long> sampleDurations = ImmutableList.of(1_000L, 2_000L, 3_000L, 5_000L);

ByteBuffer sttsBox = Boxes.stts(sampleDurations);
Long totalDuration = 0L;
for (int i = 0; i < sampleDurations.size(); i++) {
totalDuration += sampleDurations.get(i);
}
ByteBuffer sttsBox = Boxes.stts(totalDuration,sampleDurations.size());


DumpableMp4Box dumpableBox = new DumpableMp4Box(sttsBox);
DumpFileAsserts.assertOutput(
Expand All @@ -469,7 +479,12 @@ public void createSttsBox_withFewConsecutiveSameSampleDurations_matchesExpected(
throws IOException {
ImmutableList<Long> sampleDurations = ImmutableList.of(1_000L, 2_000L, 2_000L, 2_000L);

ByteBuffer sttsBox = Boxes.stts(sampleDurations);
Long totalDuration = 0L;
for (int i = 0; i < sampleDurations.size(); i++) {
totalDuration += sampleDurations.get(i);
}
ByteBuffer sttsBox = Boxes.stts(totalDuration,sampleDurations.size());


DumpableMp4Box dumpableBox = new DumpableMp4Box(sttsBox);
DumpFileAsserts.assertOutput(
Expand Down