Support QuickTime nclc color information (#397)

* Support QuickTime nclc color information

* Tighten QuickTime nclc color test fixture

* Make QuickTime muxer write nclc color box

---------

Co-authored-by: Vanilagy <[email protected]>
This commit is contained in:
Noah
2026-06-02 09:48:06 +00:00
committed by GitHub
co-authored by Vanilagy
parent 05f8ecd908
commit c0d93f45a5
4 changed files with 120 additions and 7 deletions
+4 -2
View File
@@ -741,11 +741,13 @@ export const pasp = (trackData: IsobmffVideoTrackData) => {
/** Colour Information Box: Specifies the color space of the video. */
export const colr = (trackData: IsobmffVideoTrackData) => box('colr', [
ascii('nclx'), // Colour type
ascii(trackData.muxer.isQuickTime ? 'nclc' : 'nclx'), // Colour type
u16(COLOR_PRIMARIES_MAP[trackData.info.decoderConfig.colorSpace!.primaries!]), // Colour primaries
u16(TRANSFER_CHARACTERISTICS_MAP[trackData.info.decoderConfig.colorSpace!.transfer!]), // Transfer characteristics
u16(MATRIX_COEFFICIENTS_MAP[trackData.info.decoderConfig.colorSpace!.matrix!]), // Matrix coefficients
u8((trackData.info.decoderConfig.colorSpace!.fullRange ? 1 : 0) << 7), // Full range flag
trackData.muxer.isQuickTime
? [] // Doesn't have it
: u8((trackData.info.decoderConfig.colorSpace!.fullRange ? 1 : 0) << 7), // Full range flag
]);
/** AVC Configuration Box: Provides additional information to the decoder. */
+7 -3
View File
@@ -1448,20 +1448,24 @@ export class IsobmffDemuxer extends Demuxer {
assert(track.info?.type === 'video');
const colourType = readAscii(slice, 4);
if (colourType !== 'nclx') {
if (colourType !== 'nclx' && colourType !== 'nclc') {
break;
}
const colourPrimaries = readU16Be(slice);
const transferCharacteristics = readU16Be(slice);
const matrixCoefficients = readU16Be(slice);
const fullRangeFlag = Boolean(readU8(slice) & 0x80);
let fullRange: boolean | undefined = undefined;
if (colourType === 'nclx') {
fullRange = Boolean(readU8(slice) & 0x80);
}
track.info.colorSpace = {
primaries: COLOR_PRIMARIES_MAP_INVERSE[colourPrimaries],
transfer: TRANSFER_CHARACTERISTICS_MAP_INVERSE[transferCharacteristics],
matrix: MATRIX_COEFFICIENTS_MAP_INVERSE[matrixCoefficients],
fullRange: fullRangeFlag,
fullRange,
} as VideoColorSpaceInit;
}; break;