从 Unity for Webrtc 获取 Android EGL 共享上下文



我正在尝试在Unity和WebRTC之间架起桥梁。

更新:好的,我为此创建了一个存储库,在渲染纹理时仍然遇到奇怪的伪影,我无法弄清楚 原因。如果有人想看看。

https://github.com/iBicha/WebRTC-for-Unity/

由于WebRTC能够提供来自VideoTracks的帧作为纹理,我认为最好是与Unity共享EGL上下文,这样我就可以将其直接渲染到引擎中。

我认为这是通过在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的配置属性有关。否则,这可能也是一个线程的事情?

所以诀窍是使用 GLES 2,因为这就是 EGLBase 正在做的事情(现在,让我们看看它是否在官方存储库中更新(

此外,需要正确获取 unity 上下文,并将其用作共享上下文,以便能够传递纹理。

最后,纹理需要使用特殊的GLSL着色器进行渲染,并将纹理视为samplerExternalOES(类似于Hidden/VideoDecodeAndroid着色器(。可以使用此着色器将其渲染为 RenderTexture,然后使用任何材质/着色器在场景中渲染该纹理。

一个工作演示在这里 https://github.com/iBicha/WebRTC-for-Unity/

我遇到了类似的情况,EGL14.eglGetCurrentContext总是返回EGL_NO_CONTEXT。 事实证明,这是因为默认情况下使用了 Vulkan。 解决方案也是改变Player SettingsGraphics APIs。 可能与原始帖子中的问题不同,但将其写下来以防对某人有帮助。

最新更新