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)",
"SEF slow motion with 240 fps",
"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 = {
"Dizzy crop",

View File

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

View File

@ -21,6 +21,7 @@ import android.content.Context;
import android.opengl.GLES20;
import android.opengl.Matrix;
import android.util.Pair;
import androidx.media3.common.C;
import androidx.media3.common.ColorInfo;
import androidx.media3.common.FrameProcessingException;
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});
// Color transform coefficients from
// https://cs.android.com/android/platform/superproject/+/master:frameworks/av/media/libstagefright/colorconversion/ColorConverter.cpp;l=668-670;drc=487adf977a50cac3929eba15fad0d0f461c7ff0f.
private static final float[] MATRIX_YUV_TO_BT2020_COLOR_TRANSFORM = {
1.168f, 1.168f, 1.168f,
0.0f, -0.188f, 2.148f,
1.683f, -0.652f, 0.0f,
// YUV to RGB color transform coefficients can be calculated from the BT.2020 specification, by
// inverting the RGB to YUV equations, and scaling for limited range.
// https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2020-2-201510-I!!PDF-E.pdf
private static final float[] BT2020_FULL_RANGE_YUV_TO_RGB_COLOR_TRANSFORM_MATRIX = {
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. */
@ -195,7 +203,12 @@ import java.util.Arrays;
throw new FrameProcessingException(
"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,
// PQ, and gamma, coming from opticalColorInfo.colorTransfer.