Android 5.0 Camera系统源码分析(2):Camera打开流程
- 格式:pdf
- 大小:217.74 KB
- 文档页数:20
andriod之摄像头驱动流程camera成像原理:景物通过镜头⽣产光学图像投射到sensor表⾯上,然后转为模拟电信号,经过数模变成数字图像信号,在经过DSP加⼯出来,然后在通过IO 接⼝传输到CPU处理。
由于摄像头满⾜总线、驱动、设备模型,那么看看andorid是怎么去实现摄像头的流程。
1. 注册Camera的platform平台设备点击(此处)折叠或打开1. CAMERA_HW_i2C_init2. platform_driver_register(&g_stCAMERA_HW_Driver)3. static struct platform_driver g_stCAMERA_HW_Driver = {4. .probe = CAMERA_HW_probe,5. .remove = CAMERA_HW_remove,6. .suspend = CAMERA_HW_suspend,7. .resume = CAMERA_HW_resume,8. .driver = {9. .name = "image_sensor",10. .owner = THIS_MODULE,11. }12. };2. 注册Camera的platform平台设备驱动点击(此处)折叠或打开1. platform_device_register(&sensor_dev);2. static struct platform_device sensor_dev = {3. .name = "image_sensor",4. .id = -1,5. };在在mt6575_board_init这个函数中注册了很多平台设备,包括上⾯的平台设备。
camera的平台设备与平台驱动匹配后,就会调⽤drv的probe函数,其probe函数主要完成的是i2c平台驱动的注册点击(此处)折叠或打开1. static int CAMERA_HW_probe(struct platform_device *pdev)2. {3. return i2c_add_driver(&CAMERA_HW_i2c_driver);4. }5. struct i2c_driver CAMERA_HW_i2c_driver = {6. .probe = CAMERA_HW_i2c_probe,7. .remove = CAMERA_HW_i2c_remove,8. .detect = CAMERA_HW_i2c_detect,9. = CAMERA_HW_DRVNAME,10. .id_table = CAMERA_HW_i2c_id,11. .address_data = &addr_data,12. };怎么去做i2c驱动与设备的匹配呢?内核中对于这块有详细的讲解,⽂件为instantiating-devices,现在i2c的平台驱动已经注册了,下⾯来分析下是怎么注册平台设备的。
深⼊理解Android5源代码深⼊理解Android 5 源代码1 Android系统介绍1.1 Android系统成功的秘诀1.1.1 获取了业界的⼴泛⽀持1.1.2 研发阵容强⼤1.1.3 为开发⼈员“精⼼定制”1.1.4 开源1.2 剖析Android系统架构1.2.1 底层操作系统层(OS)1.2.2 各种库(Libraries)和Android运⾏环境(RunTime)1.2.3 ApplicationFramework(应⽤程序框架)1.2.4 顶层应⽤程序(Application)1.3 五⼤组件1.3.1 Activity界⾯1.3.2 Intent和IntentFilters切换1.3.3 Service(服务)1.3.4 BroadcastReceiver发送⼴播1.3.5 ⽤ContentProvider存储数据1.4 进程和线程1.4.1 什么是进程1.4.2 什么是线程2 获取并编译Android源代码2.1 获取Android源代码2.1.1 在Linux系统中获取Android源代码2.1.2 在Windows平台获取Android源代码2.2 分析Android源代码结构2.2.1 总体结构2.2.2 应⽤程序部分2.2.3 应⽤程序框架部分2.2.4 系统服务部分2.2.5 系统程序库部分2.2.6 硬件抽象层部分2.3 Android源代码提供的接⼝2.3.1 暴露接⼝和隐藏接⼝2.3.2 调⽤隐藏接⼝2.4 编译源代码2.4.1 搭建编译环境2.4.2 在模拟器中运⾏2.5 编译源代码⽣成SDK3 分析Java Native Interface系统3.1 JNI基础3.1.1 JNI的功能结构3.1.2 JNI的调⽤层次3.1.3 分析JNI的本质3.2 分析MediaScanner3.2.1 分析Java层3.2.2 分析JNI层3.2.3 分析Native(本地)层3.3 分析Camera系统的JNI3.3.1 Java层预览接⼝3.3.2 注册预览的JNI函数3.3.3 C/C++层的预览函数4 分析HAL系统4.1 HAL基础4.1.1 推出HAL的背景4.1.2 HAL的基本结构4.2 分析HAL module架构4.2.1 hw_module_t4.2.2 结构hw_module_methods_t的定义4.2.3 hw_device_t结构4.3 分析⽂件hardware.c4.3.1 寻找动态链接库的地址4.3.2 数组variant_keys4.3.3 载⼊相应的库4.3.4 获得hw_module_t结构体4.4 分析硬件抽象层的加载过程4.5 分析硬件访问服务4.5.1 定义硬件访问服务接⼝4.5.2 具体实现4.6 分析Android官⽅实例4.6.1 获取实例⼯程源代码4.6.2 直接调⽤Service⽅法的实现代码4.6.3 通过Manager调⽤Service的实现代码4.7 HAL和系统移植4.7.1 移植各个Android部件的⽅式4.7.2 设置设备权限4.7.3 init.rc初始化4.7.4 ⽂件系统的属性5 分析IPC通信机制5.1 Binder机制概述5.2 分析Binder驱动程序5.2.1 分析数据结构5.2.2 分析设备初始化5.2.3 打开Binder设备⽂件5.2.4 内存映射5.2.5 释放物理页⾯5.2.6 分配内核缓冲区5.2.7 释放内核缓冲区5.2.8 查询内核缓冲区5.3 Binder封装库5.3.1 类BBinder5.3.2 类BpRefBase5.3.3 类IPCThreadState5.4 初始化Java层Binder框架5.5 分析MediaServer的通信机制5.5.1 MediaServer的⼊⼝函数5.5.2 ProcessState5.5.3 defaultServiceManager5.5.4 注册MediaPlayerService5.5.5 分析StartThread Pool和join Thread Pool6 分析Binder对象和Java接⼝6.1 分析实体对象(binder_node)6.2 分析本地对象(BBinder)6.3 分析引⽤对象(binder_ref)6.4 分析代理对象(BpBinder)6.5 分析Java接⼝6.5.1 获取Service Manager6.5.2 分析ActivityManagerService的Java层7 分析ServiceManager和MessageQueue 7.1 分析ServiceManager7.1.1 分析主⼊⼝函数7.1.2 打开Binder设备⽂件7.1.3 注册处理7.1.4 创建Binder实体对象7.1.5 尽职的循环7.1.6 将信息注册到ServiceManager7.1.7 分析MediaPlayerService和Client7.2 获得Service Manager接⼝7.3 分析MessageQueue7.3.1 创建MessageQueue7.3.2 提取消息7.3.3 分析函数nativePollOnce8 init进程和Zygote进程8.1 分析init进程8.1.1 分析⼊⼝函数8.1.2 分析配置⽂件8.1.3 分析Service8.1.4 解析on字段的内容8.1.5 init控制Service8.1.6 控制属性服务8.2 分析Zygote(孕育)进程8.2.1 Zygote基础8.2.2 分析Zygote的启动过程9 System进程和应⽤程序进程9.1 分析System进程9.1.1 启动System进程前的准备⼯作9.1.2 分析SystemServer9.1.3 分析EntropyService9.1.4 分析DropBoxManagerService9.1.5 分析DiskStatsService9.1.6 分析DeviceStorageManagerService(监测系统内存存储空间的状态)9.1.7 分析SamplingProfilerService9.2 分析应⽤程序进程9.2.1 创建应⽤程序9.2.2 启动线程池9.2.3 创建信息循环10 分析Activity组件10.1 Activity基础10.1.1 Activity状态10.1.2 剖析Activity中的主要函数10.2 分析Activity的启动源代码10.2.1 Launcher启动应⽤程序10.2.2 返回ActivityManagerService的远程接⼝10.2.3 解析intent的内容10.2.4 分析检查机制10.2.5 执⾏Activity组件的操作10.2.6 将Launcher推⼊Paused状态10.2.7 处理消息10.2.8 暂停完毕10.2.9 建⽴双向连接10.2.10 启动新的Activity10.2.11 通知机制10.2.12 发送消息11 应⽤程序管理服务——PackageManagerService分析11.1 PackageManagerService概述11.2 系统进程启动11.3 开始运⾏11.4 扫描APK⽂件11.5 解析并安装⽂件11.6 启动系统默认Home应⽤程序Launcher11.6.1 设置系统进程11.6.2 启动Home应⽤程序11.6.3 启动uncher11.6.4 加载应⽤程序11.6.5 获得Activity12 Content Provider存储机制12.1 Content Provider基础12.1.1 ContentProvider在应⽤程序中的架构12.1.2 ContentProvider的常⽤接⼝12.2 启动Content Provider12.2.1 获得对象接⼝12.2.2 存在校验12.2.3 启动Android应⽤程序12.2.4 根据进程启动Content Provider 12.2.5 处理消息12.2.6 具体启动12.3 Content Provider数据共享12.3.1 获取接⼝12.3.2 创建CursorWindow对象12.3.3 数据传递12.3.4 处理进程通信的请求12.3.5 数据操作13 分析⼴播机制源代码13.1 Broadcast基础13.2 发送⼴播信息13.2.1 intent描述指⽰13.2.2 传递⼴播信息13.2.3 封装传递13.2.4 处理发送请求13.2.5 查找⼴播接收者13.2.6 处理⼴播信息13.2.7 检查权限13.2.8 处理的进程通信请求13.3 分析BroadCastReceiver13.3.1 MainActivity的调⽤13.3.2 注册⼴播接收者13.3.3 获取接⼝对象13.3.4 处理进程间的通信请求14 分析电源管理系统14.1 Power Management架构基础14.2 分析Framework层14.2.1 ⽂件PowerManager.java14.2.2 提供PowerManager功能14.3 JNI层架构分析14.3.1 定义了两层之间的接⼝函数14.3.2 与Linux Kernel层进⾏交互14.4 Kernel(内核)层架构分析14.4.1 ⽂件power.c14.4.2 ⽂件earlysuspend.c14.4.3 ⽂件wakelock.c14.4.4 ⽂件resume.c14.4.5 ⽂件suspend.c14.4.6 ⽂件main.c14.4.7 proc⽂件14.5 wakelock和early_suspend14.5.1 wakelock的原理14.5.2 early_suspend的原理14.5.3 Android休眠14.5.4 Android唤醒14.6 Battery电池系统架构和管理14.6.1 实现驱动程序14.6.2 实现JNI本地代码14.6.3 Java层代码14.6.4 实现Uevent部分14.7 JobScheduler节能调度机制14.7.1 JobScheduler机制的推出背景14.7.2 JobScheduler的实现14.7.3 实现操作调度14.7.4 封装调度任务15 分析WindowManagerService系统15.1 WindowManagerService基础15.2 计算Activity窗⼝的⼤⼩15.2.1 实现View遍历15.2.2 函数relayoutWindow15.2.3 函数relayoutWindow15.2.4 拦截消息的处理类15.2.5 判断是否计算过16 分析电话系统16.1 Android电话系统详解16.1.1 电话系统简介16.1.2 电话系统结构16.1.3 驱动程序介绍16.1.4 RIL接⼝16.1.5 分析电话系统的实现流程16.2 电话系统中的⾳频模块16.2.1 ⾳频系统结构16.2.2 分析⾳频系统的层次16.3 分析拨号流程16.3.1 拨号界⾯16.3.2 实现Phone应⽤16.3.3 Call通话控制16.3.4 静态⽅法调⽤16.3.5 通话管理16.3.6 dial拨号16.3.7 状态跟踪16.3.8 RIL消息“出/⼊”⼝16.3.9 显⽰通话主界⾯17 分析短信系统17.1 短信系统的主界⾯17.2 发送普通短信17.3 发送彩信17.4 接收短信17.4.1 Java应⽤层的接收流程17.4.2 Framework层的处理过程18 Sensor传感器系统详解18.1 Android传感器系统概述18.2 Java层详解18.3 Frameworks层详解18.3.1 监听传感器的变化18.3.2 注册监听18.4 JNI层详解18.4.1 实现Native(本地)函数18.4.2 处理客户端数据18.4.3 处理服务端数据18.4.4 封装HAL层的代码18.4.5 处理消息队列18.5 HAL层详解19 分析SEAndroid系统19.1 SEAndroid概述19.1.1 内核空间19.1.2 ⽤户空间19.2 ⽂件安全上下⽂19.2.1 设置打包在ROM⾥⾯的⽂件的安全上下⽂19.2.2 设置虚拟⽂件系统的安全上下⽂19.2.3 设置应⽤程序数据⽂件的安全上下⽂19.3 进程安全上下⽂19.3.1 为独⽴进程静态地设置安全上下⽂19.3.2 为应⽤程序进程设置安全上下⽂20 分析ART系统20.1 对⽐Dalvik VM和ART20.2 启动ART20.2.1 运⾏app_process进程20.2.2 准备启动20.2.3 创建运⾏实例20.2.4 注册本地JNI函数20.2.5 启动守护进程20.2.6 解析参数20.2.7 初始化类、⽅法和域20.3 分析主函数main20.4 查找⽬标类20.4.1 函数LookupClass()20.4.2 函数DefineClass()20.4.3 函数InsertClass()20.4.4 函数LinkClass()20.5 类操作20.6 实现托管操作20.7 加载OAT⽂件20.7.1 产⽣OAT20.7.2 创建ART虚拟机20.7.3 解析启动参数并创建堆20.7.4 ⽣成指定⽬录⽂件20.7.5 加载OAT⽂件20.7.6 解析字段思维导图防⽌博客图床图⽚失效,防⽌图⽚源站外链:思维导图在线编辑链接:。
【Android】AndroidCamera实时数据采集及通过MediaCodec硬编码编。
吐槽: 其实常⽤流程都差不多,但是有时候还是会忘记某⼀步的详细⽤法,但是各位朋友请注意,官⽅已经不推荐Camera类的使⽤(现在是android.hardware.camera2),但⽆奈公司项⽬之前是使⽤Camera类实现的,并且Camera2貌似是基于API 21以上的,这Android 7的风声都放出来了,可是6.0现在出了3个多⽉了市场占有率也才貌似3%不到,什么时候才能有个标准化和统⼀规范,作为⼀名Android开发者实属不易啊,叹⽓~Android实现摄像头实时数据采集及通过硬编码编码数据的流程:/** 编码器获取数据,编码,编码后的数据的处理等⼤致流程如下:*//* 1.获取原始帧 */@OverrideonPreviewFrame( byte[] onPreviewData, Camera camera) {/* 在此可以对onPreviewData进⾏Rotate或者Scale* 也可以转换yuv的格式,例如yuv420P(YV12)或者yuv420SP(NV21/NV12)* 相关开源类库可以使⽤libyuv/ffmpeg等*/getRawFrame(onPreviewData)/* 然后将onPreviewData加⼊Camera回调*/addCallbackBuffer(onPreviewData);}private void getRawFrame( byte[] rawFrame ) { encodFrame(rawFrame); }/* 2.进⾏编码 */private byte[] encodFrame(byte[] inputData) { return encodedData; }/* 3.取得编码后的数据便可进⾏相应的操作,可以保存为本地⽂件,也可进⾏推流 */Operation ? Send(byte[] sendData) : Save(byte[] saveData)上述代码onPreviewFrame为Camera类的接⼝,使⽤Camera前需要进⾏SurfaceView及SurfaceHolder的初始化及相应interface的实现:// init the preview surfaceprivate void initview() {SurfaceView surfaceView = (SurfaceView) findViewById(R.id.record_surface);SurfaceHolder surfaceHolder = surfaceView.getHolder();surfaceHolder.addCallback(this);surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);}@Overridepublic void surfaceCreated(SurfaceHolder holder) {openCamera(holder); // 开启相机}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {releaseCamera(); // 在surfaceDestroyed的时候记得releaseCamera}private void openCamera(SurfaceHolder holder) {releaseCamera();try {camera = getCamera(Camera.CameraInfo.CAMERA_FACING_BACK); // 根据需求选择前/后置摄像头} catch (Exception e) {camera = null;if (AppContext.isDebugMode) {e.printStackTrace();}}if(mCamera != null){try {mCamera.setPreviewCallback(this);mCamera.setDisplayOrientation(90); // 此⽅法为官⽅提供的旋转显⽰部分的⽅法,并不会影响onPreviewFrame⽅法中的原始数据;if(parameters == null){parameters = mCamera.getParameters();}parameters.setPreviewFormat(ImageFormat.NV21); // 常⽤格式:NV21 / YV12parameters.setPreviewSize(width, height); // 还可以设置很多相机的参数,但是建议先遍历当前相机是否⽀持该配置,不然可能会导致出错;mCamera.setParameters(parameters);mCamera.setPreviewDisplay(holder);mCamera.startPreview();} catch (IOException e) {e.printStackTrace();}}}@TargetApi(9)private Camera getCamera(int cameraType) {Camera camera = null;try {camera = Camera.open(cameraType);} catch (Exception e) {e.printStackTrace();}return camera; // returns null if camera is unavailable}private synchronized void releaseCamera() {if (camera != null) {try {camera.setPreviewCallback(null);} catch (Exception e) {e.printStackTrace();}try {camera.stopPreview();} catch (Exception e) {e.printStackTrace();}try {camera.release();} catch (Exception e) {e.printStackTrace();}camera = null;}}MediaCodec硬编码实现部分:此处推荐参考SRS开源项⽬中的实现⽅法:// video device.private Camera camera;private MediaCodec vencoder;private MediaCodecInfo vmci;private MediaCodec.BufferInfo vebi;private byte[] vbuffer;// video camera settings.private Camera.Size vsize;private int vcolor;private int vbitrate_kbps = 300;private final static int VFPS = 20;private final static int VGOP = 5;private final static int VWIDTH = 640;private final static int VHEIGHT = 480;/* ⾸先需要初始化MediaCodec的配置 */private void initMediaCodec() {// choose the right vencoder, perfer qcom then google.vcolor = chooseVideoEncoder();// vencoder yuv to 264 es stream.// requires sdk level 16+, Android 4.1, 4.1.1, the JELLY_BEANtry {vencoder = MediaCodec.createByCodecName(vmci.getName());} catch (IOException e) {Log.e(TAG, "create vencoder failed.");e.printStackTrace();return;}vebi = new MediaCodec.BufferInfo();// setup the vencoder.// @see https:///reference/android/media/MediaCodec.htmlMediaFormat vformat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, vsize.width, vsize.height); vformat.setInteger(MediaFormat.KEY_COLOR_FORMAT, vcolor);vformat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 0);vformat.setInteger(MediaFormat.KEY_BIT_RATE, 1000 * vbitrate_kbps);vformat.setInteger(MediaFormat.KEY_FRAME_RATE, VFPS);vformat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, VGOP);Log.i(TAG, String.format("vencoder %s, color=%d, bitrate=%d, fps=%d, gop=%d, size=%dx%d",vmci.getName(), vcolor, vbitrate_kbps, VFPS, VGOP, vsize.width, vsize.height));// the following error can be ignored:// 1. the storeMetaDataInBuffers error:// [OMX.qcom.video.encoder.avc] storeMetaDataInBuffers (output) failed w/ err -2147483648// @see /mediacodec/#q12vencoder.configure(vformat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);vencoder.start();}// for the vbuffer for YV12(android YUV), @see below://https:///reference/android/hardware/Camera.Parameters.html#setPreviewFormat(int)//https:///reference/android/graphics/ImageFormat.html#YV12private int getYuvBuffer(int width, int height) {// stride = ALIGN(width, 16)int stride = (int) Math.ceil(width / 16.0) * 16;// y_size = stride * heightint y_size = stride * height;// c_stride = ALIGN(stride/2, 16)int c_stride = (int) Math.ceil(width / 32.0) * 16;// c_size = c_stride * height/2int c_size = c_stride * height / 2;// size = y_size + c_size * 2return y_size + c_size * 2;}// choose the video encoder by name.private MediaCodecInfo chooseVideoEncoder(String name, MediaCodecInfo def) {int nbCodecs = MediaCodecList.getCodecCount();for (int i = 0; i < nbCodecs; i++) {MediaCodecInfo mci = MediaCodecList.getCodecInfoAt(i);if (!mci.isEncoder()) {continue;}String[] types = mci.getSupportedTypes();for (int j = 0; j < types.length; j++) {if (types[j].equalsIgnoreCase(VCODEC)) {//Log.i(TAG, String.format("vencoder %s types: %s", mci.getName(), types[j]));if (name == null) {return mci;}if (mci.getName().contains(name)) {return mci;}}}}return def;}// choose the right supported color format. @see below://https:///reference/android/media/MediaCodecInfo.html//https:///reference/android/media/MediaCodecInfo.CodecCapabilities.htmlprivate int chooseVideoEncoder() {// choose the encoder "video/avc":// 1. select one when type matched.// 2. perfer google avc.// 3. perfer qcom avc.vmci = chooseVideoEncoder(null, null);//vmci = chooseVideoEncoder("google", vmci);//vmci = chooseVideoEncoder("qcom", vmci);int matchedColorFormat = 0;MediaCodecInfo.CodecCapabilities cc = vmci.getCapabilitiesForType(VCODEC);for (int i = 0; i < cc.colorFormats.length; i++) {int cf = cc.colorFormats[i];Log.i(TAG, String.format("vencoder %s supports color fomart 0x%x(%d)", vmci.getName(), cf, cf));// choose YUV for h.264, prefer the bigger one.// corresponding to the color space transform in onPreviewFrameif ((cf >= cc.COLOR_FormatYUV420Planar && cf <= cc.COLOR_FormatYUV420SemiPlanar)) {if (cf > matchedColorFormat) {matchedColorFormat = cf;}}}for (int i = 0; i < cc.profileLevels.length; i++) {MediaCodecInfo.CodecProfileLevel pl = cc.profileLevels[i];Log.i(TAG, String.format("vencoder %s support profile %d, level %d", vmci.getName(), pl.profile, pl.level));}Log.i(TAG, String.format("vencoder %s choose color format 0x%x(%d)", vmci.getName(), matchedColorFormat, matchedColorFormat));return matchedColorFormat;} 上述代码为SRS的部分实现,仅作参考。
AndroidCamera详解相关的类1. android.hardware.camera22. Camera3. SurfaceView---这个类⽤于向⽤户呈现实时相机预览。
4. MediaRecorder---这个类⽤于从摄像机录制视频。
5. Intent---MediaStore.ACTION_IMAGE_CAPTURE或MediaStore.ACTION_VIDEO_CAPTURE可⽤于捕获图像或视频,⽽⽆需直接使⽤Camera对象。
清单声明在使⽤Camera API开始开发应⽤程序之前,应确保您的清单具有适当的声明,以允许使⽤相机硬件和其他相关功能。
相机权限 - 您的应⽤程序必须请求使⽤设备相机的权限。
<uses-permission android:name="android.permission.CAMERA" />注意:如果您通过调⽤现有的摄像头应⽤程序来使⽤摄像头,则应⽤程序不需要请求此权限。
相机功能 - 您的应⽤程序还必须声明使⽤相机功能,例如:<uses-feature android:name="android.hardware.camera" />存储权限 - 如果应⽤程序将图像或视频保存到设备的外部存储设备(SD卡),则还必须在清单中指定此选项。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />⾳频录制权限 - 对于使⽤视频捕获录制⾳频,应⽤程序必须请求获取⾳频捕获权限。
<uses-permission android:name="android.permission.RECORD_AUDIO" />创建⾃定义摄像头为应⽤程序创建⾃定义摄像头界⾯的⼀般步骤如下:1. 检测和访问摄像机 - 创建代码以检查摄像机是否存在并请求访问。
Android Camera分析androidcamera分析完整讲解了android中camera的工作机制,代码分析。
对了解整个android工作流程会有很大的帮助。
android的camera系统分析一、camera构架分析android的camera涵盖取景(preview)和摄制照片(takepicture)的功能。
目前android公布版的camera程序虽然功能比较简单,但是其程序的架构分为客户端和服务器两个部分,它们创建在android的进程间通讯binder的结构上。
android中camera模块同样遵从andorid的框架,如下图右图cameraarchitecturecamera模块主要包含了libandroid_runtime.so、libui.so和libcameraservice.so 等几个库文件,它们之间的调用关系如下所示:在camera模块的各个库中,libui.so坐落于核心的边线,它对上层的提供更多的USB主要就是camera类。
libcameraservice.so是camera的server程序,它通过继承libui.so中的类实现server的功能,并且与libui.so中的另外一部分内容通过进程间通讯(即binder机制)的方式进行通讯。
libandroid_runtime.so和libui.so两个库就是公用的,其中除了camera除了其他方面的功能。
整个camera在运转的时候,可以大致上分为client和server两个部分,它们分别在两个进程中运转,它们之间采用binder机制同时实现进程间通讯。
这样在client调用USB,功能则在server中同时实现,但是在client中调用就似的轻易调用server中的功能,进程间通讯的部分对上层程序不可知。
从框架结构上来看,源码中icameraservice.h、icameraclient.h和icamera.h三个类定义了meidaplayer的接口和架构,icameraservice.cpp和camera.cpp两个文件则用于camera架构的实现,camera的具体功能在下层调用硬件相关的接口来实现。
AndroidCamera系统架构源码分析(1)系统:MTK Android4.4日期:2015年10月10日stamp&data setParameters Utils::Property::tryGet一. 前述之前对MTK的Camera的源码流程有过初步的了解,现在对以前了解的东西做一些梳理总结,但也仅是对源码流程一个贯穿,并不会对其进行深入分析,方便日后工作需求做一个铺垫。
此文分析的是Camera系统源码,即Frameworks层之后的,并不是APK的源码分析。
二. 分析思路1. 先从Camera的初始化开始,以cameraID为线索,简单地从Frameworks开始贯穿到底层。
主要任务Camera如何被打开的,完成源码的贯穿。
2. 然后再从startPreview开始去了解,Camera被打开之后,取出的数据流是什么,数据流经过了怎么的处理,然后又是怎么被送出到APK,显示出来的三. 上层入口针对于上面的两个分析点,从APK上层入口开始:private Camera mCamera;mCamera = Camera.open(cameraID);mCamera.startPreview();四. Camera 初始化化 Open(1) 文件列表:Camera.java: frameworks/base/core/java/android/hardwareandroid_hardware_Camera.cpp: frameworks/base/core/jniCamera.cpp: frameworks/av/cameraCameraBase.cpp: frameworks/av/cameraCameraService.cpp:frameworks/av/services/camera/libcameraservicemodule.h: frameworks/hardware/mtkcam/moduleCamDeviceManagerBase.cppmediatek/hardward/mtkcam/devicemgrCameraClient.cppframeworks/av/services/camera/libcameraservice/api1 CameraHardwareInterface.h:frameworks/av/services/camera/libcameraservice/device(2) Frameworks层第一个被调用的是Camera.java文件里的open函数。
相机分析文档一.相机的基本知识现在的手机几乎都实现照相机功能了,而且在硬件的支持下像素也越来越高,在现实生活中的用途也越来越广,而在Android中专门提供了Camera 来处理相机相关的事件,Camera 是一个专门用来连接和断开相机服务的类,Camera 下面包括如下几个事件:Camera.AutoFocusCallback:自动调焦功能;Camera.ErrorCallback:错误信息捕捉;Camera.Parameters :相机的属性参数Camera.PictureCallback:拍照、产生图片时触发;Camera.PreviewCallback:相机预览设置;Camera.ShutterCallback:快门设置;Camera.Size:图片尺寸;要在Android中使用相机服务很简单,Camera没有构造方法,我们要使用它直接通过open()方法来打开相机设备,然后通过Camera.Parameters 对相机的一些属性进行设置,比如输出图片的格式、大小等等。
下面是Camera类一些常用的方法介绍。
Camera类的方法方法说明autoFocus 设置自动对焦getParameters 得到相机的参数open 启动相机服务release 释放Camera服务setPreviewDisplay 设置预览setParameters 设置预览参数startPreview 开始预览stopPreview 停止预览takePicture 拍照这里重点说明一下拍照的方法和使用,takePicture 方法要实现3个回调函数,分别是:Camera.ShutterCallback (快门) 和两个Camera.PictureCallback(图像数据)。
这里我们在拍照之后要取得图像数据就需要实现Camera.PictureCallback 的onPictureTaken 方法。
onPictureTaken 中第一个参数就是图像数据,第二个参数则是相机。
Android 5.0 Camera系统源码分析(1):CameraService启动流程1. 前言本文将分析Android系统源码,从frameworks层到hal层,暂不涉及app层和kernel层。
由于某些函数比较复杂,在贴出代码时会适当对其进行简化。
本文属于自己对源码的总结,仅仅是贯穿代码流程,不会深入分析各个细节。
分析android系统源码,需要对android系统的某些知识点有所了解2. frameworks层Android的各个子模块的启动都是从它们的Service的启动开始的,所以我们将从CameraService的启动开始分析。
CameraService的启动就在MediaServer的main函数中,代码路径在:frameworks/av/media/mediaserver/main_mediaserver.cpp[cpp] view plain copyint main(int argc __unused, char** argv){......CameraService::instantiate();......}CameraService类定义如下:[cpp] view plain copyclass CameraService :public BinderService<CameraService>,public BnCameraService,public IBinder::DeathRecipient,public camera_module_callbacks_t{static char const* getServiceName() { return "media.camera"; }......}mediaserver的main函数中调用了CameraService的instantiate函数来创建实例,该函数的实现在其父类BinderService中实现[cpp] view plain copytemplate<typename SERVICE>class BinderService{static status_t publish(bool allowIsolated = false) {sp<IServiceManager> sm(defaultServiceManager());return sm->addService(String16(SERVICE::getServiceName()),new SERVICE(), allowIsolated);}static void instantiate() { publish(); }}1. instantiate函数只是简单的调用了publish函数2. publish函数先构造CameraService,再通过addService函数将它注册到ServiceManager当中,而getServiceName函数获取到的值为“media camera”。
Android Camera 调用流程Android Camera的代码结构Android的Camera代码主要在以下的目录中:Camera的JAVA部分packages/apps/Camera/。
其中Camera.java是主要实现的文件。
这部分内容编译成为目标是Camera.apkcom.android.camera这个包,几个主要的类文件如下:PhotoViewer:GalleryPicker.java(所有图片集)--->ImageGallery.java(某个Folder下图片列表)--->ViewImage.java(看某张具体图片)VideoPlayer:GalleryPicker.java(所有视频集)--->MovieView.java(看某一个视频)Camera:Camera.java(Camera取景及拍照)VideoCamera:VideoCamera.java(VideoCamera取景及摄像)Camera的framework供上层应用调用的部分base/core/java/android/hardware/Camera.java这部分目标是framework.jarCamera的JNI部分frameworks/base/core/jni/android_hardware_Camera.cpp这部分内容编译成为目标是libandroid_runtime.so。
Camera UI库部分frameworks/base/libs/camera这部分的内容被编译成库libcamera_client.so。
Camera服务部分frameworks/base/services/camera/libcameraservic这部分内容被编译成库libcameraservice.so。
Camera HAL层部分hardware/msm7k/libcamera或vendor/qcom/android-open/libcamera2为了实现一个具体功能的Camera,在HAL层需要一个硬件相关的Camera库(例如通过调用video for linux驱动程序和Jpeg编码程序实现或者直接用各个chip厂商实现的私有库来实现,比如Qualcomm实现的libcamera.so和libqcamera.so),实现CameraHardwareInterface规定的接口,来调用相关的库,驱动相关的driver,实现对camera 硬件的操作。
camera打开流程(CameraApp---JNI)参考:⼀.Android Camera 运⾏流程的综述总体架构CameraService服务的注册client端的应⽤层到JNI层Camera App---JNIclient到service的连接HAL层驱动层1.总体架构Android Camera 框架从整体上看是⼀个 client/service 的架构,有两个进程:client 进程,可以看成是 AP 端,主要包括 JAVA 代码与⼀些 native c/c++代码;service 进程,属于服务端,是 native c/c++代码,主要负责和 linux kernel 中的 camera driver 交互,搜集 linuxkernel 中 cameradriver 传上来的数据,并交给显⽰系统显⽰。
client 进程与 service 进程通过 Binder 机制通信, client 端通过调⽤ service 端的接⼝实现各个具体的功能。
⼆.CameraService服务的注册SystemServer.java (frameworks\base\services\java\com\android\server)在systemsever⾥⾯注册很多服务,包括CameraServicestartOtherServicesmSystemServiceManager.startService(CameraService.class);Main_mediaserver.cpp (frameworks\av\media\mediaserver)mainCameraService::instantiate();可是我们到CameraService⽂件⾥⾯却找不到instantiate()这个函数,它在哪?继续追到它的⼀个⽗类BinderService,从以上定义可以看出CameraService 继承于BinderService,所以CameraService::instantiate(); 其实是调⽤BinderService中的instantiate。
CameraProvider启动流程分析CameraProvider是Android相机框架中的一个重要组件,它负责管理系统中可用的相机设备,并为应用程序提供访问相机功能的接口。
在本文中,我们将对CameraProvider的启动流程进行详细分析。
1. 创建CameraProvider实例:首先,应用程序需要通过CameraX的静态方法`CameraX.initialize(context)`来初始化CameraX库。
在初始化过程中,CameraX会创建一个全局的CameraProvider实例,用于管理系统中的相机设备。
2. 查询可用的相机设备:一旦CameraProvider实例创建完成,应用程序可以通过调用`CameraX.getCameraProvider(`方法来获取CameraProvider实例。
然后,应用程序可以调用CameraProvider的`getCameraIdList(`方法来获取系统中可用的相机设备的ID列表。
3. 创建相机实例:在获取到相机设备的ID列表后,应用程序可以通过调用CameraProvider的`bindToLifecycle(`方法来创建相机实例。
该方法需要传入一个LifecycleOwner对象,用于管理相机实例的生命周期。
4. 配置相机参数:一旦相机实例创建完成,应用程序可以通过调用相机实例的`getCameraControl(`方法来获取相机控制器实例。
然后,应用程序可以使用相机控制器实例来配置相机的各种参数,例如闪光灯模式、曝光模式、对焦模式等。
5. 启动预览:配置相机参数完成后,应用程序可以通过调用相机实例的`getCameraInfo(`方法来获取相机信息实例。
然后,应用程序可以使用相机信息实例来获取相机的预览输出目标,例如SurfaceTexture或SurfaceView。
最后,应用程序可以调用相机实例的`setPreviewSurface(`方法,将预览输出目标设置给相机实例,从而启动相机的预览功能。
androidcamera系统架构源码分析(5)写到第五篇,我们已经把大致的流程已经贯穿完了,还有很多东西没有讲,日后慢慢再说。
不过现在有一个重要的问题,就是整个流利里各种buf,provider,bufmgr,queue类等之间的关系,说白了就是buf类和buf辅助类之前的关系。
理清这些类的关系和这些类的作用,再从Buf流理解一下整个框架,CamAdapter和CamClient是怎么通过Buf联系,会对日后的分析有一个很大的帮助。
也相当于对本文的一个总结。
本来为了避免贴太多代码,想直接写中文总结的,后来发现贴代码虽然看得更辛苦一点,但细节更清晰,还是贴代码吧DisplayClient::onThreadLoop(Command const& rCmd){ // (0) lock Processor. //pImgBufQueue的实现在ImgBufQueue.cpp里spIImgBufQueue> pImgBufQueue; pImgBufQueue = mpImgBufQueue; /** (1) Prepare all TODO buffers. pImgBufQueue里有两个Buf队列mTodoImgBufQue 和mDoneImgBufQue 下面的函数用StreamImgBuf生成好ImgBufQueNode,把buf的标志位设为eSTATUS_TODO 后调用ImgBufQueue的enqueProcessor()把所有的Buf都放入到mTodoImgBufQue做接收数据的准备**/ prepareAllTodoBuffers(pImgBufQueue); // (2) Start 只是通知队列,不做任何队列的数据处理pImgBufQueue->startProcessor(); // (3) Do until disabled. while ( 1 ) { /**(.1) 在此处会ImgBufQueue的dequeProcessor()等待通知,并接收数据收到通知后,接收的是mDoneImgBufQue,一个ImgBufQueNode队列接收到队列后把整个mDoneImgBufQue传入handleReturnBuffers()中被处理handleReturnBuffers()首先会获得单个ImgBufQueNode中的IImgBuf,即最原始的Mem 接下来就是操作mem。
一、概述随着手机摄影的普及,拍照功能成为了手机应用中的一个重要组成部分。
在开发手机应用的过程中,我们经常需要使用相机拍照功能,并将拍摄的照片保存到相册中。
本文将介绍在Android评台上实现这一功能的代码流程。
二、初始化相机在使用相机拍照之前,我们需要先初始化相机,并设置一些基本的参数。
在Android评台上,我们可以使用Camera类来实现相机的初始化工作。
我们需要通过调用Camera.open()方法来打开相机,并获取到Camera实例。
我们可以通过调用Camera.getParameters()方法来获取相机的参数设置,并对相机的预览图像、拍照分辨率等进行配置。
我们通过调用Camera.setParameters()方法来将配置好的参数应用到相机中。
三、实现拍照功能一旦相机初始化完成,我们就可以开始实现拍照功能了。
在Android 评台上,我们可以通过调用Camera.takePicture()方法来实现拍照操作。
在调用该方法之前,我们需要先设置好拍照的一些参数,如拍照回调函数、拍照声音等。
当调用了Camera.takePicture()方法之后,相机会触发拍照操作,并将拍摄的照片数据通过拍照回调函数返回给我们。
四、保存照片到相册当我们拍摄到照片数据之后,我们需要将其保存到相册中。
在Android评台上,我们可以通过调用MediaStore.Images.Media.insertImage()方法来将照片保存到相册中。
需要注意的是,我们需要将照片保存为一个文件,并将该文件的路径作为参数传递给MediaStore.Images.Media.insertImage()方法。
我们还可以通过调用Toast.makeText()方法来显示保存成功的提示信息。
五、释放相机资源在完成拍照和保存照片操作之后,我们需要及时释放相机资源,以便其他应用能够正常使用相机。
在Android评台上,我们可以通过调用Camera.release()方法来释放相机资源。
Android打开系统相机并拍照的2种显⽰⽅法本⽂实例为⼤家分享了Android打开系统相机并拍照的具体实现代码,供⼤家参考,具体内容如下⽬标效果:第⼆张为点击第⼀个按钮拍照后显⽰的,⽐较模糊,第三章为点击第⼆个按钮拍照后显⽰的,⽐较清楚。
1.activity_main.xml页⾯设置布局。
activity_main.xml页⾯:<RelativeLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity" ><Buttonandroid:id="@+id/btnOpenCamera"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:text="拍照⽴即显⽰" /><Buttonandroid:id="@+id/btnSavePhoto"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="60dp"android:text="拍照存储后显⽰" /><ImageViewandroid:id="@+id/ivShowPicture"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_centerHorizontal="true"android:layout_marginTop="130dp" /></RelativeLayout>2.MainActivity.java页⾯打开相机并获取传递回来的数据,两种⽅式第⼀个⽐较模糊,适合⼩图,第⼆个清楚些。