Android Camera2:即时更改输出表面设置的最佳,最快方法

Android Camera2:即时更改输出表面设置的最佳,最快方法,第1张

概述我正在制作一个视频流应用程序,使视频比特率适应可用的上行链路带宽,并且我希望它可以动态地更改视频分辨率,以便在较低比特率上不会出现太多压缩失真.尽管通过释放MediaCodec并在CameraCaptureSession上调用abortCaptures()和stopRepeating()然后为新分辨率配置所有内容来完成此工

我正在制作一个视频流应用程序,使视频比特率适应可用的上行链路带宽,并且我希望它可以动态地更改视频分辨率,以便在较低比特率上不会出现太多压缩失真.尽管通过释放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:即时更改输出表面设置的最佳,最快方法全部内容,希望文章能够帮你解决Android Camera2:即时更改输出表面设置的最佳,最快方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1092338.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存