SurfaceTexture updateTexImage к общим 2 EGLContexts - Проблемы на Android 4.4

Я имею в виду этот отличный пример того, как кодировать кадры предварительного просмотра камеры непосредственно в файл mp4:http://bigflake.com/mediacodec/CameraToMpegTest.java.txt

Я принял этот код так, как мне бы хотелось, чтобы изображение для предварительного просмотра отображалось на экране. Поэтому я получил что-то вроде GLTextureView с собственным EGLContext. Этот контекст затем используется как общий EGLContext при создании EGLContext для рендеринга кодера:

mEGLContext = EGL14.eglCreateContext(mEGLDisplay, configs[0], sharedContext == null ? EGL14.EGL_NO_CONTEXT : sharedContext,
                attrib_list, 0);

В моем цикле рендеринга я следовал совету fadden ... для каждого кадра я делаю следующее:

сначала я жду, пока новое изображение не появится в SurfaceTexture с помощью awaitNewImage ()затем я устанавливаю текущий контекст GLTextureView и отрисовываю кадрпосле этого я устанавливаю текущий контекст кодировщика и отображаю на нем кадр

Это выглядит примерно так:

mFrameWatcher.awaitNewImage();
mSurfaceTexture.updateTexImage();
_textureView.getEGLManager().makeCurrent();
_textureView.requestRender();
mInputSurface.makeCurrent();
mInputSurface.requestRender();

Это работало хорошо, пока я тестировал его только на своем Nexus 4 с Android 4.3.

Однако, поскольку я получил новый Nexus 5 с Android 4.4, кодировщик получает только 2 разных кадра в секунду из SurfaceTexture ... но эти 2 кадра неоднократно отрисовываются ... поэтому он кодирует 15 раз один и тот же кадр. ХОТЯ, кадры отображаются правильно для моего GLTextureView с 30 различными кадрами в секунду. Сначала я подумал, что это может быть проблема с Nexus 5 - поэтому я обновил другой Nexus 4 до Android 4.4 ... но теперь он такой же, как и в Nexus 4.

Я немного поигрался - и, наконец, мне удалось решить проблему, отсоединив и заново прикрепив SurfaceTexture к различным контекстам, когда я их переключаю. Это выглядит примерно так:

mFrameWatcher.awaitNewImage();
mSurfaceTexture.updateTexImage();
_textureView.getEGLManager().makeCurrent();
_textureView.requestRender();
mSurfaceTexture.detachFromGLContext();
mInputSurface.makeCurrent();
mSurfaceTexture.attachToGLContext(_textureViewRenderer.getTextureId());
mInputSurface.requestRender();
mSurfaceTexture.detachFromGLContext();
_textureView.getEGLManager().makeCurrent();
mSurfaceTexture.attachToGLContext(_textureViewRenderer.getTextureId());

Мой вопрос сейчас: это правильный способ сделать это? Честно говоря, я думал, что повторное присоединение SurfaceTexture не должно быть необходимым, когда я использую общие контексты. Кроме того, повторное присоединение занимает довольно много времени ... 3-6 мс для каждого кадра с просмотром по 12 мс, что может быть лучше использовано для рендеринга. Я делаю / понимаю что-то не так здесь? Почему он работает как подвеска на Nexus 4 с 4.3 без необходимости повторно прикреплять SurfaceTexture?

Ответы на вопрос(1)

Ваш ответ на вопрос