提交 16c92d6d authored 作者: kongdywang's avatar kongdywang

1. Fix the issue where the Android screen shows jagged edges in some cases.

2. Fix the issue where the texture is not restored to the interface screen when returning from Picture-in-Picture (PiP) on Android. 3. Update to 12.7 4. Fix known issues.
上级 3c925f93
#### Version: 12.7.1 2025.08.13
##### Features:
- Fix the issue where the Android screen has severe jagged edges in some cases.
- Fix the issue where rendering failure errors occur when Android stops playback.
- Fix the issue where Picture-in-Picture (PiP) restoration on Android sends an extra exit event.
- Fix known issue
#### Version: 12.7.0 2025.08.04
......
......@@ -5,7 +5,7 @@ buildLog() {
}
inputVersion=$1
export VERSION_NAME="12.7.0"
export VERSION_NAME="12.7.1"
if [ -n "$inputVersion" ]; then
VERSION_NAME=$inputVersion
fi
......
......@@ -4,7 +4,7 @@ rootProject.ext {
supportSdkVersion = "26.0.1"
minSdkVersion = 19
targetSdkVersion = 28
playerVersion = "12.7.0"
playerVersion = "12.7.1"
compat = "androidx.appcompat:appcompat:1.6.1"
/**
......
......@@ -3,6 +3,9 @@
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.REORDER_TASKS" />
<!-- for gl es 3.0 -->
<uses-feature android:glEsVersion="0x00030000" android:required="true"/>
<application>
<activity
android:name="com.tencent.vod.flutter.ui.FlutterPipImplActivity"
......
......@@ -6,6 +6,7 @@ import android.opengl.EGLConfig;
import android.opengl.EGLContext;
import android.opengl.EGLDisplay;
import android.opengl.EGLSurface;
import android.opengl.GLES30;
import android.os.Handler;
import android.os.HandlerThread;
import android.view.Surface;
......@@ -13,7 +14,6 @@ import android.view.Surface;
import com.tencent.liteav.base.util.LiteavLog;
import com.tencent.vod.flutter.common.FTXPlayerConstants;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
......@@ -209,7 +209,10 @@ public class FTXEGLRender implements SurfaceTexture.OnFrameAvailableListener {
LiteavLog.e(TAG, "unable to initialize EGL10");
return false;
}
int[] maxSamples = new int[1];
GLES30.glGetIntegerv(GLES30.GL_MAX_SAMPLES, maxSamples, 0);
//noinspection ExtractMethodRecommender
final int samples = Math.min(4, maxSamples[0]);
// Configure EGL for pbuffer and OpenGL ES 2.0, 24-bit RGB.
int[] attribList = new int[]{
EGL14.EGL_RED_SIZE, 8,
......@@ -217,8 +220,10 @@ public class FTXEGLRender implements SurfaceTexture.OnFrameAvailableListener {
EGL14.EGL_BLUE_SIZE, 8,
EGL14.EGL_ALPHA_SIZE, 8,
EGL14.EGL_DEPTH_SIZE, 8,
EGL14.EGL_STENCIL_SIZE, 8,
EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
EGL14.EGL_SURFACE_TYPE, EGL14.EGL_WINDOW_BIT,
EGL14.EGL_SAMPLE_BUFFERS, 1,
EGL14.EGL_SAMPLES, samples,
EGL14.EGL_NONE
};
......@@ -232,7 +237,7 @@ public class FTXEGLRender implements SurfaceTexture.OnFrameAvailableListener {
// Configure context for OpenGL ES 2.0.
//6、创建 EglContext
int[] attrib_list = new int[]{
EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
EGL14.EGL_CONTEXT_CLIENT_VERSION, 3,
EGL14.EGL_NONE
};
......@@ -463,9 +468,10 @@ public class FTXEGLRender implements SurfaceTexture.OnFrameAvailableListener {
// unLock render thread
mStart = false;
saveCurrentEglEnvironment();
boolean contextCompare = mEGLContextEncoder.equals(mEGLSavedContext);
final boolean contextCompare = mEGLContextEncoder.equals(mEGLSavedContext);
eglUninstall(isCompleteRelease);
mDrawHandlerThread.quitSafely();
mDrawHandler = null;
if (!contextCompare) {
LiteavLog.d(TAG, "restoreEglEnvironment");
......
package com.tencent.vod.flutter.player.render.gl;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLES30;
import android.opengl.Matrix;
import com.tencent.liteav.base.util.LiteavLog;
......@@ -13,7 +13,6 @@ public class FTXTextureRender {
private static final int FLOAT_SIZE_BYTES = 4;
private static final String TAG = "FTXTextureRender";
private static final float[] FULL_RECTANGLE_COORDS = {
-1.0f, -1.0f, 1.0f, // 0 bottom left
1.0f, -1.0f, 1.0f, // 1 bottom right
......@@ -34,42 +33,42 @@ public class FTXTextureRender {
TXGlUtilVideo.createFloatBuffer(FULL_RECTANGLE_TEX_COORDS);
private static final String VERTEX_SHADER =
"#version 300 es\n" +
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uSTMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"varying vec4 vTextureCoord;\n" +
"in vec4 aPosition;\n" +
"in vec2 aTextureCoord;\n" +
"out vec2 vTextureCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = uSTMatrix * aTextureCoord;\n" +
" vTextureCoord = aTextureCoord;\n" +
"}\n";
private static final String FRAGMENT_SHADER =
"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;\n" + // highp here doesn't seem to matter
"varying vec4 vTextureCoord;\n" +
private static final String VIDEO_FRAGMENT_SHADER =
"#version 300 es\n" +
"#extension GL_OES_EGL_image_external_essl3 : require\n" +
"precision mediump float;\n" +
"uniform samplerExternalOES sTexture;\n" +
"in vec2 vTextureCoord;\n" +
"out vec4 outColor;\n" +
"void main() {\n" +
" gl_FragColor = texture2D(sTexture, vTextureCoord.xy/vTextureCoord.z);" +
"}\n";
" outColor = texture(sTexture, vTextureCoord);\n" +
"}";
private final float[] mSTMatrix = new float[16];
private final float[] projectionMatrix = new float[16];
private int mProgram;
private int mVideoFragmentProgram;
private int muMVPMatrixHandle;
private int muSTMatrixHandle;
private int maPositionHandle;
private int maTexCoordHandle;
private int maTextureHandle;
private int mVideoWidth;
private int mVideoHeight;
private final int[] textureID = new int[1];
private long mRenderMode = FTXPlayerConstants.FTXRenderMode.FULL_FILL_CONTAINER;
int mPortWidth;
int mPortHeight;
private int mPortWidth;
private int mPortHeight;
public FTXTextureRender(int width, int height) {
Matrix.setIdentityM(mSTMatrix, 0);
mPortWidth = width;
mPortHeight = height;
}
......@@ -78,15 +77,11 @@ public class FTXTextureRender {
* Initializes GL state. Call this after the EGL surface has been created and made current.
*/
public void surfaceCreated() {
mProgram = TXGlUtilVideo.createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
if (mProgram == 0) {
throw new RuntimeException("failed creating program");
}
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
mVideoFragmentProgram = TXGlUtilVideo.createProgram(VERTEX_SHADER, VIDEO_FRAGMENT_SHADER);
maPositionHandle = GLES30.glGetAttribLocation(mVideoFragmentProgram, "aPosition");
maTexCoordHandle = GLES30.glGetAttribLocation(mVideoFragmentProgram, "aTextureCoord");
muMVPMatrixHandle = GLES30.glGetUniformLocation(mVideoFragmentProgram, "uMVPMatrix");
maTextureHandle = GLES30.glGetUniformLocation(mVideoFragmentProgram, "sTexture");
textureID[0] = initTex();
}
......@@ -96,8 +91,8 @@ public class FTXTextureRender {
}
public void deleteTexture() {
GLES20.glDeleteProgram(mProgram);
GLES20.glDeleteTextures(1, textureID, 0);
GLES30.glDeleteProgram(mVideoFragmentProgram);
GLES30.glDeleteTextures(1, textureID, 0);
}
/**
......@@ -107,17 +102,17 @@ public class FTXTextureRender {
*/
public int initTex() {
int[] tex = new int[1];
GLES20.glGenTextures(1, tex, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, tex[0]);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES30.glGenTextures(1, tex, 0);
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
GLES30.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, tex[0]);
GLES30.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
GLES30.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
GLES30.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR);
GLES30.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
return tex[0];
}
......@@ -178,8 +173,8 @@ public class FTXTextureRender {
}
public void cleanDrawCache() {
GLES20.glViewport(0, 0, mPortWidth, mPortHeight);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES30.glViewport(0, 0, mPortWidth, mPortHeight);
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
}
/**
......@@ -188,25 +183,29 @@ public class FTXTextureRender {
public void drawFrame() {
cleanDrawCache();
// video frame
GLES20.glUseProgram(mProgram);
GLES30.glUseProgram(mVideoFragmentProgram);
GLES30.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, projectionMatrix, 0);
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
GLES30.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureID[0]);
GLES30.glUniform1i(maTextureHandle, 0);
// Enable the "aPosition" vertex attribute.
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES30.glEnableVertexAttribArray(maPositionHandle);
// Connect vertexBuffer to "aPosition".
GLES20.glVertexAttribPointer(maPositionHandle, 3,
GLES20.GL_FLOAT, false, 3 * FLOAT_SIZE_BYTES, FULL_RECTANGLE_BUF);
GLES30.glVertexAttribPointer(maPositionHandle, 3,
GLES30.GL_FLOAT, false, 3 * FLOAT_SIZE_BYTES, FULL_RECTANGLE_BUF);
// Enable the "aTextureCoord" vertex attribute.
GLES20.glEnableVertexAttribArray(maTextureHandle);
GLES30.glEnableVertexAttribArray(maTexCoordHandle);
// Connect texBuffer to "aTextureCoord".
GLES20.glVertexAttribPointer(maTextureHandle, 4,
GLES20.GL_FLOAT, false, 4 * FLOAT_SIZE_BYTES, FULL_RECTANGLE_TEX_BUF);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, projectionMatrix, 0);
GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
GLES30.glVertexAttribPointer(maTexCoordHandle, 4,
GLES30.GL_FLOAT, false, 4 * FLOAT_SIZE_BYTES, FULL_RECTANGLE_TEX_BUF);
// Draw the rect.
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
// Done -- disable vertex array, texture, and program.
GLES20.glDisableVertexAttribArray(maPositionHandle);
GLES20.glDisableVertexAttribArray(maTextureHandle);
GLES20.glUseProgram(0);
GLES30.glDisableVertexAttribArray(maPositionHandle);
GLES30.glDisableVertexAttribArray(maTexCoordHandle);
GLES30.glUseProgram(0);
}
}
package com.tencent.vod.flutter.player.render.gl;
import android.opengl.GLES20;
import android.opengl.Matrix;
import android.opengl.GLES30;
import com.tencent.liteav.base.util.LiteavLog;
......@@ -12,17 +11,6 @@ import java.nio.FloatBuffer;
public class TXGlUtilVideo {
public static final String TAG = "TXGlUtilVideo";
/**
* Identity matrix for general use. Don't modify or life will get weird.
*/
public static final float[] IDENTITY_MATRIX;
static {
IDENTITY_MATRIX = new float[16];
Matrix.setIdentityM(IDENTITY_MATRIX, 0);
//Matrix.scaleM(IDENTITY_MATRIX,0,0.5f,0.5f,1);
}
private static final int SIZEOF_FLOAT = 4;
......@@ -35,36 +23,36 @@ public class TXGlUtilVideo {
* @return A handle to the program, or 0 on failure.
*/
public static int createProgram(String vertexSource, String fragmentSource) {
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
int vertexShader = loadShader(GLES30.GL_VERTEX_SHADER, vertexSource);
if (vertexShader == 0) {
return 0;
}
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
int pixelShader = loadShader(GLES30.GL_FRAGMENT_SHADER, fragmentSource);
if (pixelShader == 0) {
GLES20.glDeleteShader(vertexShader);
GLES30.glDeleteShader(vertexShader);
return 0;
}
int program = GLES20.glCreateProgram();
int program = GLES30.glCreateProgram();
checkGlError("glCreateProgram");
if (program == 0) {
LiteavLog.e(TAG, "Could not create program");
}
GLES20.glAttachShader(program, vertexShader);
GLES30.glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
GLES20.glAttachShader(program, pixelShader);
GLES30.glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
GLES20.glLinkProgram(program);
GLES30.glLinkProgram(program);
int[] linkStatus = new int[1];
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] != GLES20.GL_TRUE) {
GLES30.glGetProgramiv(program, GLES30.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] != GLES30.GL_TRUE) {
LiteavLog.e(TAG, "Could not link program: ");
LiteavLog.e(TAG, GLES20.glGetProgramInfoLog(program));
GLES20.glDeleteProgram(program);
LiteavLog.e(TAG, GLES30.glGetProgramInfoLog(program));
GLES30.glDeleteProgram(program);
program = 0;
}
GLES20.glDeleteShader(vertexShader);
GLES20.glDeleteShader(pixelShader);
GLES30.glDeleteShader(vertexShader);
GLES30.glDeleteShader(pixelShader);
return program;
}
......@@ -74,17 +62,17 @@ public class TXGlUtilVideo {
* @return A handle to the shader, or 0 on failure.
*/
public static int loadShader(int shaderType, String source) {
int shader = GLES20.glCreateShader(shaderType);
int shader = GLES30.glCreateShader(shaderType);
checkGlError("glCreateShader type=" + shaderType);
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
GLES30.glShaderSource(shader, source);
GLES30.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
int error = GLES20.glGetError();
GLES30.glGetShaderiv(shader, GLES30.GL_COMPILE_STATUS, compiled, 0);
int error = GLES30.glGetError();
if (compiled[0] == 0) {
LiteavLog.e(TAG, "Could not compile shader:" + shaderType + ",error:" + error);
LiteavLog.e(TAG, " " + GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
LiteavLog.e(TAG, " " + GLES30.glGetShaderInfoLog(shader));
GLES30.glDeleteShader(shader);
shader = 0;
}
return shader;
......@@ -94,8 +82,8 @@ public class TXGlUtilVideo {
* Checks to see if a GLES error has been raised.
*/
public static void checkGlError(String op) {
int error = GLES20.glGetError();
if (error != GLES20.GL_NO_ERROR) {
int error = GLES30.glGetError();
if (error != GLES30.GL_NO_ERROR) {
String msg = op + ": glError 0x" + Integer.toHexString(error);
LiteavLog.e(TAG, msg);
throw new RuntimeException(msg);
......
......@@ -445,9 +445,6 @@ public class FlutterPipImplActivity extends Activity implements ITXVodPlayListen
if (!closeImmediately) {
mVideoRenderView.setVisibility(View.GONE);
mVideoProgress.setVisibility(View.GONE);
mMainHandler.postDelayed(new Runnable() {
@Override
public void run() {
/*
The PiP window can launch its own Activity. Therefore,
we can initiate our own here. By executing the termination code during the launch,
......@@ -456,9 +453,6 @@ public class FlutterPipImplActivity extends Activity implements ITXVodPlayListen
it can display back to the original page.
*/
moveCurActToFront();
destroyPipAct();
}
}, 800);
} else {
destroyPipAct();
}
......
......@@ -4,7 +4,7 @@
#
Pod::Spec.new do |s|
s.name = 'super_player'
s.version = '12.7.0'
s.version = '12.7.1'
s.summary = 'The super_player Flutter plugin is one of the sub-product SDKs of the audio/video terminal SDK (Tencent Cloud Video on Demand).'
s.description = <<-DESC
player plugin.
......
......@@ -2,5 +2,5 @@
part of SuperPlayer;
abstract class FPlayerPckInfo {
static const String PLAYER_VERSION = "12.7.0";
static const String PLAYER_VERSION = "12.7.1";
}
\ No newline at end of file
......@@ -293,8 +293,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
await _livePlayerApi.exitPictureInPictureMode(PlayerMsg()
..playerId = _playerId);
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
await _livePlayerApi.enablePictureInPicture(BoolPlayerMsg()
..value = false
await _livePlayerApi.exitPictureInPictureMode(PlayerMsg()
..playerId = _playerId);
}
}
......
name: super_player
description: The super_player Flutter plugin is one of the sub-product SDKs of the audio/video terminal SDK (Tencent Cloud Video on Demand).
version: 12.7.0
version: 12.7.1
homepage: https://github.com/LiteAVSDK/Player_Flutter
environment:
......
......@@ -3,5 +3,5 @@ part of demo_super_player_lib;
class PlayerConstants {
static const PKG_NAME = "superplayer_widget";
static const String PLAYER_WIDGET_VERSION = "12.7.0";
static const String PLAYER_WIDGET_VERSION = "12.7.1";
}
name: superplayer_widget
description: superplayer,base on vodplayer
version: 12.7.0
version: 12.7.1
environment:
sdk: '>=2.17.0 <4.0.0'
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论