peertube-live-streaming/encoder/src/main/java/com/pedro/encoder/utils/gl/SizeCalculator.java

135 lines
5.2 KiB
Java

/*
* Copyright (C) 2021 pedroSG94.
*
* 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
*
* http://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 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;
/**
* Created by pedro on 22/03/19.
*/
public class SizeCalculator {
public static void calculateViewPort(boolean keepAspectRatio, int mode, int previewWidth,
int previewHeight, int streamWidth, int streamHeight) {
Pair<Point, Point> pair =
getViewport(keepAspectRatio, mode, previewWidth, previewHeight, streamWidth, streamHeight);
GLES20.glViewport(pair.first.x, pair.first.y, pair.second.x, pair.second.y);
}
public static void calculateViewPortEncoder(int streamWidth, int streamHeight, boolean isPortrait) {
Pair<Point, Point> pair;
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));
} else {
pair = new Pair<>(new Point(0, 0), new Point(streamWidth, streamHeight));
}
} else {
if (isPortrait) {
pair = new Pair<>(new Point(0, 0), new Point(streamWidth, streamHeight));
} else {
int height = (int) (streamWidth * factor);
int oY = (streamHeight - height) / 2;
pair = new Pair<>(new Point(0, oY), new Point(streamWidth, height));
}
}
GLES20.glViewport(pair.first.x, pair.first.y, pair.second.x, pair.second.y);
}
public static Pair<Point, Point> getViewport(boolean keepAspectRatio, int mode, int previewWidth,
int previewHeight, int streamWidth, int streamHeight) {
if (keepAspectRatio) {
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 ((streamAspectRatio > 1f
&& previewAspectRatio > 1f
&& streamAspectRatio > previewAspectRatio) || (streamAspectRatio < 1f
&& previewAspectRatio < 1
&& streamAspectRatio > previewAspectRatio) || (streamAspectRatio > 1f
&& previewAspectRatio < 1f)) {
if (mode == 0) {
yf = streamHeight * previewWidth / streamWidth;
yo = (yf - previewHeight) / -2;
} else {
xf = streamWidth * previewHeight / streamHeight;
xo = (xf - previewWidth) / -2;
}
} else if ((streamAspectRatio > 1f
&& previewAspectRatio > 1f
&& streamAspectRatio < previewAspectRatio) || (streamAspectRatio < 1f
&& previewAspectRatio < 1f
&& streamAspectRatio < previewAspectRatio) || (streamAspectRatio < 1f
&& previewAspectRatio > 1f)) {
if (mode == 0 || mode == 2) {
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));
return new Pair<>(new Point(0, 0), new Point(previewHeight, previewWidth));
}
}
public static void processMatrix(int rotation, boolean flipStreamHorizontal,
boolean flipStreamVertical, int width, int height, boolean isPortrait, boolean isPreview, float[] MVPMatrix) {
PointF scale = getScale(rotation,width,height, isPortrait, isPreview);
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 != 90 && rotation != 270) { //portrait
final float adjustedWidth = width * (width / (float) height);
scaleX = adjustedWidth / height;
} /*else if (isPortrait && rotation != 0 && rotation != 180) { //landscape
final float adjustedWidth = height * (height / (float) width);
scaleY = adjustedWidth / width;
}*/
}
return new PointF(scaleX, scaleY);
}
}