Android 5.0 Camera系统源码分析(3):Camera预览流程控制流

本文深入分析Android 5.0系统中Camera预览流程的源码,从APP层的setPreviewDisplay和startPreview函数,到frameworks层和Hal层的关键操作。着重讲解了DisplayClient、CamAdapter、CamNode的角色与交互,揭示了预览模式下图像数据从硬件到Surface的传输过程。
摘要由CSDN通过智能技术生成

本文分析的是Android系统源码,从frameworks层到hal层,记录了Camera进入预览模式的重点代码,主要为控制流程的代码,有关图像buffer的传递暂不涉及,硬件平台基于mt6735。由于某些函数比较复杂,在贴出代码时会适当对其进行简化。

2. APP层

这里将分析app层令Camera进入预览模式的两个重点api:setPreviewDisplay和startPreview

mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
 
 
 
  • 1
  • 2
  • 1
  • 2

3. setPreviewDisplay函数分析

预览图像最终是要在lcd上显示的,想要在lcd上显示图像就需要用到Surface 。填充Surface有两种方法,一种是注册callback函数,预览数据将在callback函数中返回,得到数据后再把它送到Surface里面;另一种是在开始预览之前就为底层设置好Surface,底层获取数据后直接把数据送到Surface里面,为底层设置好Surface就是setPreviewDisplay的作用,

3.1 frameworks层

先来看frameworks层的实现

public final void setPreviewDisplay(SurfaceHolder holder) throws IOException {
    if (holder != null) {
        setPreviewSurface(holder.getSurface());
    } else {
        setPreviewSurface((Surface)null);
    }    
}
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

setPreviewSurface是一个jni函数,它的实现在android_hardware_Camera.cpp中

static void android_hardware_Camera_setPreviewSurface(JNIEnv *env, jobject thiz, jobject jSurface)
{
    sp<Camera> camera = get_native_camera(env, thiz, NULL);
    if (camera == 0) return;

    sp<IGraphicBufferProducer> gbp; 
    sp<Surface> surface;
    if (jSurface) {
        surface = android_view_Surface_getSurface(env, jSurface);
        if (surface != NULL) {
            gbp = surface->getIGraphicBufferProducer();
        }    
    }    

    if (camera->setPreviewTarget(gbp) != NO_ERROR) {
        jniThrowException(env, "java/io/IOException", "setPreviewTexture failed");
    }    
}
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
// pass the buffered IGraphicBufferProducer to the camera service 
status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer) 
{ 
    sp <ICamera> c = mCamera; 
    return c->setPreviewTarget(bufferProducer); 
} 
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
// set the buffer consumer that the preview will use 
status_t CameraClient::setPreviewTarget( 
        const sp<IGraphicBufferProducer>& bufferProducer) { 
    sp<IBinder> binder; 
    sp<ANativeWindow> window; 
    if (bufferProducer != 0) { 
        binder = bufferProducer->asBinder(); 
        window = new Surface(bufferProducer, /*controlledByApp*/ true); 
    } 
    return setPreviewWindow(binder, window); 
}
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

ANativeWindow顾名思义“本地窗口”,Surface类继承了ANativeWindow类。按照网上的说法,ANativeWindow类是连接OpenGL和android窗口系统的桥梁,即OpenGL需要通过ANativeWindow类来间接地操作Android窗口系统。但我们接下来要操作ANativeWindow的不是OpenGL,而是CameraClient

status_t CameraClient::setPreviewWindow(const sp<IBinder>& binder, 
        const sp<ANativeWindow>& window) {
    if (window != 0) { 
        result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA); 
        if (result != NO_ERROR) { 
            ALOGE("native_window_api_connect failed: %s (%d)", strerror(-result), 
                    result); 
            return result; 
        } 
    } 

    // If preview has been already started, register preview buffers now. 
    if (mHardware->previewEnabled()) { 
        if (window != 0) { 
            native_window_set_scaling_mode(window.get(), 
                    NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 
            native_window_set_buffers_transform(window.get(), mOrientation); 
            result = mHardware->setPreviewWindow(window); 
        } 
    } 
    return result; 
}
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
/** Set the ANativeWindow to which preview frames are sent */ 
status_t setPreviewWindow(const sp<ANativeWindow>& buf) 
{ 
    mPreviewWindow = buf; 
    mHalPreviewWindow.user = this; 
    return mDevice->ops->set_preview_window(mDevice, 
               buf.get() ? &mHalPreviewWindow.nw : 0); 
}
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

ANativeWindow最终保存在mPreviewWindow变量中,而传到Hal层的则是mHalPreviewWindow.nw 操作集,Hal层将通过它来间接的操作mPreviewWindow。

appappCamera.javaCamera.javaandroid_hardware_Camera.cppandroid_hardware_Camera.cppCamera.cppCamera.cppCameraClient.cppCameraClient.cppCameraHardwareInterface.hCameraHardwareInterface.hsetPreviewDisplaysetPreviewSurfacesetPreviewTargetsetPreviewTargetsetPreviewWindowsetPreviewWindow

mDevice就是上篇博文Camera打开流程中最后讲到的从Hal返回的mDevice对象,而它的ops指针指向的是gCameraDevOps结构体,从这里开始进入Hal层

3.2 Hal层

gCameraDevOps就在Cam1Device.cpp中定义


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值