android系统学习笔记五

android中的audio系统

Audo系统主要分如下几个层次:

1.Media库提供的Audio系统本地部分接口

2.audioFlinger作为audio系统的中间层

3.audio的硬件层提供底层支持

4.audio接口通过JNIjava框架提供给上层

Audio的系统结构如下图

 

 

代码分布如下:

1audiojava部分

路径为:/frameworks/base/media/java/android/media例:audioManager

2AudioJNI部分(最终生成库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.javaaudio,

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/libsaudioFlingeraudio系统的JNI代码

代码中径为:/frameworks/base/core/jni

几个主要文件是:android_media_AudioSystem.cpp系统的总体控制

android_media_AudioRecord.cpp系统输入控制

android_media_AudioTrack.cpp系统输出控制

Audiojava代码

 

 

 

Androidvideo输入输出系统

Camera视频输入

Overlay视频输出(只有底层系统,没有java接口,

框架部分:sufaceFlinger部分提供Overlay中间层

Overlay硬件抽像层

Overlay的本地框架代码:

头文件路径:/frameworks/base/include/ui

源代码路径:/frameworks/base/libs/ui

主要类是:Ioverlayoverlay

最终被子编译成libui.so

Overlay的服务部分:

代码路径为:/frameworks/base/libs/surfaceflinger

Overlay的移植层

代码路径为:/hardware/libhardware/include/hardware
只有一个头文件,需要不同的系统根据硬件和驱动情况来实现

 

 

 

AndroidCamera系统结构

本地层代码:

Libui中提供的camera框架部分

cameraService提供中间层支持

Camera硬件抽像层

 

Java部分代码路径:

/frameworks/base/core/java/android/hardware

JNI代码:

frameworks/base/core/jni

本地框架代码:

 

Camera.hiCamera.h分别定义了CameraiCamera两个类,两个类接口形式不同,但功能类似

功能如下:

预览功能(preview

视频获取功能(recording

拍照照片(takePicture)

参数设置

ICameraService.h中定义了camera的服务类,用于获得iCamera接口;

ICameraClient.h中定义了通知功能接口,由于cameracameraService运行于两个不同的进程

 

Camera系统处理的宏观逻辑是:

上层通过调用控制接口来控制下层,并设置回调函数,下层通过回调函数向上层传递数据

 

 

 

1camera

代码路径为:\frameworks\base\include\camera

Camera.hcamera系统本地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&params);

 

//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中定义了ICameraBnCamera.,要求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&params)=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.hICameraClient.h中定义了ICameraServiceICameraClient两个类

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实现

 

 

ICameraClientCamera类继承,

代码如下:

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的硬件抽像层中得到预览内容的数据,并调用iSurfaceregisterBuffers()将内存注册到输出设备(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();

}

}

当具有输出设备时,调用iSurfacepostBuffer()函数将视频送出,当上层的ICameraClient具有预览和回调函数时,则调用这个函数将视频传递给上层,这里分为:

需要复制数据

不需要复制数据

通常显示输出设备和iCameraClicen预览的回调函数,两者有一个就能实现预览功能

 

CameraJNI代码

代码路径: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;

}

}

 

Camerajava代码:

代码的路径为:

\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的硬件抽像层

androidcamera系统最底层部分,直接负责控制硬件

其接口在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&params)=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硬件抽像层的“桩”,可以根据宏来进行配置

这个桩使用假的方式,可以实现一个取景器预览等功能,他用黑白相间的格子来代码来自硬件的视频流,这样就能在不接触硬件的情况下,可以让androidcamera系统在没有硬件的情况下运行起来

 

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_STUBfalse则联接libcamera.so(动态库),使用真实的camera硬件抽像层

如果USE_CAMERA_STUBtrue则联接libcamerastub.a,静态库),使用camera硬件抽像层的“桩”实现,假装运行在CameraHardwareStub.cppFakeCamera.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.htCameraHardwareStub.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中实现kBufferCountMemoryBase

status_tCameraHardwareStub::startPreview()

{

Mutex::Autolocklock(mLock);

if(mPreviewThread!=0){

//alreadyrunning

returnINVALID_OPERATION;

}

mPreviewThread=newPreviewThread(this);

returnNO_ERROR;

}

 

 

Camera硬功夫件抽像层的硬件实现

取景器预览的主要步骤:

初始化的过程中,建立预览数据的内存队列

startPreview()中,保存预览回调函数,建立预览线程

在视频线程循环中,等待数据到达

 

你可能感兴趣的:(android)