我使用opengl和jni播放YUV视频,视频没问题。
但是当我关闭GLSurfaceView并返回主Activity时。
主Activity中显示的字符和图像变得混乱。
所有图标都变成黑色实心矩形。所有字符都变成白色实心矩形。
代码看起来像来自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.Renderer。在JNI中,代码在Java中将一些方法注册为本机方法。 代码很复杂,我理解,但我的老板要求我快速解决这个问题。 我无法弄清楚为什么在播放YUV视频后,每个图像和字符都会变成矩形。这是怎么发生的?
答案 0 :(得分:1)
您可能会在渲染后删除纹理,您可以尝试保留它们,并在应用终止时取消分配它们