mirror of
https://github.com/samsonjs/media.git
synced 2026-04-01 10:35:48 +00:00
Shader portion is bloat given we're scaling and biasing the colors. Swap out implementation.
PiperOrigin-RevId: 524113489
This commit is contained in:
parent
2f23774d53
commit
52a9ce3265
4 changed files with 30 additions and 138 deletions
|
|
@ -45,7 +45,7 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Pixel test for contrast adjustment via {@link ContrastShaderProgram}.
|
||||
* Pixel test for contrast adjustment via {@link Contrast}.
|
||||
*
|
||||
* <p>Expected images are taken from an emulator, so tests on different emulators or physical
|
||||
* devices may fail. To test on other devices, please increase the {@link
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
#version 100
|
||||
// Copyright 2022 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// ES 2 fragment shader that samples from a (non-external) texture with
|
||||
// uTexSampler, copying from this texture to the current output
|
||||
// while adjusting contrast based on uContrastFactor.
|
||||
|
||||
precision mediump float;
|
||||
uniform sampler2D uTexSampler;
|
||||
uniform float uContrastFactor;
|
||||
varying vec2 vTexSamplingCoord;
|
||||
|
||||
void main() {
|
||||
vec4 inputColor = texture2D(uTexSampler, vTexSamplingCoord);
|
||||
|
||||
gl_FragColor = vec4(
|
||||
uContrastFactor * (inputColor.r - 0.5) + 0.5,
|
||||
uContrastFactor * (inputColor.g - 0.5) + 0.5,
|
||||
uContrastFactor * (inputColor.b - 0.5) + 0.5,
|
||||
inputColor.a);
|
||||
}
|
||||
|
|
@ -18,17 +18,17 @@ package androidx.media3.effect;
|
|||
|
||||
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.FloatRange;
|
||||
import androidx.media3.common.VideoFrameProcessingException;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
|
||||
/** A {@link GlEffect} to control the contrast of video frames. */
|
||||
/** A {@link RgbMatrix} to control the contrast of video frames. */
|
||||
@UnstableApi
|
||||
public class Contrast implements GlEffect {
|
||||
public class Contrast implements RgbMatrix {
|
||||
|
||||
/** Adjusts the contrast of video frames in the interval [-1, 1]. */
|
||||
public final float contrast;
|
||||
private final float contrast;
|
||||
|
||||
private final float[] contrastMatrix;
|
||||
|
||||
/**
|
||||
* Creates a new instance for the given contrast value.
|
||||
|
|
@ -39,12 +39,33 @@ public class Contrast implements GlEffect {
|
|||
public Contrast(@FloatRange(from = -1, to = 1) float contrast) {
|
||||
checkArgument(-1 <= contrast && contrast <= 1, "Contrast needs to be in the interval [-1, 1].");
|
||||
this.contrast = contrast;
|
||||
float contrastFactor = (1 + contrast) / (1.0001f - contrast);
|
||||
contrastMatrix =
|
||||
new float[] {
|
||||
contrastFactor,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
contrastFactor,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
contrastFactor,
|
||||
0.0f,
|
||||
(1.0f - contrastFactor) * 0.5f,
|
||||
(1.0f - contrastFactor) * 0.5f,
|
||||
(1.0f - contrastFactor) * 0.5f,
|
||||
1.0f
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleFrameGlShaderProgram toGlShaderProgram(Context context, boolean useHdr)
|
||||
throws VideoFrameProcessingException {
|
||||
return new ContrastShaderProgram(context, this, useHdr);
|
||||
public float[] getMatrix(long presentationTimeUs, boolean useHdr) {
|
||||
// Implementation is not currently time-varying, therefore matrix should not be changing between
|
||||
// frames.
|
||||
return contrastMatrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Copyright 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package androidx.media3.effect;
|
||||
|
||||
import android.content.Context;
|
||||
import android.opengl.GLES20;
|
||||
import androidx.media3.common.VideoFrameProcessingException;
|
||||
import androidx.media3.common.util.GlProgram;
|
||||
import androidx.media3.common.util.GlUtil;
|
||||
import androidx.media3.common.util.Size;
|
||||
import java.io.IOException;
|
||||
|
||||
/** Applies a {@link Contrast} to each frame in the fragment shader. */
|
||||
/* package */ final class ContrastShaderProgram extends SingleFrameGlShaderProgram {
|
||||
private static final String VERTEX_SHADER_PATH = "shaders/vertex_shader_transformation_es2.glsl";
|
||||
private static final String FRAGMENT_SHADER_PATH = "shaders/fragment_shader_contrast_es2.glsl";
|
||||
|
||||
private final GlProgram glProgram;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param context The {@link Context}.
|
||||
* @param contrastEffect The {@link Contrast} to apply to each frame in order.
|
||||
* @param useHdr Whether input textures come from an HDR source. If {@code true}, colors will be
|
||||
* in linear RGB BT.2020. If {@code false}, colors will be in linear RGB BT.709.
|
||||
* @throws VideoFrameProcessingException If a problem occurs while reading shader files.
|
||||
*/
|
||||
public ContrastShaderProgram(Context context, Contrast contrastEffect, boolean useHdr)
|
||||
throws VideoFrameProcessingException {
|
||||
super(useHdr);
|
||||
// Use 1.0001f to avoid division by zero issues.
|
||||
float contrastFactor = (1 + contrastEffect.contrast) / (1.0001f - contrastEffect.contrast);
|
||||
|
||||
try {
|
||||
glProgram = new GlProgram(context, VERTEX_SHADER_PATH, FRAGMENT_SHADER_PATH);
|
||||
} catch (IOException | GlUtil.GlException e) {
|
||||
throw new VideoFrameProcessingException(e);
|
||||
}
|
||||
|
||||
// Draw the frame on the entire normalized device coordinate space, from -1 to 1, for x and y.
|
||||
glProgram.setBufferAttribute(
|
||||
"aFramePosition",
|
||||
GlUtil.getNormalizedCoordinateBounds(),
|
||||
GlUtil.HOMOGENEOUS_COORDINATE_VECTOR_SIZE);
|
||||
|
||||
float[] identityMatrix = GlUtil.create4x4IdentityMatrix();
|
||||
glProgram.setFloatsUniform("uTransformationMatrix", identityMatrix);
|
||||
glProgram.setFloatsUniform("uTexTransformationMatrix", identityMatrix);
|
||||
glProgram.setFloatUniform("uContrastFactor", contrastFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Size configure(int inputWidth, int inputHeight) {
|
||||
return new Size(inputWidth, inputHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawFrame(int inputTexId, long presentationTimeUs)
|
||||
throws VideoFrameProcessingException {
|
||||
try {
|
||||
glProgram.use();
|
||||
glProgram.setSamplerTexIdUniform("uTexSampler", inputTexId, /* texUnitIndex= */ 0);
|
||||
glProgram.bindAttributesAndUniforms();
|
||||
|
||||
// The four-vertex triangle strip forms a quad.
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, /* first= */ 0, /* count= */ 4);
|
||||
} catch (GlUtil.GlException e) {
|
||||
throw new VideoFrameProcessingException(e, presentationTimeUs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() throws VideoFrameProcessingException {
|
||||
super.release();
|
||||
try {
|
||||
glProgram.delete();
|
||||
} catch (GlUtil.GlException e) {
|
||||
throw new VideoFrameProcessingException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue