`

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学习笔记 完整版

    Android学习笔记是Android开发者的必读书籍,书中涵盖了Android系统架构、Activity、Intent、资源管理等多方面的知识。本笔记对应的学习资源《第一行代码》是Android开发者的入门必读书籍,书中系统地介绍了Android...

    Android基础学习笔记

    Android基础学习笔记主要涵盖了一系列关于Android开发的基本概念和关键组件,以下是这些知识点的详细解析: 1. **Activity**: 是Android应用程序的基本单元,它代表用户在屏幕上看到的一个界面。每个Activity都必须...

    Android Studio 学习笔记-新手入门-(1)第一个案例

    这篇学习笔记将引导新手入门,通过创建第一个简单的案例来了解Android Studio的基本操作。 首先,让我们了解一下Android Studio的核心功能。它基于IntelliJ IDEA,具备代码自动补全、重构、调试等强大的开发特性。...

    Android Activity学习笔记

    Android Activity学习笔记 Android Activity是Android系统中最基本的组件之一,它负责处理用户交互和显示用户界面。本文将深入讲解Activity的生命周期、Activity之间的数据交互、Activity启动模式、Task和BackStack...

    Android学习笔记

    ### Android学习笔记 #### 1. Android概述 **1.1 Android的特性** - **应用框架**:Android提供了一个强大的应用框架,使得开发者能够轻松地重用基础组件和服务,简化了应用程序的开发流程。 - **Dalvik虚拟机**...

    Android学习新手笔记

    - Android系统基于Linux系统开发,拥有开放源码。 - Android系统框架由多个组件构成,其中包括Activity、Intent、Service、ContentProvider、View和BroadcastReceiver。 - Activity作为组件容器,主要负责用户...

    java学习细节 android学习笔记

    根据给定的信息,我们可以从Java和Android学习笔记中提取出一系列重要的知识点,下面将逐一进行详细解释。 ### Java基础知识 #### 1. 命令行基础操作 - **`javacmd`**: 这个命令是Java命令行工具的一部分,用于...

    Android学习笔记.doc Android学习笔记.doc

    【Android学习笔记】 Android平台是谷歌推出的一个开放源代码的移动设备操作系统,它为开发者提供了一个全面的软件包,包括操作系统、中间件和关键应用程序。这个平台的主要目标是促进移动应用的创新和多样性,允许...

    Android+学习笔记

    ### Android学习笔记知识点详解 #### 一、简介与背景 Android作为全球最受欢迎的移动操作系统之一,自2007年谷歌发布以来,迅速占领市场并持续引领移动技术的发展。随着移动互联网的兴起和发展,Android应用开发...

    Android_学习笔记

    ### Android学习笔记——从HelloWorld开始 #### 一、Google的Android SDK介绍 自从Google发布了Android SDK以来,这款开源移动操作系统迅速吸引了众多开发者的关注。Android SDK为开发者提供了丰富的工具和API,...

    android全程学习笔记

    Android全程学习笔记旨在提供一个详尽且全面的指南,涵盖了Android开发中的关键技术点和实践案例。以下是关于Android开发的一些核心知识点: 1. **第一个Android应用**:开发Android应用的起点通常是从创建并运行你...

    Android 学习笔记

    这篇学习笔记主要涵盖了关于布局的一些基本概念,特别是`fill_parent`和`wrap_content`这两种尺寸指定方式,以及如何通过XML布局文件来精确控制组件的位置。 首先,`fill_parent`和`wrap_content`是Android布局中的...

    Android_学习笔记.zip

    这个"Android_学习笔记.zip"文件很可能包含了一个详细的Android开发学习路径和关键知识点的总结。下面将基于这个主题,详细讲解Android开发的一些核心概念和技术。 首先,Android是Google开发的一款开源操作系统,...

    Android 系统相关学习笔记.zip

    在Android系统相关学习笔记中,我们可以深入探讨这个广泛而复杂的移动操作系统的核心概念和技术。Android以其开源性和灵活性,吸引了大量的开发者和爱好者。以下是一些关键的知识点: 1. **Android架构**:Android...

    android 很好的学习笔记

    【Android学习笔记详解】 在移动应用开发领域,Android操作系统占据着重要的地位,为开发者提供了...通过系统学习并实践其中的内容,你将能够逐步掌握Android开发的核心技能,为你的Android开发者之路打下坚实的基础。

    Android开发学习笔记

    ### Android开发学习笔记知识点梳理 #### 一、Android概述与架构 - **定义与发布**:Android是由Google在2007年11月5日宣布的基于Linux平台的开源手机操作系统。它不仅用于智能手机,还广泛应用于平板电脑、可穿戴...

    Android PreferenceActivity 学习笔记

    这篇学习笔记将深入探讨PreferenceActivity的使用方法、功能以及与源码相关的知识。 首先,PreferenceActivity是Android SDK提供的一种特殊类型的Activity,它允许开发者快速构建具有可配置选项的界面,类似于系统...

    Android学习笔记(5-13)

    这篇Android学习笔记主要涵盖了从第五章到第十三章的内容,是Android开发者或对Android系统感兴趣的初学者的重要参考资料。笔记详细解读了Android应用开发的核心概念和技术,旨在帮助读者深入理解并掌握Android开发...

Global site tag (gtag.js) - Google Analytics