@ltlovezh
2020-06-20T10:41:49.000000Z
字数 1668
阅读 1229
Camera
CameraService
是在独立进程运行的Camera服务,负责获取Camera信息,操作某个Camera实例.
通过Camera.open
打开指定摄像头,Java层会返回一个Camera对象,在Native层对应一个Camera对象,它实现了ICameraClient
IPC接口,用于从服务端接收回调。
Native层客户端Camera对象,也有一个对应的服务端对象CameraClient
,它实现了ICamera
IPC接口,接收客户端的请求,然后通过CameraHardwareInterface
操作一个Camera HAL设备(camera_device_t
)。
CameraClient
表示服务端一个Camera实例,内部持有一个CameraHardwareInterface
对象,该对象通过camera_device_t *mDevice
属性与一个Camera HAL物理设备进行交互。
通过Camera.setPreviewTexture
设置预览的SurfaceTexture
,通过下面的调用链一直设置到Camera HAL物理设备中(camera_device_t),用来接收Camera预览视频帧。
其中,native_window_api_connect
函数表示连接到ANativeWindow(Surface),参数NATIVE_WINDOW_API_CAMERA
指明是通过Camera向ANativeWindow生产图像数据。向ANativeWindow填充图像数据有几下几种方式:
// parameter for NATIVE_WINDOW_[API_][DIS]CONNECT
// 不同的图像数据生产方式
enum {
/* Buffers will be queued by EGL via eglSwapBuffers after being filled using OpenGL ES. 通过OpenGL生产图像数据
*/
NATIVE_WINDOW_API_EGL = 1,
/* Buffers will be queued after being filled using the CPU 这种情况下,会获取一个目标地址,可以把图像数据copy到目标地址
*/
NATIVE_WINDOW_API_CPU = 2,
/* Buffers will be queued by Stagefright after being filled by a video decoder. The video decoder can either be a software or hardware decoder. 通过解码器生成图像数据,MediaCodec解码到Surface就是这种方式
*/
NATIVE_WINDOW_API_MEDIA = 3,
/* Buffers will be queued by the the camera HAL. 通过Camera生成图像数据
*/
NATIVE_WINDOW_API_CAMERA = 4,
};
通过Camera.setDisplayOrientation
设置顺时针旋转角度,首先利用CameraClient::getOrientation
函数把旋转角度和镜像问题转换为Transform Flag
,然后把Transform Flag
设置到ANativeWindow(Surface)。
CameraClient::getOrientation根据旋转角度和是否镜像,生成一个
Transform Flag
。
GLConsumer::computeTransformMatrix根据Transform Flag
,生成一个作用于纹理的4*4的变换矩阵。
两个函数一正一反,相互配合,实现了Transform处理逻辑。