Read sample dependencies for H.265 in FragmentedMp4

Add a new flag to FragmentedMp4Extractor
FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES_H265
Read two bytes from H.265 videos to determine NAL unit type and
temporal layer id.

PiperOrigin-RevId: 714046987
This commit is contained in:
dancho 2025-01-10 07:35:42 -08:00 committed by Copybara-Service
parent 71cb246913
commit c26a633d83
10 changed files with 1228 additions and 43 deletions

View File

@ -682,16 +682,22 @@ public final class NalUnitUtil {
} }
/** /**
* Returns the number of bytes needed from the NAL unit to determine whether subsequent NAL units * Returns the number of bytes in the NAL unit header.
* can depend on the current NAL unit. *
* <p>The NAL unit header can be used to determine the NAL unit type and whether subsequent NAL
* units can depend on the current NAL unit.
*
* <p>This is {@code nalUnitHeaderBytes} from the H.264 spec, or the size of {@code
* nal_unit_header()} in H.265.
* *
* @param format The sample {@link Format}. * @param format The sample {@link Format}.
*/ */
public static int numberOfBytesToDetermineSampleDependencies(Format format) { public static int numberOfBytesInNalUnitHeader(Format format) {
if (Objects.equals(format.sampleMimeType, MimeTypes.VIDEO_H264)) { if (Objects.equals(format.sampleMimeType, MimeTypes.VIDEO_H264)) {
return 1; return 1;
} }
if (Objects.equals(format.sampleMimeType, MimeTypes.VIDEO_H265)) { if (Objects.equals(format.sampleMimeType, MimeTypes.VIDEO_H265)
|| MimeTypes.containsCodecsCorrespondingToMimeType(format.codecs, MimeTypes.VIDEO_H265)) {
return 2; return 2;
} }
return 0; return 0;

View File

@ -16,7 +16,7 @@
package androidx.media3.container; package androidx.media3.container;
import static androidx.media3.container.NalUnitUtil.isDependedOn; import static androidx.media3.container.NalUnitUtil.isDependedOn;
import static androidx.media3.container.NalUnitUtil.numberOfBytesToDetermineSampleDependencies; import static androidx.media3.container.NalUnitUtil.numberOfBytesInNalUnitHeader;
import static androidx.media3.test.utils.TestUtil.createByteArray; import static androidx.media3.test.utils.TestUtil.createByteArray;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
@ -499,10 +499,10 @@ public final class NalUnitUtilTest {
} }
@Test @Test
public void numberOfBytesToDetermineSampleDependencies_vp8_returnsZero() { public void numberOfBytesInNalUnitHeader_vp8_returnsZero() {
Format vp8Video = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_VP8).build(); Format vp8Video = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_VP8).build();
assertThat(numberOfBytesToDetermineSampleDependencies(vp8Video)).isEqualTo(0); assertThat(numberOfBytesInNalUnitHeader(vp8Video)).isEqualTo(0);
} }
@Test @Test

View File

@ -149,6 +149,14 @@ public class FragmentedMp4Extractor implements Extractor {
*/ */
public static final int FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES = 1 << 6; // 64 public static final int FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES = 1 << 6; // 64
/**
* Flag to extract additional sample dependency information, and mark output buffers with {@link
* C#BUFFER_FLAG_NOT_DEPENDED_ON} for {@linkplain MimeTypes#VIDEO_H265 H.265} video.
*
* <p>See {@link #FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES}.
*/
public static final int FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES_H265 = 1 << 7;
/** /**
* @deprecated Use {@link #newFactory(SubtitleParser.Factory)} instead. * @deprecated Use {@link #newFactory(SubtitleParser.Factory)} instead.
*/ */
@ -193,7 +201,7 @@ public class FragmentedMp4Extractor implements Extractor {
// Temporary arrays. // Temporary arrays.
private final ParsableByteArray nalStartCode; private final ParsableByteArray nalStartCode;
private final ParsableByteArray nalPrefix; private final ParsableByteArray nalPrefix;
private final ParsableByteArray nalBuffer; private final ParsableByteArray nalUnitWithoutHeaderBuffer;
private final byte[] scratchBytes; private final byte[] scratchBytes;
private final ParsableByteArray scratch; private final ParsableByteArray scratch;
@ -400,8 +408,8 @@ public class FragmentedMp4Extractor implements Extractor {
eventMessageEncoder = new EventMessageEncoder(); eventMessageEncoder = new EventMessageEncoder();
atomHeader = new ParsableByteArray(Mp4Box.LONG_HEADER_SIZE); atomHeader = new ParsableByteArray(Mp4Box.LONG_HEADER_SIZE);
nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE); nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE);
nalPrefix = new ParsableByteArray(5); nalPrefix = new ParsableByteArray(6);
nalBuffer = new ParsableByteArray(); nalUnitWithoutHeaderBuffer = new ParsableByteArray();
scratchBytes = new byte[16]; scratchBytes = new byte[16];
scratch = new ParsableByteArray(scratchBytes); scratch = new ParsableByteArray(scratchBytes);
containerAtoms = new ArrayDeque<>(); containerAtoms = new ArrayDeque<>();
@ -1533,12 +1541,10 @@ public class FragmentedMp4Extractor implements Extractor {
if (parserState == STATE_READING_SAMPLE_START) { if (parserState == STATE_READING_SAMPLE_START) {
sampleSize = trackBundle.getCurrentSampleSize(); sampleSize = trackBundle.getCurrentSampleSize();
// We must check all NAL units in the Fragmented MP4 sample for dependencies. // We must check all NAL units in the Fragmented MP4 sample for dependencies.
// When FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES is unset, or codec is not supported, // When reading sample dependencies is disabled, or codec is not supported,
// set isSampleDependedOn = true and skip parsing the payload bytes. // set isSampleDependedOn = true and skip parsing the payload bytes.
isSampleDependedOn = isSampleDependedOn =
(flags & FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES) == 0 !canReadWithinGopSampleDependencies(trackBundle.moovSampleTable.track.format);
|| !Objects.equals(
trackBundle.moovSampleTable.track.format.sampleMimeType, MimeTypes.VIDEO_H264);
if (trackBundle.currentSampleIndex < trackBundle.firstSampleToOutputIndex) { if (trackBundle.currentSampleIndex < trackBundle.firstSampleToOutputIndex) {
input.skipFully(sampleSize); input.skipFully(sampleSize);
@ -1585,57 +1591,74 @@ public class FragmentedMp4Extractor implements Extractor {
nalPrefixData[0] = 0; nalPrefixData[0] = 0;
nalPrefixData[1] = 0; nalPrefixData[1] = 0;
nalPrefixData[2] = 0; nalPrefixData[2] = 0;
int nalUnitPrefixLength = track.nalUnitLengthFieldLength + 1;
int nalUnitLengthFieldLengthDiff = 4 - track.nalUnitLengthFieldLength; int nalUnitLengthFieldLengthDiff = 4 - track.nalUnitLengthFieldLength;
// NAL units are length delimited, but the decoder requires start code delimited units. // NAL units are length delimited, but the decoder requires start code delimited units.
// Loop until we've written the sample to the track output, replacing length delimiters with // Loop until we've written the sample to the track output, replacing length delimiters with
// start codes as we encounter them. // start codes as we encounter them.
while (sampleBytesWritten < sampleSize) { while (sampleBytesWritten < sampleSize) {
if (sampleCurrentNalBytesRemaining == 0) { if (sampleCurrentNalBytesRemaining == 0) {
int numberOfNalUnitHeaderBytesToRead = 0;
if (ceaTrackOutputs.length > 0 || !isSampleDependedOn) {
// Try to read the NAL unit header if we're parsing captions or sample dependencies.
int nalUnitHeaderSize = NalUnitUtil.numberOfBytesInNalUnitHeader(track.format);
if (track.nalUnitLengthFieldLength + nalUnitHeaderSize
<= sampleSize - sampleBytesWritten) {
// In some malformed videos with padding, the NAL unit may be empty.
// See b/383201567#comment20
// Only try to read the header if there are enough bytes in this sample.
numberOfNalUnitHeaderBytesToRead = nalUnitHeaderSize;
}
}
// Read numberOfNalUnitHeaderBytesToRead in the same readFully call that reads the NAL
// length. This ensures sampleBytesRead, sampleBytesWritten and isSampleDependedOn remain
// in a consistent state if we have read failures.
int nalUnitPrefixLength =
track.nalUnitLengthFieldLength + numberOfNalUnitHeaderBytesToRead;
// Read the NAL length so that we know where we find the next one, and its type. // Read the NAL length so that we know where we find the next one, and its type.
input.readFully(nalPrefixData, nalUnitLengthFieldLengthDiff, nalUnitPrefixLength); input.readFully(nalPrefixData, nalUnitLengthFieldLengthDiff, nalUnitPrefixLength);
nalPrefix.setPosition(0); nalPrefix.setPosition(0);
int nalLengthInt = nalPrefix.readInt(); int nalLengthInt = nalPrefix.readInt();
if (nalLengthInt < 1) { if (nalLengthInt < 0) {
throw ParserException.createForMalformedContainer( throw ParserException.createForMalformedContainer(
"Invalid NAL length", /* cause= */ null); "Invalid NAL length", /* cause= */ null);
} }
sampleCurrentNalBytesRemaining = nalLengthInt - 1; sampleCurrentNalBytesRemaining = nalLengthInt - numberOfNalUnitHeaderBytesToRead;
// Write a start code for the current NAL unit. // Write a start code for the current NAL unit.
nalStartCode.setPosition(0); nalStartCode.setPosition(0);
output.sampleData(nalStartCode, 4); output.sampleData(nalStartCode, 4);
// Write the NAL unit type byte. sampleBytesWritten += 4;
output.sampleData(nalPrefix, 1); sampleSize += nalUnitLengthFieldLengthDiff;
processSeiNalUnitPayload = processSeiNalUnitPayload =
ceaTrackOutputs.length > 0 ceaTrackOutputs.length > 0
&& numberOfNalUnitHeaderBytesToRead > 0
&& NalUnitUtil.isNalUnitSei(track.format, nalPrefixData[4]); && NalUnitUtil.isNalUnitSei(track.format, nalPrefixData[4]);
sampleBytesWritten += 5; // Write the extra NAL unit bytes to the output.
sampleSize += nalUnitLengthFieldLengthDiff; output.sampleData(nalPrefix, numberOfNalUnitHeaderBytesToRead);
if (!isSampleDependedOn sampleBytesWritten += numberOfNalUnitHeaderBytesToRead;
&& Objects.equals( if (numberOfNalUnitHeaderBytesToRead > 0
trackBundle.moovSampleTable.track.format.sampleMimeType, MimeTypes.VIDEO_H264) && !isSampleDependedOn
&& NalUnitUtil.isH264NalUnitDependedOn(nalPrefixData[4])) { && NalUnitUtil.isDependedOn(
nalPrefixData,
/* offset= */ 4,
/* length= */ numberOfNalUnitHeaderBytesToRead,
track.format)) {
isSampleDependedOn = true; isSampleDependedOn = true;
} }
} else { } else {
int writtenBytes; int writtenBytes;
if (processSeiNalUnitPayload) { if (processSeiNalUnitPayload) {
// Read and write the payload of the SEI NAL unit. // Read and write the remaining payload of the SEI NAL unit.
nalBuffer.reset(sampleCurrentNalBytesRemaining); nalUnitWithoutHeaderBuffer.reset(sampleCurrentNalBytesRemaining);
input.readFully(nalBuffer.getData(), 0, sampleCurrentNalBytesRemaining); input.readFully(
output.sampleData(nalBuffer, sampleCurrentNalBytesRemaining); nalUnitWithoutHeaderBuffer.getData(), 0, sampleCurrentNalBytesRemaining);
output.sampleData(nalUnitWithoutHeaderBuffer, sampleCurrentNalBytesRemaining);
writtenBytes = sampleCurrentNalBytesRemaining; writtenBytes = sampleCurrentNalBytesRemaining;
// Unescape and process the SEI NAL unit. // Unescape and process the SEI NAL unit.
int unescapedLength = int unescapedLength =
NalUnitUtil.unescapeStream(nalBuffer.getData(), nalBuffer.limit()); NalUnitUtil.unescapeStream(
// If the format is H.265/HEVC the NAL unit header has two bytes so skip one more byte. nalUnitWithoutHeaderBuffer.getData(), nalUnitWithoutHeaderBuffer.limit());
nalBuffer.setPosition( nalUnitWithoutHeaderBuffer.setPosition(0);
Objects.equals(track.format.sampleMimeType, MimeTypes.VIDEO_H265) nalUnitWithoutHeaderBuffer.setLimit(unescapedLength);
|| MimeTypes.containsCodecsCorrespondingToMimeType(
track.format.codecs, MimeTypes.VIDEO_H265)
? 1
: 0);
nalBuffer.setLimit(unescapedLength);
if (track.format.maxNumReorderSamples == Format.NO_VALUE) { if (track.format.maxNumReorderSamples == Format.NO_VALUE) {
if (reorderingSeiMessageQueue.getMaxSize() != 0) { if (reorderingSeiMessageQueue.getMaxSize() != 0) {
@ -1645,7 +1668,7 @@ public class FragmentedMp4Extractor implements Extractor {
!= track.format.maxNumReorderSamples) { != track.format.maxNumReorderSamples) {
reorderingSeiMessageQueue.setMaxSize(track.format.maxNumReorderSamples); reorderingSeiMessageQueue.setMaxSize(track.format.maxNumReorderSamples);
} }
reorderingSeiMessageQueue.add(sampleTimeUs, nalBuffer); reorderingSeiMessageQueue.add(sampleTimeUs, nalUnitWithoutHeaderBuffer);
if ((trackBundle.getCurrentSampleFlags() & C.BUFFER_FLAG_END_OF_STREAM) != 0) { if ((trackBundle.getCurrentSampleFlags() & C.BUFFER_FLAG_END_OF_STREAM) != 0) {
reorderingSeiMessageQueue.flush(); reorderingSeiMessageQueue.flush();
@ -1666,7 +1689,7 @@ public class FragmentedMp4Extractor implements Extractor {
} }
@C.BufferFlags int sampleFlags = trackBundle.getCurrentSampleFlags(); @C.BufferFlags int sampleFlags = trackBundle.getCurrentSampleFlags();
if ((flags & FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES) != 0 && !isSampleDependedOn) { if (!isSampleDependedOn) {
sampleFlags |= C.BUFFER_FLAG_NOT_DEPENDED_ON; sampleFlags |= C.BUFFER_FLAG_NOT_DEPENDED_ON;
} }
@ -1688,6 +1711,20 @@ public class FragmentedMp4Extractor implements Extractor {
return true; return true;
} }
/**
* Returns whether reading within GOP sample dependencies is enabled for the sample {@link
* Format}.
*/
private boolean canReadWithinGopSampleDependencies(Format format) {
if (Objects.equals(format.sampleMimeType, MimeTypes.VIDEO_H264)) {
return (flags & FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES) != 0;
}
if (Objects.equals(format.sampleMimeType, MimeTypes.VIDEO_H265)) {
return (flags & FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES_H265) != 0;
}
return false;
}
/** /**
* Called immediately after outputting a non-metadata sample, to output any pending metadata * Called immediately after outputting a non-metadata sample, to output any pending metadata
* samples. * samples.

View File

@ -902,15 +902,14 @@ public final class Mp4Extractor implements Extractor, SeekMap {
int nalUnitPrefixLength = track.track.nalUnitLengthFieldLength; int nalUnitPrefixLength = track.track.nalUnitLengthFieldLength;
int numberOfBytesToDetermineSampleDependencies = 0; int numberOfBytesToDetermineSampleDependencies = 0;
if (!isSampleDependedOn if (!isSampleDependedOn
&& nalUnitPrefixLength && nalUnitPrefixLength + NalUnitUtil.numberOfBytesInNalUnitHeader(track.track.format)
+ NalUnitUtil.numberOfBytesToDetermineSampleDependencies(track.track.format)
<= track.sampleTable.sizes[sampleIndex] - sampleBytesRead) { <= track.sampleTable.sizes[sampleIndex] - sampleBytesRead) {
// Parsing sample dependencies needs the first few NAL unit bytes. Read them in the same // Parsing sample dependencies needs the first few NAL unit bytes. Read them in the same
// readFully call that reads the NAL length. This ensures sampleBytesRead, // readFully call that reads the NAL length. This ensures sampleBytesRead,
// sampleBytesWritten and isSampleDependedOn remain in a consistent state if we have // sampleBytesWritten and isSampleDependedOn remain in a consistent state if we have
// read failures. // read failures.
numberOfBytesToDetermineSampleDependencies = numberOfBytesToDetermineSampleDependencies =
NalUnitUtil.numberOfBytesToDetermineSampleDependencies(track.track.format); NalUnitUtil.numberOfBytesInNalUnitHeader(track.track.format);
nalUnitPrefixLength = nalUnitPrefixLength =
track.track.nalUnitLengthFieldLength + numberOfBytesToDetermineSampleDependencies; track.track.nalUnitLengthFieldLength + numberOfBytesToDetermineSampleDependencies;
} }

View File

@ -200,6 +200,16 @@ public final class FragmentedMp4ExtractorParameterizedTest {
/* closedCaptionFormats= */ ImmutableList.of(), "media/mp4/sample_fragmented_iamf.mp4"); /* closedCaptionFormats= */ ImmutableList.of(), "media/mp4/sample_fragmented_iamf.mp4");
} }
@Test
public void sampleWithNonReferenceH265FramesAndCaptions() throws Exception {
// Enabling the CEA-608 track enables SEI payload parsing.
List<Format> closedCaptions =
Collections.singletonList(
new Format.Builder().setSampleMimeType(MimeTypes.APPLICATION_CEA608).build());
assertExtractorBehavior(closedCaptions, "media/mp4/fragmented_captions_h265.mp4");
}
private void assertExtractorBehavior(List<Format> closedCaptionFormats, String file) private void assertExtractorBehavior(List<Format> closedCaptionFormats, String file)
throws IOException { throws IOException {
ExtractorAsserts.AssertionConfig.Builder assertionConfigBuilder = ExtractorAsserts.AssertionConfig.Builder assertionConfigBuilder =
@ -232,6 +242,7 @@ public final class FragmentedMp4ExtractorParameterizedTest {
} }
if (readWithinGopSampleDependencies) { if (readWithinGopSampleDependencies) {
flags |= FragmentedMp4Extractor.FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES; flags |= FragmentedMp4Extractor.FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES;
flags |= FragmentedMp4Extractor.FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES_H265;
} }
@FragmentedMp4Extractor.Flags int finalFlags = flags; @FragmentedMp4Extractor.Flags int finalFlags = flags;

View File

@ -0,0 +1,283 @@
seekMap:
isSeekable = false
duration = UNSET TIME
getPosition(0) = [[timeUs=0, position=3203]]
numberOfTracks = 2
track 0:
total output bytes = 24020
sample count = 61
format 0:
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
codecs = hvc1.1.6.L60.90
maxNumReorderSamples = 2
width = 416
height = 234
maxSubLayers = 1
colorInfo:
colorSpace = 2
colorRange = 2
colorTransfer = 3
lumaBitdepth = 8
chromaBitdepth = 8
initializationData:
data = length 2426, hash 25737613
sample 0:
time = 66733
flags = 1
data = length 5220, hash 5F0CCC08
sample 1:
time = 233566
flags = 0
data = length 615, hash CBFF4D3C
sample 2:
time = 166833
flags = 0
data = length 217, hash B600557D
sample 3:
time = 100100
flags = 0
data = length 177, hash 99B5D77F
sample 4:
time = 133466
flags = 0
data = length 190, hash AF7F85A2
sample 5:
time = 200200
flags = 0
data = length 225, hash BA8F2E19
sample 6:
time = 333666
flags = 0
data = length 330, hash DCBABAE8
sample 7:
time = 300300
flags = 0
data = length 183, hash 15A2DB25
sample 8:
time = 266933
flags = 0
data = length 154, hash 81018D0E
sample 9:
time = 400400
flags = 0
data = length 576, hash C9C5389F
sample 10:
time = 367033
flags = 0
data = length 173, hash 2D567C7E
sample 11:
time = 500500
flags = 0
data = length 356, hash A6D37B60
sample 12:
time = 467133
flags = 0
data = length 188, hash 11AB1597
sample 13:
time = 433766
flags = 0
data = length 174, hash 18C46868
sample 14:
time = 567233
flags = 0
data = length 331, hash EEA184AF
sample 15:
time = 533866
flags = 0
data = length 213, hash 3FAB17EE
sample 16:
time = 667333
flags = 0
data = length 371, hash D0ECAE97
sample 17:
time = 633966
flags = 0
data = length 179, hash 796F24AF
sample 18:
time = 600600
flags = 0
data = length 154, hash FD43F0C6
sample 19:
time = 734066
flags = 0
data = length 622, hash 8AD9409C
sample 20:
time = 700700
flags = 0
data = length 195, hash 4EFA8FFD
sample 21:
time = 900900
flags = 0
data = length 424, hash 5F9D809C
sample 22:
time = 834166
flags = 0
data = length 187, hash FB5137FD
sample 23:
time = 767433
flags = 0
data = length 162, hash 7B352EA
sample 24:
time = 800800
flags = 0
data = length 173, hash 42EBA5AC
sample 25:
time = 867533
flags = 0
data = length 205, hash 15D2186B
sample 26:
time = 1001000
flags = 0
data = length 342, hash 70E9AD53
sample 27:
time = 967633
flags = 0
data = length 200, hash 2C923950
sample 28:
time = 934266
flags = 0
data = length 150, hash 242935D6
sample 29:
time = 1167833
flags = 0
data = length 802, hash 60213433
sample 30:
time = 1101100
flags = 0
data = length 203, hash 21B384E5
sample 31:
time = 1034366
flags = 0
data = length 185, hash B2735872
sample 32:
time = 1067733
flags = 0
data = length 1310, hash 8D4F7E35
sample 33:
time = 1134466
flags = 0
data = length 176, hash D1D91C73
sample 34:
time = 1334666
flags = 0
data = length 258, hash 92056B3A
sample 35:
time = 1267933
flags = 0
data = length 214, hash 86C47DEC
sample 36:
time = 1201200
flags = 0
data = length 201, hash AFA1B6D4
sample 37:
time = 1234566
flags = 0
data = length 146, hash 3E1B1C72
sample 38:
time = 1301300
flags = 0
data = length 173, hash FC0B911D
sample 39:
time = 1401400
flags = 0
data = length 617, hash 35AAFB9
sample 40:
time = 1368033
flags = 0
data = length 179, hash E9838582
sample 41:
time = 1468133
flags = 0
data = length 395, hash 8F5373AC
sample 42:
time = 1434766
flags = 0
data = length 184, hash 10ED9B63
sample 43:
time = 1634966
flags = 0
data = length 460, hash ED8ECDE7
sample 44:
time = 1568233
flags = 0
data = length 184, hash BF273413
sample 45:
time = 1501500
flags = 0
data = length 162, hash FE32A96B
sample 46:
time = 1534866
flags = 0
data = length 201, hash BBB627F2
sample 47:
time = 1601600
flags = 0
data = length 169, hash AFD9804F
sample 48:
time = 1735066
flags = 0
data = length 668, hash 4B9FB50F
sample 49:
time = 1701700
flags = 0
data = length 219, hash E2A651A2
sample 50:
time = 1668333
flags = 0
data = length 162, hash ECB52FD2
sample 51:
time = 1901900
flags = 0
data = length 405, hash 7DA640B4
sample 52:
time = 1835166
flags = 0
data = length 188, hash 46D5E9D4
sample 53:
time = 1768433
flags = 0
data = length 167, hash 65F87E6A
sample 54:
time = 1801800
flags = 0
data = length 161, hash 2E37B5E0
sample 55:
time = 1868533
flags = 0
data = length 199, hash D63CF14E
sample 56:
time = 2002000
flags = 0
data = length 282, hash E748555D
sample 57:
time = 1968633
flags = 0
data = length 199, hash F341EE39
sample 58:
time = 1935266
flags = 0
data = length 166, hash 32F07BFF
sample 59:
time = 2068733
flags = 0
data = length 2246, hash E07DFCAE
sample 60:
time = 2035366
flags = 0
data = length 53, hash D9F70BD5
track 100:
total output bytes = 45
sample count = 2
format 0:
sampleMimeType = application/cea-608
sample 0:
time = 66733
flags = 1
data = length 36, hash 6E15DFAD
sample 1:
time = 1935266
flags = 1
data = length 9, hash 604EC6AA
tracksEnded = true

View File

@ -0,0 +1,283 @@
seekMap:
isSeekable = false
duration = UNSET TIME
getPosition(0) = [[timeUs=0, position=3203]]
numberOfTracks = 2
track 0:
total output bytes = 24020
sample count = 61
format 0:
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
codecs = hvc1.1.6.L60.90
maxNumReorderSamples = 2
width = 416
height = 234
maxSubLayers = 1
colorInfo:
colorSpace = 2
colorRange = 2
colorTransfer = 3
lumaBitdepth = 8
chromaBitdepth = 8
initializationData:
data = length 2426, hash 25737613
sample 0:
time = 66733
flags = 1
data = length 5220, hash 5F0CCC08
sample 1:
time = 233566
flags = 0
data = length 615, hash CBFF4D3C
sample 2:
time = 166833
flags = 0
data = length 217, hash B600557D
sample 3:
time = 100100
flags = 67108864
data = length 177, hash 99B5D77F
sample 4:
time = 133466
flags = 67108864
data = length 190, hash AF7F85A2
sample 5:
time = 200200
flags = 67108864
data = length 225, hash BA8F2E19
sample 6:
time = 333666
flags = 0
data = length 330, hash DCBABAE8
sample 7:
time = 300300
flags = 0
data = length 183, hash 15A2DB25
sample 8:
time = 266933
flags = 67108864
data = length 154, hash 81018D0E
sample 9:
time = 400400
flags = 0
data = length 576, hash C9C5389F
sample 10:
time = 367033
flags = 67108864
data = length 173, hash 2D567C7E
sample 11:
time = 500500
flags = 0
data = length 356, hash A6D37B60
sample 12:
time = 467133
flags = 0
data = length 188, hash 11AB1597
sample 13:
time = 433766
flags = 67108864
data = length 174, hash 18C46868
sample 14:
time = 567233
flags = 0
data = length 331, hash EEA184AF
sample 15:
time = 533866
flags = 67108864
data = length 213, hash 3FAB17EE
sample 16:
time = 667333
flags = 0
data = length 371, hash D0ECAE97
sample 17:
time = 633966
flags = 0
data = length 179, hash 796F24AF
sample 18:
time = 600600
flags = 67108864
data = length 154, hash FD43F0C6
sample 19:
time = 734066
flags = 0
data = length 622, hash 8AD9409C
sample 20:
time = 700700
flags = 67108864
data = length 195, hash 4EFA8FFD
sample 21:
time = 900900
flags = 0
data = length 424, hash 5F9D809C
sample 22:
time = 834166
flags = 0
data = length 187, hash FB5137FD
sample 23:
time = 767433
flags = 67108864
data = length 162, hash 7B352EA
sample 24:
time = 800800
flags = 67108864
data = length 173, hash 42EBA5AC
sample 25:
time = 867533
flags = 67108864
data = length 205, hash 15D2186B
sample 26:
time = 1001000
flags = 0
data = length 342, hash 70E9AD53
sample 27:
time = 967633
flags = 0
data = length 200, hash 2C923950
sample 28:
time = 934266
flags = 67108864
data = length 150, hash 242935D6
sample 29:
time = 1167833
flags = 0
data = length 802, hash 60213433
sample 30:
time = 1101100
flags = 0
data = length 203, hash 21B384E5
sample 31:
time = 1034366
flags = 67108864
data = length 185, hash B2735872
sample 32:
time = 1067733
flags = 67108864
data = length 1310, hash 8D4F7E35
sample 33:
time = 1134466
flags = 67108864
data = length 176, hash D1D91C73
sample 34:
time = 1334666
flags = 0
data = length 258, hash 92056B3A
sample 35:
time = 1267933
flags = 0
data = length 214, hash 86C47DEC
sample 36:
time = 1201200
flags = 67108864
data = length 201, hash AFA1B6D4
sample 37:
time = 1234566
flags = 67108864
data = length 146, hash 3E1B1C72
sample 38:
time = 1301300
flags = 67108864
data = length 173, hash FC0B911D
sample 39:
time = 1401400
flags = 0
data = length 617, hash 35AAFB9
sample 40:
time = 1368033
flags = 67108864
data = length 179, hash E9838582
sample 41:
time = 1468133
flags = 0
data = length 395, hash 8F5373AC
sample 42:
time = 1434766
flags = 67108864
data = length 184, hash 10ED9B63
sample 43:
time = 1634966
flags = 0
data = length 460, hash ED8ECDE7
sample 44:
time = 1568233
flags = 0
data = length 184, hash BF273413
sample 45:
time = 1501500
flags = 67108864
data = length 162, hash FE32A96B
sample 46:
time = 1534866
flags = 67108864
data = length 201, hash BBB627F2
sample 47:
time = 1601600
flags = 67108864
data = length 169, hash AFD9804F
sample 48:
time = 1735066
flags = 0
data = length 668, hash 4B9FB50F
sample 49:
time = 1701700
flags = 0
data = length 219, hash E2A651A2
sample 50:
time = 1668333
flags = 67108864
data = length 162, hash ECB52FD2
sample 51:
time = 1901900
flags = 0
data = length 405, hash 7DA640B4
sample 52:
time = 1835166
flags = 0
data = length 188, hash 46D5E9D4
sample 53:
time = 1768433
flags = 67108864
data = length 167, hash 65F87E6A
sample 54:
time = 1801800
flags = 67108864
data = length 161, hash 2E37B5E0
sample 55:
time = 1868533
flags = 67108864
data = length 199, hash D63CF14E
sample 56:
time = 2002000
flags = 0
data = length 282, hash E748555D
sample 57:
time = 1968633
flags = 0
data = length 199, hash F341EE39
sample 58:
time = 1935266
flags = 0
data = length 166, hash 32F07BFF
sample 59:
time = 2068733
flags = 0
data = length 2246, hash E07DFCAE
sample 60:
time = 2035366
flags = 67108864
data = length 53, hash D9F70BD5
track 100:
total output bytes = 45
sample count = 2
format 0:
sampleMimeType = application/cea-608
sample 0:
time = 66733
flags = 1
data = length 36, hash 6E15DFAD
sample 1:
time = 1935266
flags = 1
data = length 9, hash 604EC6AA
tracksEnded = true

View File

@ -0,0 +1,283 @@
seekMap:
isSeekable = false
duration = UNSET TIME
getPosition(0) = [[timeUs=0, position=3203]]
numberOfTracks = 2
track 0:
total output bytes = 24020
sample count = 61
format 0:
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
codecs = hvc1.1.6.L60.90
maxNumReorderSamples = 2
width = 416
height = 234
maxSubLayers = 1
colorInfo:
colorSpace = 2
colorRange = 2
colorTransfer = 3
lumaBitdepth = 8
chromaBitdepth = 8
initializationData:
data = length 2426, hash 25737613
sample 0:
time = 66733
flags = 1
data = length 5220, hash 5F0CCC08
sample 1:
time = 233566
flags = 0
data = length 615, hash CBFF4D3C
sample 2:
time = 166833
flags = 0
data = length 217, hash B600557D
sample 3:
time = 100100
flags = 67108864
data = length 177, hash 99B5D77F
sample 4:
time = 133466
flags = 67108864
data = length 190, hash AF7F85A2
sample 5:
time = 200200
flags = 67108864
data = length 225, hash BA8F2E19
sample 6:
time = 333666
flags = 0
data = length 330, hash DCBABAE8
sample 7:
time = 300300
flags = 0
data = length 183, hash 15A2DB25
sample 8:
time = 266933
flags = 67108864
data = length 154, hash 81018D0E
sample 9:
time = 400400
flags = 0
data = length 576, hash C9C5389F
sample 10:
time = 367033
flags = 67108864
data = length 173, hash 2D567C7E
sample 11:
time = 500500
flags = 0
data = length 356, hash A6D37B60
sample 12:
time = 467133
flags = 0
data = length 188, hash 11AB1597
sample 13:
time = 433766
flags = 67108864
data = length 174, hash 18C46868
sample 14:
time = 567233
flags = 0
data = length 331, hash EEA184AF
sample 15:
time = 533866
flags = 67108864
data = length 213, hash 3FAB17EE
sample 16:
time = 667333
flags = 0
data = length 371, hash D0ECAE97
sample 17:
time = 633966
flags = 0
data = length 179, hash 796F24AF
sample 18:
time = 600600
flags = 67108864
data = length 154, hash FD43F0C6
sample 19:
time = 734066
flags = 0
data = length 622, hash 8AD9409C
sample 20:
time = 700700
flags = 67108864
data = length 195, hash 4EFA8FFD
sample 21:
time = 900900
flags = 0
data = length 424, hash 5F9D809C
sample 22:
time = 834166
flags = 0
data = length 187, hash FB5137FD
sample 23:
time = 767433
flags = 67108864
data = length 162, hash 7B352EA
sample 24:
time = 800800
flags = 67108864
data = length 173, hash 42EBA5AC
sample 25:
time = 867533
flags = 67108864
data = length 205, hash 15D2186B
sample 26:
time = 1001000
flags = 0
data = length 342, hash 70E9AD53
sample 27:
time = 967633
flags = 0
data = length 200, hash 2C923950
sample 28:
time = 934266
flags = 67108864
data = length 150, hash 242935D6
sample 29:
time = 1167833
flags = 0
data = length 802, hash 60213433
sample 30:
time = 1101100
flags = 0
data = length 203, hash 21B384E5
sample 31:
time = 1034366
flags = 67108864
data = length 185, hash B2735872
sample 32:
time = 1067733
flags = 67108864
data = length 1310, hash 8D4F7E35
sample 33:
time = 1134466
flags = 67108864
data = length 176, hash D1D91C73
sample 34:
time = 1334666
flags = 0
data = length 258, hash 92056B3A
sample 35:
time = 1267933
flags = 0
data = length 214, hash 86C47DEC
sample 36:
time = 1201200
flags = 67108864
data = length 201, hash AFA1B6D4
sample 37:
time = 1234566
flags = 67108864
data = length 146, hash 3E1B1C72
sample 38:
time = 1301300
flags = 67108864
data = length 173, hash FC0B911D
sample 39:
time = 1401400
flags = 0
data = length 617, hash 35AAFB9
sample 40:
time = 1368033
flags = 67108864
data = length 179, hash E9838582
sample 41:
time = 1468133
flags = 0
data = length 395, hash 8F5373AC
sample 42:
time = 1434766
flags = 67108864
data = length 184, hash 10ED9B63
sample 43:
time = 1634966
flags = 0
data = length 460, hash ED8ECDE7
sample 44:
time = 1568233
flags = 0
data = length 184, hash BF273413
sample 45:
time = 1501500
flags = 67108864
data = length 162, hash FE32A96B
sample 46:
time = 1534866
flags = 67108864
data = length 201, hash BBB627F2
sample 47:
time = 1601600
flags = 67108864
data = length 169, hash AFD9804F
sample 48:
time = 1735066
flags = 0
data = length 668, hash 4B9FB50F
sample 49:
time = 1701700
flags = 0
data = length 219, hash E2A651A2
sample 50:
time = 1668333
flags = 67108864
data = length 162, hash ECB52FD2
sample 51:
time = 1901900
flags = 0
data = length 405, hash 7DA640B4
sample 52:
time = 1835166
flags = 0
data = length 188, hash 46D5E9D4
sample 53:
time = 1768433
flags = 67108864
data = length 167, hash 65F87E6A
sample 54:
time = 1801800
flags = 67108864
data = length 161, hash 2E37B5E0
sample 55:
time = 1868533
flags = 67108864
data = length 199, hash D63CF14E
sample 56:
time = 2002000
flags = 0
data = length 282, hash E748555D
sample 57:
time = 1968633
flags = 0
data = length 199, hash F341EE39
sample 58:
time = 1935266
flags = 0
data = length 166, hash 32F07BFF
sample 59:
time = 2068733
flags = 0
data = length 2246, hash E07DFCAE
sample 60:
time = 2035366
flags = 67108864
data = length 53, hash D9F70BD5
track 100:
total output bytes = 45
sample count = 2
format 0:
sampleMimeType = application/cea-608
sample 0:
time = 66733
flags = 1
data = length 36, hash 6E15DFAD
sample 1:
time = 1935266
flags = 1
data = length 9, hash 604EC6AA
tracksEnded = true

View File

@ -0,0 +1,283 @@
seekMap:
isSeekable = false
duration = UNSET TIME
getPosition(0) = [[timeUs=0, position=3203]]
numberOfTracks = 2
track 0:
total output bytes = 24020
sample count = 61
format 0:
id = 1
containerMimeType = video/mp4
sampleMimeType = video/hevc
codecs = hvc1.1.6.L60.90
maxNumReorderSamples = 2
width = 416
height = 234
maxSubLayers = 1
colorInfo:
colorSpace = 2
colorRange = 2
colorTransfer = 3
lumaBitdepth = 8
chromaBitdepth = 8
initializationData:
data = length 2426, hash 25737613
sample 0:
time = 66733
flags = 1
data = length 5220, hash 5F0CCC08
sample 1:
time = 233566
flags = 0
data = length 615, hash CBFF4D3C
sample 2:
time = 166833
flags = 0
data = length 217, hash B600557D
sample 3:
time = 100100
flags = 0
data = length 177, hash 99B5D77F
sample 4:
time = 133466
flags = 0
data = length 190, hash AF7F85A2
sample 5:
time = 200200
flags = 0
data = length 225, hash BA8F2E19
sample 6:
time = 333666
flags = 0
data = length 330, hash DCBABAE8
sample 7:
time = 300300
flags = 0
data = length 183, hash 15A2DB25
sample 8:
time = 266933
flags = 0
data = length 154, hash 81018D0E
sample 9:
time = 400400
flags = 0
data = length 576, hash C9C5389F
sample 10:
time = 367033
flags = 0
data = length 173, hash 2D567C7E
sample 11:
time = 500500
flags = 0
data = length 356, hash A6D37B60
sample 12:
time = 467133
flags = 0
data = length 188, hash 11AB1597
sample 13:
time = 433766
flags = 0
data = length 174, hash 18C46868
sample 14:
time = 567233
flags = 0
data = length 331, hash EEA184AF
sample 15:
time = 533866
flags = 0
data = length 213, hash 3FAB17EE
sample 16:
time = 667333
flags = 0
data = length 371, hash D0ECAE97
sample 17:
time = 633966
flags = 0
data = length 179, hash 796F24AF
sample 18:
time = 600600
flags = 0
data = length 154, hash FD43F0C6
sample 19:
time = 734066
flags = 0
data = length 622, hash 8AD9409C
sample 20:
time = 700700
flags = 0
data = length 195, hash 4EFA8FFD
sample 21:
time = 900900
flags = 0
data = length 424, hash 5F9D809C
sample 22:
time = 834166
flags = 0
data = length 187, hash FB5137FD
sample 23:
time = 767433
flags = 0
data = length 162, hash 7B352EA
sample 24:
time = 800800
flags = 0
data = length 173, hash 42EBA5AC
sample 25:
time = 867533
flags = 0
data = length 205, hash 15D2186B
sample 26:
time = 1001000
flags = 0
data = length 342, hash 70E9AD53
sample 27:
time = 967633
flags = 0
data = length 200, hash 2C923950
sample 28:
time = 934266
flags = 0
data = length 150, hash 242935D6
sample 29:
time = 1167833
flags = 0
data = length 802, hash 60213433
sample 30:
time = 1101100
flags = 0
data = length 203, hash 21B384E5
sample 31:
time = 1034366
flags = 0
data = length 185, hash B2735872
sample 32:
time = 1067733
flags = 0
data = length 1310, hash 8D4F7E35
sample 33:
time = 1134466
flags = 0
data = length 176, hash D1D91C73
sample 34:
time = 1334666
flags = 0
data = length 258, hash 92056B3A
sample 35:
time = 1267933
flags = 0
data = length 214, hash 86C47DEC
sample 36:
time = 1201200
flags = 0
data = length 201, hash AFA1B6D4
sample 37:
time = 1234566
flags = 0
data = length 146, hash 3E1B1C72
sample 38:
time = 1301300
flags = 0
data = length 173, hash FC0B911D
sample 39:
time = 1401400
flags = 0
data = length 617, hash 35AAFB9
sample 40:
time = 1368033
flags = 0
data = length 179, hash E9838582
sample 41:
time = 1468133
flags = 0
data = length 395, hash 8F5373AC
sample 42:
time = 1434766
flags = 0
data = length 184, hash 10ED9B63
sample 43:
time = 1634966
flags = 0
data = length 460, hash ED8ECDE7
sample 44:
time = 1568233
flags = 0
data = length 184, hash BF273413
sample 45:
time = 1501500
flags = 0
data = length 162, hash FE32A96B
sample 46:
time = 1534866
flags = 0
data = length 201, hash BBB627F2
sample 47:
time = 1601600
flags = 0
data = length 169, hash AFD9804F
sample 48:
time = 1735066
flags = 0
data = length 668, hash 4B9FB50F
sample 49:
time = 1701700
flags = 0
data = length 219, hash E2A651A2
sample 50:
time = 1668333
flags = 0
data = length 162, hash ECB52FD2
sample 51:
time = 1901900
flags = 0
data = length 405, hash 7DA640B4
sample 52:
time = 1835166
flags = 0
data = length 188, hash 46D5E9D4
sample 53:
time = 1768433
flags = 0
data = length 167, hash 65F87E6A
sample 54:
time = 1801800
flags = 0
data = length 161, hash 2E37B5E0
sample 55:
time = 1868533
flags = 0
data = length 199, hash D63CF14E
sample 56:
time = 2002000
flags = 0
data = length 282, hash E748555D
sample 57:
time = 1968633
flags = 0
data = length 199, hash F341EE39
sample 58:
time = 1935266
flags = 0
data = length 166, hash 32F07BFF
sample 59:
time = 2068733
flags = 0
data = length 2246, hash E07DFCAE
sample 60:
time = 2035366
flags = 0
data = length 53, hash D9F70BD5
track 100:
total output bytes = 45
sample count = 2
format 0:
sampleMimeType = application/cea-608
sample 0:
time = 66733
flags = 1
data = length 36, hash 6E15DFAD
sample 1:
time = 1935266
flags = 1
data = length 9, hash 604EC6AA
tracksEnded = true