Skip to content

Commit

Permalink
Merge pull request #1551 from pedroSG94/feature/encoder-testing
Browse files Browse the repository at this point in the history
Feature/encoder testing
  • Loading branch information
pedroSG94 authored Aug 26, 2024
2 parents d58327e + 2e960d8 commit 33d5756
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import androidx.annotation.RequiresApi;

import com.pedro.encoder.R;
import com.pedro.encoder.utils.ViewPort;
import com.pedro.encoder.utils.gl.AspectRatioMode;
import com.pedro.encoder.utils.gl.GlUtil;
import com.pedro.encoder.utils.gl.SizeCalculator;
Expand All @@ -32,6 +33,8 @@
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import kotlin.Pair;

/**
* Created by pedro on 29/01/18.
*/
Expand Down Expand Up @@ -92,8 +95,9 @@ public void draw(int width, int height, AspectRatioMode mode, int rotation,
boolean flipStreamVertical, boolean flipStreamHorizontal) {
GlUtil.checkGlError("drawScreen start");

SizeCalculator.processMatrix(rotation, flipStreamHorizontal, flipStreamVertical, MVPMatrix);
SizeCalculator.calculateViewPort(mode, width, height, streamWidth, streamHeight);
updateMatrix(rotation, SizeCalculator.calculateFlip(flipStreamHorizontal, flipStreamVertical), MVPMatrix);
ViewPort viewport = SizeCalculator.calculateViewPort(mode, width, height, streamWidth, streamHeight);
GLES20.glViewport(viewport.getX(), viewport.getY(), viewport.getWidth(), viewport.getHeight());

draw();
}
Expand All @@ -102,8 +106,9 @@ public void drawEncoder(int width, int height, boolean isPortrait, int rotation,
boolean flipStreamVertical, boolean flipStreamHorizontal) {
GlUtil.checkGlError("drawScreen start");

SizeCalculator.processMatrix(rotation, flipStreamHorizontal, flipStreamVertical, MVPMatrix);
SizeCalculator.calculateViewPortEncoder(width, height, isPortrait);
updateMatrix(rotation, SizeCalculator.calculateFlip(flipStreamHorizontal, flipStreamVertical), MVPMatrix);
ViewPort viewport = SizeCalculator.calculateViewPortEncoder(width, height, isPortrait);
GLES20.glViewport(viewport.getX(), viewport.getY(), viewport.getWidth(), viewport.getHeight());

draw();
}
Expand All @@ -112,7 +117,7 @@ public void drawPreview(int width, int height, boolean isPortrait,
AspectRatioMode mode, int rotation, boolean flipStreamVertical, boolean flipStreamHorizontal) {
GlUtil.checkGlError("drawScreen start");

SizeCalculator.processMatrix(rotation, flipStreamHorizontal, flipStreamVertical, MVPMatrix);
updateMatrix(rotation, SizeCalculator.calculateFlip(flipStreamHorizontal, flipStreamVertical), MVPMatrix);
float factor = (float) streamWidth / (float) streamHeight;
int w;
int h;
Expand All @@ -123,7 +128,8 @@ public void drawPreview(int width, int height, boolean isPortrait,
w = isPortrait ? streamWidth : streamHeight;
h = isPortrait ? streamHeight : streamWidth;
}
SizeCalculator.calculateViewPort(mode, width, height, w, h);
ViewPort viewport = SizeCalculator.calculateViewPort(mode, width, height, w, h);
GLES20.glViewport(viewport.getX(), viewport.getY(), viewport.getWidth(), viewport.getHeight());

draw();
}
Expand Down Expand Up @@ -168,4 +174,10 @@ public void setStreamSize(int streamWidth, int streamHeight) {
this.streamWidth = streamWidth;
this.streamHeight = streamHeight;
}

private void updateMatrix(int rotation, Pair<Float, Float> scale, float[] MVPMatrix) {
Matrix.setIdentityM(MVPMatrix, 0);
Matrix.scaleM(MVPMatrix, 0, scale.getFirst(), scale.getSecond(), 1f);
Matrix.rotateM(MVPMatrix, 0, rotation, 0f, 0f, -1f);
}
}
8 changes: 8 additions & 0 deletions encoder/src/main/java/com/pedro/encoder/utils/ViewPort.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.pedro.encoder.utils

data class ViewPort(
val x: Int,
val y: Int,
val width: Int,
val height: Int
)
121 changes: 38 additions & 83 deletions encoder/src/main/java/com/pedro/encoder/utils/gl/SizeCalculator.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,114 +16,69 @@

package com.pedro.encoder.utils.gl;

import android.graphics.Point;
import android.graphics.PointF;
import android.opengl.GLES20;
import android.opengl.Matrix;
import android.util.Pair;
import com.pedro.encoder.utils.ViewPort;

import kotlin.Pair;

/**
* Created by pedro on 22/03/19.
*/

public class SizeCalculator {

public static void calculateViewPort(AspectRatioMode mode, int previewWidth,
public static ViewPort calculateViewPort(AspectRatioMode mode, int previewWidth,
int previewHeight, int streamWidth, int streamHeight) {
Pair<Point, Point> pair =
getViewport(mode, previewWidth, previewHeight, streamWidth, streamHeight);
GLES20.glViewport(pair.first.x, pair.first.y, pair.second.x, pair.second.y);
if (mode == AspectRatioMode.NONE) {
return new ViewPort(0, 0, previewWidth, previewHeight);
}
float streamAspectRatio = (float) streamWidth / (float) streamHeight;
float previewAspectRatio = (float) previewWidth / (float) previewHeight;
int xo = 0;
int yo = 0;
int xf = previewWidth;
int yf = previewHeight;
if (mode == AspectRatioMode.Adjust) {
if (streamAspectRatio > previewAspectRatio) {
yf = streamHeight * previewWidth / streamWidth;
yo = (yf - previewHeight) / -2;
} else {
xf = streamWidth * previewHeight / streamHeight;
xo = (xf - previewWidth) / -2;
}
} else { //AspectRatioMode.Fill
if (streamAspectRatio > previewAspectRatio) {
xf = streamWidth * previewHeight / streamHeight;
xo = (xf - previewWidth) / -2;
} else {
yf = streamHeight * previewWidth / streamWidth;
yo = (yf - previewHeight) / -2;
}
}
return new ViewPort(xo, yo, xf, yf);
}

public static void calculateViewPortEncoder(int streamWidth, int streamHeight, boolean isPortrait) {
Pair<Point, Point> pair;
public static ViewPort calculateViewPortEncoder(int streamWidth, int streamHeight, boolean isPortrait) {
float factor = (float) streamWidth / (float) streamHeight;
if (factor >= 1f) {
if (isPortrait) {
int width = (int) (streamHeight / factor);
int oX = (streamWidth - width) / 2;
pair = new Pair<>(new Point(oX, 0), new Point(width, streamHeight));
return new ViewPort(oX, 0, width, streamHeight);
} else {
pair = new Pair<>(new Point(0, 0), new Point(streamWidth, streamHeight));
return new ViewPort(0, 0, streamWidth, streamHeight);
}
} else {
if (isPortrait) {
pair = new Pair<>(new Point(0, 0), new Point(streamWidth, streamHeight));
return new ViewPort(0, 0, streamWidth, streamHeight);
} else {
int height = (int) (streamWidth * factor);
int oY = (streamHeight - height) / 2;
pair = new Pair<>(new Point(0, oY), new Point(streamWidth, height));
return new ViewPort(0, oY, streamWidth, height);
}
}
GLES20.glViewport(pair.first.x, pair.first.y, pair.second.x, pair.second.y);
}

public static Pair<Point, Point> getViewport(AspectRatioMode mode, int previewWidth,
int previewHeight, int streamWidth, int streamHeight) {
if (mode != AspectRatioMode.NONE) {
float streamAspectRatio = (float) streamWidth / (float) streamHeight;
float previewAspectRatio = (float) previewWidth / (float) previewHeight;
int xo = 0;
int yo = 0;
int xf = previewWidth;
int yf = previewHeight;
if ((previewAspectRatio > 1f && streamAspectRatio > previewAspectRatio) ||
(streamAspectRatio <= 1f && previewAspectRatio <= 1 && streamAspectRatio > previewAspectRatio) ||
(streamAspectRatio > 1f && previewAspectRatio < 1f)) {
if (mode == AspectRatioMode.Adjust) {
yf = streamHeight * previewWidth / streamWidth;
yo = (yf - previewHeight) / -2;
} else { //fill
xf = streamWidth * previewHeight / streamHeight;
xo = (xf - previewWidth) / -2;
}
} else if ((streamAspectRatio >= 1f && previewAspectRatio >= 1f && streamAspectRatio < previewAspectRatio) ||
(previewAspectRatio < 1f && streamAspectRatio < previewAspectRatio) ||
(streamAspectRatio < 1f && previewAspectRatio > 1f)) {
if (mode == AspectRatioMode.Adjust) {
xf = streamWidth * previewHeight / streamHeight;
xo = (xf - previewWidth) / -2;
} else {
yf = streamHeight * previewWidth / streamWidth;
yo = (yf - previewHeight) / -2;
}
}
return new Pair<>(new Point(xo, yo), new Point(xf, yf));
} else {
return new Pair<>(new Point(0, 0), new Point(previewWidth, previewHeight));
}
}

public static void processMatrix(int rotation, boolean flipStreamHorizontal,
boolean flipStreamVertical, float[] MVPMatrix) {
PointF scale = new PointF(1f, 1f);

float xFlip = flipStreamHorizontal ? -1f : 1f;
float yFlip = flipStreamVertical ? -1f : 1f;
scale = new PointF(scale.x * xFlip, scale.y * yFlip);

updateMatrix(rotation, scale, MVPMatrix);
}

private static void updateMatrix(int rotation, PointF scale, float[] MVPMatrix) {
Matrix.setIdentityM(MVPMatrix, 0);
Matrix.scaleM(MVPMatrix, 0, scale.x, scale.y, 1f);
Matrix.rotateM(MVPMatrix, 0, rotation, 0f, 0f, -1f);
}

private static PointF getScale(int rotation, int width, int height, boolean isPortrait,
boolean isPreview) {
float scaleX = 1f;
float scaleY = 1f;
if (!isPreview) {
if (isPortrait && rotation != 0 && rotation != 180) { //portrait
final float adjustedWidth = width * (width / (float) height);
scaleY = adjustedWidth / height;
} else if (!isPortrait && rotation != 90 && rotation != 270) { //landscape
final float adjustedWidth = height * (height / (float) width);
scaleX = adjustedWidth / width;
}
}
return new PointF(scaleX, scaleY);
public static Pair<Float, Float> calculateFlip(boolean flipStreamHorizontal, boolean flipStreamVertical) {
return new Pair<>(flipStreamHorizontal ? -1f : 1f, flipStreamVertical ? -1f : 1f);
}
}
78 changes: 78 additions & 0 deletions encoder/src/test/java/com/pedro/encoder/SizeCalculatorTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.pedro.encoder

import com.pedro.encoder.utils.ViewPort
import com.pedro.encoder.utils.gl.AspectRatioMode
import com.pedro.encoder.utils.gl.SizeCalculator
import junit.framework.TestCase.assertEquals
import org.junit.Test


class SizeCalculatorTest {

@Test
fun `calculate viewport preview cases with adjust mode`() {
//higher aspect ratio than preview
val result = SizeCalculator.calculateViewPort(AspectRatioMode.Adjust, 100, 100, 160, 90)
assertEquals(ViewPort(0, 22, 100, 56), result)
//lower aspect ratio than preview
val result2 = SizeCalculator.calculateViewPort(AspectRatioMode.Adjust, 100, 100, 90, 160)
assertEquals(ViewPort(22, 0, 56, 100), result2)
//equal
val result3 = SizeCalculator.calculateViewPort(AspectRatioMode.Adjust, 100, 100, 100, 100)
assertEquals(ViewPort(0, 0, 100, 100), result3)
}

@Test
fun `calculate viewport preview cases with fill mode`() {
//higher aspect ratio than preview
val result = SizeCalculator.calculateViewPort(AspectRatioMode.Fill, 100, 100, 160, 90)
assertEquals(ViewPort(-38, 0, 177, 100), result)
//lower aspect ratio than preview
val result2 = SizeCalculator.calculateViewPort(AspectRatioMode.Fill, 100, 100, 90, 160)
assertEquals(ViewPort(0, -38, 100, 177), result2)
//equal
val result3 = SizeCalculator.calculateViewPort(AspectRatioMode.Fill, 100, 100, 160, 90)
assertEquals(ViewPort(-38, 0, 177, 100), result3)
}

@Test
fun `calculate viewport preview cases with none mode`() {
val result = SizeCalculator.calculateViewPort(AspectRatioMode.NONE, 100, 100, 160, 90)
assertEquals(ViewPort(0, 0, 100, 100), result)
val result2 = SizeCalculator.calculateViewPort(AspectRatioMode.NONE, 100, 100, 90, 160)
assertEquals(ViewPort(0, 0, 100, 100), result2)
val result3 = SizeCalculator.calculateViewPort(AspectRatioMode.NONE, 100, 100, 100, 100)
assertEquals(ViewPort(0, 0, 100, 100), result3)
}

@Test
fun `calculate flipH and flipV cases`() {
val result = SizeCalculator.calculateFlip(true, true)
assertEquals(Pair(-1f, -1f), result)
val result2 = SizeCalculator.calculateFlip(false, false)
assertEquals(Pair(1f, 1f), result2)
val result3 = SizeCalculator.calculateFlip(true, false)
assertEquals(Pair(-1f, 1f), result3)
val result4 = SizeCalculator.calculateFlip(false, true)
assertEquals(Pair(1f, -1f), result4)
}

@Test
fun `calculate viewport encoder cases`() {
//aspect ratio factor > 1f
val result = SizeCalculator.calculateViewPortEncoder(160, 90, true)
assertEquals(ViewPort(55, 0, 50, 90), result)
val result2 = SizeCalculator.calculateViewPortEncoder(160, 90, false)
assertEquals(ViewPort(0, 0, 160, 90), result2)
//aspect ratio factor < 1f
val result3 = SizeCalculator.calculateViewPortEncoder(90, 160, true)
assertEquals(ViewPort(0, 0, 90, 160), result3)
val result4 = SizeCalculator.calculateViewPortEncoder(90, 160, false)
assertEquals(ViewPort(0, 55, 90, 50), result4)
//aspect ratio factor = 1f
val result5 = SizeCalculator.calculateViewPortEncoder(100, 100, true)
assertEquals(ViewPort(0, 0, 100, 100), result5)
val result6 = SizeCalculator.calculateViewPortEncoder(100, 100, false)
assertEquals(ViewPort(0, 0, 100, 100), result6)
}
}

0 comments on commit 33d5756

Please sign in to comment.