diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/video/HevcConfig.java b/library/extractor/src/main/java/com/google/android/exoplayer2/video/HevcConfig.java index 7e688b2e42..6b8e633555 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/video/HevcConfig.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/video/HevcConfig.java @@ -45,7 +45,7 @@ public final class HevcConfig { int csdLength = 0; int csdStartPosition = data.getPosition(); for (int i = 0; i < numberOfArrays; i++) { - data.skipBytes(1); // completeness (1), nal_unit_type (7) + data.skipBytes(1); // completeness (1), reserved (1), nal_unit_type (6) int numberOfNalUnits = data.readUnsignedShort(); for (int j = 0; j < numberOfNalUnits; j++) { int nalUnitLength = data.readUnsignedShort(); @@ -63,7 +63,8 @@ public final class HevcConfig { float pixelWidthHeightRatio = 1; @Nullable String codecs = null; for (int i = 0; i < numberOfArrays; i++) { - int nalUnitType = data.readUnsignedByte() & 0x7F; // completeness (1), nal_unit_type (7) + int nalUnitType = + data.readUnsignedByte() & 0x3F; // completeness (1), reserved (1), nal_unit_type (6) int numberOfNalUnits = data.readUnsignedShort(); for (int j = 0; j < numberOfNalUnits; j++) { int nalUnitLength = data.readUnsignedShort(); diff --git a/library/extractor/src/test/java/com/google/android/exoplayer2/video/HevcConfigTest.java b/library/extractor/src/test/java/com/google/android/exoplayer2/video/HevcConfigTest.java index a4c312e8f7..d87948bb69 100644 --- a/library/extractor/src/test/java/com/google/android/exoplayer2/video/HevcConfigTest.java +++ b/library/extractor/src/test/java/com/google/android/exoplayer2/video/HevcConfigTest.java @@ -162,6 +162,86 @@ public final class HevcConfigTest { 64 }; + private static final byte[] HVCC_BOX_PAYLOAD_WITH_SET_RESERVED_BIT = + new byte[] { + // Header + 1, + 1, + 96, + 0, + 0, + 0, + -80, + 0, + 0, + 0, + 0, + 0, + -103, + -16, + 0, + -4, + -4, + -8, + -8, + 0, + 0, + 15, + + // Number of arrays + 1, + + // NAL unit type = SPS (Ignoring reserved bit) + // completeness (1), reserved (1), nal_unit_type (6) + 97, + // Number of NAL units + 0, + 1, + // NAL unit length + 0, + 39, + // NAL unit + 66, + 1, + 1, + 1, + 96, + 0, + 0, + 3, + 0, + -80, + 0, + 0, + 3, + 0, + 0, + 3, + 0, + -103, + -96, + 1, + -32, + 32, + 2, + 32, + 124, + 78, + 90, + -18, + 76, + -110, + -22, + 86, + 10, + 12, + 12, + 5, + -38, + 20, + 37 + }; + @Test public void parseHevcDecoderConfigurationRecord() throws Exception { ParsableByteArray data = new ParsableByteArray(HVCC_BOX_PAYLOAD); @@ -170,4 +250,14 @@ public final class HevcConfigTest { assertThat(hevcConfig.codecs).isEqualTo("hvc1.1.6.L153.B0"); assertThat(hevcConfig.nalUnitLengthFieldLength).isEqualTo(4); } + + /** https://github.com/google/ExoPlayer/issues/10366 */ + @Test + public void parseHevcDecoderConfigurationRecord_ignoresReservedBit() throws Exception { + ParsableByteArray data = new ParsableByteArray(HVCC_BOX_PAYLOAD_WITH_SET_RESERVED_BIT); + HevcConfig hevcConfig = HevcConfig.parse(data); + + assertThat(hevcConfig.codecs).isEqualTo("hvc1.1.6.L153.B0"); + assertThat(hevcConfig.nalUnitLengthFieldLength).isEqualTo(4); + } }