android中的audio系统
Audo系统主要分如下几个层次:
1.Media库提供的Audio系统本地部分接口
2.audioFlinger作为audio系统的中间层
3.audio的硬件层提供底层支持
4.audio接口通过JNI和java框架提供给上层
Audio的系统结构如下图
代码分布如下:
1audio的java部分
路径为:/frameworks/base/media/java/android/media例:audioManager
2Audio的JNI部分(最终生成库libandroid_runtime.so)
/frameworks/base/core/jni
3audio的框架部分
头文件部分:/frameworks/base/include/media
源代码部分:/frameworks/base/media/libmedia
是media库的一部分,最终被编译成libmedia.so提供audio部分接口
4audioFlinger
代码路径:/frameworks/base/libs/surfaceflinger_client
最终被编译成:libaudioflinger.soaudio系统的本地服务部分
5audo的硬件抽像层接口
代码路径:/hardware/libhardware_legacy/include/hardware_legacy
作为本地框架层和驱动程序的接口
Audio系统和上层接口一般以pcm作为输入和输出格式
Audio自上而下:
1.java的audio类,
2.audio本地框架类libmedia.so的一部分,对上层提供接口,由本地代码实现
3.audioFlinger继承libmeida接口,提供libaudiofilnger.so
4.audio的硬件抽像层
各个层次之间的对应关系
Media库中的框架部分
主要实现三个类:audioSystemaudioTrackaudioRecorder
IaudioFlingeraudioTrack实现IaudioTrack播放
audioRecorder实现IaudioRecorder录制
Audio系统的头文件
路径是:/frameworks/base/include/media
AudioSystem.h对上层的总管接口
IAudioFlinger.h需要下层实现的总管接口
audioTrack.h放音部分对上接口
IaudioTrack.h放音部分需要下层实现的接口
audioRecorder录音部分对上接口
IaudioRecorder录音部分需要下层实现接口
audioFlinger本地代码
代码路径:
/frameworks/base/libs/audioFlingeraudio系统的JNI代码
代码中径为:/frameworks/base/core/jni
几个主要文件是:android_media_AudioSystem.cpp系统的总体控制
android_media_AudioRecord.cpp系统输入控制
android_media_AudioTrack.cpp系统输出控制
Audio的java代码
Android的video输入输出系统
Camera视频输入
Overlay视频输出(只有底层系统,没有java接口,)
框架部分:sufaceFlinger部分提供Overlay中间层
Overlay硬件抽像层
Overlay的本地框架代码:
头文件路径:/frameworks/base/include/ui
源代码路径:/frameworks/base/libs/ui
主要类是:Ioverlay和overlay
最终被子编译成libui.so
Overlay的服务部分:
代码路径为:/frameworks/base/libs/surfaceflinger
Overlay的移植层
代码路径为:/hardware/libhardware/include/hardware
只有一个头文件,需要不同的系统根据硬件和驱动情况来实现
Android的Camera系统结构
本地层代码:
Libui中提供的camera框架部分
cameraService提供中间层支持
Camera硬件抽像层
Java部分代码路径:
/frameworks/base/core/java/android/hardware
JNI代码:
frameworks/base/core/jni
本地框架代码:
Camera.h和iCamera.h分别定义了Camera和iCamera两个类,两个类接口形式不同,但功能类似
功能如下:
预览功能(preview)
视频获取功能(recording)
拍照照片(takePicture)
参数设置
ICameraService.h中定义了camera的服务类,用于获得iCamera接口;
ICameraClient.h中定义了通知功能接口,由于camera和cameraService运行于两个不同的进程
Camera系统处理的宏观逻辑是:
上层通过调用控制接口来控制下层,并设置回调函数,下层通过回调函数向上层传递数据
1camera类
代码路径为:\frameworks\base\include\camera
Camera.h是camera系统本地API接口,分为以下几个部分:
拍照部分
辅助部分
代码如下:
//表示错误消息的枚举值
enum{
CAMERA_MSG_ERROR=0x001,//错误消息
CAMERA_MSG_SHUTTER=0x002,//快门消息
CAMERA_MSG_FOCUS=0x004,//聚焦消息
CAMERA_MSG_ZOOM=0x008,//缩放消息
CAMERA_MSG_PREVIEW_FRAME=0x010,//预览帧消息
CAMERA_MSG_VIDEO_FRAME=0x020,//视频帧消息
CAMERA_MSG_POSTVIEW_FRAME=0x040,//拍照后停止帧消息
CAMERA_MSG_RAW_IMAGE=0x080,//原始数据格式照片光消息
CAMERA_MSG_COMPRESSED_IMAGE=0x100,//压缩格式照片消息
CAMERA_MSG_ALL_MSGS=0x1FF//所有消息
};
classCameraListener:virtualpublicRefBase
{
public:
virtualvoidnotify(int32_tmsgType,int32_text1,int32_text2)=0;//消息通知
virtualvoidpostData(int32_tmsgType,constsp<IMemory>&dataPtr)=0;//传递没有时间戳的帧数据
virtualvoidpostDataTimestamp(nsecs_ttimestamp,int32_tmsgType,constsp<IMemory>&dataPtr)=0;//传递有时间戳的帧数据
};
//回调函数rawCallbackjpegCallbackpreviewCallbackrecordingCallback等回调函数均可以用
//postData()和postDataTimestamp()用枚举值进行区分
classCamera:publicBnCameraClient,publicIBinder::DeathRecipient
{
public:
//constructacameraclientfromanexistingremote
staticsp<Camera>create(constsp<ICamera>&camera);
staticint32_tgetNumberOfCameras();
staticstatus_tgetCameraInfo(intcameraId,
structCameraInfo*cameraInfo);
staticsp<Camera>connect(intcameraId);
~Camera();
//核心按制部分
voidinit();
status_treconnect();
voiddisconnect();
status_tlock();
status_tunlock();
status_tgetStatus(){returnmStatus;}
//passthebufferedISurfacetothecameraservice
//预览部分
status_tsetPreviewDisplay(constsp<Surface>&surface);
status_tsetPreviewDisplay(constsp<ISurface>&surface);
//startpreviewmode,mustcallsetPreviewDisplayfirst
status_tstartPreview();
//stoppreviewmode
voidstopPreview();
//getpreviewstate
boolpreviewEnabled();
//startrecordingmode,mustcallsetPreviewDisplayfirst
//记录视频部分
status_tstartRecording();
//stoprecordingmode
voidstopRecording();
//getrecordingstate
boolrecordingEnabled();
//releasearecordingframe
voidreleaseRecordingFrame(constsp<IMemory>&mem);
//autoFocus-statusreturnedfromcallback
//拍照和辅助功能
status_tautoFocus();
//cancelautofocus
status_tcancelAutoFocus();
//takeapicture-picturereturnedfromcallback
status_ttakePicture();
//setpreview/captureparameters-key/valuepairs
status_tsetParameters(constString8¶ms);
//getpreview/captureparameters-key/valuepairs
String8getParameters()const;
//sendcommandtocameradriver
status_tsendCommand(int32_tcmd,int32_targ1,int32_targ2);
voidsetListener(constsp<CameraListener>&listener);
voidsetPreviewCallbackFlags(intpreview_callback_flag);
//ICameraClientinterface
//数据流的传输是通过回调函数来实现
virtualvoidnotifyCallback(int32_tmsgType,int32_text,int32_text2);
virtualvoiddataCallback(int32_tmsgType,constsp<IMemory>&dataPtr);
virtualvoiddataCallbackTimestamp(nsecs_ttimestamp,int32_tmsgType,constsp<IMemory>&dataPtr);
sp<ICamera>remote();
private:
Camera();
Camera(constCamera&);
Camera&operator=(constCamera);
virtualvoidbinderDied(constwp<IBinder>&who);
classDeathNotifier:publicIBinder::DeathRecipient
{
public:
DeathNotifier(){
}
virtualvoidbinderDied(constwp<IBinder>&who);
};
staticsp<DeathNotifier>mDeathNotifier;
//helperfunctiontoobtaincameraservicehandle
staticconstsp<ICameraService>&getCameraService();
sp<ICamera>mCamera;
status_tmStatus;
sp<CameraListener>mListener;
friendclassDeathNotifier;
staticMutexmLock;
staticsp<ICameraService>mCameraService;
};
};
预览功能的两种方式:
一、不设预览设备,设置回调函数setPreviewCallback().可以得到取景器预览的数据流,自行输出到指定设备
二、设置预览设备setPreviewDisplay(),不设回调函数,由CameraService会进行取景器输出,
数据流不通过上层,
一般使用第二种方式,他又分为:使用overlay和不使用overlay
视频录制功能
使用startRecording()和stopRecording()为起点和终点,通过设置回调函数setRecordingCallbak()来接受视频录制的数据,releaseRecordingFrame()函数是调用者通知下层“当前帧已结束”camera的照片功能使用takePicture()接口setRawCallback或者setJpegCallBack回调函数来取数据
2ICamera类
ICamera.h中定义了ICamera和BnCamera类.,要求CameraService进行实现,
代码如下:
classICamera:publicIInterface
{
public:
DECLARE_META_INTERFACE(Camera);
virtualvoiddisconnect()=0;
//connectnewclientwithexistingcameraremote
virtualstatus_tconnect(constsp<ICameraClient>&client)=0;
//preventotherprocessesfromusingthisICamerainterface
virtualstatus_tlock()=0;
//allowotherprocessestousethisICamerainterface
virtualstatus_tunlock()=0;
//passthebufferedISurfacetothecameraservice
virtualstatus_tsetPreviewDisplay(constsp<ISurface>&surface)=0;
//setthepreviewcallbackflagtoaffecthowthereceivedframesfrom
//previewarehandled.
virtualvoidsetPreviewCallbackFlag(intflag)=0;
//startpreviewmode,mustcallsetPreviewDisplayfirst
virtualstatus_tstartPreview()=0;
//stoppreviewmode
virtualvoidstopPreview()=0;
//getpreviewstate
virtualboolpreviewEnabled()=0;
//startrecordingmode
virtualstatus_tstartRecording()=0;
//stoprecordingmode
virtualvoidstopRecording()=0;
//getrecordingstate
virtualboolrecordingEnabled()=0;
//releasearecordingframe
virtualvoidreleaseRecordingFrame(constsp<IMemory>&mem)=0;
//autofocus
virtualstatus_tautoFocus()=0;
//cancelautofocus
virtualstatus_tcancelAutoFocus()=0;
//takeapicture
virtualstatus_ttakePicture()=0;
//setpreview/captureparameters-key/valuepairs
virtualstatus_tsetParameters(constString8¶ms)=0;
//getpreview/captureparameters-key/valuepairs
virtualString8getParameters()const=0;
//sendcommandtocameradriver
virtualstatus_tsendCommand(int32_tcmd,int32_targ1,int32_targ2)=0;
};
//----------------------------------------------------------------------------
classBnCamera:publicBnInterface<ICamera>
{
public:
virtualstatus_tonTransact(uint32_tcode,
constParcel&data,
Parcel*reply,
uint32_tflags=0);
};
};
3ICameraService.h和ICameraClient.h中定义了ICameraService和ICameraClient两个类
ICameraService类需要下层去实现
代码如下:
classICameraService:publicIInterface
{
public:
enum{
GET_NUMBER_OF_CAMERAS=IBinder::FIRST_CALL_TRANSACTION,
GET_CAMERA_INFO,
CONNECT
};
public:
DECLARE_META_INTERFACE(CameraService);
virtualint32_tgetNumberOfCameras()=0;
virtualstatus_tgetCameraInfo(intcameraId,
structCameraInfo*cameraInfo)=0;
virtualsp<ICamera>connect(constsp<ICameraClient>&cameraClient,
intcameraId)=0;
};
//----------------------------------------------------------------------------
classBnCameraService:publicBnInterface<ICameraService>
{
public:
virtualstatus_tonTransact(uint32_tcode,
constParcel&data,
Parcel*reply,
uint32_tflags=0);
};
};
ICameraService通过传入一个ICameraClient作为参数,来取得一个ICamera类型的接口,这个接口是实际的camera实现
ICameraClient被Camera类继承,
代码如下:
classICameraClient:publicIInterface
{
public:
DECLARE_META_INTERFACE(CameraClient);
virtualvoidnotifyCallback(int32_tmsgType,int32_text1,int32_text2)=0;
virtualvoiddataCallback(int32_tmsgType,constsp<IMemory>&data)=0;
virtualvoiddataCallbackTimestamp(nsecs_ttimestamp,int32_tmsgType,constsp<IMemory>&data)=0;
};
//以上函数均可调用postData()和postDataTimestamp()
//----------------------------------------------------------------------------
classBnCameraClient:publicBnInterface<ICameraClient>
{
public:
virtualstatus_tonTransact(uint32_tcode,
constParcel&data,
Parcel*reply,
uint32_tflags=0);
};
};
该类型的功能主要是起回调作用,通过被继承将回调函数传给Camaera的下层cameraService
Camera.cpp1.6以后增加的cameraListener相当于1.5之前的回调函数
代码路径为:\frameworks\base\libs\camera
该类实现了ICameraClient中的几个函数,代码如下:
voidCamera::dataCallbackTimestamp(nsecs_ttimestamp,int32_tmsgType,constsp<IMemory>&dataPtr)
{
sp<CameraListener>listener;
{
Mutex::Autolock_l(mLock);
listener=mListener;
}
if(listener!=NULL){
listener->postDataTimestamp(timestamp,msgType,dataPtr);
}else{
LOGW("Nolistenerwasset.Droparecordingframe.");
releaseRecordingFrame(dataPtr);
}
}
CameraService:他是camera系统中的中间层实现,继承libui提供的接口,没有对外的API
CameraService.cpp中定义类CameraService,它继承BnCameraService的实现
基运作过程中:cameraService:connect()函数用来得到cameraService:client,主要调用这个类的接口来实现camera功能.
cameraService具体实现是通过Camera的硬件抽像层来完成,以下是拍照的接口
status_tCameraService::Client::takePicture(){
LOG1("takePicture(pid%d)",getCallingPid());
Mutex::Autolocklock(mLock);
status_tresult=checkPidAndHardware();
if(result!=NO_ERROR)returnresult;
enableMsgType(CAMERA_MSG_SHUTTER|
CAMERA_MSG_POSTVIEW_FRAME|
CAMERA_MSG_RAW_IMAGE|
CAMERA_MSG_COMPRESSED_IMAGE);
returnmHardware->takePicture();
}
cameraService需要处理的一个逻辑是取景器的预览问题
如果上层设置了预览输出设备,预览在cameraService以下处理,
如果使用overlay数据流在camera的硬件抽像层处理,
如果不使用overlay数据流在cameraService中处理
预览功能是从以下函数开始
status_tCameraService::Client::startPreview(){
LOG1("startPreview(pid%d)",getCallingPid());
returnstartCameraMode(CAMERA_PREVIEW_MODE);
}
之后调用以下:
status_tCameraService::Client::startPreviewMode(){
LOG1("startPreviewMode");
status_tresult=NO_ERROR;
//ifpreviewhasbeenenabled,nothingneedstobedone
if(mHardware->previewEnabled()){
returnNO_ERROR;
}
if(mUseOverlay){//如果mUseOverlay为真,则表示使用overlay
//Ifpreviewdisplayhasbeenset,setoverlaynow.
if(mSurface!=0){
result=setOverlay();
}
if(result!=NO_ERROR)returnresult;
result=mHardware->startPreview();
}else{//不使用overlay的情况
enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
result=mHardware->startPreview();
if(result!=NO_ERROR)returnresult;
//Ifpreviewdisplayhasbeenset,registerpreviewbuffersnow.
if(mSurface!=0){
//Unregisterherebecausethesurfacemaybepreviouslyregistered
//withtheraw(snapshot)heap.
mSurface->unregisterBuffers();
result=registerPreviewBuffers();
}
}
returnresult;
}
对于使用overlay的情况,取景器的预览是在camera的硬件层中处理,cameraService只需要调用setoverlay()把overlay设备设置到其中即可.
对于不合用overlay的情况,需要从camera的硬件抽像层中得到预览内容的数据,并调用iSurface的registerBuffers()将内存注册到输出设备(ISurface)中
设置到Camera硬件抽像层中的回调函数,他会调用handlePreviewData(),将视频发送到输出设备
voidCameraService::Client::dataCallback(int32_tmsgType,
constsp<IMemory>&dataPtr,void*user){
LOG2("dataCallback(%d)",msgType);
sp<Client>client=getClientFromCookie(user);
if(client==0)return;
if(!client->lockIfMessageWanted(msgType))return;
if(dataPtr==0){
LOGE("Nulldatareturnedindatacallback");
client->handleGenericNotify(CAMERA_MSG_ERROR,UNKNOWN_ERROR,0);
return;
}
switch(msgType){
caseCAMERA_MSG_PREVIEW_FRAME:
client->handlePreviewData(dataPtr);//将数据发送到输出设备
break;
caseCAMERA_MSG_POSTVIEW_FRAME:
client->handlePostview(dataPtr);
break;
caseCAMERA_MSG_RAW_IMAGE:
client->handleRawPicture(dataPtr);
break;
caseCAMERA_MSG_COMPRESSED_IMAGE:
client->handleCompressedPicture(dataPtr);
break;
default:
client->handleGenericData(msgType,dataPtr);
break;
}
}
handlePreviewData()用来处理surface输出情况,
voidCameraService::Client::handlePreviewData(constsp<IMemory>&mem){
ssize_toffset;
size_tsize;
sp<IMemoryHeap>heap=mem->getMemory(&offset,&size);
if(!mUseOverlay){
if(mSurface!=0){
mSurface->postBuffer(offset);//将视频数据送出
}
}
//localcopyofthecallbackflags
intflags=mPreviewCallbackFlag;
//iscallbackenabled?
if(!(flags&FRAME_CALLBACK_FLAG_ENABLE_MASK)){
//Iftheenablebitisoff,thecopy-outandone-shotbitsareignored
LOG2("framecallbackisdisabled");
mLock.unlock();
return;
}
//holdastrongpointertotheclient
sp<ICameraClient>c=mCameraClient;
//clearcallbackflagsifnoclientorone-shotmode
if(c==0||(mPreviewCallbackFlag&FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)){
LOG2("Disablepreviewcallback");
mPreviewCallbackFlag&=~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK|
FRAME_CALLBACK_FLAG_COPY_OUT_MASK|
FRAME_CALLBACK_FLAG_ENABLE_MASK);
if(mUseOverlay){
disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
}
}
if(c!=0){
//Isthereceivedframecopiedoutornot?
//进行ICameraClient的回调函数的处理,
if(flags&FRAME_CALLBACK_FLAG_COPY_OUT_MASK){
LOG2("frameiscopied");
//复制传递内存
copyFrameAndPostCopiedFrame(c,heap,offset,size);
}else{
LOG2("frameisforwarded");
mLock.unlock();
//直接传递内存
c->dataCallback(CAMERA_MSG_PREVIEW_FRAME,mem);
}
}else{
mLock.unlock();
}
}
当具有输出设备时,调用iSurface的postBuffer()函数将视频送出,当上层的ICameraClient具有预览和回调函数时,则调用这个函数将视频传递给上层,这里分为:
需要复制数据
不需要复制数据
通常显示输出设备和iCameraClicen预览的回调函数,两者有一个就能实现预览功能
Camera的JNI代码
代码路径:D:\tools\android_src\android_src\frameworks\base\core\jni
接口的特点是:包括取景器,拍摄照片,不包括视频录制的接口
设置回调函数后,数据流可传到java层,回调函数来自java环境
Java部分代码
staticJNINativeMethodcamMethods[]={
...
{"setPreviewDisplay",
"(Landroid/view/Surface;)V",
(void*)android_hardware_Camera_setPreviewDisplay}
...
}
setPreviewDisplay函数的处理过程如下(以serviceView为参数,将一个外部的surface设置给camera的本地接口,由本地进行取景器的输出处理)
staticvoidandroid_hardware_Camera_setPreviewDisplay(JNIEnv*env,jobjectthiz,jobjectjSurface)
{
LOGV("setPreviewDisplay");
sp<Camera>camera=get_native_camera(env,thiz,NULL);
if(camera==0)return;
sp<Surface>surface=NULL;
if(jSurface!=NULL){
surface=reinterpret_cast<Surface*>(env->GetIntField(jSurface,fields.surface));
}
if(camera->setPreviewDisplay(surface)!=NO_ERROR){
jniThrowException(env,"java/io/IOException","setPreviewDisplayfailed");
}
}
仅当设置时才会使用:
staticvoidandroid_hardware_Camera_setHasPreviewCallback(JNIEnv*env,jobjectthiz,jbooleaninstalled,jbooleanmanualBuffer)
{
LOGV("setHasPreviewCallback:installed:%d,manualBuffer:%d",(int)installed,(int)manualBuffer);
//Important:Onlyinstallpreview_callbackiftheJavacodehascalled
//setPreviewCallback()withanon-nullvalue,otherwisewe'dpaytomemcpy
//eachpreviewframefornothing.
JNICameraContext*context;
sp<Camera>camera=get_native_camera(env,thiz,&context);
if(camera==0)return;
//setCallbackModewilltakecareofsettingthecontextflagsandcalling
//camera->setPreviewCallbackFlagswithinamutexforus.
context->setCallbackMode(env,installed,manualBuffer);
}
previewCallback()可以将预览数据传达递到java层。
由于视频流的数据量很大,所以不会送到java层进行处理,只通过设置输出设备(surface),在本地处理;
照片处理的函数:这个函数没有参数,可以通过java层的回调函数实现
staticJNINativeMethodcamMethods[]={
。。。
{"native_takePicture",
"()V",
(void*)android_hardware_Camera_takePicture},
。。。
}
函数的实现
staticvoidandroid_hardware_Camera_takePicture(JNIEnv*env,jobjectthiz)
{
LOGV("takePicture");
JNICameraContext*context;
sp<Camera>camera=get_native_camera(env,thiz,&context);
if(camera==0)return;
//l回调函数
if(camera->takePicture()!=NO_ERROR){
jniThrowException(env,"java/lang/RuntimeException","takePicturefailed");
return;
}
}
Camera的java代码:
代码的路径为:
\frameworks\base\core\java\android\hardware
部分代码如下:
publicclassCamera{
//对应的本地方法
publicnativefinalvoidstartPreview();
publicnativefinalvoidstopPreview();
publicnativefinalbooleanpreviewEnabled();
//拍照函数的定义
publicfinalvoidtakePicture(ShutterCallbackshutter,PictureCallbackraw,
PictureCallbackpostview,PictureCallbackjpeg){
mShutterCallback=shutter;
mRawImageCallback=raw;
mPostviewCallback=postview;
mJpegCallback=jpeg;
native_takePicture();
}
}
外部接口的takePicture将调用本地方法privatenativefinalvoidnative_takePicture();
publicinterfacePictureCallback{
/**
*Calledwhenimagedataisavailableafterapictureistaken.
*Theformatofthedatadependsonthecontextofthecallback
*and{@linkCamera.Parameters}settings.
*
*@paramdataabytearrayofthepicturedata
*@paramcameratheCameraserviceobject
*/
voidonPictureTaken(byte[]data,Cameracamera);
};
得到的是内存中的照片数据
Camera的硬件抽像层
是android中camera系统最底层部分,直接负责控制硬件
其接口在CameraHardwareInterface.h头文件中进行定义,代码路径为:
\frameworks\base\include\camera
其接口类型与上层接口类型类似,包含:取景器预览,视频录制,照片拍摄
Camera硬件抽像层需要实现这个类,最终编译生成libcamera.so
其代码如下
namespaceandroid{
classOverlay;
//指针
typedefstructimage_rect_struct
{
uint32_twidth;/*Imagewidth*/
uint32_theight;/*Imageheight*/
}image_rect_type;
typedefvoid(*notify_callback)(int32_tmsgType,
int32_text1,
int32_text2,
void*user);
typedefvoid(*data_callback)(int32_tmsgType,
constsp<IMemory>&dataPtr,
void*user);
typedefvoid(*data_callback_timestamp)(nsecs_ttimestamp,
int32_tmsgType,
constsp<IMemory>&dataPtr,
void*user);
classCameraHardwareInterface:publicvirtualRefBase{
public:
virtual~CameraHardwareInterface(){}
/**ReturntheIMemoryHeapforthepreviewimageheap*/
virtualsp<IMemoryHeap>getPreviewHeap()const=0;
/**ReturntheIMemoryHeapfortherawimageheap*/
virtualsp<IMemoryHeap>getRawHeap()const=0;
/**Setthenotificationanddatacallbacks*/
virtualvoidsetCallbacks(notify_callbacknotify_cb,
data_callbackdata_cb,
data_callback_timestampdata_cb_timestamp,
void*user)=0;
virtualvoidenableMsgType(int32_tmsgType)=0;
virtualvoiddisableMsgType(int32_tmsgType)=0;
virtualboolmsgTypeEnabled(int32_tmsgType)=0;
virtualstatus_tstartPreview()=0;
virtualbooluseOverlay(){returnfalse;}
virtualstatus_tsetOverlay(constsp<Overlay>&overlay){returnBAD_VALUE;}
/**
*Stopapreviouslystartedpreview.
*/
virtualvoidstopPreview()=0;
/**
*Returnstrueifpreviewisenabled.
*/
virtualboolpreviewEnabled()=0;
virtualstatus_tstartRecording()=0;
virtualvoidstopRecording()=0;
virtualboolrecordingEnabled()=0;
virtualvoidreleaseRecordingFrame(constsp<IMemory>&mem)=0;
virtualstatus_tautoFocus()=0;
virtualstatus_tcancelAutoFocus()=0;
virtualstatus_ttakePicture()=0;
virtualstatus_tcancelPicture()=0;
virtualstatus_tsetParameters(constCameraParameters¶ms)=0;
virtualCameraParametersgetParameters()const=0;
virtualstatus_tsendCommand(int32_tcmd,int32_targ1,int32_targ2)=0;
virtualvoidrelease()=0;
virtualstatus_tdump(intfd,constVector<String16>&args)const=0;
};
extern"C"intHAL_getNumberOfCameras();
extern"C"voidHAL_getCameraInfo(intcameraId,structCameraInfo*cameraInfo);
/*HALshouldreturnNULLifitfailstoopencamerahardware.*/
extern"C"sp<CameraHardwareInterface>HAL_openCameraHardware(intcameraId);
};
cameraHardsareInterface中的startPreview()stopRecording()takePicture()直接传入回调函数的支持,
函数中定义的回调函数指针,用于数据的传输和信息的传递
CameraParameters.h这个类是用于定义camera系统参数的类,在cameraHardwareInterface中通过setParameter()和getParameter()
部分代码如下:
classCameraParameters
{
public:
CameraParameters();
CameraParameters(constString8¶ms){unflatten(params);}
~CameraParameters();
String8flatten()const;
voidunflatten(constString8¶ms);
voidset(constchar*key,constchar*value);//设置键和键值
voidset(constchar*key,intvalue);
voidsetFloat(constchar*key,floatvalue);
constchar*get(constchar*key)const;//取得键和键值
intgetInt(constchar*key)const;
floatgetFloat(constchar*key)const;
voidremove(constchar*key);
voidsetPreviewSize(intwidth,intheight);
voidgetPreviewSize(int*width,int*height)const;
voidgetSupportedPreviewSizes(Vector<Size>&sizes)const;
voidsetPreviewFrameRate(intfps);
intgetPreviewFrameRate()const;
voidgetPreviewFpsRange(int*min_fps,int*max_fps)const;
voidsetPreviewFormat(constchar*format);
constchar*getPreviewFormat()const;
voidsetPictureSize(intwidth,intheight);
voidgetPictureSize(int*width,int*height)const;
voidgetSupportedPictureSizes(Vector<Size>&sizes)const;
voidsetPictureFormat(constchar*format);
constchar*getPictureFormat()const;
voiddump()const;
status_tdump(intfd,constVector<String16>&args)const;
}
该函数中除了预览大小、格式、照片大小、格式等,还可以使作键和键值来进行任意设置,
Camera中默认不使用overlay(),如果想使用可以通过setOverlay()进行设置
Camera硬功夫件抽像层的桩实现
cameraService中,实现了一个camera硬件抽像层的“桩”,可以根据宏来进行配置
这个桩使用假的方式,可以实现一个取景器预览等功能,他用黑白相间的格子来代码来自硬件的视频流,这样就能在不接触硬件的情况下,可以让android的camera系统在没有硬件的情况下运行起来
cameraService的.mk文件
文件的路径是:\frameworks\base\services\camera\libcameraservice
代码内容是:
LOCAL_PATH:=$(callmy-dir)
#SetUSE_CAMERA_STUBifyoudon'twanttousethehardwarecamera.
#forcethesebuildstousecamerastubonly
ifneq($(filtersoonergenericsim,$(TARGET_DEVICE)),)
USE_CAMERA_STUB:=true
endif
ifeq($(USE_CAMERA_STUB),)
USE_CAMERA_STUB:=false
endif
ifeq($(USE_CAMERA_STUB),true)
#
#libcamerastub
#
include$(CLEAR_VARS)
LOCAL_SRC_FILES:=\
CameraHardwareStub.cpp\
FakeCamera.cpp
LOCAL_MODULE:=libcamerastub
ifeq($(TARGET_SIMULATOR),true)
LOCAL_CFLAGS+=-DSINGLE_PROCESS
endif
LOCAL_SHARED_LIBRARIES:=libui
include$(BUILD_STATIC_LIBRARY)
endif#USE_CAMERA_STUB
#
#libcameraservice
#
include$(CLEAR_VARS)
LOCAL_SRC_FILES:=\
CameraService.cpp
LOCAL_SHARED_LIBRARIES:=\
libui\
libutils\
libbinder\
libcutils\
libmedia\
libcamera_client\
libsurfaceflinger_client
LOCAL_MODULE:=libcameraservice
ifeq($(TARGET_SIMULATOR),true)
LOCAL_CFLAGS+=-DSINGLE_PROCESS
endif
ifeq($(USE_CAMERA_STUB),true)
LOCAL_STATIC_LIBRARIES+=libcamerastub
else
LOCAL_SHARED_LIBRARIES+=libcamera
endif
include$(BUILD_SHARED_LIBRARY)
如果USE_CAMERA_STUB为false则联接libcamera.so(动态库),使用真实的camera硬件抽像层
如果USE_CAMERA_STUB为true则联接libcamerastub.a,静态库),使用camera硬件抽像层的“桩”实现,假装运行在CameraHardwareStub.cpp和FakeCamera.cpp中实现
头文件的部分代码如下:
classFakeCamera{
public:
FakeCamera(intwidth,intheight);
~FakeCamera();
voidsetSize(intwidth,intheight);
voidgetNextFrameAsYuv420(uint8_t*buffer);//颜色空间格式
//Writetothefdastringrepresentingthecurrentstate.
voiddump(intfd)const;
private:
//TODO:removetheuint16_tbufferparameverywheresinceitisafieldof
//thisclass.
voidgetNextFrameAsRgb565(uint16_t*buffer);//颜色空间格式
voiddrawSquare(uint16_t*buffer,intx,inty,intsize,intcolor,intshadow);
voiddrawCheckerboard(uint16_t*buffer,intsize);
staticconstintkRed=0xf800;
staticconstintkGreen=0x07c0;
staticconstintkBlue=0x003e;
intmWidth,mHeight;
intmCounter;
intmCheckX,mCheckY;
uint16_t*mTmpRgb16Buffer;
};
};
CameraHardwareStub.ht和CameraHardwareStub.cpp继承CameraHardwareInterface
initHeapLocked函数在CameraHardwareStub.cpp中,代码如下:
voidCameraHardwareStub::initHeapLocked()
{
//Createrawheap.
intpicture_width,picture_height;
mParameters.getPictureSize(&picture_width,&picture_height);
mRawHeap=newMemoryHeapBase(picture_width*picture_height*3/2);
intpreview_width,preview_height;
mParameters.getPreviewSize(&preview_width,&preview_height);
LOGD("initHeapLocked:previewsize=%dx%d",preview_width,preview_height);
//Notethatweenforceyuv420spinsetParameters().
inthow_big=preview_width*preview_height*3/2;
//Ifwearebeingreinitializedtothesamesizeasbefore,no
//workneedstobedone.
if(how_big==mPreviewFrameSize)
return;
mPreviewFrameSize=how_big;
//Makeanewmmap'edheapthatcanbesharedacrossprocesses.
//usecodebelowtotestwithpmem
mPreviewHeap=newMemoryHeapBase(mPreviewFrameSize*kBufferCount);
//MakeanIMemoryforeachframesothatwecanreusethemincallbacks.
for(inti=0;i<kBufferCount;i++){
mBuffers[i]=newMemoryBase(mPreviewHeap,i*mPreviewFrameSize,mPreviewFrameSize);
}
//Recreatethefakecameratoreflectthecurrentsize.
deletemFakeCamera;
mFakeCamera=newFakeCamera(preview_width,preview_height);
}
在这个过程中开辟两块内存
一个是拍照照片的内存mRawHeap
一个是取景器预览的内存mPreviewHeap
由于mPreviewHeap是一个序列,所以在mPreviewHeap中实现kBufferCount个MemoryBase
status_tCameraHardwareStub::startPreview()
{
Mutex::Autolocklock(mLock);
if(mPreviewThread!=0){
//alreadyrunning
returnINVALID_OPERATION;
}
mPreviewThread=newPreviewThread(this);
returnNO_ERROR;
}
Camera硬功夫件抽像层的硬件实现
取景器预览的主要步骤:
初始化的过程中,建立预览数据的内存队列
在startPreview()中,保存预览回调函数,建立预览线程
在视频线程循环中,等待数据到达