В настоящее время мы работаем над приложением, которое должно захватывать видео с двух камер (мы используем устаревший API камер, поскольку наше устройство имеет только HAL1), визуализировать оба с использованием OpenGL и сохранять результаты в основной памяти как ByteBuffers. Поток с одной из камер также отображается на дисплее с помощью пользовательского представления.
Наше устройство поддерживает одновременную работу 2 камер, и у нас не было проблем с созданием двух отдельных представлений, но у меня возникли проблемы при объединении всего в одном виде.
У меня есть поверхность EGL windows (на основе этой библиотеки ), используемая для рисования с первой камеры, настроенная так:
public void initEgl(Surface surface, EGLContext eglContext) {
mEgl = (EGL10) EGLContext.getEGL();
mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
throw new RuntimeException("eglGetDisplay failed");
}
int[] version = new int[2];
if (!mEgl.eglInitialize(mEglDisplay, version)) {
throw new RuntimeException("eglInitialize failed");
}
int[] attrib_list = new int[]{
EGL10.EGL_RED_SIZE, mRedSize,
EGL10.EGL_GREEN_SIZE, mGreenSize,
EGL10.EGL_BLUE_SIZE, mBlueSize,
EGL10.EGL_ALPHA_SIZE, mAlphaSize,
EGL10.EGL_DEPTH_SIZE, mDepthSize,
EGL10.EGL_STENCIL_SIZE, mStencilSize,
EGL10.EGL_RENDERABLE_TYPE, 4,//egl版本 2.0
EGL10.EGL_NONE};
int[] num_config = new int[1];
if (!mEgl.eglChooseConfig(mEglDisplay, attrib_list, null, 1,
num_config)) {
throw new IllegalArgumentException("eglChooseConfig failed");
}
int numConfigs = num_config[0];
if (numConfigs <= 0) {
throw new IllegalArgumentException(
"No configs match configSpec");
}
EGLConfig[] configs = new EGLConfig[numConfigs];
if (!mEgl.eglChooseConfig(mEglDisplay, attrib_list, configs, numConfigs,
num_config)) {
throw new IllegalArgumentException("eglChooseConfig#2 failed");
}
EGLConfig eglConfig = chooseConfig(mEgl, mEglDisplay, configs);
if (eglConfig == null) {
eglConfig = configs[0];
}
int[] contextAttr = new int[]{
EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
EGL10.EGL_NONE
};
if (eglContext == null) {
mEglContext = mEgl.eglCreateContext(mEglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, contextAttr);
} else {
mEglContext = mEgl.eglCreateContext(mEglDisplay, eglConfig, eglContext, contextAttr);
}
mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, eglConfig, surface, null);
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
throw new RuntimeException("eglMakeCurrent fail");
}
}
Рендеринг затем выполняется в отдельном потоке, и это прекрасно работает. Теперь, чтобы добавить вторую камеру, я создаю отдельный контекст EGL в отдельном потоке, который настроен точно так же, с одним небольшим отличием: он использует pbuffer вместо окна:
int[] attrib_list = new int[]{
EGL10.EGL_RED_SIZE, mRedSize,
EGL10.EGL_GREEN_SIZE, mGreenSize,
EGL10.EGL_BLUE_SIZE, mBlueSize,
EGL10.EGL_ALPHA_SIZE, mAlphaSize,
EGL10.EGL_DEPTH_SIZE, mDepthSize,
EGL10.EGL_STENCIL_SIZE, mStencilSize,
EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT,
EGL10.EGL_RENDERABLE_TYPE, 4,//egl版本 2.0
EGL10.EGL_NONE};
int[] pbufferAttr = new int[] {
EGL10.EGL_WIDTH, 1280,
EGL10.EGL_HEIGHT, 1280,
EGL10.EGL_NONE
};
mEglSurface = mEgl.eglCreatePbufferSurface(mEglDisplay, eglConfig, pbufferAttr);
Практически все остальное то же самое. Однако, используя его, я получаю следующие ошибки:
E/IMGSRV: :0: IsTextureConsistent: IMGEGLImage is not consistent
E/IMGSRV: :0: GrallocGetBufferParams: Failed to lookup buffer (ID=38061)
W/GLConsumer: [SurfaceTexture-2-4584-1] bindTextureImage: clearing GL error: 0x500
Нет, я понимаю, что OpenGL является поточно-ориентированным, поскольку один контекст является текущим и используется только в одном потоке (что имеет место здесь, так как два контекста EGL имеют разные поверхности и представляют циклы рендеринга в отдельных потоках), поэтому я предполагаю, что фундаментальная установка, подобная этой, не должна возникать.
В чем может быть проблема?