从 unity for webrtc 获取 android EGL 共享上下文

get android EGL shared context from unity for webrtc

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

Update: Alright, I created a repo for this, still experiencing weird artifacts with rendering the textures, which I can't figure out the reason why. If anyone wants to take a look.

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。我觉得我很接近答案,但缺少一些东西。

Update:我认为 eglGetCurrentContext() 没有返回上下文,因为它不是从 Unity 主线程调用的。既然我得到了上下文,I420Frame 帧的 textureId 就有意义了。但他们没有渲染。我认为这与我传递给 EglBase.createEgl14 的配置属性有关。或者这也可能是一个线程问题?

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

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

最后需要用特殊的GLSL shader渲染贴图,将贴图当作samplerExternalOES(类似于Hidden/VideoDecodeAndroid shader)。可以使用此着色器将其渲染到 RenderTexture,然后使用任何 material/shader 在场景中渲染该纹理。

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

我有过类似的情况 EGL14.eglGetCurrentContext 总是 returns EGL_NO_CONTEXT。原来是因为默认使用了Vulkan。解决方案也是在 Player Settings 中更改 Graphics APIs。可能和原来的问题不一样post,但写下来以防万一对某人有帮助。