从Unity获取Android EGL共享上下文用于WebRTC

3
我正在尝试在Unity和WebRTC之间建立桥梁。
更新:好的,我为此创建了一个存储库,但在渲染纹理时仍会出现奇怪的伪影,我无法找到原因。如果有人想看一下,请访问以下链接:https://github.com/iBicha/WebRTC-for-Unity/ 由于WebRTC能够将VideoTracks提供的帧作为纹理,所以我认为最好共享EGL上下文与Unity,这样我就可以直接将其渲染到引擎中。
我发现这可以通过设置PeerConnectionFactory上的视频硬件加速选项来实现,如下所示:
    PeerConnectionFactory.initializeAndroidGlobals(mainActivity.getApplicationContext(), true);
    PeerConnectionFactory factory = new PeerConnectionFactory(new PeerConnectionFactory.Options());
    EglBase rootEglBase = EglBase.createEgl14(EGL14.eglGetCurrentContext(), EglBase.CONFIG_PIXEL_RGBA_BUFFER);
    factory.setVideoHwAccelerationOptions(rootEglBase.getEglBaseContext(),rootEglBase.getEglBaseContext());

当然,这只是关于它应该如何工作的一些假设。
由于`setVideoHwAccelerationOptions`需要一个`EglBase.Context`,这意味着我需要从Unity中找到上下文并将其转换为该上下文。
为了做到这一点,我发现`EglBase.createEgl14`可能会起作用,但我需要正确的配置属性,而我找不到。尝试了几种组合,但都没有成功。
我基本上被卡住了,不知道该怎么办。
另一个选择是从帧中获取ByteBuffer,并将它们传递给Unity,但那会影响性能并浪费资源,因为Unity和WebRTC都使用OpenGL。我感觉我离答案很近,但缺少了某些东西。
更新:我发现`eglGetCurrentContext()`没有返回上下文,因为它没有从主Unity线程调用。现在我有了上下文,`I420Frame`帧的textureId有意义。但它们没有渲染。我认为这与我传递给`EglBase.createEgl14`的配置属性有关。或者这也可能是线程问题?

我刚刚意识到实际问题是 EGL14.eglGetCurrentContext() 返回 EGL_NO_CONTEXT,这意味着 Unity 播放器没有调用 eglMakeCurrent。这是否意味着没有办法获取上下文来创建共享上下文以传递数据? - Brahim Hadriche
好的,我为此创建了一个仓库,但在渲染纹理时仍然遇到奇怪的伪影问题,我无法找出原因。如果有人想要看一下,请访问以下链接:https://github.com/iBicha/WebRTC-for-Unity/ - Brahim Hadriche
2个回答

1
所以诀窍是使用GLES 2,因为这就是EGLBase正在做的事情(目前来看,让我们看看它是否会在官方存储库中更新)。同时,Unity上下文需要正确获取并用作共享上下文,以便能够传递纹理。最后,纹理需要使用特殊的GLSL着色器渲染,并将纹理视为samplerExternalOES(类似于Hidden/VideoDecodeAndroid着色器)。可以使用此着色器将其渲染到RenderTexture中,然后使用任何材质/着色器将该纹理渲染到场景中。一个有效的演示在这里 https://github.com/iBicha/WebRTC-for-Unity/

0

我曾经遇到过类似的情况,EGL14.eglGetCurrentContext 总是返回 EGL_NO_CONTEXT。原来是因为默认使用了 Vulkan。解决方法也是在 Player Settings 中更改 Graphics APIs。可能与原帖中的问题不同,但还是记录下来以防对某些人有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接