Change the default value of lastSampleDurationBehavior
to LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS This CL also combines LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER and LAST_SAMPLE_DURATION_BEHAVIOR_DUPLICATE_PREVIOUS. The reason for combining the two enums is that, when the option to use END_OF_STREAM_BUFFER is selected and if the EOS buffer is not provided then the muxer anyways fallbacks to duplicate duration behavior. The last sample with 0 durations seems less useful so change the default behavior to non-zero duration. This will also match the behavior with MediaMuxer. PiperOrigin-RevId: 675189932
This commit is contained in:
parent
0ce6d9620e
commit
47d45a82ca
@ -821,7 +821,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
|
||||
currentSampleTimeUs = nextSampleTimeUs;
|
||||
}
|
||||
|
||||
long lastSampleDurationVuFromEndOfStream = 0;
|
||||
long lastSampleDurationVuFromEndOfStream = C.LENGTH_UNSET;
|
||||
if (endOfStreamTimestampUs != C.TIME_UNSET) {
|
||||
lastSampleDurationVuFromEndOfStream =
|
||||
vuFromUs(endOfStreamTimestampUs, videoUnitTimescale)
|
||||
@ -1244,16 +1244,18 @@ import org.checkerframework.checker.nullness.qual.PolyNull;
|
||||
@Mp4Muxer.LastSampleDurationBehavior int lastSampleDurationBehavior,
|
||||
int lastSampleDurationVuFromEndOfStream) {
|
||||
switch (lastSampleDurationBehavior) {
|
||||
case Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_DUPLICATE_PREVIOUS:
|
||||
case Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_SET_TO_ZERO:
|
||||
return 0;
|
||||
case Mp4Muxer
|
||||
.LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS:
|
||||
if (lastSampleDurationVuFromEndOfStream != C.LENGTH_UNSET) {
|
||||
return lastSampleDurationVuFromEndOfStream;
|
||||
}
|
||||
// For a track having less than 3 samples, duplicating the last frame duration will
|
||||
// significantly increase the overall track duration, so avoid that.
|
||||
return sampleDurationsExceptLast.size() < 2
|
||||
? 0
|
||||
: Iterables.getLast(sampleDurationsExceptLast);
|
||||
case Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_SET_TO_ZERO:
|
||||
return 0;
|
||||
case Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER:
|
||||
return lastSampleDurationVuFromEndOfStream;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected value for the last frame duration behavior " + lastSampleDurationBehavior);
|
||||
|
@ -23,7 +23,7 @@ import static androidx.media3.muxer.Boxes.BOX_HEADER_SIZE;
|
||||
import static androidx.media3.muxer.Boxes.MFHD_BOX_CONTENT_SIZE;
|
||||
import static androidx.media3.muxer.Boxes.TFHD_BOX_CONTENT_SIZE;
|
||||
import static androidx.media3.muxer.Boxes.getTrunBoxContentSize;
|
||||
import static androidx.media3.muxer.Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_DUPLICATE_PREVIOUS;
|
||||
import static androidx.media3.muxer.Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS;
|
||||
import static androidx.media3.muxer.MuxerUtil.UNSIGNED_INT_MAX_VALUE;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
@ -101,7 +101,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
this.annexBToAvccConverter = annexBToAvccConverter;
|
||||
this.fragmentDurationUs = fragmentDurationMs * 1_000;
|
||||
this.sampleCopyEnabled = sampleCopyEnabled;
|
||||
lastSampleDurationBehavior = LAST_SAMPLE_DURATION_BEHAVIOR_DUPLICATE_PREVIOUS;
|
||||
lastSampleDurationBehavior =
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS;
|
||||
tracks = new ArrayList<>();
|
||||
minInputPresentationTimeUs = Long.MAX_VALUE;
|
||||
currentFragmentSequenceNumber = 1;
|
||||
@ -334,7 +335,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
? minInputPresentationTimeUs
|
||||
: pendingSamplesBufferInfo.get(0).presentationTimeUs,
|
||||
track.videoUnitTimebase(),
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_DUPLICATE_PREVIOUS,
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS,
|
||||
track.endOfStreamTimestampUs);
|
||||
|
||||
List<Integer> sampleCompositionTimeOffsets =
|
||||
|
@ -147,20 +147,13 @@ public final class Mp4Muxer implements Muxer {
|
||||
@Target(TYPE_USE)
|
||||
@IntDef({
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_TO_ZERO,
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_DUPLICATE_PREVIOUS,
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS
|
||||
})
|
||||
public @interface LastSampleDurationBehavior {}
|
||||
|
||||
/** The duration of the last sample is set to 0. */
|
||||
public static final int LAST_SAMPLE_DURATION_BEHAVIOR_SET_TO_ZERO = 0;
|
||||
|
||||
/**
|
||||
* Use the difference between the last timestamp and the one before that as the duration of the
|
||||
* last sample.
|
||||
*/
|
||||
public static final int LAST_SAMPLE_DURATION_BEHAVIOR_DUPLICATE_PREVIOUS = 1;
|
||||
|
||||
/**
|
||||
* Use the {@link MediaCodec#BUFFER_FLAG_END_OF_STREAM end of stream sample} to set the duration
|
||||
* of the last sample.
|
||||
@ -174,9 +167,10 @@ public final class Mp4Muxer implements Muxer {
|
||||
* #writeSampleData written}, no more samples can be written for that track.
|
||||
*
|
||||
* <p>If no explicit {@link MediaCodec#BUFFER_FLAG_END_OF_STREAM} sample is passed, then the
|
||||
* duration of the last sample will be set to 0.
|
||||
* duration of the last sample will be same as that of the sample before that.
|
||||
*/
|
||||
public static final int LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER = 2;
|
||||
public static final int
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS = 1;
|
||||
|
||||
/** The specific MP4 file format. */
|
||||
@Documented
|
||||
@ -216,7 +210,8 @@ public final class Mp4Muxer implements Muxer {
|
||||
*/
|
||||
public Builder(FileOutputStream outputStream) {
|
||||
this.outputStream = outputStream;
|
||||
lastSampleDurationBehavior = LAST_SAMPLE_DURATION_BEHAVIOR_SET_TO_ZERO;
|
||||
lastSampleDurationBehavior =
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS;
|
||||
sampleCopyEnabled = true;
|
||||
attemptStreamableOutputEnabled = true;
|
||||
outputFileFormat = FILE_FORMAT_DEFAULT;
|
||||
@ -225,7 +220,8 @@ public final class Mp4Muxer implements Muxer {
|
||||
/**
|
||||
* Sets the {@link LastSampleDurationBehavior}.
|
||||
*
|
||||
* <p>The default value is {@link #LAST_SAMPLE_DURATION_BEHAVIOR_SET_TO_ZERO}.
|
||||
* <p>The default value is {@link
|
||||
* #LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS}.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Mp4Muxer.Builder setLastSampleDurationBehavior(
|
||||
|
@ -15,8 +15,7 @@
|
||||
*/
|
||||
package androidx.media3.muxer;
|
||||
|
||||
import static androidx.media3.muxer.Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_DUPLICATE_PREVIOUS;
|
||||
import static androidx.media3.muxer.Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER;
|
||||
import static androidx.media3.muxer.Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS;
|
||||
import static androidx.media3.muxer.Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_SET_TO_ZERO;
|
||||
import static androidx.media3.muxer.MuxerTestUtil.FAKE_AUDIO_FORMAT;
|
||||
import static androidx.media3.muxer.MuxerTestUtil.FAKE_CSD_0;
|
||||
@ -534,7 +533,7 @@ public class BoxesTest {
|
||||
sampleBufferInfos,
|
||||
/* firstSamplePresentationTimeUs= */ 0L,
|
||||
VU_TIMEBASE,
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_DUPLICATE_PREVIOUS,
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS,
|
||||
C.TIME_UNSET);
|
||||
|
||||
assertThat(durationsVu).containsExactly(3_000, 5_000, 5_000);
|
||||
@ -568,7 +567,7 @@ public class BoxesTest {
|
||||
sampleBufferInfos,
|
||||
/* firstSamplePresentationTimeUs= */ 0L,
|
||||
VU_TIMEBASE,
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER,
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS,
|
||||
/* endOfStreamTimestampUs= */ 10_000);
|
||||
|
||||
assertThat(durationsVu).containsExactly(100, 100, 100, 100, 600);
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
package androidx.media3.muxer;
|
||||
|
||||
import static androidx.media3.muxer.Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER;
|
||||
import static androidx.media3.muxer.Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS;
|
||||
import static androidx.media3.muxer.MuxerTestUtil.FAKE_VIDEO_FORMAT;
|
||||
import static androidx.media3.muxer.MuxerTestUtil.XMP_SAMPLE_DATA;
|
||||
import static androidx.media3.muxer.MuxerTestUtil.getFakeSampleAndSampleInfo;
|
||||
@ -683,7 +683,7 @@ public class Mp4MuxerEndToEndTest {
|
||||
Mp4Muxer mp4Muxer =
|
||||
new Mp4Muxer.Builder(new FileOutputStream(outputFilePath))
|
||||
.setLastSampleDurationBehavior(
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER)
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS)
|
||||
.build();
|
||||
mp4Muxer.addMetadataEntry(
|
||||
new Mp4TimestampData(
|
||||
@ -725,13 +725,13 @@ public class Mp4MuxerEndToEndTest {
|
||||
|
||||
@Test
|
||||
public void
|
||||
createMp4File_withLastSampleDurationBehaviorUsingEndOfStreamFlagButNoEndOfStreamSample_outputsDurationEqualsToLastSampleTimestamp()
|
||||
createMp4File_withLastSampleDurationBehaviorUsingEndOfStreamFlagButNoEndOfStreamSample_writesExpectedDurationForTheLastSample()
|
||||
throws Exception {
|
||||
String outputFilePath = temporaryFolder.newFile().getPath();
|
||||
Mp4Muxer mp4Muxer =
|
||||
new Mp4Muxer.Builder(new FileOutputStream(outputFilePath))
|
||||
.setLastSampleDurationBehavior(
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER)
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS)
|
||||
.build();
|
||||
mp4Muxer.addMetadataEntry(
|
||||
new Mp4TimestampData(
|
||||
@ -742,8 +742,8 @@ public class Mp4MuxerEndToEndTest {
|
||||
getFakeSampleAndSampleInfo(/* presentationTimeUs= */ 100L);
|
||||
Pair<ByteBuffer, BufferInfo> sample3 =
|
||||
getFakeSampleAndSampleInfo(/* presentationTimeUs= */ 200L);
|
||||
long lastSampleTimestampUs = 300L;
|
||||
Pair<ByteBuffer, BufferInfo> sample4 = getFakeSampleAndSampleInfo(lastSampleTimestampUs);
|
||||
Pair<ByteBuffer, BufferInfo> sample4 =
|
||||
getFakeSampleAndSampleInfo(/* presentationTimeUs= */ 300L);
|
||||
|
||||
try {
|
||||
TrackToken track = mp4Muxer.addTrack(FAKE_VIDEO_FORMAT);
|
||||
@ -759,7 +759,7 @@ public class Mp4MuxerEndToEndTest {
|
||||
TestUtil.extractAllSamplesFromFilePath(
|
||||
new Mp4Extractor(new DefaultSubtitleParserFactory()), outputFilePath);
|
||||
fakeExtractorOutput.track(/* id= */ 0, C.TRACK_TYPE_VIDEO).assertSampleCount(4);
|
||||
assertThat(fakeExtractorOutput.seekMap.getDurationUs()).isEqualTo(lastSampleTimestampUs);
|
||||
assertThat(fakeExtractorOutput.seekMap.getDurationUs()).isEqualTo(400L);
|
||||
}
|
||||
|
||||
private static void writeFakeSamples(Mp4Muxer muxer, TrackToken trackToken, int sampleCount)
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 933300
|
||||
duration = 999900
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052], [timeUs=533322, position=428455]]
|
||||
getPosition(466650) = [[timeUs=0, position=400052], [timeUs=533322, position=428455]]
|
||||
getPosition(933300) = [[timeUs=533322, position=428455]]
|
||||
getPosition(499950) = [[timeUs=0, position=400052], [timeUs=533322, position=428455]]
|
||||
getPosition(999900) = [[timeUs=533322, position=428455]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 50100
|
||||
@ -15,7 +15,7 @@ track 0:
|
||||
maxInputSize = 10464
|
||||
width = 176
|
||||
height = 144
|
||||
frameRate = 16.072002
|
||||
frameRate = 15.0015
|
||||
colorInfo:
|
||||
lumaBitdepth = 8
|
||||
chromaBitdepth = 8
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 933300
|
||||
duration = 999900
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052]]
|
||||
getPosition(466650) = [[timeUs=0, position=400052]]
|
||||
getPosition(933300) = [[timeUs=0, position=400052]]
|
||||
getPosition(499950) = [[timeUs=0, position=400052]]
|
||||
getPosition(999900) = [[timeUs=0, position=400052]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 45694
|
||||
@ -17,7 +17,7 @@ track 0:
|
||||
maxInputSize = 9256
|
||||
width = 176
|
||||
height = 144
|
||||
frameRate = 16.072002
|
||||
frameRate = 15.0015
|
||||
colorInfo:
|
||||
lumaBitdepth = 8
|
||||
chromaBitdepth = 8
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 2992000
|
||||
duration = 3008000
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=1, position=400241]]
|
||||
getPosition(1496000) = [[timeUs=1496000, position=412467]]
|
||||
getPosition(2992000) = [[timeUs=2992000, position=424658]]
|
||||
getPosition(1504000) = [[timeUs=1504000, position=412467]]
|
||||
getPosition(3008000) = [[timeUs=3008000, position=424658]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 24785
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 2966600
|
||||
duration = 3000000
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052], [timeUs=1000000, position=578564]]
|
||||
getPosition(1483300) = [[timeUs=1000000, position=578564], [timeUs=2000000, position=671623]]
|
||||
getPosition(2966600) = [[timeUs=2000000, position=671623]]
|
||||
getPosition(1500000) = [[timeUs=1000000, position=578564], [timeUs=2000000, position=671623]]
|
||||
getPosition(3000000) = [[timeUs=2000000, position=671623]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 378802
|
||||
@ -15,7 +15,7 @@ track 0:
|
||||
maxInputSize = 115022
|
||||
width = 642
|
||||
height = 642
|
||||
frameRate = 30.33776
|
||||
frameRate = 30.0
|
||||
colorInfo:
|
||||
colorSpace = 1
|
||||
colorRange = 2
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 2993500
|
||||
duration = 3013500
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=1, position=400052]]
|
||||
getPosition(1496750) = [[timeUs=1496750, position=449844]]
|
||||
getPosition(2993500) = [[timeUs=2993500, position=499769]]
|
||||
getPosition(1506750) = [[timeUs=1506750, position=449844]]
|
||||
getPosition(3013500) = [[timeUs=3013500, position=499769]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 100872
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 3966600
|
||||
duration = 3999900
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052], [timeUs=1000000, position=552554]]
|
||||
getPosition(1983300) = [[timeUs=1000000, position=552554], [timeUs=2000000, position=638317]]
|
||||
getPosition(3966600) = [[timeUs=3000000, position=753611]]
|
||||
getPosition(1999950) = [[timeUs=1000000, position=552554], [timeUs=2000000, position=638317]]
|
||||
getPosition(3999900) = [[timeUs=3000000, position=753611]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 416333
|
||||
@ -17,7 +17,7 @@ track 0:
|
||||
maxNumReorderSamples = 1
|
||||
width = 800
|
||||
height = 640
|
||||
frameRate = 30.25261
|
||||
frameRate = 30.00075
|
||||
colorInfo:
|
||||
lumaBitdepth = 8
|
||||
chromaBitdepth = 8
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 3966600
|
||||
duration = 3999900
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052], [timeUs=1000000, position=547447]]
|
||||
getPosition(1983300) = [[timeUs=1000000, position=547447], [timeUs=2000000, position=631674]]
|
||||
getPosition(3966600) = [[timeUs=3000000, position=744000]]
|
||||
getPosition(1999950) = [[timeUs=1000000, position=547447], [timeUs=2000000, position=631674]]
|
||||
getPosition(3999900) = [[timeUs=3000000, position=744000]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 406132
|
||||
@ -17,7 +17,7 @@ track 0:
|
||||
maxNumReorderSamples = 2
|
||||
width = 800
|
||||
height = 640
|
||||
frameRate = 30.25261
|
||||
frameRate = 30.00075
|
||||
colorInfo:
|
||||
lumaBitdepth = 8
|
||||
chromaBitdepth = 8
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 3966600
|
||||
duration = 3999900
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052]]
|
||||
getPosition(1983300) = [[timeUs=0, position=400052]]
|
||||
getPosition(3966600) = [[timeUs=0, position=400052]]
|
||||
getPosition(1999950) = [[timeUs=0, position=400052]]
|
||||
getPosition(3999900) = [[timeUs=0, position=400052]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 305806
|
||||
@ -15,7 +15,7 @@ track 0:
|
||||
maxInputSize = 100600
|
||||
width = 800
|
||||
height = 640
|
||||
frameRate = 30.25261
|
||||
frameRate = 30.00075
|
||||
colorInfo:
|
||||
colorRange = 2
|
||||
lumaBitdepth = 8
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 2980000
|
||||
duration = 3000000
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=1, position=400052]]
|
||||
getPosition(1490000) = [[timeUs=1490000, position=404418]]
|
||||
getPosition(2980000) = [[timeUs=2980000, position=408843]]
|
||||
getPosition(1500000) = [[timeUs=1500000, position=404477]]
|
||||
getPosition(3000000) = [[timeUs=3000000, position=408843]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 8850
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 3000000
|
||||
duration = 3020000
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=1, position=400052]]
|
||||
getPosition(1500000) = [[timeUs=1500000, position=402452]]
|
||||
getPosition(3000000) = [[timeUs=3000000, position=404852]]
|
||||
getPosition(1510000) = [[timeUs=1510000, position=402452]]
|
||||
getPosition(3020000) = [[timeUs=3020000, position=404852]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 4832
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 66700
|
||||
duration = 100000
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052]]
|
||||
getPosition(33350) = [[timeUs=0, position=400052]]
|
||||
getPosition(66700) = [[timeUs=0, position=400052]]
|
||||
getPosition(50000) = [[timeUs=0, position=400052]]
|
||||
getPosition(100000) = [[timeUs=0, position=400052]]
|
||||
numberOfTracks = 3
|
||||
track 0:
|
||||
total output bytes = 387
|
||||
@ -65,7 +65,7 @@ track 2:
|
||||
maxNumReorderSamples = 0
|
||||
width = 1920
|
||||
height = 1080
|
||||
frameRate = 44.977512
|
||||
frameRate = 30.0
|
||||
colorInfo:
|
||||
colorSpace = 2
|
||||
colorRange = 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 4203200
|
||||
duration = 4236500
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052], [timeUs=1002944, position=2283470]]
|
||||
getPosition(2101600) = [[timeUs=2003555, position=4184649], [timeUs=3003433, position=4426916]]
|
||||
getPosition(4203200) = [[timeUs=4003266, position=6438541]]
|
||||
getPosition(2118250) = [[timeUs=2003555, position=4184649], [timeUs=3003433, position=4426916]]
|
||||
getPosition(4236500) = [[timeUs=4003266, position=6438541]]
|
||||
numberOfTracks = 2
|
||||
track 0:
|
||||
total output bytes = 7944083
|
||||
@ -17,7 +17,7 @@ track 0:
|
||||
maxNumReorderSamples = 0
|
||||
width = 1280
|
||||
height = 720
|
||||
frameRate = 30.215075
|
||||
frameRate = 29.977577
|
||||
colorInfo:
|
||||
colorSpace = 6
|
||||
colorRange = 2
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 3000
|
||||
duration = 4000
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052], [timeUs=3000, position=400108]]
|
||||
getPosition(1500) = [[timeUs=0, position=400052], [timeUs=3000, position=400108]]
|
||||
getPosition(3000) = [[timeUs=3000, position=400108]]
|
||||
getPosition(2000) = [[timeUs=0, position=400052], [timeUs=3000, position=400108]]
|
||||
getPosition(4000) = [[timeUs=2000, position=400220]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 224
|
||||
@ -17,7 +17,7 @@ track 0:
|
||||
maxNumReorderSamples = 2
|
||||
width = 12
|
||||
height = 10
|
||||
frameRate = 1333.3334
|
||||
frameRate = 999.99994
|
||||
colorInfo:
|
||||
colorRange = 1
|
||||
lumaBitdepth = 8
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 273900
|
||||
duration = 414800
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052], [timeUs=273900, position=400108]]
|
||||
getPosition(136950) = [[timeUs=0, position=400052], [timeUs=273900, position=400108]]
|
||||
getPosition(273900) = [[timeUs=273900, position=400108]]
|
||||
getPosition(207400) = [[timeUs=0, position=400052], [timeUs=273900, position=400108]]
|
||||
getPosition(414800) = [[timeUs=33188, position=400220]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 224
|
||||
@ -17,7 +17,7 @@ track 0:
|
||||
maxNumReorderSamples = 2
|
||||
width = 12
|
||||
height = 10
|
||||
frameRate = 14.603869
|
||||
frameRate = 9.643202
|
||||
colorInfo:
|
||||
colorRange = 1
|
||||
lumaBitdepth = 8
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 4137400
|
||||
duration = 4171600
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052], [timeUs=1002944, position=2283470]]
|
||||
getPosition(2068700) = [[timeUs=2003555, position=4184649], [timeUs=3003433, position=4426916]]
|
||||
getPosition(4137400) = [[timeUs=4003266, position=6438541]]
|
||||
getPosition(2085800) = [[timeUs=2003555, position=4184649], [timeUs=3003433, position=4426916]]
|
||||
getPosition(4171600) = [[timeUs=4003266, position=6438541]]
|
||||
numberOfTracks = 2
|
||||
track 0:
|
||||
total output bytes = 7822354
|
||||
@ -17,7 +17,7 @@ track 0:
|
||||
maxNumReorderSamples = 0
|
||||
width = 1280
|
||||
height = 720
|
||||
frameRate = 30.21221
|
||||
frameRate = 29.964523
|
||||
colorInfo:
|
||||
colorSpace = 6
|
||||
colorRange = 2
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 1064600
|
||||
duration = 1087800
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052]]
|
||||
getPosition(532300) = [[timeUs=0, position=400052]]
|
||||
getPosition(1064600) = [[timeUs=0, position=400052]]
|
||||
getPosition(543900) = [[timeUs=0, position=400052]]
|
||||
getPosition(1087800) = [[timeUs=0, position=400052]]
|
||||
numberOfTracks = 2
|
||||
track 0:
|
||||
total output bytes = 69084
|
||||
@ -15,7 +15,7 @@ track 0:
|
||||
maxInputSize = 46460
|
||||
width = 1080
|
||||
height = 720
|
||||
frameRate = 31.004547
|
||||
frameRate = 29.973022
|
||||
colorInfo:
|
||||
lumaBitdepth = 8
|
||||
chromaBitdepth = 8
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 1065600
|
||||
duration = 1088800
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052]]
|
||||
getPosition(532800) = [[timeUs=0, position=400052]]
|
||||
getPosition(1065600) = [[timeUs=0, position=400052]]
|
||||
getPosition(544400) = [[timeUs=0, position=400052]]
|
||||
getPosition(1088800) = [[timeUs=0, position=400052]]
|
||||
numberOfTracks = 2
|
||||
track 0:
|
||||
total output bytes = 9529
|
||||
@ -211,7 +211,7 @@ track 1:
|
||||
maxNumReorderSamples = 0
|
||||
width = 1080
|
||||
height = 720
|
||||
frameRate = 31.004547
|
||||
frameRate = 29.973022
|
||||
colorInfo:
|
||||
colorSpace = 1
|
||||
colorRange = 2
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 933300
|
||||
duration = 999900
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052], [timeUs=533322, position=428455]]
|
||||
getPosition(466650) = [[timeUs=0, position=400052], [timeUs=533322, position=428455]]
|
||||
getPosition(933300) = [[timeUs=533322, position=428455]]
|
||||
getPosition(499950) = [[timeUs=0, position=400052], [timeUs=533322, position=428455]]
|
||||
getPosition(999900) = [[timeUs=533322, position=428455]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 50100
|
||||
@ -15,7 +15,7 @@ track 0:
|
||||
maxInputSize = 10464
|
||||
width = 176
|
||||
height = 144
|
||||
frameRate = 16.072002
|
||||
frameRate = 15.0015
|
||||
colorInfo:
|
||||
colorRange = 2
|
||||
lumaBitdepth = 8
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 933300
|
||||
duration = 999900
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052]]
|
||||
getPosition(466650) = [[timeUs=0, position=400052]]
|
||||
getPosition(933300) = [[timeUs=0, position=400052]]
|
||||
getPosition(499950) = [[timeUs=0, position=400052]]
|
||||
getPosition(999900) = [[timeUs=0, position=400052]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 45694
|
||||
@ -17,7 +17,7 @@ track 0:
|
||||
maxInputSize = 9256
|
||||
width = 176
|
||||
height = 144
|
||||
frameRate = 16.072002
|
||||
frameRate = 15.0015
|
||||
colorInfo:
|
||||
colorRange = 2
|
||||
lumaBitdepth = 8
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 2992000
|
||||
duration = 3008000
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=1, position=400241]]
|
||||
getPosition(1496000) = [[timeUs=1496000, position=412467]]
|
||||
getPosition(2992000) = [[timeUs=2992000, position=424658]]
|
||||
getPosition(1504000) = [[timeUs=1504000, position=412467]]
|
||||
getPosition(3008000) = [[timeUs=3008000, position=424658]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 24785
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 3000000
|
||||
duration = 3020000
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=1, position=400052]]
|
||||
getPosition(1500000) = [[timeUs=1500000, position=449844]]
|
||||
getPosition(3000000) = [[timeUs=3000000, position=499769]]
|
||||
getPosition(1510000) = [[timeUs=1510000, position=449844]]
|
||||
getPosition(3020000) = [[timeUs=3020000, position=499769]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 100872
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 2980000
|
||||
duration = 3000000
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=1, position=400052]]
|
||||
getPosition(1490000) = [[timeUs=1490000, position=404418]]
|
||||
getPosition(2980000) = [[timeUs=2980000, position=408843]]
|
||||
getPosition(1500000) = [[timeUs=1500000, position=404477]]
|
||||
getPosition(3000000) = [[timeUs=3000000, position=408843]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 8850
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 3000000
|
||||
duration = 3020000
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=1, position=400052]]
|
||||
getPosition(1500000) = [[timeUs=1500000, position=402452]]
|
||||
getPosition(3000000) = [[timeUs=3000000, position=404852]]
|
||||
getPosition(1510000) = [[timeUs=1510000, position=402452]]
|
||||
getPosition(3020000) = [[timeUs=3020000, position=404852]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 4832
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 66700
|
||||
duration = 100000
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052]]
|
||||
getPosition(33350) = [[timeUs=0, position=400052]]
|
||||
getPosition(66700) = [[timeUs=0, position=400052]]
|
||||
getPosition(50000) = [[timeUs=0, position=400052]]
|
||||
getPosition(100000) = [[timeUs=0, position=400052]]
|
||||
numberOfTracks = 2
|
||||
track 0:
|
||||
total output bytes = 678996
|
||||
@ -17,7 +17,7 @@ track 0:
|
||||
maxNumReorderSamples = 0
|
||||
width = 1920
|
||||
height = 1080
|
||||
frameRate = 44.977512
|
||||
frameRate = 30.0
|
||||
rotationDegrees = 90
|
||||
colorInfo:
|
||||
colorSpace = 2
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 1064600
|
||||
duration = 1087800
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052]]
|
||||
getPosition(532300) = [[timeUs=0, position=400052]]
|
||||
getPosition(1064600) = [[timeUs=0, position=400052]]
|
||||
getPosition(543900) = [[timeUs=0, position=400052]]
|
||||
getPosition(1087800) = [[timeUs=0, position=400052]]
|
||||
numberOfTracks = 2
|
||||
track 0:
|
||||
total output bytes = 69084
|
||||
@ -15,7 +15,7 @@ track 0:
|
||||
maxInputSize = 46460
|
||||
width = 1080
|
||||
height = 720
|
||||
frameRate = 31.004547
|
||||
frameRate = 29.973022
|
||||
colorInfo:
|
||||
colorRange = 2
|
||||
lumaBitdepth = 8
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 1065600
|
||||
duration = 1088800
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052]]
|
||||
getPosition(532800) = [[timeUs=0, position=400052]]
|
||||
getPosition(1065600) = [[timeUs=0, position=400052]]
|
||||
getPosition(544400) = [[timeUs=0, position=400052]]
|
||||
getPosition(1088800) = [[timeUs=0, position=400052]]
|
||||
numberOfTracks = 2
|
||||
track 0:
|
||||
total output bytes = 301213
|
||||
@ -17,7 +17,7 @@ track 0:
|
||||
maxNumReorderSamples = 0
|
||||
width = 1080
|
||||
height = 720
|
||||
frameRate = 31.004547
|
||||
frameRate = 29.973022
|
||||
colorInfo:
|
||||
colorSpace = 1
|
||||
colorRange = 2
|
||||
|
@ -1,10 +1,10 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 966600
|
||||
duration = 999900
|
||||
getPosition(0) = [[timeUs=0, position=400052]]
|
||||
getPosition(1) = [[timeUs=0, position=400052], [timeUs=333333, position=416043]]
|
||||
getPosition(483300) = [[timeUs=333333, position=416043], [timeUs=666666, position=428793]]
|
||||
getPosition(966600) = [[timeUs=666666, position=428793]]
|
||||
getPosition(499950) = [[timeUs=333333, position=416043], [timeUs=666666, position=428793]]
|
||||
getPosition(999900) = [[timeUs=666666, position=428793]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 41647
|
||||
@ -17,7 +17,7 @@ track 0:
|
||||
maxNumReorderSamples = 2
|
||||
width = 854
|
||||
height = 480
|
||||
frameRate = 31.036623
|
||||
frameRate = 30.003
|
||||
colorInfo:
|
||||
colorRange = 2
|
||||
lumaBitdepth = 8
|
||||
|
@ -1813,7 +1813,7 @@ public class TransformerEndToEndTest {
|
||||
FakeExtractorOutput fakeExtractorOutput =
|
||||
TestUtil.extractAllSamplesFromFilePath(mp4Extractor, exportTestResult.filePath);
|
||||
// TODO: b/324903070 - The generated output file has incorrect duration.
|
||||
assertThat(fakeExtractorOutput.seekMap.getDurationUs()).isEqualTo(1_555_700);
|
||||
assertThat(fakeExtractorOutput.seekMap.getDurationUs()).isEqualTo(1_578_900);
|
||||
assertThat(fakeExtractorOutput.numberOfTracks).isEqualTo(1);
|
||||
FakeTrackOutput audioTrack = fakeExtractorOutput.trackOutputs.get(0);
|
||||
int expectedSampleCount = 68;
|
||||
|
@ -16,7 +16,7 @@
|
||||
package androidx.media3.transformer;
|
||||
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static androidx.media3.muxer.Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER;
|
||||
import static androidx.media3.muxer.Mp4Muxer.LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS;
|
||||
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaCodec.BufferInfo;
|
||||
@ -153,7 +153,7 @@ public final class InAppMuxer implements Muxer {
|
||||
*
|
||||
* <p>The default is {@link C#TIME_UNSET} to not set any duration in the output. In this case
|
||||
* the video track duration is determined by the samples written to it and the duration of the
|
||||
* last sample is set to 0.
|
||||
* last sample will be same as that of the sample before that.
|
||||
*
|
||||
* @param videoDurationUs The duration of the video track (in microseconds) in the output, or
|
||||
* {@link C#TIME_UNSET} to not set any duration. Only applicable when a video track is
|
||||
@ -186,7 +186,7 @@ public final class InAppMuxer implements Muxer {
|
||||
Mp4Muxer.Builder builder = new Mp4Muxer.Builder(outputStream);
|
||||
if (videoDurationUs != C.TIME_UNSET) {
|
||||
builder.setLastSampleDurationBehavior(
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER);
|
||||
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS);
|
||||
}
|
||||
muxer = builder.build();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user