在安卓系统上使用opengles播放YUV视频后活动混乱

Activity messed after playing YUV video use opengles on Android

本文关键字:YUV 播放 视频 混乱 活动 opengles 系统      更新时间:2023-10-16

我用opengl es和jni来播放YUV视频,视频还可以。

但当我关闭GLSurfaceView并返回主活动时。

主"活动"中显示的字符和图像变得混乱。

所有图标都变为黑色实心矩形。所有字符都变为白色实心矩形。

代码看起来像是来自WebRTC,并由其他人修改。我是一名C程序员,不熟悉OpenGl。所以解决这个问题对我来说是一个很大的问题。

我在JNI中创建这样的句柄:

bool isAttached = false;
JNIEnv* env = NULL;
if (_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
// try to attach the thread and get the env
// Attach this thread to JVM
jint res = _jvm->AttachCurrentThread(&env, NULL);
// Get the JNI env for this thread
if ((res < 0) || !env) {
LOGE("%s: Could not attach thread to JVM (%d, %p)",
__FUNCTION__, res, env);
return -1;
}
isAttached = true;
}
// get the ViEAndroidGLES20 class
jclass javaRenderClassLocal = reinterpret_cast<jclass> (env->FindClass("com/wg/rgc/library/gl/ViEAndroidGLES20"));
if (!javaRenderClassLocal) {
LOGE("%s: could not find ViEAndroidGLES20", __FUNCTION__);
return -1;
}
_javaRenderClass = reinterpret_cast<jclass> (env->NewGlobalRef(javaRenderClassLocal));
if (!_javaRenderClass) {
LOGE("%s: could not create Java SurfaceHolder class reference",
__FUNCTION__);
return -1;
}
// Delete local class ref, we only use the global ref
env->DeleteLocalRef(javaRenderClassLocal);
jmethodID cidUseOpenGL = env->GetStaticMethodID(_javaRenderClass,
"UseOpenGL2",
"(Ljava/lang/Object;)Z");
if (cidUseOpenGL == NULL) {
LOGE("%s: could not get UseOpenGL ID", __FUNCTION__);
return false;
}
jboolean res = env->CallStaticBooleanMethod(_javaRenderClass,
cidUseOpenGL, (jobject) _ptrWindow);
// create a reference to the object (to tell JNI that we are referencing it
// after this function has returned)
_javaRenderObj = reinterpret_cast<jobject> (env->NewGlobalRef((jobject)_ptrWindow));
if (!_javaRenderObj)
{
LOGE("%s: could not create Java SurfaceRender object reference",
__FUNCTION__);
return -1;
}
// get the method ID for the ReDraw function
_redrawCid = env->GetMethodID(_javaRenderClass, "ReDraw", "()V");
if (_redrawCid == NULL) {
LOGE("%s: could not get ReDraw ID", __FUNCTION__);
return -1;
}
_registerNativeCID = env->GetMethodID(_javaRenderClass,
"RegisterNativeObject", "(J)V");
if (_registerNativeCID == NULL) {
LOGE("%s: could not get RegisterNativeObject ID", __FUNCTION__);
return -1;
}
_deRegisterNativeCID = env->GetMethodID(_javaRenderClass,
"DeRegisterNativeObject", "()V");
if (_deRegisterNativeCID == NULL) {
LOGE("%s: could not get DeRegisterNativeObject ID",
__FUNCTION__);
return -1;
}
JNINativeMethod nativeFunctions[2] = {
{ "DrawNative",
"(J)V",
(void*) &AndroidNativeOpenGl2Channel::DrawNativeStatic, },
{ "CreateOpenGLNative",
"(JII)I",
(void*) &AndroidNativeOpenGl2Channel::CreateOpenGLNativeStatic },
};
if (env->RegisterNatives(_javaRenderClass, nativeFunctions, 2) == 0) {
LOGE("%s: Registered native functions", __FUNCTION__);
}
else {
LOGE("%s: Failed to register native functions", __FUNCTION__);
return -1;
}
env->CallVoidMethod(_javaRenderObj, _registerNativeCID, (jlong) this);
if (isAttached) {
if (_jvm->DetachCurrentThread() < 0) {
LOGE("%s: Could not detach thread from JVM", __FUNCTION__);
}
}
LOGE("%s done", __FUNCTION__);
if (_openGLRenderer.SetCoordinates(0, 1.0, 1.0, 0, 0) != 0) {
return -1;
}
isAlreadyInit = 1;  //Init finish
return 0;

我在JNI中这样关闭这个句柄:

bool isAttached = false;
JNIEnv* env = NULL;
if (_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
// try to attach the thread and get the env
// Attach this thread to JVM
jint res = _jvm->AttachCurrentThread(&env, NULL);
// Get the JNI env for this thread
if ((res < 0) || !env) {
LOGE("%s: Could not attach thread to JVM (%d, %p)",
__FUNCTION__, res, env);
env = NULL;
} else {
isAttached = true;
}
}
if (env && _deRegisterNativeCID) {
env->CallVoidMethod(_javaRenderObj, _deRegisterNativeCID);
}
env->DeleteGlobalRef(_javaRenderObj);
env->DeleteGlobalRef(_javaRenderClass);
if (isAttached) {
if (_jvm->DetachCurrentThread() < 0) {
LOGE("%s: Could not detach thread from JVM",
__FUNCTION__);
}
}

方法env->CallVoidMethod(_javaRenderObj,_deRegisterNativeCID);在Java src:中称为Java方法

nativeFunctionLock.lock();
nativeFunctionsRegisted = false;
openGLCreated = false;
this.nativeObject = 0;
nativeFunctionLock.unlock();

Java src中的代码看起来像是对GLSurfaceView的扩展,并实现了GLSurfaceView.Render。在JNI中,代码将一些方法注册为Java中的本地方法。代码对我来说很难理解,但我的老板要求我尽快解决这个问题。我不明白为什么在播放YUV视频后,每个图像和字符都变成了矩形。这是怎么发生的?

您可能会在渲染后删除纹理,您可以尝试保留它们,并在应用程序终止时取消分配它们