Получить андроид EGL общий контекст от единства для webrtc

Я пытаюсь соединить Unity и WebRTC.

Обновление: Хорошо, я создал репо для этого, все еще испытывая странные артефакты с рендерингом текстур, которые я не могу понять, почему. Если кто-то хочет взглянуть.

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

Поскольку WebRTC способен предоставлять кадры из VideoTracks в качестве текстуры, я подумал, что было бы лучше, если бы он разделял контекст 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. Теперь, когда я получил контекст, textureId I420Frame кадры имеют смысл. Но они не оказывают. Я думаю, что это связано с атрибутами конфигурации, которые я передаю EglBase.createEgl14, Или это тоже может быть многопоточность?

1 ответ

Решение

Так что хитрость в том, чтобы использовать GLES 2, потому что это то, что делает EGLBase (сейчас давайте посмотрим, будет ли он обновлен в официальном репо)

Кроме того, контекст единства должен быть правильно получен и использован в качестве контекста совместного использования, чтобы иметь возможность передавать текстуры.

Наконец, текстуру необходимо визуализировать с помощью специального шейдера GLSL, а текстуру следует обрабатывать как samplelerExternalOES (аналогично шейдеру Hidden/VideoDecodeAndroid). Можно использовать его для RenderTexture с помощью этого шейдера, а затем использовать любой материал / шейдер для визуализации этой текстуры на сцене.

Рабочая демоверсия находится здесь https://github.com/iBicha/WebRTC-for-Unity/

У меня была похожая ситуация, что EGL14.eglGetCurrentContext всегда возвращается EGL_NO_CONTEXT, Оказывается, потому что Vulkan использовался по умолчанию. Решение было также изменить Graphics APIs в Player Settings, Вероятно, это не то же самое, что проблема в оригинальном сообщении, но записать ее на всякий случай, если она кому-нибудь пригодится.

Другие вопросы по тегам