1AndroidCameraHAL3分析本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。欢迎和大家交流。qq:1037701636email:gzzaigcn2009@163.comSoftware:系统源码Android5.1Camera3研读前沿:当初在研读Camera1.0相关的内容时,主要围绕着CameraClient、CameraHardwareInterface等方面进行工作的开展,无论是数据流还是控制流看起来都很简单、明了,一系列的流程化操作使得整个框架学起来特别的容易。因为没有Camera2.0相关的基础,所以这次直接看3.0相关的源码时,显得十分的吃紧,再加上底层高通HAL3.0实现的过程也是相当的复杂,都给整个研读过程带来了很多的困难。可以说,自身目前对Camera3.0框架的熟悉度也大概只有70%左右,希望通过总结来进一步梳理他的工作原理与整个框架,并进一步熟悉与加深理解。1.Camera3下的整体架构图。整个CameraService建立起一个可用操作底层Cameradevice大致需要经过Camera2Client、Camera3Device以及HAL层的camera3_device_t三个部分。2从上图中可以发现Camera3架构看上去明显比camera1来的复杂,但他更加的模块化。对比起Android4.2.2Camer系统架构图(HAL和回调处理)一文中描述的单顺序执行流程,Camera3将更多的工作集中在了Framework去完成,将更多的控制权掌握在自己的手里,从而与HAL的交互的数据信息更少,也进一步减轻了一些在旧版本中HAL层所需要做的事情。2.Camera2Client的建立与初始化过程在建立好Camera2Client后会进行initialize操作,完成各个处理模块的创建:?123....mStreamingProcessor=newStreamingProcessor(this);//preview和recorderthreadName=String8::format(C2-%d-StreamProc,mCameraId);345678910111213141516171819202122232425mStreamingProcessor-run(threadName.string());//预览与录像mFrameProcessor=newFrameProcessor(mDevice,this);//3AthreadName=String8::format(C2-%d-FrameProc,mCameraId);mFrameProcessor-run(threadName.string());//3AmCaptureSequencer=newCaptureSequencer(this);threadName=String8::format(C2-%d-CaptureSeq,mCameraId);mCaptureSequencer-run(threadName.string());//录像,拍照mJpegProcessor=newJpegProcessor(this,mCaptureSequencer);threadName=String8::format(C2-%d-JpegProc,mCameraId);mJpegProcessor-run(threadName.string());....mCallbackProcessor=newCallbackProcessor(this);//回调处理threadName=String8::format(C2-%d-CallbkProc,mCameraId);mCallbackProcessor-run(threadName.string());依次分别创建了:StreamingProcessor并启动一个他所属的thread,该模块主要负责处理previews与record两种视频流的处理,用于从hal层获取原始的视频数据FrameProcessor并启动一个thread,该模块专门用于处理回调回来的每一帧的3A等信息,即每一帧视频除去原始视频数据外,还应该有其他附加的数据信息,如3A值。CaptureSequencer并启动一个thread,该模块需要和其他模块配合使用,主要用于向APP层告知capture到的picture。JpegProcessor并启动一个thread,该模块和streamprocessor类似,他启动一个拍照流,一般用于从HAL层获取jpeg编码后的图像照片数据。此外ZslProcessor模块称之为0秒快拍,其本质是直接从原始的Preview流中获取预存着的最近的几帧,直接编码后返回给APP,而不需要再经过takepicture去请求获取jpeg数据。0秒快拍技术得意于当下处理器CSI2MIPI性能的提升以及Sensor支持全像素高帧率的实时输出。一般手机拍照在按下快门后都会有一定的延时,是因为需要切换底层Camera以及ISP等的工作模式,并重新设置参数以及重新对焦等等,都需要花一定时间后才抓取一帧用于编码为jpeg图像。以上5个模块整合在一起基本上实现了Camera应用开发所需的基本业务功能。43.预览Preview下的控制流研读Camera具体的业务处理功能,一般从视频实时预览Preview入手。一般熟悉Camera架构的人,可以从一个app端的一个api一直连续打通到底层hal的一个控制命令。大致可以如下图所示:对于preview部分到CameraService的控制流可以参考博文Android4.2.2的preview的数据流和控制流以及最终的预览显示,本文将直接从Camera2Client::startPreview()作为入口来分析整个Framework层中Preview相关的数据流。?123456789status_tCamera2Client::startPreview(){ATRACE_CALL();ALOGV(%s:E,__FUNCTION__);Mutex::Autolockicl(mBinderSerializationLock);status_tres;if((res=checkPid(__FUNCTION__))!=OK)returnres;SharedParameters::Lockl(mParameters);returnstartPreviewL(l.mParameters,false);}startPreview通过startPreviewL提取参数后真正的开始执行Preview相关的控制流。该函数看上去内容虽然较多,但基本采用了同一种处理方式:?5123456789101112131415161718192021222324252627282930313233343536373839404142434445464748status_tCamera2Client::startPreviewL(Parameters¶ms,boolrestart){//restart==falseATRACE_CALL();status_tres;......intlastPreviewStreamId=mStreamingProcessor-getPreviewStreamId();//获取上一层Previewstreamidres=mStreamingProcessor-updatePreviewStream(params);//创建camera3devicestream,Camera3OutputStream.....intlastJpegStreamId=mJpegProcessor-getStreamId();res=updateProcessorStream(mJpegProcessor,params);//预览启动时就建立一个jpeg的outstream.....res=mCallbackProcessor-updateStream(params);//回调处理建立一个Camera3outputstreamif(res!=OK){ALOGE(%s:Camera%d:Unabletoupdatecallbackstream:%s(%d),__FUNCTION__,mCameraId,strerror(-res),res);returnres;}outputStreams.push(getCallbackStreamId());......outputStreams.push(getPreviewStreamId());//预览stream......if(!params.recordingHint){if(!restart){res=mStreamingProcessor-updatePreviewRequest(params);//request处理,更新了mPreviewrequestif(res!=OK){ALOGE(%s:Camera%d:Can'tsetuppreviewrequest:%s(%d),__FUNCTION__,mCameraId,strerror(-res),res);returnres;}}res=mStreamingProcessor-startStream(StreamingProcessor::PREVIEW,outputStreams);//启动stream,传入outputStreams即stream的id}else{if(!restart){res=mStreamingProcessor-updateRecordingRequest(params);if(res!=OK){ALOGE(%s:Camera%d:Can'tsetuppreviewrequestwithrecordhint:%s(%d),__FUNCTION__,mCameraId,strerror(-res),res);returnres;}}res=mStreamingProcessor-startStream(StreamingProcessor::RECORD,outputStreams);}......}(1).mStreamingProcessor-updatePreviewStream()由预览与录像处理模块更新一个预览流,其实现过程如下:?1234567891011status_tStreamingProcessor::updatePreviewStream(constParameters¶ms){ATRACE_CALL();Mutex::Autolockm(mMutex);status_tres;spcameradevicebasedevice=mDevice.promote();//Camera3Deviceif(device==0){ALOGE(%s:Camera%d:Devicedoesnotexist,__FUNCTION__,mId);returnINVALID_OPERATION;}if(mPreviewStreamId!=NO_STREAM){//Checkifstreamparametershavetochange6121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556uint32_tcurrentWidth,currentHeight;res=device-getStreamInfo(mPreviewStreamId,¤tWidth,¤tHeight,0);if(res!=OK){ALOGE(%s:Camera%d:Errorqueryingpreviewstreaminfo:%s(%d),__FUNCTION__,mId,strerror(-res),res);r