diff --git a/src/codec-data.ts b/src/codec-data.ts index 9afcab2..acb5988 100644 --- a/src/codec-data.ts +++ b/src/codec-data.ts @@ -1726,6 +1726,16 @@ export type Vp9CodecInfo = { matrixCoefficients: number; }; +// The color spaces from section 7.2.2 of the VP9 spec The matrix column is taken from FFmpeg's libavcodec/vp9.c +const VP9_COLOR_SPACE_TABLE = { + 1: { colourPrimaries: 5, transferCharacteristics: 6, matrixCoefficients: 5 }, // CS_BT_601 + 2: { colourPrimaries: 1, transferCharacteristics: 1, matrixCoefficients: 1 }, // CS_BT_709 + 3: { colourPrimaries: 6, transferCharacteristics: 6, matrixCoefficients: 6 }, // CS_SMPTE_170 + 4: { colourPrimaries: 7, transferCharacteristics: 7, matrixCoefficients: 7 }, // CS_SMPTE_240 + 5: { colourPrimaries: 9, transferCharacteristics: 14, matrixCoefficients: 9 }, // CS_BT_2020 + 7: { colourPrimaries: 1, transferCharacteristics: 13, matrixCoefficients: 0 }, // CS_RGB (sRGB) +}; + export const extractVp9CodecInfoFromPacket = ( packet: Uint8Array, ): Vp9CodecInfo | null => { @@ -1834,26 +1844,10 @@ export const extractVp9CodecInfoFromPacket = ( } } - // Map color_space to standard values - const matrixCoefficients = colorSpace === 7 - ? 0 - : colorSpace === 2 - ? 1 - : colorSpace === 1 - ? 6 - : 2; - - const colourPrimaries = colorSpace === 2 - ? 1 - : colorSpace === 1 - ? 6 - : 2; - - const transferCharacteristics = colorSpace === 2 - ? 1 - : colorSpace === 1 - ? 6 - : 2; + const colorSpaceValues = VP9_COLOR_SPACE_TABLE[colorSpace as keyof typeof VP9_COLOR_SPACE_TABLE]; + const colourPrimaries = colorSpaceValues?.colourPrimaries ?? 2; + const transferCharacteristics = colorSpaceValues?.transferCharacteristics ?? 2; + const matrixCoefficients = colorSpaceValues?.matrixCoefficients ?? 2; return { profile, diff --git a/test/browser/color-space.test.ts b/test/browser/color-space.test.ts index 880d4fd..c54046d 100644 --- a/test/browser/color-space.test.ts +++ b/test/browser/color-space.test.ts @@ -36,10 +36,15 @@ test('Color space extraction, HEVC in MP4', async () => { }); test('Color space extraction, VP9 in MP4', async () => { - const source = await encodePackets('vp9', 'vp09.00.10.08'); + const source = await readPackets('/vp9-smpte170m.webm'); const buffer = await remuxWithoutColorSpace(new Mp4OutputFormat(), source); - await expectCompleteColorSpace(new BufferSource(buffer)); + await expectColorSpace(new BufferSource(buffer), { + primaries: 'smpte170m', + transfer: 'smpte170m', + matrix: 'smpte170m', + fullRange: false, + }); }); test('Color space extraction, AV1 in MP4', async () => { @@ -75,10 +80,15 @@ test('Color space extraction, HEVC in Matroska', async () => { }); test('Color space extraction, VP9 in Matroska', async () => { - const source = await encodePackets('vp9', 'vp09.00.10.08'); + const source = await readPackets('/vp9-smpte170m.webm'); const buffer = await remuxWithoutColorSpace(new MkvOutputFormat(), source); - await expectCompleteColorSpace(new BufferSource(buffer)); + await expectColorSpace(new BufferSource(buffer), { + primaries: 'smpte170m', + transfer: 'smpte170m', + matrix: 'smpte170m', + fullRange: false, + }); }); test('Color space extraction, AV1 in Matroska', async () => { diff --git a/test/public/vp9-smpte170m.webm b/test/public/vp9-smpte170m.webm new file mode 100644 index 0000000..06c83ef Binary files /dev/null and b/test/public/vp9-smpte170m.webm differ