前段时间我问了这个问题,得到了答案。
我已经按照答案建议实施了一个中介Surface
,但现在我遇到了另一个问题。在我申请期间的某些时间点,我VirtualDisplay
可以更改分辨率。所以,我还想更新中介的大小Surface
以匹配VirtualDisplay
. 我希望这将是setDefaultBufferSize
对Surface's
底层的简单调用SurfaceTexture
,但这似乎不起作用。
我已经在释放我的中间体Surface
并SurfaceTexture
制作新的中间体时四处寻找,但是我必须将输出表面设置为VirtualDisplay
null 并执行一些其他同步步骤,如果可能的话我想避免这些步骤。
有没有办法在创建后动态更新Surface
/的大小SurfaceTexture
?
更新:
我尝试过调用VirtualDisplay.setSurface(null)
,VirtualDisplay.resize(newSize.width, newSize.height)
然后向线程发送一条消息,该线程处理中介的回调以SurfaceTexture
通过调整纹理大小setDefaultBufferSize
,然后让主线程轮询辅助线程,直到该集合调用完成然后调用VirtualDisplay.setSurface(surfaceFromSecondaryThread)
这有时有效。其他时候,纹理全是绿色的,上面有一个灰色条(这也是我的 glClearColor,不确定这是否相关,如此处所示)。有时在我的VirtualDisplay
. 所以,这似乎是一个时间问题,但我不确定我应该等待什么时间。状态的文档setDefaultBufferSize
:
For OpenGL ES, the EGLSurface should be destroyed (via eglDestroySurface), made not-current (via eglMakeCurrent), and then recreated (via eglCreateWindowSurface) to ensure that the new default size has taken effect.
问题是我的代码没有从 SurfaceTexture/Surface 创建 EGLSurface,所以我无法销毁它。我假设生产者 ( VirtualDisplay
) 确实如此,但是没有公共 API 可供我使用 EGLSurface。
[更新 2] 因此,当我看到问题(带条的绿屏、损坏,可能是因为我glClearColor
的为绿色)时,如果我glReadPixels
在调用之前执行 aeglSwapBuffers
来写入Surface
for the MediaCodec
,我会读取绿色像素。这告诉我这不是MediaCodec
问题,要么写入的信息Surface
已VirtualDisplay
损坏(并且仍然损坏),要么从 YUV 空间到 RGBA 空间的转换从Surface
-> OpenGL 纹理以某种方式损坏。我倾向于有一个问题VirtualDisplay