mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add support to fetch ColorInfo
from hvcc
box in AtomParsers
#minor-release PiperOrigin-RevId: 517086016
This commit is contained in:
parent
eb6fc93b15
commit
e4446c37fb
@ -1208,6 +1208,15 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
pixelWidthHeightRatio = hevcConfig.pixelWidthHeightRatio;
|
||||
}
|
||||
codecs = hevcConfig.codecs;
|
||||
// Modify these values only if they have not already been set. If 'Atom.TYPE_colr' atom is
|
||||
// present, these values may be overridden.
|
||||
if (colorSpace == Format.NO_VALUE
|
||||
&& colorRange == Format.NO_VALUE
|
||||
&& colorTransfer == Format.NO_VALUE) {
|
||||
colorSpace = hevcConfig.colorSpace;
|
||||
colorRange = hevcConfig.colorRange;
|
||||
colorTransfer = hevcConfig.colorTransfer;
|
||||
}
|
||||
} else if (childAtomType == Atom.TYPE_dvcC || childAtomType == Atom.TYPE_dvvC) {
|
||||
@Nullable DolbyVisionConfig dolbyVisionConfig = DolbyVisionConfig.parse(parent);
|
||||
if (dolbyVisionConfig != null) {
|
||||
|
@ -19,6 +19,8 @@ import static java.lang.Math.min;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.video.ColorInfo;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
@ -105,6 +107,9 @@ public final class NalUnitUtil {
|
||||
public final int width;
|
||||
public final int height;
|
||||
public final float pixelWidthHeightRatio;
|
||||
public final @C.ColorSpace int colorSpace;
|
||||
public final @C.ColorRange int colorRange;
|
||||
public final @C.ColorTransfer int colorTransfer;
|
||||
|
||||
public H265SpsData(
|
||||
int generalProfileSpace,
|
||||
@ -116,7 +121,10 @@ public final class NalUnitUtil {
|
||||
int seqParameterSetId,
|
||||
int width,
|
||||
int height,
|
||||
float pixelWidthHeightRatio) {
|
||||
float pixelWidthHeightRatio,
|
||||
@C.ColorSpace int colorSpace,
|
||||
@C.ColorRange int colorRange,
|
||||
@C.ColorTransfer int colorTransfer) {
|
||||
this.generalProfileSpace = generalProfileSpace;
|
||||
this.generalTierFlag = generalTierFlag;
|
||||
this.generalProfileIdc = generalProfileIdc;
|
||||
@ -127,6 +135,9 @@ public final class NalUnitUtil {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.pixelWidthHeightRatio = pixelWidthHeightRatio;
|
||||
this.colorSpace = colorSpace;
|
||||
this.colorRange = colorRange;
|
||||
this.colorTransfer = colorTransfer;
|
||||
}
|
||||
}
|
||||
|
||||
@ -483,6 +494,10 @@ public final class NalUnitUtil {
|
||||
public static H265SpsData parseH265SpsNalUnitPayload(
|
||||
byte[] nalData, int nalOffset, int nalLimit) {
|
||||
ParsableNalUnitBitArray data = new ParsableNalUnitBitArray(nalData, nalOffset, nalLimit);
|
||||
// HDR related metadata.
|
||||
@C.ColorSpace int colorSpace = Format.NO_VALUE;
|
||||
@C.ColorRange int colorRange = Format.NO_VALUE;
|
||||
@C.ColorTransfer int colorTransfer = Format.NO_VALUE;
|
||||
data.skipBits(4); // sps_video_parameter_set_id
|
||||
int maxSubLayersMinus1 = data.readBits(3);
|
||||
data.skipBit(); // sps_temporal_id_nesting_flag
|
||||
@ -589,10 +604,17 @@ public final class NalUnitUtil {
|
||||
data.skipBit(); // overscan_appropriate_flag
|
||||
}
|
||||
if (data.readBit()) { // video_signal_type_present_flag
|
||||
data.skipBits(4); // video_format, video_full_range_flag
|
||||
data.skipBits(3); // video_format
|
||||
boolean fullRangeFlag = data.readBit(); // video_full_range_flag
|
||||
if (data.readBit()) { // colour_description_present_flag
|
||||
// colour_primaries, transfer_characteristics, matrix_coeffs
|
||||
data.skipBits(24);
|
||||
int colorPrimaries = data.readBits(8); // colour_primaries
|
||||
int transferCharacteristics = data.readBits(8); // transfer_characteristics
|
||||
data.skipBits(8); // matrix_coeffs
|
||||
|
||||
colorSpace = ColorInfo.isoColorPrimariesToColorSpace(colorPrimaries);
|
||||
colorRange = fullRangeFlag ? C.COLOR_RANGE_FULL : C.COLOR_RANGE_LIMITED;
|
||||
colorTransfer =
|
||||
ColorInfo.isoTransferCharacteristicsToColorTransfer(transferCharacteristics);
|
||||
}
|
||||
}
|
||||
if (data.readBit()) { // chroma_loc_info_present_flag
|
||||
@ -617,7 +639,10 @@ public final class NalUnitUtil {
|
||||
seqParameterSetId,
|
||||
frameWidth,
|
||||
frameHeight,
|
||||
pixelWidthHeightRatio);
|
||||
pixelWidthHeightRatio,
|
||||
colorSpace,
|
||||
colorRange,
|
||||
colorTransfer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.video;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.ParserException;
|
||||
import com.google.android.exoplayer2.util.CodecSpecificDataUtil;
|
||||
@ -60,6 +61,9 @@ public final class HevcConfig {
|
||||
int bufferPosition = 0;
|
||||
int width = Format.NO_VALUE;
|
||||
int height = Format.NO_VALUE;
|
||||
@C.ColorSpace int colorSpace = Format.NO_VALUE;
|
||||
@C.ColorRange int colorRange = Format.NO_VALUE;
|
||||
@C.ColorTransfer int colorTransfer = Format.NO_VALUE;
|
||||
float pixelWidthHeightRatio = 1;
|
||||
@Nullable String codecs = null;
|
||||
for (int i = 0; i < numberOfArrays; i++) {
|
||||
@ -83,6 +87,9 @@ public final class HevcConfig {
|
||||
buffer, bufferPosition, bufferPosition + nalUnitLength);
|
||||
width = spsData.width;
|
||||
height = spsData.height;
|
||||
colorSpace = spsData.colorSpace;
|
||||
colorRange = spsData.colorRange;
|
||||
colorTransfer = spsData.colorTransfer;
|
||||
pixelWidthHeightRatio = spsData.pixelWidthHeightRatio;
|
||||
codecs =
|
||||
CodecSpecificDataUtil.buildHevcCodecString(
|
||||
@ -101,7 +108,15 @@ public final class HevcConfig {
|
||||
List<byte[]> initializationData =
|
||||
csdLength == 0 ? Collections.emptyList() : Collections.singletonList(buffer);
|
||||
return new HevcConfig(
|
||||
initializationData, lengthSizeMinusOne + 1, width, height, pixelWidthHeightRatio, codecs);
|
||||
initializationData,
|
||||
lengthSizeMinusOne + 1,
|
||||
width,
|
||||
height,
|
||||
pixelWidthHeightRatio,
|
||||
codecs,
|
||||
colorSpace,
|
||||
colorRange,
|
||||
colorTransfer);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw ParserException.createForMalformedContainer("Error parsing HEVC config", e);
|
||||
}
|
||||
@ -128,6 +143,22 @@ public final class HevcConfig {
|
||||
/** The pixel width to height ratio. */
|
||||
public final float pixelWidthHeightRatio;
|
||||
|
||||
/**
|
||||
* The {@link C.ColorSpace} of the video or {@link Format#NO_VALUE} if unknown or not applicable.
|
||||
*/
|
||||
public final @C.ColorSpace int colorSpace;
|
||||
|
||||
/**
|
||||
* The {@link C.ColorRange} of the video or {@link Format#NO_VALUE} if unknown or not applicable.
|
||||
*/
|
||||
public final @C.ColorRange int colorRange;
|
||||
|
||||
/**
|
||||
* The {@link C.ColorTransfer} of the video or {@link Format#NO_VALUE} if unknown or not
|
||||
* applicable.
|
||||
*/
|
||||
public final @C.ColorTransfer int colorTransfer;
|
||||
|
||||
/**
|
||||
* An RFC 6381 codecs string representing the video format, or {@code null} if not known.
|
||||
*
|
||||
@ -141,12 +172,18 @@ public final class HevcConfig {
|
||||
int width,
|
||||
int height,
|
||||
float pixelWidthHeightRatio,
|
||||
@Nullable String codecs) {
|
||||
@Nullable String codecs,
|
||||
@C.ColorSpace int colorSpace,
|
||||
@C.ColorRange int colorRange,
|
||||
@C.ColorTransfer int colorTransfer) {
|
||||
this.initializationData = initializationData;
|
||||
this.nalUnitLengthFieldLength = nalUnitLengthFieldLength;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.pixelWidthHeightRatio = pixelWidthHeightRatio;
|
||||
this.codecs = codecs;
|
||||
this.colorSpace = colorSpace;
|
||||
this.colorRange = colorRange;
|
||||
this.colorTransfer = colorTransfer;
|
||||
}
|
||||
}
|
||||
|
@ -192,6 +192,9 @@ public final class NalUnitUtilTest {
|
||||
assertThat(spsData.pixelWidthHeightRatio).isEqualTo(1);
|
||||
assertThat(spsData.seqParameterSetId).isEqualTo(0);
|
||||
assertThat(spsData.width).isEqualTo(3840);
|
||||
assertThat(spsData.colorSpace).isEqualTo(6);
|
||||
assertThat(spsData.colorRange).isEqualTo(2);
|
||||
assertThat(spsData.colorTransfer).isEqualTo(6);
|
||||
}
|
||||
|
||||
private static byte[] buildTestData() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user