Получить андроид EGL общий контекст от единства для webrtc
Я пытаюсь соединить Unity и WebRTC.
Обновление: Хорошо, я создал репо для этого, все еще испытывая странные артефакты с рендерингом текстур, которые я не могу понять, почему. Если кто-то хочет взглянуть.
Поскольку 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
, Вероятно, это не то же самое, что проблема в оригинальном сообщении, но записать ее на всякий случай, если она кому-нибудь пригодится.