Problem
HEVC allows bit depths from 8 to 16. ISO/IEC 23008-2, 7.4.3.2.1 says
"bit_depth_luma_minus8 shall be in the range of 0 to 8, inclusive", and the
same for chroma. Several profiles use the upper end, among them Monochrome 16,
Main 4:4:4 16 Intra and Main 4:4:4 16 Still Picture.
HEVCDecoderConfigurationRecord (ISO/IEC 14496-15:2022, 8.3.2.1.2) stores
these values in 3 bits:
bit(5) reserved = '11111'b;
unsigned int(3) bit_depth_luma_minus8;
bit(5) reserved = '11111'b;
unsigned int(3) bit_depth_chroma_minus8;
The fields hold 0 to 7, that is 8 to 15 bits. According to 8.3.2.1.3 they
contain "the matching values" of the parameter sets, which is not possible for
a stream with 16 bits. Such a stream cannot be stored with a correct
configuration record.
What happens today
Writers store the low 3 bits of the value. GPAC 2.2.1 writes 0xF8 into both
fields of a 16 bit stream, which is the same byte as for 8 bits. Every writer
that computes value | 0xF8 does the same, because bit 3 of the value falls
onto a reserved bit that is set anyway.
Readers that take the bit depth from the record see 8 bits per pixel. libheif reports
8 bits for such an image and converts it to 8 bits on output, although the
decoder delivers 16 bits. For this reason libheif now refuses to encode HEVC
with 16 bits.
Proposal
Define version 2 of the record, in which the two fields have 4 bits:
unsigned int(8) configurationVersion;
...
if (configurationVersion == 1) {
bit(5) reserved = '11111'b;
unsigned int(3) bit_depth_luma_minus8;
bit(5) reserved = '11111'b;
unsigned int(3) bit_depth_chroma_minus8;
}
else {
bit(4) reserved = '1111'b;
unsigned int(4) bit_depth_luma_minus8;
bit(4) reserved = '1111'b;
unsigned int(4) bit_depth_chroma_minus8;
}
The size of the record and the position of all other fields stay the same.
Version 2 should be used only when a bit depth of 16 has to be signalled.
Streams with up to 15 bits keep version 1, so that everything that can be
stored today remains readable by existing readers.
Using one of the reserved bits without changing the version does not work.
A reader of version 1 would read the low 3 bits and take a stream with 16 bits
for one with 8 bits. With a new version it refuses the stream instead, as
8.3.2.1.1 requires for an unrecognized version.
Related records
VvcDecoderConfigurationRecord (11.2.4.2.2) has the same limit.
bit_depth_minus8 has 3 bits, and ISO/IEC 23090-3:2022, 7.4.3.4 allows
sps_bitdepth_minus8 from 0 to 8. This record has no version field of its
own, but VvcConfigurationBox is a FullBox, so its version could be used.
AVCDecoderConfigurationRecord: the fields are wide enough, but 5.3.2.1.3
limits them to the range 0 to 4, while ISO/IEC 14496-10:2022, 7.4.2.1.1
allows 0 to 6 (14 bits in the High 4:4:4 Predictive profile).
- The EVC record (12.3.3.2) and the LCEVC record of Amendment 1 use 3 bit
fields too. I have not checked the value ranges of these codecs.
Problem
HEVC allows bit depths from 8 to 16. ISO/IEC 23008-2, 7.4.3.2.1 says
"bit_depth_luma_minus8 shall be in the range of 0 to 8, inclusive", and the
same for chroma. Several profiles use the upper end, among them Monochrome 16,
Main 4:4:4 16 Intra and Main 4:4:4 16 Still Picture.
HEVCDecoderConfigurationRecord(ISO/IEC 14496-15:2022, 8.3.2.1.2) storesthese values in 3 bits:
The fields hold 0 to 7, that is 8 to 15 bits. According to 8.3.2.1.3 they
contain "the matching values" of the parameter sets, which is not possible for
a stream with 16 bits. Such a stream cannot be stored with a correct
configuration record.
What happens today
Writers store the low 3 bits of the value. GPAC 2.2.1 writes
0xF8into bothfields of a 16 bit stream, which is the same byte as for 8 bits. Every writer
that computes
value | 0xF8does the same, because bit 3 of the value fallsonto a reserved bit that is set anyway.
Readers that take the bit depth from the record see 8 bits per pixel. libheif reports
8 bits for such an image and converts it to 8 bits on output, although the
decoder delivers 16 bits. For this reason libheif now refuses to encode HEVC
with 16 bits.
Proposal
Define version 2 of the record, in which the two fields have 4 bits:
The size of the record and the position of all other fields stay the same.
Version 2 should be used only when a bit depth of 16 has to be signalled.
Streams with up to 15 bits keep version 1, so that everything that can be
stored today remains readable by existing readers.
Using one of the reserved bits without changing the version does not work.
A reader of version 1 would read the low 3 bits and take a stream with 16 bits
for one with 8 bits. With a new version it refuses the stream instead, as
8.3.2.1.1 requires for an unrecognized version.
Related records
VvcDecoderConfigurationRecord(11.2.4.2.2) has the same limit.bit_depth_minus8has 3 bits, and ISO/IEC 23090-3:2022, 7.4.3.4 allowssps_bitdepth_minus8from 0 to 8. This record has no version field of itsown, but
VvcConfigurationBoxis aFullBox, so its version could be used.AVCDecoderConfigurationRecord: the fields are wide enough, but 5.3.2.1.3limits them to the range 0 to 4, while ISO/IEC 14496-10:2022, 7.4.2.1.1
allows 0 to 6 (14 bits in the High 4:4:4 Predictive profile).
fields too. I have not checked the value ranges of these codecs.