Skip to content

Commit 8bafa18

Browse files
rohitjoinscopybara-github
authored andcommitted
Align Matroska and MP4 color info extraction
Previously, `MatroskaExtractor` relied exclusively on container-level EBML tags for building `ColorInfo` and defaulted bit depths to `Format.NO_VALUE`. This resulted in missing or inaccurate metadata compared to MP4 extraction, which properly utilizes codec bitstream information. This change updates `MatroskaExtractor` to replicate the color info extraction logic from `Mp4Extractor` (`BoxParser`): - Color information (color space, transfer, range) and bit depths are now extracted from the codec bitstream (`AvcConfig`, `HevcConfig`) and safely take precedence over container-level metadata. - Luma and chroma bit depths are now tracked and overridden independently. - The default bit depth for video tracks is now set to 8, and `ColorInfo` is unconditionally built for all video tracks. Extractor test dump files have been updated to reflect the newly populated `ColorInfo` fields. PiperOrigin-RevId: 879691350
1 parent b8a4643 commit 8bafa18

110 files changed

Lines changed: 399 additions & 30 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

RELEASENOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
* Extractors:
2323
* WAV, Matroska, and MP4: Add support for 64-bit floating point PCM audio
2424
([#3090](https://github.com/androidx/media/pull/3090)).
25+
* Matroska: Use codec bitstream metadata to populate accurate `ColorInfo`.
2526
* Inspector:
2627
* Audio:
2728
* Convert parameters of `AudioSink.configure` to data class. Custom

libraries/extractor/src/main/java/androidx/media3/extractor/mkv/MatroskaExtractor.java

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -830,9 +830,6 @@ protected void startMasterElement(int id, long contentPosition, long contentSize
830830
currentTrack = new Track();
831831
currentTrack.isWebm = isWebm;
832832
break;
833-
case ID_MASTERING_METADATA:
834-
getCurrentTrack(id).hasColorInfo = true;
835-
break;
836833
default:
837834
break;
838835
}
@@ -1248,32 +1245,30 @@ protected void integerElement(int id, long value) throws ParserException {
12481245
break;
12491246
case ID_COLOUR_PRIMARIES:
12501247
assertInTrackEntry(id);
1251-
currentTrack.hasColorInfo = true;
12521248
int colorSpace = ColorInfo.isoColorPrimariesToColorSpace((int) value);
12531249
if (colorSpace != Format.NO_VALUE) {
1254-
currentTrack.colorSpace = colorSpace;
1250+
currentTrack.containerColorSpace = colorSpace;
12551251
}
12561252
break;
12571253
case ID_COLOUR_TRANSFER:
12581254
assertInTrackEntry(id);
12591255
int colorTransfer = ColorInfo.isoTransferCharacteristicsToColorTransfer((int) value);
12601256
if (colorTransfer != Format.NO_VALUE) {
1261-
currentTrack.colorTransfer = colorTransfer;
1257+
currentTrack.containerColorTransfer = colorTransfer;
12621258
}
12631259
break;
12641260
case ID_COLOUR_BITS_PER_CHANNEL:
12651261
assertInTrackEntry(id);
1266-
currentTrack.hasColorInfo = true;
12671262
currentTrack.bitsPerChannel = (int) value;
12681263
break;
12691264
case ID_COLOUR_RANGE:
12701265
assertInTrackEntry(id);
12711266
switch ((int) value) {
12721267
case 1: // Broadcast range.
1273-
currentTrack.colorRange = C.COLOR_RANGE_LIMITED;
1268+
currentTrack.containerColorRange = C.COLOR_RANGE_LIMITED;
12741269
break;
12751270
case 2:
1276-
currentTrack.colorRange = C.COLOR_RANGE_FULL;
1271+
currentTrack.containerColorRange = C.COLOR_RANGE_FULL;
12771272
break;
12781273
default:
12791274
break;
@@ -2253,10 +2248,9 @@ protected static final class Track {
22532248
public float projectionPoseRoll = 0f;
22542249
public byte @MonotonicNonNull [] projectionData = null;
22552250
public @C.StereoMode int stereoMode = Format.NO_VALUE;
2256-
public boolean hasColorInfo = false;
2257-
public @C.ColorSpace int colorSpace = Format.NO_VALUE;
2258-
public @C.ColorTransfer int colorTransfer = Format.NO_VALUE;
2259-
public @C.ColorRange int colorRange = Format.NO_VALUE;
2251+
public @C.ColorSpace int containerColorSpace = Format.NO_VALUE;
2252+
public @C.ColorTransfer int containerColorTransfer = Format.NO_VALUE;
2253+
public @C.ColorRange int containerColorRange = Format.NO_VALUE;
22602254
public int maxContentLuminance = DEFAULT_MAX_CLL;
22612255
public int maxFrameAverageLuminance = DEFAULT_MAX_FALL;
22622256
public float primaryRChromaticityX = Format.NO_VALUE;
@@ -2300,6 +2294,11 @@ public void initializeFormat(int trackId) throws ParserException {
23002294
@C.PcmEncoding int pcmEncoding = Format.NO_VALUE;
23012295
@Nullable List<byte[]> initializationData = null;
23022296
@Nullable String codecs = null;
2297+
@C.ColorSpace int bitstreamColorSpace = Format.NO_VALUE;
2298+
@C.ColorTransfer int bitstreamColorTransfer = Format.NO_VALUE;
2299+
@C.ColorRange int bitstreamColorRange = Format.NO_VALUE;
2300+
int bitstreamLumaBitdepth = Format.NO_VALUE;
2301+
int bitstreamChromaBitdepth = Format.NO_VALUE;
23032302
switch (codecId) {
23042303
case CODEC_ID_VP8:
23052304
mimeType = MimeTypes.VIDEO_VP8;
@@ -2328,13 +2327,23 @@ public void initializeFormat(int trackId) throws ParserException {
23282327
initializationData = avcConfig.initializationData;
23292328
nalUnitLengthFieldLength = avcConfig.nalUnitLengthFieldLength;
23302329
codecs = avcConfig.codecs;
2330+
bitstreamColorSpace = avcConfig.colorSpace;
2331+
bitstreamColorTransfer = avcConfig.colorTransfer;
2332+
bitstreamColorRange = avcConfig.colorRange;
2333+
bitstreamLumaBitdepth = avcConfig.bitdepthLuma;
2334+
bitstreamChromaBitdepth = avcConfig.bitdepthChroma;
23312335
break;
23322336
case CODEC_ID_H265:
23332337
mimeType = MimeTypes.VIDEO_H265;
23342338
HevcConfig hevcConfig = HevcConfig.parse(new ParsableByteArray(getCodecPrivate(codecId)));
23352339
initializationData = hevcConfig.initializationData;
23362340
nalUnitLengthFieldLength = hevcConfig.nalUnitLengthFieldLength;
23372341
codecs = hevcConfig.codecs;
2342+
bitstreamColorSpace = hevcConfig.colorSpace;
2343+
bitstreamColorTransfer = hevcConfig.colorTransfer;
2344+
bitstreamColorRange = hevcConfig.colorRange;
2345+
bitstreamLumaBitdepth = hevcConfig.bitdepthLuma;
2346+
bitstreamChromaBitdepth = hevcConfig.bitdepthChroma;
23382347
break;
23392348
case CODEC_ID_FOURCC:
23402349
Pair<String, @NullableType List<byte[]>> pair =
@@ -2524,19 +2533,47 @@ public void initializeFormat(int trackId) throws ParserException {
25242533
if (displayWidth != Format.NO_VALUE && displayHeight != Format.NO_VALUE) {
25252534
pixelWidthHeightRatio = ((float) (height * displayWidth)) / (width * displayHeight);
25262535
}
2527-
@Nullable ColorInfo colorInfo = null;
2528-
if (hasColorInfo) {
2529-
@Nullable byte[] hdrStaticInfo = getHdrStaticInfo();
2530-
colorInfo =
2531-
new ColorInfo.Builder()
2532-
.setColorSpace(colorSpace)
2533-
.setColorRange(colorRange)
2534-
.setColorTransfer(colorTransfer)
2535-
.setHdrStaticInfo(hdrStaticInfo)
2536-
.setLumaBitdepth(bitsPerChannel)
2537-
.setChromaBitdepth(bitsPerChannel)
2538-
.build();
2539-
}
2536+
2537+
@C.ColorSpace int colorSpace;
2538+
@C.ColorTransfer int colorTransfer;
2539+
@C.ColorRange int colorRange;
2540+
2541+
// Bitstream color space/transfer override container values as a block.
2542+
if (bitstreamColorSpace != Format.NO_VALUE || bitstreamColorTransfer != Format.NO_VALUE) {
2543+
colorSpace = bitstreamColorSpace;
2544+
colorTransfer = bitstreamColorTransfer;
2545+
colorRange = bitstreamColorRange;
2546+
} else if (bitstreamColorRange != Format.NO_VALUE
2547+
&& this.containerColorRange == Format.NO_VALUE) {
2548+
colorSpace = this.containerColorSpace;
2549+
colorTransfer = this.containerColorTransfer;
2550+
colorRange = bitstreamColorRange;
2551+
} else {
2552+
colorSpace = this.containerColorSpace;
2553+
colorTransfer = this.containerColorTransfer;
2554+
colorRange = this.containerColorRange;
2555+
}
2556+
2557+
// Set default luma and chroma bit depths to 8 as old codecs might not even signal them.
2558+
int lumaBitdepth =
2559+
bitstreamLumaBitdepth != Format.NO_VALUE
2560+
? bitstreamLumaBitdepth
2561+
: (this.bitsPerChannel != Format.NO_VALUE ? this.bitsPerChannel : 8);
2562+
int chromaBitdepth =
2563+
bitstreamChromaBitdepth != Format.NO_VALUE
2564+
? bitstreamChromaBitdepth
2565+
: (this.bitsPerChannel != Format.NO_VALUE ? this.bitsPerChannel : 8);
2566+
2567+
@Nullable byte[] hdrStaticInfo = getHdrStaticInfo();
2568+
ColorInfo colorInfo =
2569+
new ColorInfo.Builder()
2570+
.setColorSpace(colorSpace)
2571+
.setColorRange(colorRange)
2572+
.setColorTransfer(colorTransfer)
2573+
.setHdrStaticInfo(hdrStaticInfo)
2574+
.setLumaBitdepth(lumaBitdepth)
2575+
.setChromaBitdepth(chromaBitdepth)
2576+
.build();
25402577
int rotationDegrees = Format.NO_VALUE;
25412578

25422579
if (name != null && TRACK_NAME_TO_ROTATION_DEGREES.containsKey(name)) {

libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.0.dump

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ track 1:
1616
codecs = avc1.640034
1717
width = 1080
1818
height = 720
19+
colorInfo:
20+
lumaBitdepth = 8
21+
chromaBitdepth = 8
1922
selectionFlags = [default]
2023
language = und
2124
metadata = entries=[ThumbnailMetadata: presentationTimeUs=67000]

libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.1.dump

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ track 1:
1616
codecs = avc1.640034
1717
width = 1080
1818
height = 720
19+
colorInfo:
20+
lumaBitdepth = 8
21+
chromaBitdepth = 8
1922
selectionFlags = [default]
2023
language = und
2124
metadata = entries=[ThumbnailMetadata: presentationTimeUs=67000]

libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.2.dump

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ track 1:
1616
codecs = avc1.640034
1717
width = 1080
1818
height = 720
19+
colorInfo:
20+
lumaBitdepth = 8
21+
chromaBitdepth = 8
1922
selectionFlags = [default]
2023
language = und
2124
metadata = entries=[ThumbnailMetadata: presentationTimeUs=67000]

libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.3.dump

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ track 1:
1616
codecs = avc1.640034
1717
width = 1080
1818
height = 720
19+
colorInfo:
20+
lumaBitdepth = 8
21+
chromaBitdepth = 8
1922
selectionFlags = [default]
2023
language = und
2124
metadata = entries=[ThumbnailMetadata: presentationTimeUs=67000]

libraries/test_data/src/test/assets/extractordumps/mkv/sample.mkv.unknown_length.dump

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ track 1:
1616
codecs = avc1.640034
1717
width = 1080
1818
height = 720
19+
colorInfo:
20+
lumaBitdepth = 8
21+
chromaBitdepth = 8
1922
selectionFlags = [default]
2023
language = und
2124
metadata = entries=[ThumbnailMetadata: presentationTimeUs=67000]

libraries/test_data/src/test/assets/extractordumps/mkv/sample_with_htc_rotation_track_name.mkv.0.dump

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ track 1:
1717
width = 1080
1818
height = 720
1919
rotationDegrees = 90
20+
colorInfo:
21+
lumaBitdepth = 8
22+
chromaBitdepth = 8
2023
selectionFlags = [default]
2124
language = und
2225
metadata = entries=[ThumbnailMetadata: presentationTimeUs=0]

libraries/test_data/src/test/assets/extractordumps/mkv/sample_with_htc_rotation_track_name.mkv.1.dump

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ track 1:
1717
width = 1080
1818
height = 720
1919
rotationDegrees = 90
20+
colorInfo:
21+
lumaBitdepth = 8
22+
chromaBitdepth = 8
2023
selectionFlags = [default]
2124
language = und
2225
metadata = entries=[ThumbnailMetadata: presentationTimeUs=0]

libraries/test_data/src/test/assets/extractordumps/mkv/sample_with_htc_rotation_track_name.mkv.2.dump

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ track 1:
1717
width = 1080
1818
height = 720
1919
rotationDegrees = 90
20+
colorInfo:
21+
lumaBitdepth = 8
22+
chromaBitdepth = 8
2023
selectionFlags = [default]
2124
language = und
2225
metadata = entries=[ThumbnailMetadata: presentationTimeUs=0]

0 commit comments

Comments
 (0)