Add colr box

This commit is contained in:
Vanilagy
2024-11-24 15:04:57 +01:00
parent 29ecccb26a
commit 29749451bb
7 changed files with 143 additions and 68 deletions
+12 -3
View File
@@ -1,4 +1,4 @@
import { toUint8Array, assert, isU32, last, TransformationMatrix, textEncoder } from '../misc';
import { toUint8Array, assert, isU32, last, TransformationMatrix, textEncoder, COLOR_PRIMARIES_MAP, TRANSFER_CHARACTERISTICS_MAP, MATRIX_COEFFICIENTS_MAP, colorSpaceIsComplete } from '../misc';
import { AudioCodec, AudioSource, SubtitleCodec, VideoCodec, VideoSource } from '../source';
import { formatSubtitleTimestamp } from '../subtitles';
import { Writer } from '../writer';
@@ -525,8 +525,17 @@ export const videoSampleDescription = (
u16(0x0018), // Depth
i16(0xffff) // Pre-defined
], [
VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source.codec](trackData)
// TODO colr
VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source.codec](trackData),
colorSpaceIsComplete(trackData.info.decoderConfig.colorSpace) ? colr(trackData) : null
]);
/** Colour Information Box: Specifies the color space of the video. */
export const colr = (trackData: IsobmffVideoTrackData) => box('colr', [
ascii('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
]);
// TODO: All muxers should ensure that the decoder config description is provided for the codecs that require it. This
+5 -18
View File
@@ -1,4 +1,4 @@
import { assert, readBits, textEncoder, toUint8Array, writeBits } from '../misc';
import { assert, COLOR_PRIMARIES_MAP, colorSpaceIsComplete, MATRIX_COEFFICIENTS_MAP, readBits, textEncoder, toUint8Array, TRANSFER_CHARACTERISTICS_MAP, writeBits } from '../misc';
import { Muxer } from '../muxer';
import { Output, OutputAudioTrack, OutputSubtitleTrack, OutputTrack, OutputVideoTrack } from '../output';
import { MkvOutputFormat, WebMOutputFormat } from '../output_format';
@@ -398,27 +398,14 @@ export class MatroskaMuxer extends Muxer {
(() => {
if (trackData.info.decoderConfig.colorSpace) {
let colorSpace = trackData.info.decoderConfig.colorSpace;
if (!colorSpace.matrix || !colorSpace.transfer || !colorSpace.primaries || colorSpace.fullRange == null) {
if (!colorSpaceIsComplete(colorSpace)) {
return null;
}
return {id: EBMLId.Colour, data: [
{ id: EBMLId.MatrixCoefficients, data: {
'rgb': 1,
'bt709': 1,
'bt470bg': 5,
'smpte170m': 6
}[colorSpace.matrix] },
{ id: EBMLId.TransferCharacteristics, data: {
'bt709': 1,
'smpte170m': 6,
'iec61966-2-1': 13
}[colorSpace.transfer] },
{ id: EBMLId.Primaries, data: {
'bt709': 1,
'bt470bg': 5,
'smpte170m': 6
}[colorSpace.primaries] },
{ id: EBMLId.MatrixCoefficients, data: MATRIX_COEFFICIENTS_MAP[colorSpace.matrix!] },
{ id: EBMLId.TransferCharacteristics, data: TRANSFER_CHARACTERISTICS_MAP[colorSpace.transfer!] },
{ id: EBMLId.Primaries, data: COLOR_PRIMARIES_MAP[colorSpace.primaries!] },
{ id: EBMLId.Range, data: [1, 2][Number(colorSpace.fullRange)]! }
] };
}
+24 -1
View File
@@ -50,4 +50,27 @@ export const toUint8Array = (source: AllowSharedBufferSource): Uint8Array => {
}
};
export const textEncoder = new TextEncoder();
export const textEncoder = new TextEncoder();
// These maps are taken from https://www.matroska.org/technical/elements.html,
// which references the tables in ITU-T H.273 - they should be valid for Matroska and ISOBMFF.
export const COLOR_PRIMARIES_MAP: Record<VideoColorPrimaries, number> = {
'bt709': 1, // ITU-R BT.709
'bt470bg': 5, // ITU-R BT.470BG
'smpte170m': 6 // ITU-R BT.601 525 - SMPTE 170M
};
export const TRANSFER_CHARACTERISTICS_MAP: Record<VideoTransferCharacteristics, number> = {
'bt709': 1, // ITU-R BT.709
'smpte170m': 6, // SMPTE 170M
'iec61966-2-1': 13 // IEC 61966-2-1
};
export const MATRIX_COEFFICIENTS_MAP: Record<VideoMatrixCoefficients, number> = {
'rgb': 0, // Identity
'bt709': 1, // ITU-R BT.709
'bt470bg': 5, // ITU-R BT.470BG
'smpte170m': 6 // SMPTE 170M
};
export const colorSpaceIsComplete = (colorSpace: VideoColorSpaceInit | undefined) => {
return !!colorSpace && !!colorSpace.primaries && !!colorSpace.transfer && !!colorSpace.matrix && colorSpace.fullRange !== undefined;
};