Android Camera 系统 imx代码

2023-10-11 01:38
文章标签 代码 android 系统 camera imx

本文主要是介绍Android Camera 系统 imx代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. Overview

1.1 物理架构

1.2 Android架构

2. CameraService

3. HAL

4. Overlay

5. Video for Linux


1. Overview

 本文以Freescale IMX为例剖析camera摄像头的系统架构。

 

1.1 物理架构

 硬件方面,camera系统分为主控制器和摄像头设备,功能上主要有preview预览,takePicture拍照和recording录像。

1) IPU - Image Process Unit 图像处理单元,用于控制摄像机和显示屏。

2)图像采集 - 由camera采集的图像数据信息通过IPU的CSI接口控制。

3)DMA映射到内存 - IPU将采集到得数据通过DMA映射到一段内存。

4)队列机制 - 为了更高效地传送数据,将内存中的数据取出加入一队列,并传送到另一队列。

5)视频输出 - 将视频数据从队列中取出,通过IPU控制这段独立显存,最终将视频显示出来。

 

1.2 Android架构

Android的camera系统架构自上而下分别为应用层-框架层-硬件抽象层-linux驱动层。

1) APP - Framework

应用层与java框架层的间主要由Binder机制进行通信。

系统初始化时会开启一个CameraService的守护进程,为上层应用提供camera对的功能接口。

2) Framework - HAL

框架层与硬件抽象层间通过回调函数传递数据。

3) Overlay

Overlay层由ServiceFlinger和OverlayHal组成,实现视频输出功能,只有camera框架层或者视频框架层能调用它,上层无法直接调用。

4) HAL - driver

抽象层位于用户空间,通过系统调用如open(),read(),ioctl()等与内核空间进行数据传递。

 

2 CameraService

 Camera的主要功能有取景Preview,拍照takePicture和摄影Recording,下文以取景为例,剖析camera系统架构。

 

要实现取景Preview功能,主要须调用CameraService::Client::startPreview()和CameraService::Client::setOverlay(),前者通过mHardware->startPreview();调用cameraHal硬件抽象层以实现取景的整个流程,后者通过mSurface->createOverlay();调用surfaceFlinger层创建overlay_object对象。

 

3 HAL

 

startPreview主要完成三项任务,配置图象,配置内存,开启两个存取buf队列的线程。

1) cameraPreviewConfig()配置预览图象参数

CameraOpen() - 通过打开设备节点/dev/video0得以由系统接口与设备驱动交互。

S_FMT - ioctl()的指令,设置图象像素格式,将数据由硬件抽象层传递至Linux驱动,这里也就是v4l2。

G_FMT - 得到图象像素格式,将数据由底层驱动v4l2返回至硬件抽象层。

S_PARM - 设置模式的指令,这个指令传到底层后,将会实现对camera硬件的控制。

2) cameraPreviewStart()开启预览,实际上配置了内存

REQBUFS - 申请内存,通过dma_alloc_coherent()为camera申请一端连续的dma内存。

QUERYBUF - 询问内存,将申请到内存的物理地址,虚拟地址等数据从内核空间传递到用户空间。

QBUF - 加入队列,将通过询问得到的buf加入一个队列。

3) PreviewShowFrameThread()和PreviewShowFrameThread()

PreviewCaptureFrameThread()捕捉一帧数据的线程,通过DQBUF,从队列中取出一个buf数据,这里,一个buf即一帧数据即一张图片。注意,如果camera没有采集到图片,这个线程会在DQBUF阻塞。

PreviewShowFrameThread()显示一帧数据的线程。

mDataCb() - 回调函数,将采集到的图象数据传回CameraService,再由CameraService传递给上层应用。

mOverlay->dequeueBuffer() - 调用Overlay层,从Overlay层得到一个空闲的overlaybuffer,将图象数据拷贝到这个buffer里。至于这个buffer后续的工作,即视频输出,则交给了Overlay去完成。

QUERYBUF & QBUF - 由于已经从队列里取出了一个buf,需要再询问并加入另一个buf到队列里。

4) Overlay

CameraService::Client::startPreview()完成mHardware->startPreview();后便去执行CameraService::Client::setOverlay(),如果没有任何overlay,则创建一个新的,通过mHardware->setOverlay(new Overlay(mOverlayRef))调用到SurfaceFlinger层,再由overlay_dev->createOverlay();调用到overlay的硬件抽象层,抽象层创建并初始化overlay对象,与cameraHal类似,通过ioctl()指令与底层v4l2通信,配置视频参数和内存空间。随后开启一个overlay线程,用于存取队列中的视频数据。

注意,SurfaceFlinger里也会开启一个处理overlay的surfaceFlinger线程,用于等待用户事件,作相应的overlay控制。

 

5 Video for Linux

 

v4l2 - video for linux 2是linux为视频驱动抽象出的一层统一的接口,数据结构如下,

v4l2作为master主设备由(*attach)与camera从设备进行绑定。

初始化函数probe()如下,

1) init_camera_struct()初始化v4l2主设备的数据结构,实现open(), read(), ioctl(), mmap()等操作。

2) v4l2_int_device_register(),注册v4l2主设备,绑定camera从设备。

3) video_register_device()注册linux video设备,建立/dev/video0设备节点。

这篇关于Android Camera 系统 imx代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/184589

相关文章

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

MySQL进行数据库审计的详细步骤和示例代码

《MySQL进行数据库审计的详细步骤和示例代码》数据库审计通过触发器、内置功能及第三方工具记录和监控数据库活动,确保安全、完整与合规,Java代码实现自动化日志记录,整合分析系统提升监控效率,本文给大... 目录一、数据库审计的基本概念二、使用触发器进行数据库审计1. 创建审计表2. 创建触发器三、Java

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序