Mp4Muxer: disable sample batching and copying by default.

When sample batching is disabled, copying of the ByteBuffer data
is not necessary as samples are written as they arrive.
Copying of the BufferInfo is necessary because the info is needed
for writing the moov atom.

The input ByteBuffer can be in little endian order, or have its
position set. AnnexBUtils now ensures big endian order before
inspecting bytes, and supports reading from a non-zero position.

This change reduces the amount of memory allocations by Mp4Muxer
in its default configuration

PiperOrigin-RevId: 723401822
This commit is contained in:
dancho 2025-02-05 01:02:25 -08:00 committed by Copybara-Service
parent 05e66d9cf6
commit f8f66bdfaa
16 changed files with 162 additions and 273 deletions

View File

@ -24,6 +24,7 @@
* DRM:
* Effect:
* Muxers:
* Disable `Mp4Muxer` sample batching and copying by default.
* IMA extension:
* Session:
* UI:

View File

@ -15,8 +15,6 @@
*/
package androidx.media3.muxer;
import static androidx.media3.common.util.Assertions.checkArgument;
import androidx.media3.common.util.UnstableApi;
import com.google.common.collect.ImmutableList;
import java.nio.ByteBuffer;
@ -35,9 +33,6 @@ public interface AnnexBToAvccConverter {
return inputBuffer;
}
checkArgument(
inputBuffer.position() == 0, "The input buffer should have position set to 0.");
ImmutableList<ByteBuffer> nalUnitList = AnnexBUtils.findNalUnits(inputBuffer);
int totalBytesNeeded = 0;

View File

@ -20,6 +20,7 @@ import static androidx.media3.common.util.Assertions.checkState;
import androidx.media3.common.MimeTypes;
import com.google.common.collect.ImmutableList;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/** NAL unit utilities for start codes and emulation prevention. */
/* package */ final class AnnexBUtils {
@ -40,11 +41,13 @@ import java.nio.ByteBuffer;
if (input.remaining() == 0) {
return ImmutableList.of();
}
input = input.asReadOnlyBuffer();
input.order(ByteOrder.BIG_ENDIAN);
// The algorithm always searches for 0x000001 start code but it will work for 0x00000001 start
// code as well because the first 0 will be considered as a leading 0 and will be skipped.
int nalStartCodeIndex = skipLeadingZerosAndFindNalStartCodeIndex(input, /* currentIndex= */ 0);
int nalStartCodeIndex = skipLeadingZerosAndFindNalStartCodeIndex(input, input.position());
int nalStartIndex = nalStartCodeIndex + THREE_BYTE_NAL_START_CODE_SIZE;
boolean readingNalUnit = true;
@ -69,7 +72,6 @@ import java.nio.ByteBuffer;
}
}
input.rewind();
return nalUnits.build();
}

View File

@ -219,8 +219,6 @@ public final class Mp4Muxer implements AutoCloseable {
this.outputStream = outputStream;
lastSampleDurationBehavior =
LAST_SAMPLE_DURATION_BEHAVIOR_SET_FROM_END_OF_STREAM_BUFFER_OR_DUPLICATE_PREVIOUS;
sampleCopyEnabled = true;
sampleBatchingEnabled = true;
attemptStreamableOutputEnabled = true;
outputFileFormat = FILE_FORMAT_DEFAULT;
}
@ -259,7 +257,11 @@ public final class Mp4Muxer implements AutoCloseable {
* to reuse them immediately. Otherwise, the muxer takes ownership of the {@link ByteBuffer} and
* the {@link BufferInfo} and the caller must not modify them.
*
* <p>The default value is {@code true}.
* <p>When {@linkplain #setSampleBatchingEnabled(boolean) sample batching} is disabled, samples
* are written as they {@linkplain #writeSampleData(int, ByteBuffer, BufferInfo) arrive} and
* sample copying is disabled.
*
* <p>The default value is {@code false}.
*/
@CanIgnoreReturnValue
public Mp4Muxer.Builder setSampleCopyingEnabled(boolean enabled) {
@ -274,7 +276,13 @@ public final class Mp4Muxer implements AutoCloseable {
* samples are written as they {@linkplain #writeSampleData(int, ByteBuffer, BufferInfo)
* arrive}.
*
* <p>The default value is {@code true}.
* <p>When sample batching is enabled, and {@linkplain #setSampleCopyingEnabled(boolean) sample
* copying} is disabled the {@link ByteBuffer} contents provided to {@link #writeSampleData(int,
* ByteBuffer, BufferInfo)} should not be modified. Otherwise, if sample batching is disabled or
* sample copying is enabled, the {@linkplain ByteBuffer sample data} contents can be modified
* after calling {@link #writeSampleData(int, ByteBuffer, BufferInfo)}.
*
* <p>The default value is {@code false}.
*/
@CanIgnoreReturnValue
public Mp4Muxer.Builder setSampleBatchingEnabled(boolean enabled) {
@ -391,7 +399,7 @@ public final class Mp4Muxer implements AutoCloseable {
outputChannel = outputStream.getChannel();
this.lastSampleDurationBehavior = lastFrameDurationBehavior;
this.annexBToAvccConverter = annexBToAvccConverter;
this.sampleCopyEnabled = sampleCopyEnabled;
this.sampleCopyEnabled = sampleBatchingEnabled && sampleCopyEnabled;
this.sampleBatchingEnabled = sampleBatchingEnabled;
this.attemptStreamableOutputEnabled = attemptStreamableOutputEnabled;
this.outputFileFormat = outputFileFormat;
@ -470,14 +478,6 @@ public final class Mp4Muxer implements AutoCloseable {
/**
* Writes encoded sample data.
*
* <p>When sample batching is {@linkplain Mp4Muxer.Builder#setSampleBatchingEnabled(boolean)
* enabled}, provide sample data ({@link ByteBuffer}, {@link BufferInfo}) that won't be modified
* after calling the {@link #writeSampleData(int, ByteBuffer, BufferInfo)} method, unless sample
* copying is also {@linkplain Mp4Muxer.Builder#setSampleCopyingEnabled(boolean) enabled}. This
* ensures data integrity within the batch. If sample copying is {@linkplain
* Mp4Muxer.Builder#setSampleCopyingEnabled(boolean) enabled}, it's safe to modify the data after
* the method returns, as the muxer internally creates a sample copy.
*
* @param trackId The track id for which this sample is being written.
* @param byteBuffer The encoded sample. The muxer takes ownership of the buffer if {@link
* Builder#setSampleCopyingEnabled(boolean) sample copying} is disabled. Otherwise, the

View File

@ -92,22 +92,21 @@ import java.util.List;
}
ByteBuffer byteBufferToAdd = byteBuffer;
BufferInfo bufferInfoToAdd = bufferInfo;
if (sampleCopyEnabled) {
// Copy sample data and release the original buffer.
byteBufferToAdd = ByteBuffer.allocateDirect(byteBuffer.remaining());
byteBufferToAdd.put(byteBuffer);
byteBufferToAdd.rewind();
bufferInfoToAdd = new BufferInfo();
bufferInfoToAdd.set(
/* newOffset= */ byteBufferToAdd.position(),
/* newSize= */ byteBufferToAdd.remaining(),
bufferInfo.presentationTimeUs,
bufferInfo.flags);
}
// Always copy the buffer info as it is retained until the track is finalized.
BufferInfo bufferInfoToAdd = new BufferInfo();
bufferInfoToAdd.set(
/* newOffset= */ byteBufferToAdd.position(),
/* newSize= */ byteBufferToAdd.remaining(),
bufferInfo.presentationTimeUs,
bufferInfo.flags);
pendingSamplesBufferInfo.addLast(bufferInfoToAdd);
pendingSamplesByteBuffer.addLast(byteBufferToAdd);
}

View File

@ -22,6 +22,7 @@ import static org.junit.Assert.assertThrows;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -53,6 +54,17 @@ public class AnnexBUtilsTest {
assertThat(components).containsExactly(ByteBuffer.wrap(getBytesFromHexString("ABCDEF")));
}
@Test
public void
findNalUnits_singleNalUnitWithFourByteStartCodeAndLittleEndianOrder_returnsSingleElement() {
ByteBuffer buffer =
ByteBuffer.wrap(getBytesFromHexString("00000001ABCDEF")).order(ByteOrder.LITTLE_ENDIAN);
ImmutableList<ByteBuffer> components = AnnexBUtils.findNalUnits(buffer);
assertThat(components).containsExactly(ByteBuffer.wrap(getBytesFromHexString("ABCDEF")));
}
@Test
public void findNalUnits_singleNalUnitWithThreeByteStartCode_returnsSingleElement() {
ByteBuffer buffer = ByteBuffer.wrap(getBytesFromHexString("000001ABCDEF"));
@ -100,6 +112,34 @@ public class AnnexBUtilsTest {
assertThrows(IllegalStateException.class, () -> AnnexBUtils.findNalUnits(buffer));
}
@Test
public void findNalUnits_withPositionAndLimitSet_returnsNalUnit() {
ByteBuffer buffer =
ByteBuffer.wrap(getBytesFromHexString("12345600000001ABCDEF002233445566778899"));
buffer.position(3);
buffer.limit(10);
ImmutableList<ByteBuffer> components = AnnexBUtils.findNalUnits(buffer);
assertThat(components).containsExactly(ByteBuffer.wrap(getBytesFromHexString("ABCDEF")));
}
@Test
public void findNalUnits_withMultipleNalUnitsAndPositionSet_returnsAllNalUnits() {
ByteBuffer buffer =
ByteBuffer.wrap(getBytesFromHexString("123456000001ABCDEF000001DDCC000001BBAA"));
buffer.position(3);
ImmutableList<ByteBuffer> components = AnnexBUtils.findNalUnits(buffer);
assertThat(components)
.containsExactly(
ByteBuffer.wrap(getBytesFromHexString("ABCDEF")),
ByteBuffer.wrap(getBytesFromHexString("DDCC")),
ByteBuffer.wrap(getBytesFromHexString("BBAA")))
.inOrder();
}
@Test
public void findNalUnits_withTrailingZeroes_stripsTrailingZeroes() {
// The first NAL unit has some training zeroes.

View File

@ -138,8 +138,10 @@ public class Mp4MuxerEndToEndTest {
// Muxer not closed.
// Audio sample written = 192 out of 195.
// Video sample written = 125 out of 127.
// The output depends on Mp4Muxer.MOOV_BOX_UPDATE_INTERVAL_US and whether or not
// sample batching is enabled.
// Audio sample written = 187 out of 195.
// Video sample written = 93 out of 127.
// Output is still a valid MP4 file.
FakeExtractorOutput fakeExtractorOutput =
TestUtil.extractAllSamplesFromFilePath(

View File

@ -20,7 +20,6 @@ import static androidx.media3.container.MdtaMetadataEntry.TYPE_INDICATOR_FLOAT32
import static androidx.media3.container.MdtaMetadataEntry.TYPE_INDICATOR_STRING;
import static androidx.media3.muxer.MuxerTestUtil.FAKE_VIDEO_FORMAT;
import static androidx.media3.muxer.MuxerTestUtil.XMP_SAMPLE_DATA;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.media.MediaCodec.BufferInfo;
@ -292,7 +291,6 @@ public class Mp4MuxerMetadataTest {
try {
muxer.writeSampleData(trackId, sampleAndSampleInfo.first, sampleAndSampleInfo.second);
assertThat(sampleAndSampleInfo.first.remaining()).isEqualTo(0);
} finally {
muxer.close();
}

View File

@ -3,8 +3,8 @@ seekMap:
duration = 4236600
getPosition(0) = [[timeUs=0, position=400052]]
getPosition(1) = [[timeUs=0, position=400052], [timeUs=1002955, position=430177]]
getPosition(2118300) = [[timeUs=2003566, position=2503758], [timeUs=3003444, position=4426916]]
getPosition(4236600) = [[timeUs=4003277, position=4459282]]
getPosition(2118300) = [[timeUs=2003566, position=2562813], [timeUs=3003444, position=4426916]]
getPosition(4236600) = [[timeUs=4003277, position=6370233]]
numberOfTracks = 2
track 0:
total output bytes = 7944083

View File

@ -1,6 +1,6 @@
ftyp (28 bytes):
Data = length 20, hash EF896440
moov (881 bytes):
moov (913 bytes):
mvhd (108 bytes):
Data = length 100, hash 2613A5C
meta (191 bytes):
@ -10,20 +10,20 @@ moov (881 bytes):
Data = length 70, hash C5147150
ilst (72 bytes):
Data = length 64, hash 3B286CD9
trak (574 bytes):
trak (606 bytes):
tkhd (92 bytes):
Data = length 84, hash 3D79758F
mdia (474 bytes):
mdia (506 bytes):
mdhd (32 bytes):
Data = length 24, hash 41542D81
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (390 bytes):
minf (422 bytes):
vmhd (20 bytes):
Data = length 12, hash EE830681
dinf (36 bytes):
Data = length 28, hash D535436B
stbl (326 bytes):
stbl (358 bytes):
stsd (166 bytes):
Data = length 158, hash 11532063
stts (24 bytes):
@ -31,19 +31,19 @@ moov (881 bytes):
stsz (40 bytes):
Data = length 32, hash B3F09E
stsc (28 bytes):
Data = length 20, hash 8FA6E089
co64 (24 bytes):
Data = length 16, hash E4EE6662
Data = length 20, hash 8F6E8285
co64 (56 bytes):
Data = length 48, hash A4175473
stss (36 bytes):
Data = length 28, hash 53024615
free (399127 bytes):
Data = length 399119, hash 82DEBDDF
free (399095 bytes):
Data = length 399087, hash A215F9DF
mdat (296 bytes):
Data = length 280, hash 8DCFD2E3
axte (400628 bytes):
ftyp (28 bytes):
Data = length 20, hash EF896440
moov (1446 bytes):
moov (1510 bytes):
mvhd (108 bytes):
Data = length 100, hash 2613A5D
meta (182 bytes):
@ -53,20 +53,20 @@ axte (400628 bytes):
Data = length 72, hash 4E5C3894
ilst (61 bytes):
Data = length 53, hash 75D49FBD
trak (574 bytes):
trak (606 bytes):
tkhd (92 bytes):
Data = length 84, hash 3D79758F
mdia (474 bytes):
mdia (506 bytes):
mdhd (32 bytes):
Data = length 24, hash 41542D81
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (390 bytes):
minf (422 bytes):
vmhd (20 bytes):
Data = length 12, hash EE830681
dinf (36 bytes):
Data = length 28, hash D535436B
stbl (326 bytes):
stbl (358 bytes):
stsd (166 bytes):
Data = length 158, hash 11532063
stts (24 bytes):
@ -74,25 +74,25 @@ axte (400628 bytes):
stsz (40 bytes):
Data = length 32, hash B3F09E
stsc (28 bytes):
Data = length 20, hash 8FA6E089
co64 (24 bytes):
Data = length 16, hash E4EE6662
Data = length 20, hash 8F6E8285
co64 (56 bytes):
Data = length 48, hash A4175473
stss (36 bytes):
Data = length 28, hash 53024615
trak (574 bytes):
trak (606 bytes):
tkhd (92 bytes):
Data = length 84, hash 2ECB0510
mdia (474 bytes):
mdia (506 bytes):
mdhd (32 bytes):
Data = length 24, hash 41542D81
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (390 bytes):
minf (422 bytes):
vmhd (20 bytes):
Data = length 12, hash EE830681
dinf (36 bytes):
Data = length 28, hash D535436B
stbl (326 bytes):
stbl (358 bytes):
stsd (166 bytes):
Data = length 158, hash 11532063
stts (24 bytes):
@ -100,12 +100,12 @@ axte (400628 bytes):
stsz (40 bytes):
Data = length 32, hash B3F09E
stsc (28 bytes):
Data = length 20, hash 8FA6E089
co64 (24 bytes):
Data = length 16, hash E4EE6699
Data = length 20, hash 8F6E8285
co64 (56 bytes):
Data = length 48, hash 44DD22A5
stss (36 bytes):
Data = length 28, hash 53024615
free (398562 bytes):
Data = length 398554, hash C1D2F8C1
free (398498 bytes):
Data = length 398490, hash B07980C1
mdat (576 bytes):
Data = length 560, hash 9E0D5FC5

View File

@ -1,22 +1,22 @@
ftyp (28 bytes):
Data = length 20, hash EF896440
moov (1838 bytes):
moov (1934 bytes):
mvhd (108 bytes):
Data = length 100, hash 2613A5E
trak (574 bytes):
trak (606 bytes):
tkhd (92 bytes):
Data = length 84, hash 3D79758F
mdia (474 bytes):
mdia (506 bytes):
mdhd (32 bytes):
Data = length 24, hash 41542D81
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (390 bytes):
minf (422 bytes):
vmhd (20 bytes):
Data = length 12, hash EE830681
dinf (36 bytes):
Data = length 28, hash D535436B
stbl (326 bytes):
stbl (358 bytes):
stsd (166 bytes):
Data = length 158, hash 11532063
stts (24 bytes):
@ -24,25 +24,25 @@ moov (1838 bytes):
stsz (40 bytes):
Data = length 32, hash B3F09E
stsc (28 bytes):
Data = length 20, hash 8FA6E089
co64 (24 bytes):
Data = length 16, hash E4EE6662
Data = length 20, hash 8F6E8285
co64 (56 bytes):
Data = length 48, hash A4175473
stss (36 bytes):
Data = length 28, hash 53024615
trak (574 bytes):
trak (606 bytes):
tkhd (92 bytes):
Data = length 84, hash 2ECB0510
mdia (474 bytes):
mdia (506 bytes):
mdhd (32 bytes):
Data = length 24, hash 41542D81
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (390 bytes):
minf (422 bytes):
vmhd (20 bytes):
Data = length 12, hash EE830681
dinf (36 bytes):
Data = length 28, hash D535436B
stbl (326 bytes):
stbl (358 bytes):
stsd (166 bytes):
Data = length 158, hash 11532063
stts (24 bytes):
@ -50,25 +50,25 @@ moov (1838 bytes):
stsz (40 bytes):
Data = length 32, hash B3F09E
stsc (28 bytes):
Data = length 20, hash 8FA6E089
co64 (24 bytes):
Data = length 16, hash E4EE6699
Data = length 20, hash 8F6E8285
co64 (56 bytes):
Data = length 48, hash 44DD22A5
stss (36 bytes):
Data = length 28, hash 53024615
trak (574 bytes):
trak (606 bytes):
tkhd (92 bytes):
Data = length 84, hash 201C9491
mdia (474 bytes):
mdia (506 bytes):
mdhd (32 bytes):
Data = length 24, hash 41542D81
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (390 bytes):
minf (422 bytes):
vmhd (20 bytes):
Data = length 12, hash EE830681
dinf (36 bytes):
Data = length 28, hash D535436B
stbl (326 bytes):
stbl (358 bytes):
stsd (166 bytes):
Data = length 158, hash 11532063
stts (24 bytes):
@ -76,12 +76,12 @@ moov (1838 bytes):
stsz (40 bytes):
Data = length 32, hash B3F09E
stsc (28 bytes):
Data = length 20, hash 8FA6E089
co64 (24 bytes):
Data = length 16, hash E4EE66D0
Data = length 20, hash 8F6E8285
co64 (56 bytes):
Data = length 48, hash 9F5A9CB8
stss (36 bytes):
Data = length 28, hash 53024615
free (398170 bytes):
Data = length 398162, hash E06B79C1
free (398074 bytes):
Data = length 398066, hash B24945C1
mdat (856 bytes):
Data = length 840, hash A66AA6A7

View File

@ -4,23 +4,23 @@ free (400008 bytes):
Data = length 400000, hash BBC7B001
mdat (2800016 bytes):
Data = length 2800000, hash 7A1CC21
moov (400650 bytes):
moov (800642 bytes):
mvhd (108 bytes):
Data = length 100, hash 2613A5C
trak (400534 bytes):
trak (800526 bytes):
tkhd (92 bytes):
Data = length 84, hash 3D79758F
mdia (400434 bytes):
mdia (800426 bytes):
mdhd (32 bytes):
Data = length 24, hash 41542D81
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (400350 bytes):
minf (800342 bytes):
vmhd (20 bytes):
Data = length 12, hash EE830681
dinf (36 bytes):
Data = length 28, hash D535436B
stbl (400286 bytes):
stbl (800278 bytes):
stsd (166 bytes):
Data = length 158, hash 11532063
stts (24 bytes):
@ -28,8 +28,8 @@ moov (400650 bytes):
stsz (200020 bytes):
Data = length 200012, hash 719AE8EE
stsc (28 bytes):
Data = length 20, hash 2BB02571
co64 (24 bytes):
Data = length 16, hash E4EE6662
Data = length 20, hash 8F6E8285
co64 (400016 bytes):
Data = length 400008, hash 32E48395
stss (200016 bytes):
Data = length 200008, hash 8ABF61C3

View File

@ -2,23 +2,23 @@ ftyp (28 bytes):
Data = length 20, hash EF896440
mdat (56016 bytes):
Data = length 56000, hash F535891
moov (8650 bytes):
moov (16642 bytes):
mvhd (108 bytes):
Data = length 100, hash 2613A5C
trak (8534 bytes):
trak (16526 bytes):
tkhd (92 bytes):
Data = length 84, hash 3D79758F
mdia (8434 bytes):
mdia (16426 bytes):
mdhd (32 bytes):
Data = length 24, hash 41542D81
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (8350 bytes):
minf (16342 bytes):
vmhd (20 bytes):
Data = length 12, hash EE830681
dinf (36 bytes):
Data = length 28, hash D535436B
stbl (8286 bytes):
stbl (16278 bytes):
stsd (166 bytes):
Data = length 158, hash 11532063
stts (24 bytes):
@ -26,8 +26,8 @@ moov (8650 bytes):
stsz (4020 bytes):
Data = length 4012, hash 537BD986
stsc (28 bytes):
Data = length 20, hash 932CC0C9
co64 (24 bytes):
Data = length 16, hash E4EE4D2E
Data = length 20, hash 8F6E8285
co64 (8016 bytes):
Data = length 8008, hash E71FBD7C
stss (4016 bytes):
Data = length 4008, hash 729103FF

View File

@ -23,7 +23,7 @@ track 0:
colorRange = 1
lumaBitdepth = 8
chromaBitdepth = 8
metadata = entries=[mdta: key=auxiliary.tracks.length, value=1490, mdta: key=auxiliary.tracks.offset, value=400892, Mp4Timestamp: creation time=1000000, modification time=5000000, timescale=10000]
metadata = entries=[mdta: key=auxiliary.tracks.length, value=1554, mdta: key=auxiliary.tracks.offset, value=400892, Mp4Timestamp: creation time=1000000, modification time=5000000, timescale=10000]
initializationData:
data = length 28, hash 410B510
data = length 9, hash FBADD682

View File

@ -1,22 +1,22 @@
ftyp (28 bytes):
Data = length 20, hash EF896440
moov (674 bytes):
moov (682 bytes):
mvhd (108 bytes):
Data = length 100, hash 105FA889
trak (558 bytes):
trak (566 bytes):
tkhd (92 bytes):
Data = length 84, hash AC22063C
mdia (458 bytes):
mdia (466 bytes):
mdhd (32 bytes):
Data = length 24, hash 88615B36
hdlr (44 bytes):
Data = length 36, hash A0852FF2
minf (374 bytes):
minf (382 bytes):
vmhd (20 bytes):
Data = length 12, hash EE830681
dinf (36 bytes):
Data = length 28, hash D535436B
stbl (310 bytes):
stbl (318 bytes):
stsd (166 bytes):
Data = length 158, hash 11532063
stts (32 bytes):
@ -24,12 +24,12 @@ moov (674 bytes):
stsz (28 bytes):
Data = length 20, hash 3836F7F3
stsc (28 bytes):
Data = length 20, hash 8F7C9A06
co64 (24 bytes):
Data = length 16, hash E4EE6662
Data = length 20, hash 8F6E8285
co64 (32 bytes):
Data = length 24, hash 6E04DBFB
stss (24 bytes):
Data = length 16, hash 7940D386
free (399334 bytes):
Data = length 399326, hash 3C185041
free (399326 bytes):
Data = length 399318, hash 3D692141
mdat (128 bytes):
Data = length 112, hash 1AAF8FF5

View File

@ -1,15 +1,15 @@
seekMap:
isSeekable = true
duration = 4171700
duration = 3989300
getPosition(0) = [[timeUs=0, position=400052]]
getPosition(1) = [[timeUs=0, position=400052], [timeUs=1002955, position=430177]]
getPosition(2085850) = [[timeUs=2003566, position=2503758], [timeUs=3003444, position=4426916]]
getPosition(4171700) = [[timeUs=4003277, position=4459282]]
getPosition(1994650) = [[timeUs=1002955, position=430177], [timeUs=2003566, position=2562813]]
getPosition(3989300) = [[timeUs=3003444, position=4426916]]
numberOfTracks = 2
track 0:
total output bytes = 7822354
sample count = 125
track duration = 4171700
total output bytes = 5843480
sample count = 93
track duration = 3103400
format 0:
id = 1
containerMimeType = video/mp4
@ -19,7 +19,7 @@ track 0:
maxNumReorderSamples = 0
width = 1280
height = 720
frameRate = 29.96
frameRate = 29.97
maxSubLayers = 1
colorInfo:
colorSpace = 6
@ -400,140 +400,12 @@ track 0:
data = length 56416, hash 3CB6F5AD
sample 92:
time = 3070100
flags = 0
data = length 54110, hash 7B27C656
sample 93:
time = 3103422
flags = 0
data = length 68308, hash C7F4AE80
sample 94:
time = 3136755
flags = 0
data = length 67629, hash 48E625B6
sample 95:
time = 3170111
flags = 0
data = length 66968, hash D46F0E01
sample 96:
time = 3203411
flags = 0
data = length 53022, hash 91852F32
sample 97:
time = 3236733
flags = 0
data = length 66729, hash 12CA7617
sample 98:
time = 3270066
flags = 0
data = length 53556, hash 904B00CF
sample 99:
time = 3303388
flags = 0
data = length 63459, hash AB813676
sample 100:
time = 3336722
flags = 0
data = length 63637, hash 8B0750F6
sample 101:
time = 3370044
flags = 0
data = length 64700, hash 8922E5BE
sample 102:
time = 3403377
flags = 0
data = length 54680, hash 4F49EB3D
sample 103:
time = 3436700
flags = 0
data = length 62600, hash 9DF2F9F5
sample 104:
time = 3470033
flags = 0
data = length 69506, hash DB702311
sample 105:
time = 3503366
flags = 0
data = length 50277, hash 1034F0A6
sample 106:
time = 3536722
flags = 0
data = length 52100, hash 33745B51
sample 107:
time = 3570011
flags = 0
data = length 65067, hash F73FE2C7
sample 108:
time = 3603344
flags = 0
data = length 68940, hash 4331DA16
sample 109:
time = 3636677
flags = 0
data = length 55215, hash 68087A40
sample 110:
time = 3670011
flags = 0
data = length 56090, hash 2F483911
sample 111:
time = 3703333
flags = 0
data = length 58356, hash D7D190C6
sample 112:
time = 3736655
flags = 0
data = length 57368, hash 2F6B7918
sample 113:
time = 3769988
flags = 0
data = length 56591, hash 19B696D2
sample 114:
time = 3803311
flags = 0
data = length 54748, hash 7E0CE70E
sample 115:
time = 3836633
flags = 0
data = length 73133, hash CFA46EE4
sample 116:
time = 3869966
flags = 0
data = length 52577, hash 5E174B5
sample 117:
time = 3903300
flags = 0
data = length 74756, hash 5A571060
sample 118:
time = 3936622
flags = 0
data = length 67171, hash 6F13FB2C
sample 119:
time = 3969944
flags = 0
data = length 42130, hash DAE94DB2
sample 120:
time = 4003277
flags = 1
data = length 120199, hash 32DEA792
sample 121:
time = 4036600
flags = 0
data = length 51028, hash FC7AF64F
sample 122:
time = 4069922
flags = 0
data = length 51879, hash 74852E0E
sample 123:
time = 4103255
flags = 0
data = length 51443, hash B735512A
sample 124:
time = 4137455
flags = 536870912
data = length 65012, hash DB29A2CD
data = length 54110, hash 7B27C656
track 1:
total output bytes = 131233
sample count = 192
track duration = 4095900
total output bytes = 127864
sample count = 187
track duration = 3989300
format 0:
averageBitrate = 256000
peakBitrate = 256000
@ -1294,26 +1166,6 @@ track 1:
data = length 580, hash B38C9C63
sample 186:
time = 4010937
flags = 1
data = length 583, hash 5668BFCE
sample 187:
time = 4032270
flags = 1
data = length 631, hash 7E86C98E
sample 188:
time = 4053604
flags = 1
data = length 656, hash 95A41C9B
sample 189:
time = 4074937
flags = 1
data = length 822, hash 2A045560
sample 190:
time = 4096270
flags = 1
data = length 643, hash 551E7C72
sample 191:
time = 4117604
flags = 536870913
data = length 617, hash 463482D9
data = length 583, hash 5668BFCE
tracksEnded = true