Test and fix H265Reader

- Update H265Reader to output the same samples after a seek to 0.
- Add a TsExtractor test for H.265.

PiperOrigin-RevId: 306675050
This commit is contained in:
kimvde 2020-04-15 18:49:16 +01:00 committed by bachinger
parent 7214ad2d6f
commit ed977d1429
8 changed files with 504 additions and 13 deletions

View file

@ -172,9 +172,8 @@ public final class H265Reader implements ElementaryStreamReader {
@RequiresNonNull("sampleReader")
private void startNalUnit(long position, int offset, int nalUnitType, long pesTimeUs) {
if (hasOutputFormat) {
sampleReader.startNalUnit(position, offset, nalUnitType, pesTimeUs);
} else {
sampleReader.startNalUnit(position, offset, nalUnitType, pesTimeUs, hasOutputFormat);
if (!hasOutputFormat) {
vps.startNalUnit(nalUnitType);
sps.startNalUnit(nalUnitType);
pps.startNalUnit(nalUnitType);
@ -185,9 +184,8 @@ public final class H265Reader implements ElementaryStreamReader {
@RequiresNonNull("sampleReader")
private void nalUnitData(byte[] dataArray, int offset, int limit) {
if (hasOutputFormat) {
sampleReader.readNalUnitData(dataArray, offset, limit);
} else {
sampleReader.readNalUnitData(dataArray, offset, limit);
if (!hasOutputFormat) {
vps.appendToNalUnit(dataArray, offset, limit);
sps.appendToNalUnit(dataArray, offset, limit);
pps.appendToNalUnit(dataArray, offset, limit);
@ -198,9 +196,8 @@ public final class H265Reader implements ElementaryStreamReader {
@RequiresNonNull({"output", "sampleReader"})
private void endNalUnit(long position, int offset, int discardPadding, long pesTimeUs) {
if (hasOutputFormat) {
sampleReader.endNalUnit(position, offset);
} else {
sampleReader.endNalUnit(position, offset, hasOutputFormat);
if (!hasOutputFormat) {
vps.endNalUnit(discardPadding);
sps.endNalUnit(discardPadding);
pps.endNalUnit(discardPadding);
@ -454,7 +451,8 @@ public final class H265Reader implements ElementaryStreamReader {
writingParameterSets = false;
}
public void startNalUnit(long position, int offset, int nalUnitType, long pesTimeUs) {
public void startNalUnit(
long position, int offset, int nalUnitType, long pesTimeUs, boolean hasOutputFormat) {
isFirstSlice = false;
isFirstParameterSet = false;
nalUnitTimeUs = pesTimeUs;
@ -464,7 +462,9 @@ public final class H265Reader implements ElementaryStreamReader {
if (nalUnitType >= VPS_NUT) {
if (!writingParameterSets && readingSample) {
// This is a non-VCL NAL unit, so flush the previous sample.
outputSample(offset);
if (hasOutputFormat) {
outputSample(offset);
}
readingSample = false;
}
if (nalUnitType <= PPS_NUT) {
@ -491,14 +491,14 @@ public final class H265Reader implements ElementaryStreamReader {
}
}
public void endNalUnit(long position, int offset) {
public void endNalUnit(long position, int offset, boolean hasOutputFormat) {
if (writingParameterSets && isFirstSlice) {
// This sample has parameter sets. Reset the key-frame flag based on the first slice.
sampleIsKeyframe = nalUnitHasKeyframeData;
writingParameterSets = false;
} else if (isFirstParameterSet || isFirstSlice) {
// This NAL unit is at the start of a new sample (access unit).
if (readingSample) {
if (hasOutputFormat && readingSample) {
// Output the sample ending before this NAL unit.
int nalUnitLength = (int) (position - nalUnitStartPosition);
outputSample(offset + nalUnitLength);

View file

@ -54,6 +54,11 @@ public final class TsExtractorTest {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_h264_mpeg_audio.ts");
}
@Test
public void sampleWithH265() throws Exception {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_h265.ts");
}
@Test
@Ignore
// TODO(internal: b/153539929) Re-enable when ExtractorAsserts is less strict around repeated

Binary file not shown.

View file

@ -0,0 +1,141 @@
seekMap:
isSeekable = true
duration = 900000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(1) = [[timeUs=1, position=0]]
getPosition(450000) = [[timeUs=450000, position=11421]]
getPosition(900000) = [[timeUs=900000, position=23030]]
numberOfTracks = 2
track 256:
total output bytes = 19364
sample count = 29
format 0:
id = 1/256
sampleMimeType = video/hevc
width = 854
height = 480
initializationData:
data = length 83, hash 7F428
sample 0:
time = 66666
flags = 1
data = length 2510, hash 796A98BE
sample 1:
time = 100000
flags = 0
data = length 1219, hash 131AA4E4
sample 2:
time = 266666
flags = 0
data = length 7810, hash 3F881DB9
sample 3:
time = 200000
flags = 0
data = length 2306, hash 9A77959C
sample 4:
time = 133333
flags = 0
data = length 1058, hash B887F7EF
sample 5:
time = 166666
flags = 0
data = length 98, hash D95BF6E3
sample 6:
time = 233333
flags = 0
data = length 61, hash 574C41C3
sample 7:
time = 433333
flags = 0
data = length 296, hash E92DB288
sample 8:
time = 366666
flags = 0
data = length 137, hash 586DADD6
sample 9:
time = 300000
flags = 0
data = length 218, hash 91E82C9F
sample 10:
time = 333333
flags = 0
data = length 177, hash 4A4FEEC0
sample 11:
time = 400000
flags = 0
data = length 82, hash 2E2ADD8
sample 12:
time = 533333
flags = 0
data = length 290, hash 63CF7D90
sample 13:
time = 500000
flags = 0
data = length 268, hash E8CBAC11
sample 14:
time = 466666
flags = 0
data = length 178, hash C5B1613E
sample 15:
time = 566666
flags = 0
data = length 271, hash 76652FC5
sample 16:
time = 733333
flags = 0
data = length 257, hash 960B5DF4
sample 17:
time = 666666
flags = 0
data = length 206, hash 87358D00
sample 18:
time = 600000
flags = 0
data = length 130, hash 4D7A038D
sample 19:
time = 633333
flags = 0
data = length 114, hash 2B3C616E
sample 20:
time = 700000
flags = 0
data = length 95, hash 37D79559
sample 21:
time = 900000
flags = 0
data = length 233, hash 80308C9E
sample 22:
time = 833333
flags = 0
data = length 203, hash E70BA5F2
sample 23:
time = 766666
flags = 0
data = length 95, hash BA6FA2D3
sample 24:
time = 800000
flags = 0
data = length 103, hash 51291041
sample 25:
time = 866666
flags = 0
data = length 111, hash EE9DCFC9
sample 26:
time = 1033333
flags = 0
data = length 253, hash D0CEFBA7
sample 27:
time = 966666
flags = 0
data = length 134, hash 8802EEF0
sample 28:
time = 933333
flags = 0
data = length 80, hash C635D9C2
track 8448:
total output bytes = 0
sample count = 0
format 0:
id = 1/8448
sampleMimeType = application/cea-608
tracksEnded = true

View file

@ -0,0 +1,105 @@
seekMap:
isSeekable = true
duration = 900000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(1) = [[timeUs=1, position=0]]
getPosition(450000) = [[timeUs=450000, position=11421]]
getPosition(900000) = [[timeUs=900000, position=23030]]
numberOfTracks = 2
track 256:
total output bytes = 3806
sample count = 20
format 0:
id = 1/256
sampleMimeType = video/hevc
width = 854
height = 480
initializationData:
data = length 83, hash 7F428
sample 0:
time = 300000
flags = 0
data = length 218, hash 91E82C9F
sample 1:
time = 333333
flags = 0
data = length 177, hash 4A4FEEC0
sample 2:
time = 400000
flags = 0
data = length 82, hash 2E2ADD8
sample 3:
time = 533333
flags = 0
data = length 290, hash 63CF7D90
sample 4:
time = 500000
flags = 0
data = length 268, hash E8CBAC11
sample 5:
time = 466666
flags = 0
data = length 178, hash C5B1613E
sample 6:
time = 566666
flags = 0
data = length 271, hash 76652FC5
sample 7:
time = 733333
flags = 0
data = length 257, hash 960B5DF4
sample 8:
time = 666666
flags = 0
data = length 206, hash 87358D00
sample 9:
time = 600000
flags = 0
data = length 130, hash 4D7A038D
sample 10:
time = 633333
flags = 0
data = length 114, hash 2B3C616E
sample 11:
time = 700000
flags = 0
data = length 95, hash 37D79559
sample 12:
time = 900000
flags = 0
data = length 233, hash 80308C9E
sample 13:
time = 833333
flags = 0
data = length 203, hash E70BA5F2
sample 14:
time = 766666
flags = 0
data = length 95, hash BA6FA2D3
sample 15:
time = 800000
flags = 0
data = length 103, hash 51291041
sample 16:
time = 866666
flags = 0
data = length 111, hash EE9DCFC9
sample 17:
time = 1033333
flags = 0
data = length 253, hash D0CEFBA7
sample 18:
time = 966666
flags = 0
data = length 134, hash 8802EEF0
sample 19:
time = 933333
flags = 0
data = length 80, hash C635D9C2
track 8448:
total output bytes = 0
sample count = 0
format 0:
id = 1/8448
sampleMimeType = application/cea-608
tracksEnded = true

View file

@ -0,0 +1,69 @@
seekMap:
isSeekable = true
duration = 900000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(1) = [[timeUs=1, position=0]]
getPosition(450000) = [[timeUs=450000, position=11421]]
getPosition(900000) = [[timeUs=900000, position=23030]]
numberOfTracks = 2
track 256:
total output bytes = 1796
sample count = 11
format 0:
id = 1/256
sampleMimeType = video/hevc
width = 854
height = 480
initializationData:
data = length 83, hash 7F428
sample 0:
time = 600000
flags = 0
data = length 130, hash 4D7A038D
sample 1:
time = 633333
flags = 0
data = length 114, hash 2B3C616E
sample 2:
time = 700000
flags = 0
data = length 95, hash 37D79559
sample 3:
time = 900000
flags = 0
data = length 233, hash 80308C9E
sample 4:
time = 833333
flags = 0
data = length 203, hash E70BA5F2
sample 5:
time = 766666
flags = 0
data = length 95, hash BA6FA2D3
sample 6:
time = 800000
flags = 0
data = length 103, hash 51291041
sample 7:
time = 866666
flags = 0
data = length 111, hash EE9DCFC9
sample 8:
time = 1033333
flags = 0
data = length 253, hash D0CEFBA7
sample 9:
time = 966666
flags = 0
data = length 134, hash 8802EEF0
sample 10:
time = 933333
flags = 0
data = length 80, hash C635D9C2
track 8448:
total output bytes = 0
sample count = 0
format 0:
id = 1/8448
sampleMimeType = application/cea-608
tracksEnded = true

View file

@ -0,0 +1,33 @@
seekMap:
isSeekable = true
duration = 900000
getPosition(0) = [[timeUs=0, position=0]]
getPosition(1) = [[timeUs=1, position=0]]
getPosition(450000) = [[timeUs=450000, position=11421]]
getPosition(900000) = [[timeUs=900000, position=23030]]
numberOfTracks = 2
track 256:
total output bytes = 396
sample count = 2
format 0:
id = 1/256
sampleMimeType = video/hevc
width = 854
height = 480
initializationData:
data = length 83, hash 7F428
sample 0:
time = 966666
flags = 0
data = length 134, hash 8802EEF0
sample 1:
time = 933333
flags = 0
data = length 80, hash C635D9C2
track 8448:
total output bytes = 0
sample count = 0
format 0:
id = 1/8448
sampleMimeType = application/cea-608
tracksEnded = true

View file

@ -0,0 +1,138 @@
seekMap:
isSeekable = false
duration = UNSET TIME
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 2
track 256:
total output bytes = 19364
sample count = 29
format 0:
id = 1/256
sampleMimeType = video/hevc
width = 854
height = 480
initializationData:
data = length 83, hash 7F428
sample 0:
time = 66666
flags = 1
data = length 2510, hash 796A98BE
sample 1:
time = 100000
flags = 0
data = length 1219, hash 131AA4E4
sample 2:
time = 266666
flags = 0
data = length 7810, hash 3F881DB9
sample 3:
time = 200000
flags = 0
data = length 2306, hash 9A77959C
sample 4:
time = 133333
flags = 0
data = length 1058, hash B887F7EF
sample 5:
time = 166666
flags = 0
data = length 98, hash D95BF6E3
sample 6:
time = 233333
flags = 0
data = length 61, hash 574C41C3
sample 7:
time = 433333
flags = 0
data = length 296, hash E92DB288
sample 8:
time = 366666
flags = 0
data = length 137, hash 586DADD6
sample 9:
time = 300000
flags = 0
data = length 218, hash 91E82C9F
sample 10:
time = 333333
flags = 0
data = length 177, hash 4A4FEEC0
sample 11:
time = 400000
flags = 0
data = length 82, hash 2E2ADD8
sample 12:
time = 533333
flags = 0
data = length 290, hash 63CF7D90
sample 13:
time = 500000
flags = 0
data = length 268, hash E8CBAC11
sample 14:
time = 466666
flags = 0
data = length 178, hash C5B1613E
sample 15:
time = 566666
flags = 0
data = length 271, hash 76652FC5
sample 16:
time = 733333
flags = 0
data = length 257, hash 960B5DF4
sample 17:
time = 666666
flags = 0
data = length 206, hash 87358D00
sample 18:
time = 600000
flags = 0
data = length 130, hash 4D7A038D
sample 19:
time = 633333
flags = 0
data = length 114, hash 2B3C616E
sample 20:
time = 700000
flags = 0
data = length 95, hash 37D79559
sample 21:
time = 900000
flags = 0
data = length 233, hash 80308C9E
sample 22:
time = 833333
flags = 0
data = length 203, hash E70BA5F2
sample 23:
time = 766666
flags = 0
data = length 95, hash BA6FA2D3
sample 24:
time = 800000
flags = 0
data = length 103, hash 51291041
sample 25:
time = 866666
flags = 0
data = length 111, hash EE9DCFC9
sample 26:
time = 1033333
flags = 0
data = length 253, hash D0CEFBA7
sample 27:
time = 966666
flags = 0
data = length 134, hash 8802EEF0
sample 28:
time = 933333
flags = 0
data = length 80, hash C635D9C2
track 8448:
total output bytes = 0
sample count = 0
format 0:
id = 1/8448
sampleMimeType = application/cea-608
tracksEnded = true