HDR: Update limited range and add full range YUV to RGB color transforms.

PiperOrigin-RevId: 467910378
This commit is contained in:
huangdarwin 2022-08-16 13:33:32 +00:00 committed by Marc Baechinger
parent 59be732230
commit d963dfbd3e
3 changed files with 26 additions and 13 deletions

View File

@ -96,7 +96,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
"H264 video and AAC audio (portrait, H < W, 90\u00B0)", "H264 video and AAC audio (portrait, H < W, 90\u00B0)",
"SEF slow motion with 240 fps", "SEF slow motion with 240 fps",
"480p DASH (non-square pixels)", "480p DASH (non-square pixels)",
"HDR (HDR10) H265 video (encoding may fail)", "HDR (HDR10) H265 limited range video (encoding may fail)",
}; };
private static final String[] DEMO_EFFECTS = { private static final String[] DEMO_EFFECTS = {
"Dizzy crop", "Dizzy crop",

View File

@ -18,7 +18,7 @@
// the sampler uses the EXT_YUV_target extension specified at // the sampler uses the EXT_YUV_target extension specified at
// https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_YUV_target.txt, // https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_YUV_target.txt,
// 2. Applies a YUV to RGB conversion using the specified color transform // 2. Applies a YUV to RGB conversion using the specified color transform
// uColorTransform, yielding HLG BT.2020 RGB, // uYuvToRgbColorTransform, yielding HLG BT.2020 RGB,
// 3. If uApplyHlgOetf is 1, outputs HLG BT.2020 RGB. If 0, outputs // 3. If uApplyHlgOetf is 1, outputs HLG BT.2020 RGB. If 0, outputs
// linear BT.2020 RGB for intermediate shaders by applying the HLG OETF. // linear BT.2020 RGB for intermediate shaders by applying the HLG OETF.
// 4. Copies this converted texture color to the current output. // 4. Copies this converted texture color to the current output.
@ -27,8 +27,7 @@
#extension GL_EXT_YUV_target : require #extension GL_EXT_YUV_target : require
precision mediump float; precision mediump float;
uniform __samplerExternal2DY2YEXT uTexSampler; uniform __samplerExternal2DY2YEXT uTexSampler;
// YUV to RGB conversion matrix. uniform mat3 uYuvToRgbColorTransform;
uniform mat3 uColorTransform;
uniform float uApplyHlgOetf; uniform float uApplyHlgOetf;
in vec2 vTexSamplingCoord; in vec2 vTexSamplingCoord;
out vec4 outColor; out vec4 outColor;
@ -63,8 +62,9 @@ highp vec4 hlgOetf(highp vec4 hlgColor) {
/** Convert YUV to RGBA. */ /** Convert YUV to RGBA. */
vec4 yuvToRgba(vec3 yuv) { vec4 yuvToRgba(vec3 yuv) {
vec3 yuvOffset = vec3(yuv.x - 0.0625, yuv.y - 0.5, yuv.z - 0.5); const vec3 yuvOffset = vec3(0.0625, 0.5, 0.5);
return vec4(uColorTransform * yuvOffset, 1.0); vec3 rgb = uYuvToRgbColorTransform * (yuv - yuvOffset);
return vec4(rgb, 1.0);
} }
void main() { void main() {

View File

@ -21,6 +21,7 @@ import android.content.Context;
import android.opengl.GLES20; import android.opengl.GLES20;
import android.opengl.Matrix; import android.opengl.Matrix;
import android.util.Pair; import android.util.Pair;
import androidx.media3.common.C;
import androidx.media3.common.ColorInfo; import androidx.media3.common.ColorInfo;
import androidx.media3.common.FrameProcessingException; import androidx.media3.common.FrameProcessingException;
import androidx.media3.common.util.GlProgram; import androidx.media3.common.util.GlProgram;
@ -64,12 +65,19 @@ import java.util.Arrays;
new float[] {-1, 1, 0, 1}, new float[] {-1, 1, 0, 1},
new float[] {1, 1, 0, 1}, new float[] {1, 1, 0, 1},
new float[] {1, -1, 0, 1}); new float[] {1, -1, 0, 1});
// Color transform coefficients from
// https://cs.android.com/android/platform/superproject/+/master:frameworks/av/media/libstagefright/colorconversion/ColorConverter.cpp;l=668-670;drc=487adf977a50cac3929eba15fad0d0f461c7ff0f. // YUV to RGB color transform coefficients can be calculated from the BT.2020 specification, by
private static final float[] MATRIX_YUV_TO_BT2020_COLOR_TRANSFORM = { // inverting the RGB to YUV equations, and scaling for limited range.
1.168f, 1.168f, 1.168f, // https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2020-2-201510-I!!PDF-E.pdf
0.0f, -0.188f, 2.148f, private static final float[] BT2020_FULL_RANGE_YUV_TO_RGB_COLOR_TRANSFORM_MATRIX = {
1.683f, -0.652f, 0.0f, 1.0000f, 1.0000f, 1.0000f,
0.0000f, -0.1646f, 1.8814f,
1.4746f, -0.5714f, 0.0000f
};
private static final float[] BT2020_LIMITED_RANGE_YUV_TO_RGB_COLOR_TRANSFORM_MATRIX = {
1.1689f, 1.1689f, 1.1689f,
0.0000f, -0.1881f, 2.1502f,
1.6853f, -0.6530f, 0.0000f,
}; };
/** The {@link MatrixTransformation MatrixTransformations} to apply. */ /** The {@link MatrixTransformation MatrixTransformations} to apply. */
@ -195,7 +203,12 @@ import java.util.Arrays;
throw new FrameProcessingException( throw new FrameProcessingException(
"The EXT_YUV_target extension is required for HDR editing input."); "The EXT_YUV_target extension is required for HDR editing input.");
} }
glProgram.setFloatsUniform("uColorTransform", MATRIX_YUV_TO_BT2020_COLOR_TRANSFORM); glProgram.setFloatsUniform(
"uYuvToRgbColorTransform",
opticalColorInfo.colorRange == C.COLOR_RANGE_FULL
? BT2020_FULL_RANGE_YUV_TO_RGB_COLOR_TRANSFORM_MATRIX
: BT2020_LIMITED_RANGE_YUV_TO_RGB_COLOR_TRANSFORM_MATRIX);
// TODO(b/227624622): Implement PQ and gamma TFs, and use an @IntDef to select between HLG, // TODO(b/227624622): Implement PQ and gamma TFs, and use an @IntDef to select between HLG,
// PQ, and gamma, coming from opticalColorInfo.colorTransfer. // PQ, and gamma, coming from opticalColorInfo.colorTransfer.