Ignore reserved bit in parsing NAL unit type

`HevcConfig.parse` misreads reserved bit to determine NAL unit type. This is currently meant to be always set to 0, but could be given some kind of meaning in a future revision.

Issue: google/ExoPlayer#10366
PiperOrigin-RevId: 460487613
This commit is contained in:
rohks 2022-07-12 16:53:03 +00:00 committed by Rohit Singh
parent ab1fff404c
commit 0f665fbeb8
2 changed files with 93 additions and 2 deletions

View File

@ -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();

View File

@ -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);
}
}