mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
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.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.opengl.EGL14;
|
import android.opengl.EGL14;
|
||||||
import android.opengl.EGLConfig;
|
import android.opengl.EGLConfig;
|
||||||
import android.opengl.EGLContext;
|
import android.opengl.EGLContext;
|
||||||
@ -837,7 +836,7 @@ public final class GlUtil {
|
|||||||
* @param drawFboId The framebuffer object to draw into.
|
* @param drawFboId The framebuffer object to draw into.
|
||||||
* @param drawRect The rectangular region of {@code drawFboId} 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 {
|
throws GlException {
|
||||||
int[] boundFramebuffer = new int[1];
|
int[] boundFramebuffer = new int[1];
|
||||||
GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, boundFramebuffer, /* offset= */ 0);
|
GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, boundFramebuffer, /* offset= */ 0);
|
||||||
@ -848,13 +847,13 @@ public final class GlUtil {
|
|||||||
checkGlError();
|
checkGlError();
|
||||||
GLES30.glBlitFramebuffer(
|
GLES30.glBlitFramebuffer(
|
||||||
readRect.left,
|
readRect.left,
|
||||||
readRect.top,
|
|
||||||
readRect.right,
|
|
||||||
readRect.bottom,
|
readRect.bottom,
|
||||||
|
readRect.right,
|
||||||
|
readRect.top,
|
||||||
drawRect.left,
|
drawRect.left,
|
||||||
drawRect.top,
|
|
||||||
drawRect.right,
|
|
||||||
drawRect.bottom,
|
drawRect.bottom,
|
||||||
|
drawRect.right,
|
||||||
|
drawRect.top,
|
||||||
GLES30.GL_COLOR_BUFFER_BIT,
|
GLES30.GL_COLOR_BUFFER_BIT,
|
||||||
GLES30.GL_LINEAR);
|
GLES30.GL_LINEAR);
|
||||||
checkGlError();
|
checkGlError();
|
||||||
|
@ -26,7 +26,6 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.style.AbsoluteSizeSpan;
|
import android.text.style.AbsoluteSizeSpan;
|
||||||
@ -34,6 +33,7 @@ import android.text.style.ForegroundColorSpan;
|
|||||||
import android.text.style.TypefaceSpan;
|
import android.text.style.TypefaceSpan;
|
||||||
import androidx.media3.common.GlTextureInfo;
|
import androidx.media3.common.GlTextureInfo;
|
||||||
import androidx.media3.common.util.Consumer;
|
import androidx.media3.common.util.Consumer;
|
||||||
|
import androidx.media3.common.util.GlRect;
|
||||||
import androidx.media3.common.util.Size;
|
import androidx.media3.common.util.Size;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.test.utils.TextureBitmapReader;
|
import androidx.media3.test.utils.TextureBitmapReader;
|
||||||
@ -140,12 +140,8 @@ public class ByteBufferGlEffectTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Rect getScaledRegion(long presentationTimeUs) {
|
public GlRect getScaledRegion(long presentationTimeUs) {
|
||||||
return new Rect(
|
return new GlRect(INPUT_FRAME_WIDTH, INPUT_FRAME_HEIGHT);
|
||||||
/* left= */ 0,
|
|
||||||
/* top= */ 0,
|
|
||||||
/* right= */ INPUT_FRAME_WIDTH,
|
|
||||||
/* bottom= */ INPUT_FRAME_HEIGHT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,11 +19,11 @@ import static androidx.media3.common.util.Assertions.checkNotNull;
|
|||||||
import static androidx.media3.common.util.Assertions.checkState;
|
import static androidx.media3.common.util.Assertions.checkState;
|
||||||
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
|
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.GlObjectsProvider;
|
import androidx.media3.common.GlObjectsProvider;
|
||||||
import androidx.media3.common.GlTextureInfo;
|
import androidx.media3.common.GlTextureInfo;
|
||||||
import androidx.media3.common.VideoFrameProcessingException;
|
import androidx.media3.common.VideoFrameProcessingException;
|
||||||
|
import androidx.media3.common.util.GlRect;
|
||||||
import androidx.media3.common.util.GlUtil;
|
import androidx.media3.common.util.GlUtil;
|
||||||
import androidx.media3.common.util.Size;
|
import androidx.media3.common.util.Size;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
@ -107,8 +107,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
textureInfo.fboId,
|
textureInfo.fboId,
|
||||||
processor.getScaledRegion(presentationTimeUs),
|
processor.getScaledRegion(presentationTimeUs),
|
||||||
effectInputTexture.fboId,
|
effectInputTexture.fboId,
|
||||||
new Rect(
|
new GlRect(effectInputTexture.width, effectInputTexture.height));
|
||||||
/* left= */ 0, /* top= */ 0, effectInputTexture.width, effectInputTexture.height));
|
|
||||||
|
|
||||||
TexturePixelBuffer texturePixelBuffer = new TexturePixelBuffer(effectInputTexture);
|
TexturePixelBuffer texturePixelBuffer = new TexturePixelBuffer(effectInputTexture);
|
||||||
unmappedPixelBuffers.add(texturePixelBuffer);
|
unmappedPixelBuffers.add(texturePixelBuffer);
|
||||||
|
@ -20,10 +20,10 @@ import static androidx.media3.common.util.Assertions.checkArgument;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
import androidx.media3.common.GlTextureInfo;
|
import androidx.media3.common.GlTextureInfo;
|
||||||
import androidx.media3.common.VideoFrameProcessingException;
|
import androidx.media3.common.VideoFrameProcessingException;
|
||||||
|
import androidx.media3.common.util.GlRect;
|
||||||
import androidx.media3.common.util.Size;
|
import androidx.media3.common.util.Size;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
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
|
* @return The rectangular region of the input image that will be scaled to fill the effect
|
||||||
* input image.
|
* input image.
|
||||||
*/
|
*/
|
||||||
// TODO: b/b/361286064 - This method misuses android.graphics.Rect for OpenGL coordinates.
|
GlRect getScaledRegion(long presentationTimeUs);
|
||||||
// Implement a custom GlUtils.Rect to correctly label lower left corner as (0, 0).
|
|
||||||
Rect getScaledRegion(long presentationTimeUs);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processing the image data in the {@code image}.
|
* 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.checkArgument;
|
||||||
import static androidx.media3.common.util.Assertions.checkState;
|
import static androidx.media3.common.util.Assertions.checkState;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
import androidx.annotation.IntRange;
|
import androidx.annotation.IntRange;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.GlObjectsProvider;
|
import androidx.media3.common.GlObjectsProvider;
|
||||||
import androidx.media3.common.GlTextureInfo;
|
import androidx.media3.common.GlTextureInfo;
|
||||||
import androidx.media3.common.VideoFrameProcessingException;
|
import androidx.media3.common.VideoFrameProcessingException;
|
||||||
|
import androidx.media3.common.util.GlRect;
|
||||||
import androidx.media3.common.util.GlUtil;
|
import androidx.media3.common.util.GlUtil;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
@ -213,10 +213,9 @@ import java.util.concurrent.TimeUnit;
|
|||||||
checkState(inputTexture.fboId != C.INDEX_UNSET);
|
checkState(inputTexture.fboId != C.INDEX_UNSET);
|
||||||
GlUtil.blitFrameBuffer(
|
GlUtil.blitFrameBuffer(
|
||||||
inputTexture.fboId,
|
inputTexture.fboId,
|
||||||
new Rect(/* left= */ 0, /* top= */ 0, /* right= */ inputWidth, /* bottom= */ inputHeight),
|
new GlRect(inputWidth, inputHeight),
|
||||||
outputTexture.fboId,
|
outputTexture.fboId,
|
||||||
new Rect(
|
new GlRect(inputWidth, inputHeight));
|
||||||
/* left= */ 0, /* top= */ 0, /* right= */ inputWidth, /* bottom= */ inputHeight));
|
|
||||||
|
|
||||||
Future<T> task =
|
Future<T> task =
|
||||||
concurrentEffect.queueInputFrame(glObjectsProvider, outputTexture, presentationTimeUs);
|
concurrentEffect.queueInputFrame(glObjectsProvider, outputTexture, presentationTimeUs);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user