Commit 304d579e by huangdarwin Committed by Ian Baker

FrameProcessor: Add aspect ratio changes to Presentation.

PiperOrigin-RevId: 441250773
parent 0ad508b1
...@@ -68,11 +68,10 @@ public final class AdvancedFrameProcessorPixelTest { ...@@ -68,11 +68,10 @@ public final class AdvancedFrameProcessorPixelTest {
height = inputBitmap.getHeight(); height = inputBitmap.getHeight();
// This surface is needed for focussing a render target, but the tests don't write output to it. // This surface is needed for focussing a render target, but the tests don't write output to it.
// The frame processor's output is written to a framebuffer instead. // The frame processor's output is written to a framebuffer instead.
EGLSurface eglSurface = GlUtil.getEglSurface(eglDisplay, new SurfaceTexture(false)); EGLSurface eglSurface =
GlUtil.getEglSurface(eglDisplay, new SurfaceTexture(/* singleBufferMode= */ false));
GlUtil.focusEglSurface(eglDisplay, eglContext, eglSurface, width, height); GlUtil.focusEglSurface(eglDisplay, eglContext, eglSurface, width, height);
inputTexId = inputTexId = BitmapTestUtil.createGlTextureFromBitmap(inputBitmap);
BitmapTestUtil.createGlTextureFromBitmap(
BitmapTestUtil.readBitmap(FIRST_FRAME_PNG_ASSET_STRING));
outputTexId = GlUtil.createTexture(width, height); outputTexId = GlUtil.createTexture(width, height);
int frameBuffer = GlUtil.createFboForTexture(outputTexId); int frameBuffer = GlUtil.createFboForTexture(outputTexId);
GlUtil.focusFramebuffer(eglDisplay, eglContext, eglSurface, frameBuffer, width, height); GlUtil.focusFramebuffer(eglDisplay, eglContext, eglSurface, frameBuffer, width, height);
......
...@@ -67,6 +67,21 @@ public class BitmapTestUtil { ...@@ -67,6 +67,21 @@ public class BitmapTestUtil {
"media/bitmap/sample_mp4_first_frame_crop_smaller.png"; "media/bitmap/sample_mp4_first_frame_crop_smaller.png";
public static final String CROP_LARGER_EXPECTED_OUTPUT_PNG_ASSET_STRING = public static final String CROP_LARGER_EXPECTED_OUTPUT_PNG_ASSET_STRING =
"media/bitmap/sample_mp4_first_frame_crop_larger.png"; "media/bitmap/sample_mp4_first_frame_crop_larger.png";
public static final String ASPECT_RATIO_SCALE_TO_FIT_NARROW_EXPECTED_OUTPUT_PNG_ASSET_STRING =
"media/bitmap/sample_mp4_first_frame_aspect_ratio_scale_to_fit_narrow.png";
public static final String ASPECT_RATIO_SCALE_TO_FIT_WIDE_EXPECTED_OUTPUT_PNG_ASSET_STRING =
"media/bitmap/sample_mp4_first_frame_aspect_ratio_scale_to_fit_wide.png";
public static final String
ASPECT_RATIO_SCALE_TO_FIT_WITH_CROP_NARROW_EXPECTED_OUTPUT_PNG_ASSET_STRING =
"media/bitmap/sample_mp4_first_frame_aspect_ratio_scale_to_fit_with_crop_narrow.png";
public static final String
ASPECT_RATIO_SCALE_TO_FIT_WITH_CROP_WIDE_EXPECTED_OUTPUT_PNG_ASSET_STRING =
"media/bitmap/sample_mp4_first_frame_aspect_ratio_scale_to_fit_with_crop_wide.png";
public static final String ASPECT_RATIO_STRETCH_TO_FIT_NARROW_EXPECTED_OUTPUT_PNG_ASSET_STRING =
"media/bitmap/sample_mp4_first_frame_aspect_ratio_stretch_to_fit_narrow.png";
public static final String ASPECT_RATIO_STRETCH_TO_FIT_WIDE_EXPECTED_OUTPUT_PNG_ASSET_STRING =
"media/bitmap/sample_mp4_first_frame_aspect_ratio_stretch_to_fit_wide.png";
/** /**
* Maximum allowed average pixel difference between the expected and actual edited images in pixel * Maximum allowed average pixel difference between the expected and actual edited images in pixel
* difference-based tests. The value is chosen so that differences in decoder behavior across * difference-based tests. The value is chosen so that differences in decoder behavior across
......
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
package com.google.android.exoplayer2.transformer; package com.google.android.exoplayer2.transformer;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.google.android.exoplayer2.transformer.BitmapTestUtil.CROP_LARGER_EXPECTED_OUTPUT_PNG_ASSET_STRING;
import static com.google.android.exoplayer2.transformer.BitmapTestUtil.CROP_SMALLER_EXPECTED_OUTPUT_PNG_ASSET_STRING;
import static com.google.android.exoplayer2.transformer.BitmapTestUtil.FIRST_FRAME_PNG_ASSET_STRING; import static com.google.android.exoplayer2.transformer.BitmapTestUtil.FIRST_FRAME_PNG_ASSET_STRING;
import static com.google.android.exoplayer2.transformer.BitmapTestUtil.MAXIMUM_AVERAGE_PIXEL_ABSOLUTE_DIFFERENCE; import static com.google.android.exoplayer2.transformer.BitmapTestUtil.MAXIMUM_AVERAGE_PIXEL_ABSOLUTE_DIFFERENCE;
import static com.google.android.exoplayer2.transformer.BitmapTestUtil.REQUEST_OUTPUT_HEIGHT_EXPECTED_OUTPUT_PNG_ASSET_STRING; import static com.google.android.exoplayer2.transformer.BitmapTestUtil.REQUEST_OUTPUT_HEIGHT_EXPECTED_OUTPUT_PNG_ASSET_STRING;
...@@ -178,10 +176,9 @@ public final class FrameProcessorChainPixelTest { ...@@ -178,10 +176,9 @@ public final class FrameProcessorChainPixelTest {
} }
@Test @Test
public void public void processData_withPresentationFrameProcessor_setResolution_producesExpectedOutput()
processData_withPresentationFrameProcessor_requestOutputHeight_producesExpectedOutput() throws Exception {
throws Exception { String testId = "processData_withPresentationFrameProcessor_setResolution";
String testId = "processData_withPresentationFrameProcessor_requestOutputHeight";
GlFrameProcessor glFrameProcessor = GlFrameProcessor glFrameProcessor =
new PresentationFrameProcessor.Builder(getApplicationContext()).setResolution(480).build(); new PresentationFrameProcessor.Builder(getApplicationContext()).setResolution(480).build();
setUpAndPrepareFirstFrame(glFrameProcessor); setUpAndPrepareFirstFrame(glFrameProcessor);
...@@ -200,51 +197,6 @@ public final class FrameProcessorChainPixelTest { ...@@ -200,51 +197,6 @@ public final class FrameProcessorChainPixelTest {
} }
@Test @Test
public void processData_withPresentationFrameProcessor_cropSmaller_producesExpectedOutput()
throws Exception {
String testId = "updateProgramAndDraw_cropSmaller";
GlFrameProcessor glFrameProcessor =
new PresentationFrameProcessor.Builder(getApplicationContext())
.setCrop(/* left= */ -.9f, /* right= */ .1f, /* bottom= */ -1f, /* top= */ .5f)
.build();
setUpAndPrepareFirstFrame(glFrameProcessor);
Bitmap expectedBitmap =
BitmapTestUtil.readBitmap(CROP_SMALLER_EXPECTED_OUTPUT_PNG_ASSET_STRING);
Bitmap actualBitmap = processFirstFrameAndEnd();
// TODO(b/207848601): switch to using proper tooling for testing against golden data.
float averagePixelAbsoluteDifference =
BitmapTestUtil.getAveragePixelAbsoluteDifferenceArgb8888(
expectedBitmap, actualBitmap, testId);
BitmapTestUtil.saveTestBitmapToCacheDirectory(
testId, /* bitmapLabel= */ "actual", actualBitmap, /* throwOnFailure= */ false);
assertThat(averagePixelAbsoluteDifference).isAtMost(MAXIMUM_AVERAGE_PIXEL_ABSOLUTE_DIFFERENCE);
}
@Test
public void processData_withPresentationFrameProcessor_cropLarger_producesExpectedOutput()
throws Exception {
String testId = "updateProgramAndDraw_cropLarger";
GlFrameProcessor glFrameProcessor =
new PresentationFrameProcessor.Builder(getApplicationContext())
.setCrop(/* left= */ -2f, /* right= */ 2f, /* bottom= */ -1f, /* top= */ 2f)
.build();
setUpAndPrepareFirstFrame(glFrameProcessor);
Bitmap expectedBitmap = BitmapTestUtil.readBitmap(CROP_LARGER_EXPECTED_OUTPUT_PNG_ASSET_STRING);
Bitmap actualBitmap = processFirstFrameAndEnd();
// TODO(b/207848601): switch to using proper tooling for testing against golden data.
float averagePixelAbsoluteDifference =
BitmapTestUtil.getAveragePixelAbsoluteDifferenceArgb8888(
expectedBitmap, actualBitmap, testId);
BitmapTestUtil.saveTestBitmapToCacheDirectory(
testId, /* bitmapLabel= */ "actual", actualBitmap, /* throwOnFailure= */ false);
assertThat(averagePixelAbsoluteDifference).isAtMost(MAXIMUM_AVERAGE_PIXEL_ABSOLUTE_DIFFERENCE);
}
@Test
public void processData_withScaleToFitFrameProcessor_rotate45_producesExpectedOutput() public void processData_withScaleToFitFrameProcessor_rotate45_producesExpectedOutput()
throws Exception { throws Exception {
String testId = "processData_withScaleToFitFrameProcessor_rotate45"; String testId = "processData_withScaleToFitFrameProcessor_rotate45";
......
...@@ -131,7 +131,7 @@ public final class PresentationFrameProcessorTest { ...@@ -131,7 +131,7 @@ public final class PresentationFrameProcessorTest {
PresentationFrameProcessor presentationFrameProcessor = PresentationFrameProcessor presentationFrameProcessor =
new PresentationFrameProcessor.Builder(getApplicationContext()) new PresentationFrameProcessor.Builder(getApplicationContext())
.setCrop(left, right, bottom, top) .setCrop(left, right, bottom, top)
.setResolution(100) .setResolution(requestedHeight)
.build(); .build();
presentationFrameProcessor.configureOutputSizeAndTransformationMatrix(inputWidth, inputHeight); presentationFrameProcessor.configureOutputSizeAndTransformationMatrix(inputWidth, inputHeight);
...@@ -157,7 +157,7 @@ public final class PresentationFrameProcessorTest { ...@@ -157,7 +157,7 @@ public final class PresentationFrameProcessorTest {
int requestedHeight = 100; int requestedHeight = 100;
PresentationFrameProcessor presentationFrameProcessor = PresentationFrameProcessor presentationFrameProcessor =
new PresentationFrameProcessor.Builder(getApplicationContext()) new PresentationFrameProcessor.Builder(getApplicationContext())
.setResolution(100) .setResolution(requestedHeight)
.setCrop(left, right, bottom, top) .setCrop(left, right, bottom, top)
.build(); .build();
...@@ -174,6 +174,70 @@ public final class PresentationFrameProcessorTest { ...@@ -174,6 +174,70 @@ public final class PresentationFrameProcessorTest {
} }
@Test @Test
public void getOutputSize_setAspectRatio_changesDimensions() {
int inputWidth = 300;
int inputHeight = 200;
float aspectRatio = 2f;
PresentationFrameProcessor presentationFrameProcessor =
new PresentationFrameProcessor.Builder(getApplicationContext())
.setAspectRatio(aspectRatio, PresentationFrameProcessor.SCALE_TO_FIT)
.build();
presentationFrameProcessor.configureOutputSizeAndTransformationMatrix(inputWidth, inputHeight);
Size outputSize = presentationFrameProcessor.getOutputSize();
assertThat(presentationFrameProcessor.getOutputRotationDegrees()).isEqualTo(0);
assertThat(outputSize.getWidth()).isEqualTo(Math.round(aspectRatio * inputHeight));
assertThat(outputSize.getHeight()).isEqualTo(inputHeight);
}
@Test
public void getOutputSize_setAspectRatioAndResolution_changesDimensions() {
int inputWidth = 300;
int inputHeight = 200;
float aspectRatio = 2f;
int requestedHeight = 100;
PresentationFrameProcessor presentationFrameProcessor =
new PresentationFrameProcessor.Builder(getApplicationContext())
.setAspectRatio(aspectRatio, PresentationFrameProcessor.SCALE_TO_FIT)
.setResolution(requestedHeight)
.build();
presentationFrameProcessor.configureOutputSizeAndTransformationMatrix(inputWidth, inputHeight);
Size outputSize = presentationFrameProcessor.getOutputSize();
assertThat(presentationFrameProcessor.getOutputRotationDegrees()).isEqualTo(0);
assertThat(outputSize.getWidth()).isEqualTo(Math.round(aspectRatio * requestedHeight));
assertThat(outputSize.getHeight()).isEqualTo(requestedHeight);
}
@Test
public void getOutputSize_setAspectRatioAndCrop_throwsIllegalStateException() {
PresentationFrameProcessor.Builder presentationFrameProcessor =
new PresentationFrameProcessor.Builder(getApplicationContext())
.setAspectRatio(/* aspectRatio= */ 2f, PresentationFrameProcessor.SCALE_TO_FIT);
assertThrows(
IllegalStateException.class,
() ->
presentationFrameProcessor.setCrop(
/* left= */ -.5f, /* right= */ .5f, /* bottom= */ .5f, /* top= */ 1f));
}
@Test
public void getOutputSize_setCropAndAspectRatio_throwsIllegalStateException() {
PresentationFrameProcessor.Builder presentationFrameProcessor =
new PresentationFrameProcessor.Builder(getApplicationContext())
.setCrop(/* left= */ -.5f, /* right= */ .5f, /* bottom= */ .5f, /* top= */ 1f);
assertThrows(
IllegalStateException.class,
() ->
presentationFrameProcessor.setAspectRatio(
/* aspectRatio= */ 2f, PresentationFrameProcessor.SCALE_TO_FIT));
}
@Test
public void getOutputRotationDegreesBeforeConfigure_throwsIllegalStateException() { public void getOutputRotationDegreesBeforeConfigure_throwsIllegalStateException() {
PresentationFrameProcessor presentationFrameProcessor = PresentationFrameProcessor presentationFrameProcessor =
new PresentationFrameProcessor.Builder(getApplicationContext()).build(); new PresentationFrameProcessor.Builder(getApplicationContext()).build();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment