Android Camera2:即时更改输出表面设置的最佳,最快方法
作者:互联网
我正在制作一个视频流应用程序,使视频比特率适应可用的上行链路带宽,并且我希望它可以动态地更改视频分辨率,以便在较低比特率上不会出现太多压缩失真.尽管通过释放MediaCodec并在CameraCaptureSession上调用abortCaptures()和stopRepeating()然后为新分辨率配置所有内容来完成此工作,但这会在流中造成非常明显的中断-在我的测试中至少需要半秒钟.
当相机本身不支持所需的分辨率时,我使用OpenGL缩放图像,类似于this.我使用两个表面初始化捕获会话-一个用于向用户预览(使用TextureView),一个用于编码器,即直接使用MediaCodec的输入表面或使用我的OpenGL纹理表面.
这可以通过使用MediaCodec.createPersistentInputSurface()来解决,因为我将能够在分辨率变化中重用此缩放器实例,并且无需执行任何捕获操作,因为就相机而言,没有表面变化担心,但仅自API 23起可用,我也需要此实现来支持API 21.
然后还有曲面失效和重新创建的问题.例如,当用户按下“后退”按钮时,活动及其包含的TextureView被破坏,从而使预览图面无效.然后,当用户再次导航到该活动时,将创建一个新的TextureView,我需要开始在其中显示预览,而不会给缩放器/编码器看到的流引入任何滞后.
因此,我的问题通常是:如何在CameraCaptureSession中更改输出表面的集合,或重新创建CameraCaptureSession,同时将尽可能少的延迟引入视频流?
解决方法:
事实证明,实际上包含纹理(包括相机提供帧的纹理)的OpenGL上下文与任何特定的输出目标都不相关.因此,我可以使视频缩放器在初始化后更改其输出表面,如下所示:
...
}else if(inputMessage.what==MSG_CHANGE_SURFACE){
// Detach the current thread from the context, as a precaution
EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
checkEglError("eglMakeCurrent 1");
// Destroy the old EGL surface and release its Android counterpart
// the old surface belongs to the previous, now released, MediaCodec instance
EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface);
checkEglError("eglDestroySurface");
surface.release(); // surface is a field that holds the current MediaCodec encoder input surface
surface=(Surface) inputMessage.obj;
dstW=inputMessage.arg1; // these are used in glViewport and the fragment shader
dstH=inputMessage.arg2;
// Create a new EGL surface for the new MediaCodec instance
int[] surfaceAttribs={
EGL14.EGL_NONE
};
mEGLSurface=EGL14.eglCreateWindowSurface(mEGLDisplay, configs[0], surface, surfaceAttribs, 0);
checkEglError("eglCreateWindowSurface");
// Make it current for the current thread
EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext);
checkEglError("eglMakeCurrent 2");
// That's it, any subsequent draw calls will render to the new surface
}
使用这种方法,无需重新初始化CameraCaptureSession,因为相机输出到的表面集没有变化.
标签:android-camera2,mediacodec,android-camera,android 来源: https://codeday.me/bug/20191024/1923006.html