Repository navigation
[DASH] HDR10/HLG signalled via CICP EssentialProperty is not surfaced as HDR to DefaultTrackSelector #3426
Description
Version
Media3 main branch
More version details
No response
Devices that reproduce the issue
Any device, this is a manifest‑parsing bug, not device‑specific. Verified on Samsung SM‑S908E (S22 Ultra) and Pixel 8 running Android 14.
Devices that do not reproduce the issue
N/A
Reproducible in the demo app?
Yes
Reproduction steps
- Use a DASH manifest containing an HEVC Main10 HDR10 Representation and an HEVC SDR Representation of the same or higher resolution.
Signal HDR10 using the DASH CICP descriptors in the MPD, for example:
<AdaptationSet ... contentType="video">
<EssentialProperty schemeIdUri="urn:mpeg:mpegB:cicp:MatrixCoefficients" value="9"></EssentialProperty>
<EssentialProperty schemeIdUri="urn:mpeg:mpegB:cicp:ColourPrimaries" value="9"></EssentialProperty>
<EssentialProperty schemeIdUri="urn:mpeg:mpegB:cicp:TransferCharacteristics" value="16"></EssentialProperty>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"></Role>
<Representation sar="1:1" mimeType="video/mp4" codecs=.../>
...
- Start playback and observe which
Representationis selected and itsFormat.colorInfo.
Expected result
The DASH parser should propagate the HDR information from the MPD into Format.colorInfo, allowing DefaultTrackSelector to identify the Representation as HDR during track selection.
When both HDR and SDR representations are otherwise comparable, the HDR representation should therefore be preferred on a device/display that supports HDR.
Actual result
DashManifestParser.buildFormat() does not populate Format.colorInfo for HDR10/HLG based on the CICP descriptors in the DASH MPD.
As a result, Format.colorInfo is null for the HDR10 Representation and DefaultTrackSelector.VideoTrackInfo.isHdr evaluates to false.
The HDR preference in DefaultTrackSelector therefore has no effect:
.compareFalseFirst(info1.isHdr, info2.isHdr)
.compare(info1.pixelCount, info2.pixelCount, qualityOrdering);
Track selection can consequently prefer the SDR Representation based on resolution/bitrate, even though an HDR10-capable Representation is available and the device supports HDR.
The actual HDR ColorInfo can be discovered later from the MP4 initialization segment by BoxParser.parseVideoSampleEntry through the colr box. However, this happens after the Representation has already been selected. The newly discovered color information therefore cannot influence the original track-selection decision.
Media
Root cause:
DashManifestParser.buildFormat() currently populates Format.colorInfo for Dolby Vision:
@Nullable ColorInfo colorInfo = null;
if (MimeTypes.isDolbyVisionCodec(codecs, supplementalCodecs)) {
sampleMimeType = MimeTypes.VIDEO_DOLBY_VISION;
colorInfo =
Util.getColorInfoForDolbyVision(
codecs, supplementalCodecs, supplementalProfiles);
codecs = supplementalCodecs != null ? supplementalCodecs : codecs;
}
However, the DASH CICP descriptors used to signal HDR10/HLG are not currently mapped to Format.colorInfo.
The relevant descriptors are:
urn:mpeg:mpegB:cicp:MatrixCoefficients
urn:mpeg:mpegB:cicp:ColourPrimaries
urn:mpeg:mpegB:cicp:TransferCharacteristics
These descriptors are used by DASH specifications/profiles to signal color characteristics in the MPD.
Media3 already contains the required mapping helpers:
ColorInfo.isoColorPrimariesToColorSpace(int)
Util.isoTransferCharacteristicsToColorTransfer(int)
but these mappings are not currently used by DashManifestParser when constructing the Format.
Media: Any DASH manifest that follows DASH‑IF IOP §4.3 for HDR10 will reproduce.
Proposed fix
Parse the CICP descriptors from the DASH EssentialProperty and SupplementalProperty elements and populate Format.colorInfo during DashManifestParser.buildFormat().
For example:
private static final String CICP_SCHEME_PRIMARIES =
"urn:mpeg:mpegB:cicp:ColourPrimaries";
private static final String CICP_SCHEME_TRANSFER =
"urn:mpeg:mpegB:cicp:TransferCharacteristics";
private static final String CICP_SCHEME_MATRIX =
"urn:mpeg:mpegB:cicp:MatrixCoefficients";
@Nullable
private static ColorInfo parseColorInfoFromMpdProperties(
List<Descriptor> essentialProperties,
List<Descriptor> supplementalProperties) {
int isoTransfer = Format.NO_VALUE;
int isoPrimaries = Format.NO_VALUE;
boolean hasBt2020Matrix = false;
for (Descriptor descriptor :
Iterables.concat(essentialProperties, supplementalProperties)) {
if (descriptor.value == null) {
continue;
}
try {
int value = Integer.parseInt(descriptor.value.trim());
switch (descriptor.schemeIdUri) {
case CICP_SCHEME_TRANSFER:
isoTransfer = value;
break;
case CICP_SCHEME_PRIMARIES:
isoPrimaries = value;
break;
case CICP_SCHEME_MATRIX:
hasBt2020Matrix = value == 9;
break;
}
} catch (NumberFormatException ignored) {
// Ignore malformed values.
}
}
@C.ColorTransfer
int transfer =
isoTransfer == Format.NO_VALUE
? Format.NO_VALUE
: Util.isoTransferCharacteristicsToColorTransfer(isoTransfer);
// Only expose HDR information here. Leave SDR unchanged so that
// extraction can provide the exact values when available.
if (transfer != C.COLOR_TRANSFER_ST2084
&& transfer != C.COLOR_TRANSFER_HLG) {
return null;
}
@C.ColorSpace
int colorSpace =
isoPrimaries == Format.NO_VALUE
? (hasBt2020Matrix ? C.COLOR_SPACE_BT2020 : Format.NO_VALUE)
: ColorInfo.isoColorPrimariesToColorSpace(isoPrimaries);
return new ColorInfo.Builder()
.setColorSpace(colorSpace)
.setColorTransfer(transfer)
.build();
}
Then, after the existing Dolby Vision handling:
if (colorInfo == null && MimeTypes.isVideo(sampleMimeType)) {
colorInfo =
parseColorInfoFromMpdProperties(
essentialProperties, supplementalProperties);
}
This would allow HDR10/HLG information available in the DASH MPD to participate in track selection, while preserving the existing extraction path for more detailed color information.
Bug Report
- You will email the zip file produced by
adb bugreportto android-media-github@google.com after filing this issue.
Activity
microkatz commentedon Sep 22, 2026
@akhilesh-dubey
Thanks for the detailed report and analysis!
We've prepared a fix to parse the DASH CICP descriptors (ColourPrimaries, TransferCharacteristics, MatrixCoefficients, and VideoFullRangeFlag) from EssentialProperty and SupplementalProperty elements into Format.colorInfo in DashManifestParser, so that HDR10 and HLG representations are properly surfaced to DefaultTrackSelector during track selection.
We're working on getting the fix reviewed and submitted to main shortly—this issue will be updated automatically once the commit lands.
akhilesh-dubey commentedon Sep 23, 2026
Thanks for the update, appreciate it!
Parse DASH CICP properties into Format.colorInfo
microkatz commentedon Oct 1, 2026
Hello @akhilesh-dubey,
I have submitted a fix, ebccde8, into the main branch that will ensure parsing of the CICP properties.
Hopefully this addresses your issue and so I will close this ticket. If it does not then feel free to re-open or create a new ticket!