mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
FrameProcessor: Improve PresentationFrameProcessor javadocs.
PiperOrigin-RevId: 442835160
This commit is contained in:
parent
7e76f773e6
commit
6138a0b07f
7 changed files with 104 additions and 58 deletions
|
|
@ -182,7 +182,7 @@ public final class PresentationFrameProcessorPixelTest {
|
||||||
String testId = "drawFrame_changeAspectRatio_scaleToFit_narrow";
|
String testId = "drawFrame_changeAspectRatio_scaleToFit_narrow";
|
||||||
presentationFrameProcessor =
|
presentationFrameProcessor =
|
||||||
new PresentationFrameProcessor.Builder()
|
new PresentationFrameProcessor.Builder()
|
||||||
.setAspectRatio(1f, PresentationFrameProcessor.SCALE_TO_FIT)
|
.setAspectRatio(1f, PresentationFrameProcessor.LAYOUT_SCALE_TO_FIT)
|
||||||
.build();
|
.build();
|
||||||
presentationFrameProcessor.initialize(
|
presentationFrameProcessor.initialize(
|
||||||
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
||||||
|
|
@ -211,7 +211,7 @@ public final class PresentationFrameProcessorPixelTest {
|
||||||
String testId = "drawFrame_changeAspectRatio_scaleToFit_wide";
|
String testId = "drawFrame_changeAspectRatio_scaleToFit_wide";
|
||||||
presentationFrameProcessor =
|
presentationFrameProcessor =
|
||||||
new PresentationFrameProcessor.Builder()
|
new PresentationFrameProcessor.Builder()
|
||||||
.setAspectRatio(2f, PresentationFrameProcessor.SCALE_TO_FIT)
|
.setAspectRatio(2f, PresentationFrameProcessor.LAYOUT_SCALE_TO_FIT)
|
||||||
.build();
|
.build();
|
||||||
presentationFrameProcessor.initialize(
|
presentationFrameProcessor.initialize(
|
||||||
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
||||||
|
|
@ -240,7 +240,7 @@ public final class PresentationFrameProcessorPixelTest {
|
||||||
String testId = "drawFrame_changeAspectRatio_scaleToFitWithCrop_narrow";
|
String testId = "drawFrame_changeAspectRatio_scaleToFitWithCrop_narrow";
|
||||||
presentationFrameProcessor =
|
presentationFrameProcessor =
|
||||||
new PresentationFrameProcessor.Builder()
|
new PresentationFrameProcessor.Builder()
|
||||||
.setAspectRatio(1f, PresentationFrameProcessor.SCALE_TO_FIT_WITH_CROP)
|
.setAspectRatio(1f, PresentationFrameProcessor.LAYOUT_SCALE_TO_FIT_WITH_CROP)
|
||||||
.build();
|
.build();
|
||||||
presentationFrameProcessor.initialize(
|
presentationFrameProcessor.initialize(
|
||||||
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
||||||
|
|
@ -269,7 +269,7 @@ public final class PresentationFrameProcessorPixelTest {
|
||||||
String testId = "drawFrame_changeAspectRatio_scaleToFitWithCrop_wide";
|
String testId = "drawFrame_changeAspectRatio_scaleToFitWithCrop_wide";
|
||||||
presentationFrameProcessor =
|
presentationFrameProcessor =
|
||||||
new PresentationFrameProcessor.Builder()
|
new PresentationFrameProcessor.Builder()
|
||||||
.setAspectRatio(2f, PresentationFrameProcessor.SCALE_TO_FIT_WITH_CROP)
|
.setAspectRatio(2f, PresentationFrameProcessor.LAYOUT_SCALE_TO_FIT_WITH_CROP)
|
||||||
.build();
|
.build();
|
||||||
presentationFrameProcessor.initialize(
|
presentationFrameProcessor.initialize(
|
||||||
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
||||||
|
|
@ -298,7 +298,7 @@ public final class PresentationFrameProcessorPixelTest {
|
||||||
String testId = "drawFrame_changeAspectRatio_stretchToFit_narrow";
|
String testId = "drawFrame_changeAspectRatio_stretchToFit_narrow";
|
||||||
presentationFrameProcessor =
|
presentationFrameProcessor =
|
||||||
new PresentationFrameProcessor.Builder()
|
new PresentationFrameProcessor.Builder()
|
||||||
.setAspectRatio(1f, PresentationFrameProcessor.STRETCH_TO_FIT)
|
.setAspectRatio(1f, PresentationFrameProcessor.LAYOUT_STRETCH_TO_FIT)
|
||||||
.build();
|
.build();
|
||||||
presentationFrameProcessor.initialize(
|
presentationFrameProcessor.initialize(
|
||||||
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
||||||
|
|
@ -327,7 +327,7 @@ public final class PresentationFrameProcessorPixelTest {
|
||||||
String testId = "drawFrame_changeAspectRatio_stretchToFit_wide";
|
String testId = "drawFrame_changeAspectRatio_stretchToFit_wide";
|
||||||
presentationFrameProcessor =
|
presentationFrameProcessor =
|
||||||
new PresentationFrameProcessor.Builder()
|
new PresentationFrameProcessor.Builder()
|
||||||
.setAspectRatio(2f, PresentationFrameProcessor.STRETCH_TO_FIT)
|
.setAspectRatio(2f, PresentationFrameProcessor.LAYOUT_STRETCH_TO_FIT)
|
||||||
.build();
|
.build();
|
||||||
presentationFrameProcessor.initialize(
|
presentationFrameProcessor.initialize(
|
||||||
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
getApplicationContext(), inputTexId, inputWidth, inputHeight);
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,14 @@ import java.io.IOException;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies a transformation matrix in the vertex shader.
|
* Applies a transformation matrix in the vertex shader, and copies input pixels into an output
|
||||||
|
* frame based on their locations after applying this matrix.
|
||||||
*
|
*
|
||||||
* <p>Operations are done on normalized device coordinates (-1 to 1 on x and y axes). No automatic
|
* <p>Operations are done on normalized device coordinates (-1 to 1 on x and y axes). No automatic
|
||||||
* adjustments (like done in {@link ScaleToFitFrameProcessor}) are applied on the transformation.
|
* adjustments (like done in {@link ScaleToFitFrameProcessor}) are applied on the transformation.
|
||||||
* Width and height are not modified. The background color will default to black.
|
* Width and height are not modified.
|
||||||
|
*
|
||||||
|
* <p>The background color of the output frame will be black.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("FunctionalInterfaceClash") // b/228192298
|
@SuppressWarnings("FunctionalInterfaceClash") // b/228192298
|
||||||
public final class AdvancedFrameProcessor implements GlFrameProcessor {
|
public final class AdvancedFrameProcessor implements GlFrameProcessor {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ import android.util.Size;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages a GLSL shader program for processing a frame.
|
* Manages a GLSL shader program for processing a frame. Implementations generally copy input pixels
|
||||||
|
* into an output frame, with changes to pixels specific to the implementation.
|
||||||
*
|
*
|
||||||
* <p>Methods must be called in the following order:
|
* <p>Methods must be called in the following order:
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -38,33 +38,72 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls how a frame is viewed, by cropping, changing aspect ratio, or changing resolution.
|
* Controls how a frame is presented, by copying input pixels into an output frame, with options to
|
||||||
|
* set the output resolution, crop the input, and choose how to map the input pixels onto the output
|
||||||
|
* frame geometry (for example, by stretching the input frame to match the specified output frame,
|
||||||
|
* or fitting the input frame using letterboxing).
|
||||||
*
|
*
|
||||||
* <p>Cropping or aspect ratio is applied before setting resolution.
|
* <p>Cropping or aspect ratio is applied before setting resolution.
|
||||||
|
*
|
||||||
|
* <p>The background color of the output frame will be black.
|
||||||
*/
|
*/
|
||||||
public final class PresentationFrameProcessor implements GlFrameProcessor {
|
public final class PresentationFrameProcessor implements GlFrameProcessor {
|
||||||
/**
|
/**
|
||||||
* Strategies for how to apply the presented frame. One of {@link #SCALE_TO_FIT}, {@link
|
* Strategies controlling the layout of input pixels in the output frame.
|
||||||
* #SCALE_TO_FIT_WITH_CROP}, or {@link #STRETCH_TO_FIT}.
|
*
|
||||||
|
* <p>One of {@link #LAYOUT_SCALE_TO_FIT}, {@link #LAYOUT_SCALE_TO_FIT_WITH_CROP}, or {@link
|
||||||
|
* #LAYOUT_STRETCH_TO_FIT}.
|
||||||
|
*
|
||||||
|
* <p>May scale either width or height, leaving the other output dimension equal to its input,
|
||||||
|
* unless {@link Builder#setResolution(int)} rescales width and height.
|
||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(SOURCE)
|
@Retention(SOURCE)
|
||||||
@Target(TYPE_USE)
|
@Target(TYPE_USE)
|
||||||
@IntDef({SCALE_TO_FIT, SCALE_TO_FIT_WITH_CROP, STRETCH_TO_FIT})
|
@IntDef({LAYOUT_SCALE_TO_FIT, LAYOUT_SCALE_TO_FIT_WITH_CROP, LAYOUT_STRETCH_TO_FIT})
|
||||||
public @interface PresentationStrategy {}
|
public @interface Layout {}
|
||||||
/**
|
/**
|
||||||
* Empty pixels added above and below the input frame (for letterboxing), or to the left and right
|
* Empty pixels added above and below the input frame (for letterboxing), or to the left and right
|
||||||
* of the input frame (for pillarboxing), until the desired aspect ratio is achieved. All input
|
* of the input frame (for pillarboxing), until the desired aspect ratio is achieved. All input
|
||||||
* frame pixels will be within the output frame.
|
* frame pixels will be within the output frame.
|
||||||
|
*
|
||||||
|
* <p>When applying:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>letterboxing, the output width will default to the input width, and the output height
|
||||||
|
* will be scaled appropriately.
|
||||||
|
* <li>pillarboxing, the output height will default to the input height, and the output width
|
||||||
|
* will be scaled appropriately.
|
||||||
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public static final int SCALE_TO_FIT = 0;
|
public static final int LAYOUT_SCALE_TO_FIT = 0;
|
||||||
/**
|
/**
|
||||||
* Pixels cropped from the input frame, until the desired aspect ratio is achieved. Pixels will be
|
* Pixels cropped from the input frame, until the desired aspect ratio is achieved. Pixels may be
|
||||||
* cropped either from the top and bottom, or from the left and right sides, of the input frame.
|
* cropped either from the bottom and top, or from the left and right sides, of the input frame.
|
||||||
|
*
|
||||||
|
* <p>When cropping from the:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>bottom and top, the output width will default to the input width, and the output height
|
||||||
|
* will be scaled appropriately.
|
||||||
|
* <li>left and right, the output height will default to the input height, and the output width
|
||||||
|
* will be scaled appropriately.
|
||||||
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public static final int SCALE_TO_FIT_WITH_CROP = 1;
|
public static final int LAYOUT_SCALE_TO_FIT_WITH_CROP = 1;
|
||||||
/** Frame stretched larger on the x or y axes to fit the desired aspect ratio. */
|
/**
|
||||||
public static final int STRETCH_TO_FIT = 2;
|
* Frame stretched larger on the x or y axes to fit the desired aspect ratio.
|
||||||
|
*
|
||||||
|
* <p>When stretching to a:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>taller aspect ratio, the output width will default to the input width, and the output
|
||||||
|
* height will be scaled appropriately.
|
||||||
|
* <li>narrower aspect ratio, the output height will default to the input height, and the output
|
||||||
|
* width will be scaled appropriately.
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static final int LAYOUT_STRETCH_TO_FIT = 2;
|
||||||
|
|
||||||
/** A builder for {@link PresentationFrameProcessor} instances. */
|
/** A builder for {@link PresentationFrameProcessor} instances. */
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
@ -76,7 +115,7 @@ public final class PresentationFrameProcessor implements GlFrameProcessor {
|
||||||
private float cropBottom;
|
private float cropBottom;
|
||||||
private float cropTop;
|
private float cropTop;
|
||||||
private float aspectRatio;
|
private float aspectRatio;
|
||||||
private @PresentationStrategy int presentationStrategy;
|
private @Layout int layout;
|
||||||
|
|
||||||
/** Creates a builder with default values. */
|
/** Creates a builder with default values. */
|
||||||
public Builder() {
|
public Builder() {
|
||||||
|
|
@ -91,7 +130,7 @@ public final class PresentationFrameProcessor implements GlFrameProcessor {
|
||||||
/**
|
/**
|
||||||
* Sets the output resolution using the output height.
|
* Sets the output resolution using the output height.
|
||||||
*
|
*
|
||||||
* <p>The default value {@link C#LENGTH_UNSET} corresponds to using the same height as the
|
* <p>The default value, {@link C#LENGTH_UNSET}, corresponds to using the same height as the
|
||||||
* input. Output width of the displayed frame will scale to preserve the frame's aspect ratio
|
* input. Output width of the displayed frame will scale to preserve the frame's aspect ratio
|
||||||
* after other transformations.
|
* after other transformations.
|
||||||
*
|
*
|
||||||
|
|
@ -111,10 +150,12 @@ public final class PresentationFrameProcessor implements GlFrameProcessor {
|
||||||
* frame corresponds to the square ranging from -1 to 1 on the x and y axes.
|
* frame corresponds to the square ranging from -1 to 1 on the x and y axes.
|
||||||
*
|
*
|
||||||
* <p>{@code left} and {@code bottom} default to -1, and {@code right} and {@code top} default
|
* <p>{@code left} and {@code bottom} default to -1, and {@code right} and {@code top} default
|
||||||
* to 1. To crop to a smaller subset of the input frame, use values between -1 and 1. To crop to
|
* to 1, which corresponds to not applying any crop. To crop to a smaller subset of the input
|
||||||
* a larger frame, use values below -1 and above 1.
|
* frame, use values between -1 and 1. To crop to a larger frame, use values below -1 and above
|
||||||
|
* 1.
|
||||||
*
|
*
|
||||||
* <p>Width and height values set may be rescaled by {@link #setResolution(int)}.
|
* <p>Width and height values set may be rescaled by {@link #setResolution(int)}, which is
|
||||||
|
* applied after cropping changes.
|
||||||
*
|
*
|
||||||
* <p>Only one of {@code setCrop} or {@link #setAspectRatio(float, int)} can be called for one
|
* <p>Only one of {@code setCrop} or {@link #setAspectRatio(float, int)} can be called for one
|
||||||
* {@link PresentationFrameProcessor}.
|
* {@link PresentationFrameProcessor}.
|
||||||
|
|
@ -142,43 +183,40 @@ public final class PresentationFrameProcessor implements GlFrameProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resize a frame's width or height to conform to an {@code aspectRatio}, given a {@link
|
* Sets the aspect ratio (width/height ratio) for the output frame.
|
||||||
* PresentationStrategy}, and leaving input pixels unchanged.
|
|
||||||
*
|
*
|
||||||
* <p>Width and height values set here may be rescaled by {@link #setResolution(int)}.
|
* <p>Resizes a frame's width or height to conform to an {@code aspectRatio}, given a {@link
|
||||||
|
* Layout}. {@code aspectRatio} defaults to {@link C#LENGTH_UNSET}, which corresponds to the
|
||||||
|
* same aspect ratio as the input frame. {@code layout} defaults to {@link #LAYOUT_SCALE_TO_FIT}
|
||||||
|
*
|
||||||
|
* <p>Width and height values set may be rescaled by {@link #setResolution(int)}, which is
|
||||||
|
* applied after aspect ratio changes.
|
||||||
*
|
*
|
||||||
* <p>Only one of {@link #setCrop(float, float, float, float)} or {@code setAspectRatio} can be
|
* <p>Only one of {@link #setCrop(float, float, float, float)} or {@code setAspectRatio} can be
|
||||||
* called for one {@link PresentationFrameProcessor}.
|
* called for one {@link PresentationFrameProcessor}.
|
||||||
*
|
*
|
||||||
* @param aspectRatio The aspect ratio of the output frame, defined as width/height. Must be
|
* @param aspectRatio The aspect ratio (width/height ratio) of the output frame. Must be
|
||||||
* positive.
|
* positive.
|
||||||
* @return This builder.
|
* @return This builder.
|
||||||
*/
|
*/
|
||||||
public Builder setAspectRatio(
|
public Builder setAspectRatio(float aspectRatio, @Layout int layout) {
|
||||||
float aspectRatio, @PresentationStrategy int presentationStrategy) {
|
|
||||||
checkArgument(aspectRatio > 0, "aspect ratio " + aspectRatio + " must be positive");
|
checkArgument(aspectRatio > 0, "aspect ratio " + aspectRatio + " must be positive");
|
||||||
checkArgument(
|
checkArgument(
|
||||||
presentationStrategy == SCALE_TO_FIT
|
layout == LAYOUT_SCALE_TO_FIT
|
||||||
|| presentationStrategy == SCALE_TO_FIT_WITH_CROP
|
|| layout == LAYOUT_SCALE_TO_FIT_WITH_CROP
|
||||||
|| presentationStrategy == STRETCH_TO_FIT,
|
|| layout == LAYOUT_STRETCH_TO_FIT,
|
||||||
"invalid presentationStrategy " + presentationStrategy);
|
"invalid layout " + layout);
|
||||||
checkState(
|
checkState(
|
||||||
cropLeft == -1f && cropRight == 1f && cropBottom == -1f && cropTop == 1f,
|
cropLeft == -1f && cropRight == 1f && cropBottom == -1f && cropTop == 1f,
|
||||||
"setAspectRatio and setCrop cannot be called in the same instance");
|
"setAspectRatio and setCrop cannot be called in the same instance");
|
||||||
this.aspectRatio = aspectRatio;
|
this.aspectRatio = aspectRatio;
|
||||||
this.presentationStrategy = presentationStrategy;
|
this.layout = layout;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PresentationFrameProcessor build() {
|
public PresentationFrameProcessor build() {
|
||||||
return new PresentationFrameProcessor(
|
return new PresentationFrameProcessor(
|
||||||
heightPixels,
|
heightPixels, cropLeft, cropRight, cropBottom, cropTop, aspectRatio, layout);
|
||||||
cropLeft,
|
|
||||||
cropRight,
|
|
||||||
cropBottom,
|
|
||||||
cropTop,
|
|
||||||
aspectRatio,
|
|
||||||
presentationStrategy);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,7 +230,7 @@ public final class PresentationFrameProcessor implements GlFrameProcessor {
|
||||||
private final float cropBottom;
|
private final float cropBottom;
|
||||||
private final float cropTop;
|
private final float cropTop;
|
||||||
private final float requestedAspectRatio;
|
private final float requestedAspectRatio;
|
||||||
private final @PresentationStrategy int presentationStrategy;
|
private final @Layout int layout;
|
||||||
|
|
||||||
private int outputRotationDegrees;
|
private int outputRotationDegrees;
|
||||||
private int outputWidth;
|
private int outputWidth;
|
||||||
|
|
@ -208,14 +246,14 @@ public final class PresentationFrameProcessor implements GlFrameProcessor {
|
||||||
float cropBottom,
|
float cropBottom,
|
||||||
float cropTop,
|
float cropTop,
|
||||||
float requestedAspectRatio,
|
float requestedAspectRatio,
|
||||||
@PresentationStrategy int presentationStrategy) {
|
@Layout int layout) {
|
||||||
this.requestedHeightPixels = requestedHeightPixels;
|
this.requestedHeightPixels = requestedHeightPixels;
|
||||||
this.cropLeft = cropLeft;
|
this.cropLeft = cropLeft;
|
||||||
this.cropRight = cropRight;
|
this.cropRight = cropRight;
|
||||||
this.cropBottom = cropBottom;
|
this.cropBottom = cropBottom;
|
||||||
this.cropTop = cropTop;
|
this.cropTop = cropTop;
|
||||||
this.requestedAspectRatio = requestedAspectRatio;
|
this.requestedAspectRatio = requestedAspectRatio;
|
||||||
this.presentationStrategy = presentationStrategy;
|
this.layout = layout;
|
||||||
|
|
||||||
outputWidth = C.LENGTH_UNSET;
|
outputWidth = C.LENGTH_UNSET;
|
||||||
outputHeight = C.LENGTH_UNSET;
|
outputHeight = C.LENGTH_UNSET;
|
||||||
|
|
@ -324,7 +362,7 @@ public final class PresentationFrameProcessor implements GlFrameProcessor {
|
||||||
@RequiresNonNull("transformationMatrix")
|
@RequiresNonNull("transformationMatrix")
|
||||||
private void applyAspectRatio() {
|
private void applyAspectRatio() {
|
||||||
float inputAspectRatio = (float) outputWidth / outputHeight;
|
float inputAspectRatio = (float) outputWidth / outputHeight;
|
||||||
if (presentationStrategy == SCALE_TO_FIT) {
|
if (layout == LAYOUT_SCALE_TO_FIT) {
|
||||||
if (requestedAspectRatio > inputAspectRatio) {
|
if (requestedAspectRatio > inputAspectRatio) {
|
||||||
transformationMatrix.setScale(inputAspectRatio / requestedAspectRatio, 1f);
|
transformationMatrix.setScale(inputAspectRatio / requestedAspectRatio, 1f);
|
||||||
outputWidth = Math.round(outputHeight * requestedAspectRatio);
|
outputWidth = Math.round(outputHeight * requestedAspectRatio);
|
||||||
|
|
@ -332,7 +370,7 @@ public final class PresentationFrameProcessor implements GlFrameProcessor {
|
||||||
transformationMatrix.setScale(1f, requestedAspectRatio / inputAspectRatio);
|
transformationMatrix.setScale(1f, requestedAspectRatio / inputAspectRatio);
|
||||||
outputHeight = Math.round(outputWidth / requestedAspectRatio);
|
outputHeight = Math.round(outputWidth / requestedAspectRatio);
|
||||||
}
|
}
|
||||||
} else if (presentationStrategy == SCALE_TO_FIT_WITH_CROP) {
|
} else if (layout == LAYOUT_SCALE_TO_FIT_WITH_CROP) {
|
||||||
if (requestedAspectRatio > inputAspectRatio) {
|
if (requestedAspectRatio > inputAspectRatio) {
|
||||||
transformationMatrix.setScale(1f, requestedAspectRatio / inputAspectRatio);
|
transformationMatrix.setScale(1f, requestedAspectRatio / inputAspectRatio);
|
||||||
outputHeight = Math.round(outputWidth / requestedAspectRatio);
|
outputHeight = Math.round(outputWidth / requestedAspectRatio);
|
||||||
|
|
@ -340,7 +378,7 @@ public final class PresentationFrameProcessor implements GlFrameProcessor {
|
||||||
transformationMatrix.setScale(inputAspectRatio / requestedAspectRatio, 1f);
|
transformationMatrix.setScale(inputAspectRatio / requestedAspectRatio, 1f);
|
||||||
outputWidth = Math.round(outputHeight * requestedAspectRatio);
|
outputWidth = Math.round(outputHeight * requestedAspectRatio);
|
||||||
}
|
}
|
||||||
} else if (presentationStrategy == STRETCH_TO_FIT) {
|
} else if (layout == LAYOUT_STRETCH_TO_FIT) {
|
||||||
if (requestedAspectRatio > inputAspectRatio) {
|
if (requestedAspectRatio > inputAspectRatio) {
|
||||||
outputWidth = Math.round(outputHeight * requestedAspectRatio);
|
outputWidth = Math.round(outputHeight * requestedAspectRatio);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,12 @@ import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies a simple rotation and/or scale in the vertex shader. All input frames' pixels will be
|
* Applies a simple rotation and/or scale in the vertex shader.
|
||||||
* preserved, potentially changing the width and height of the frame by scaling dimensions to fit.
|
*
|
||||||
* The background color will default to black.
|
* <p>All input frames' pixels will be preserved and copied into an output frame, potentially
|
||||||
|
* changing the width and height of the frame by scaling dimensions to fit.
|
||||||
|
*
|
||||||
|
* <p>The background color of the output frame will be black.
|
||||||
*/
|
*/
|
||||||
public final class ScaleToFitFrameProcessor implements GlFrameProcessor {
|
public final class ScaleToFitFrameProcessor implements GlFrameProcessor {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,8 @@ public final class TransformationRequest {
|
||||||
* Sets the x and y axis scaling factors to apply to each frame's width and height, stretching
|
* Sets the x and y axis scaling factors to apply to each frame's width and height, stretching
|
||||||
* the video along these axes appropriately.
|
* the video along these axes appropriately.
|
||||||
*
|
*
|
||||||
* <p>The values default to 1, which corresponds to not scaling along both axes.
|
* <p>The default value for {@code scaleX} and {@code scaleY}, 1, corresponds to not scaling
|
||||||
|
* along the x and y axes, respectively.
|
||||||
*
|
*
|
||||||
* @param scaleX The multiplier by which the frame will scale horizontally, along the x-axis.
|
* @param scaleX The multiplier by which the frame will scale horizontally, along the x-axis.
|
||||||
* @param scaleY The multiplier by which the frame will scale vertically, along the y-axis.
|
* @param scaleY The multiplier by which the frame will scale vertically, along the y-axis.
|
||||||
|
|
@ -137,7 +138,7 @@ public final class TransformationRequest {
|
||||||
*
|
*
|
||||||
* <p>For example, a 1920x1440 video can be scaled to 640x480 by calling setResolution(480).
|
* <p>For example, a 1920x1440 video can be scaled to 640x480 by calling setResolution(480).
|
||||||
*
|
*
|
||||||
* <p>The default value {@link C#LENGTH_UNSET} leaves the width and height unchanged unless
|
* <p>The default value, {@link C#LENGTH_UNSET}, leaves the width and height unchanged unless
|
||||||
* {@linkplain #setScale(float,float) scaling} or @linkplain #setRotationDegrees(float)
|
* {@linkplain #setScale(float,float) scaling} or @linkplain #setRotationDegrees(float)
|
||||||
* rotation} are requested.
|
* rotation} are requested.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ public final class PresentationFrameProcessorTest {
|
||||||
float aspectRatio = 2f;
|
float aspectRatio = 2f;
|
||||||
PresentationFrameProcessor presentationFrameProcessor =
|
PresentationFrameProcessor presentationFrameProcessor =
|
||||||
new PresentationFrameProcessor.Builder()
|
new PresentationFrameProcessor.Builder()
|
||||||
.setAspectRatio(aspectRatio, PresentationFrameProcessor.SCALE_TO_FIT)
|
.setAspectRatio(aspectRatio, PresentationFrameProcessor.LAYOUT_SCALE_TO_FIT)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
presentationFrameProcessor.configureOutputSizeAndTransformationMatrix(inputWidth, inputHeight);
|
presentationFrameProcessor.configureOutputSizeAndTransformationMatrix(inputWidth, inputHeight);
|
||||||
|
|
@ -194,7 +194,7 @@ public final class PresentationFrameProcessorTest {
|
||||||
int requestedHeight = 100;
|
int requestedHeight = 100;
|
||||||
PresentationFrameProcessor presentationFrameProcessor =
|
PresentationFrameProcessor presentationFrameProcessor =
|
||||||
new PresentationFrameProcessor.Builder()
|
new PresentationFrameProcessor.Builder()
|
||||||
.setAspectRatio(aspectRatio, PresentationFrameProcessor.SCALE_TO_FIT)
|
.setAspectRatio(aspectRatio, PresentationFrameProcessor.LAYOUT_SCALE_TO_FIT)
|
||||||
.setResolution(requestedHeight)
|
.setResolution(requestedHeight)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
@ -210,7 +210,7 @@ public final class PresentationFrameProcessorTest {
|
||||||
public void getOutputSize_setAspectRatioAndCrop_throwsIllegalStateException() {
|
public void getOutputSize_setAspectRatioAndCrop_throwsIllegalStateException() {
|
||||||
PresentationFrameProcessor.Builder presentationFrameProcessor =
|
PresentationFrameProcessor.Builder presentationFrameProcessor =
|
||||||
new PresentationFrameProcessor.Builder()
|
new PresentationFrameProcessor.Builder()
|
||||||
.setAspectRatio(/* aspectRatio= */ 2f, PresentationFrameProcessor.SCALE_TO_FIT);
|
.setAspectRatio(/* aspectRatio= */ 2f, PresentationFrameProcessor.LAYOUT_SCALE_TO_FIT);
|
||||||
|
|
||||||
assertThrows(
|
assertThrows(
|
||||||
IllegalStateException.class,
|
IllegalStateException.class,
|
||||||
|
|
@ -229,7 +229,7 @@ public final class PresentationFrameProcessorTest {
|
||||||
IllegalStateException.class,
|
IllegalStateException.class,
|
||||||
() ->
|
() ->
|
||||||
presentationFrameProcessor.setAspectRatio(
|
presentationFrameProcessor.setAspectRatio(
|
||||||
/* aspectRatio= */ 2f, PresentationFrameProcessor.SCALE_TO_FIT));
|
/* aspectRatio= */ 2f, PresentationFrameProcessor.LAYOUT_SCALE_TO_FIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue