在Android上播放YUV视频使用opengles后,活动搞乱了

时间:2015-04-29 12:57:26

标签: java android c++ opengl-es

我使用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视频后,每个图像和字符都会变成矩形。这是怎么发生的?

1 个答案:

答案 0 :(得分:1)

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