Add GlRect helper class
Adds a class that represents an image rectangle in OpenGL coordinate convention. android.graphics.Rect puts (0, 0) as the top-left corner: it enforces `Rect.top <= Rect.bottom` and this matches `android.graphics.Bitmap` coordinates: docs https://developer.android.com/reference/android/graphics/Rect This is different from OpenGL coordinates where (0, 0) is at the bottom-left corner. I.e. GlRect.bottom <= GlRect.top: docs https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glReadPixels.xhtml The reason for this change is to allow a public API GlRect getScaledRegion() which selects a region of pixels of a GL texture to be copied to CPU memory. PiperOrigin-RevId: 669231826
This commit is contained in:
parent
388d1f17b9
commit
dc9854cc5b
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2024 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
|
||||
*
|
||||
* https://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.common.util;
|
||||
|
||||
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||
|
||||
/**
|
||||
* Represents a rectangle by the coordinates of its 4 edges (left, bottom, right, top).
|
||||
*
|
||||
* <p>Note that the right and top coordinates are exclusive.
|
||||
*
|
||||
* <p>This class represents coordinates in the OpenGL coordinate convention: {@code left <= right}
|
||||
* and {@code bottom <= top}.
|
||||
*/
|
||||
@UnstableApi
|
||||
public final class GlRect {
|
||||
public int left;
|
||||
public int bottom;
|
||||
public int right;
|
||||
public int top;
|
||||
|
||||
/** Creates an instance from (0, 0) to the specified width and height. */
|
||||
public GlRect(int width, int height) {
|
||||
this(/* left= */ 0, /* bottom= */ 0, width, height);
|
||||
}
|
||||
|
||||
/** Creates an instance. */
|
||||
public GlRect(int left, int bottom, int right, int top) {
|
||||
checkArgument(left <= right && bottom <= top);
|
||||
this.left = left;
|
||||
this.bottom = bottom;
|
||||
this.right = right;
|
||||
this.top = top;
|
||||
}
|
||||
}
|
@ -23,7 +23,6 @@ import static androidx.media3.common.util.Assertions.checkState;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.opengl.EGL14;
|
||||
import android.opengl.EGLConfig;
|
||||
import android.opengl.EGLContext;
|
||||
@ -837,7 +836,7 @@ public final class GlUtil {
|
||||
* @param drawFboId The framebuffer object to draw into.
|
||||
* @param drawRect The rectangular region of {@code drawFboId} to draw into.
|
||||
*/
|
||||
public static void blitFrameBuffer(int readFboId, Rect readRect, int drawFboId, Rect drawRect)
|
||||
public static void blitFrameBuffer(int readFboId, GlRect readRect, int drawFboId, GlRect drawRect)
|
||||
throws GlException {
|
||||
int[] boundFramebuffer = new int[1];
|
||||
GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, boundFramebuffer, /* offset= */ 0);
|
||||
@ -848,13 +847,13 @@ public final class GlUtil {
|
||||
checkGlError();
|
||||
GLES30.glBlitFramebuffer(
|
||||
readRect.left,
|
||||
readRect.top,
|
||||
readRect.right,
|
||||
readRect.bottom,
|
||||
readRect.right,
|
||||
readRect.top,
|
||||
drawRect.left,
|
||||
drawRect.top,
|
||||
drawRect.right,
|
||||
drawRect.bottom,
|
||||
drawRect.right,
|
||||
drawRect.top,
|
||||
GLES30.GL_COLOR_BUFFER_BIT,
|
||||
GLES30.GL_LINEAR);
|
||||
checkGlError();
|
||||
|
@ -26,7 +26,6 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.AbsoluteSizeSpan;
|
||||
@ -34,6 +33,7 @@ import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.TypefaceSpan;
|
||||
import androidx.media3.common.GlTextureInfo;
|
||||
import androidx.media3.common.util.Consumer;
|
||||
import androidx.media3.common.util.GlRect;
|
||||
import androidx.media3.common.util.Size;
|
||||
import androidx.media3.common.util.Util;
|
||||
import androidx.media3.test.utils.TextureBitmapReader;
|
||||
@ -140,12 +140,8 @@ public class ByteBufferGlEffectTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rect getScaledRegion(long presentationTimeUs) {
|
||||
return new Rect(
|
||||
/* left= */ 0,
|
||||
/* top= */ 0,
|
||||
/* right= */ INPUT_FRAME_WIDTH,
|
||||
/* bottom= */ INPUT_FRAME_HEIGHT);
|
||||
public GlRect getScaledRegion(long presentationTimeUs) {
|
||||
return new GlRect(INPUT_FRAME_WIDTH, INPUT_FRAME_HEIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,11 +19,11 @@ import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static androidx.media3.common.util.Assertions.checkState;
|
||||
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.GlObjectsProvider;
|
||||
import androidx.media3.common.GlTextureInfo;
|
||||
import androidx.media3.common.VideoFrameProcessingException;
|
||||
import androidx.media3.common.util.GlRect;
|
||||
import androidx.media3.common.util.GlUtil;
|
||||
import androidx.media3.common.util.Size;
|
||||
import androidx.media3.common.util.Util;
|
||||
@ -107,8 +107,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
textureInfo.fboId,
|
||||
processor.getScaledRegion(presentationTimeUs),
|
||||
effectInputTexture.fboId,
|
||||
new Rect(
|
||||
/* left= */ 0, /* top= */ 0, effectInputTexture.width, effectInputTexture.height));
|
||||
new GlRect(effectInputTexture.width, effectInputTexture.height));
|
||||
|
||||
TexturePixelBuffer texturePixelBuffer = new TexturePixelBuffer(effectInputTexture);
|
||||
unmappedPixelBuffers.add(texturePixelBuffer);
|
||||
|
@ -20,10 +20,10 @@ import static androidx.media3.common.util.Assertions.checkArgument;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Rect;
|
||||
import android.opengl.GLES20;
|
||||
import androidx.media3.common.GlTextureInfo;
|
||||
import androidx.media3.common.VideoFrameProcessingException;
|
||||
import androidx.media3.common.util.GlRect;
|
||||
import androidx.media3.common.util.Size;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
@ -143,9 +143,7 @@ import java.util.concurrent.Future;
|
||||
* @return The rectangular region of the input image that will be scaled to fill the effect
|
||||
* input image.
|
||||
*/
|
||||
// TODO: b/b/361286064 - This method misuses android.graphics.Rect for OpenGL coordinates.
|
||||
// Implement a custom GlUtils.Rect to correctly label lower left corner as (0, 0).
|
||||
Rect getScaledRegion(long presentationTimeUs);
|
||||
GlRect getScaledRegion(long presentationTimeUs);
|
||||
|
||||
/**
|
||||
* Processing the image data in the {@code image}.
|
||||
|
@ -18,13 +18,13 @@ package androidx.media3.effect;
|
||||
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||
import static androidx.media3.common.util.Assertions.checkState;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.GlObjectsProvider;
|
||||
import androidx.media3.common.GlTextureInfo;
|
||||
import androidx.media3.common.VideoFrameProcessingException;
|
||||
import androidx.media3.common.util.GlRect;
|
||||
import androidx.media3.common.util.GlUtil;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
@ -213,10 +213,9 @@ import java.util.concurrent.TimeUnit;
|
||||
checkState(inputTexture.fboId != C.INDEX_UNSET);
|
||||
GlUtil.blitFrameBuffer(
|
||||
inputTexture.fboId,
|
||||
new Rect(/* left= */ 0, /* top= */ 0, /* right= */ inputWidth, /* bottom= */ inputHeight),
|
||||
new GlRect(inputWidth, inputHeight),
|
||||
outputTexture.fboId,
|
||||
new Rect(
|
||||
/* left= */ 0, /* top= */ 0, /* right= */ inputWidth, /* bottom= */ inputHeight));
|
||||
new GlRect(inputWidth, inputHeight));
|
||||
|
||||
Future<T> task =
|
||||
concurrentEffect.queueInputFrame(glObjectsProvider, outputTexture, presentationTimeUs);
|
||||
|
Loading…
x
Reference in New Issue
Block a user