Android TextureView接收GraphicBuffer并且更新View的过程

本文探讨了Android程序使用TextureView显示camera图像时出现的30fps帧率和视频抖动问题。通过分析,揭示了TextureView与BufferQueue的绑定方式以及刷新机制。文章详细解释了SurfaceTexture、BufferQueue、GLConsumer的角色,并跟踪了从onFrameAvailable到屏幕绘制的整个过程,提出了帧率优化的思路。
摘要由CSDN通过智能技术生成

懒人模式:发现问题,澄清问题,解决问题

问题:程序使用TextureView显示camera的图像。camera的捕获帧率为60帧每秒(60fps),但是UI实际显示帧率只有大概30fps,而且视频有抖动(video jitters)。如果把TextureView换成如下代码生成的Surface对象,则帧率看起来正常。

sp<ISurfaceComposer> composer = ComposerService::getComposerService();
sp<ISurfaceComposerClient> session = composer->createScopedConnection();

sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
DisplayInfo dinfo;
SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
// create the native surface
sp<SurfaceControl> control = session()->createSurface(String8("cameraSurface"), dinfo.w, dinfo.h, HAL_PIXEL_FORMAT_YCBCR_420_888);

SurfaceComposerClient::openGlobalTransaction();
control->setLayer(0x40000000);
SurfaceComposerClient::closeGlobalTransaction();

sp<Surface> s = control->getSurface();

实际上,上面的代码Copy自BootAnimation.cpp,使用SourceInsight用关键字CreateSurface搜索出来的。通过穷搜代码,发现TextureView的背后也是BufferQueue, Surface是BufferQueueProducer的一个Wrapper。那么,问题来了:

a. TextureView是如何和BufferQueue绑定的?

b. TextureView是如何刷新它的View的?

下面通过代码一步一步跟踪并回答上面两个问题。

1. TextureView和SurfaceTexture关联,并且设置onFrameAvailableListener

public void setSurfaceTexture(SurfaceTexture surfaceTexture) {
        ...............
        mSurface = surfaceTexture;
        
        ........................

        /*
         * If the view is visible and we already made a layer, update the
         * listener in the new surface to use the existing listener in the view.
         * Otherwise this will be called when the view becomes visible or the
         * layer is created
         */
        if (((mViewFlags & VISIBILITY_MASK) == VISIBLE) && mLayer != null) {
            mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler);
        }
        .................................
    }

2. mUpdateListener是TextureView的一个变量,一旦收到onFrameAvailable调用,则调用updateLayer() 和invalidate()。写UI代码的人或许不熟悉updateLayer,但是invalidate一定很熟悉,就是通知UI主线程去用opengl合成不同的窗口区域啊。

private final SurfaceTexture.OnFrameAvailableListener mUpdateListener =
            new SurfaceTexture.OnFrameAvailableListener() {
        @Override
        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
            updateLayer();
         
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值