- 浏览: 261308 次
- 性别:
- 来自: 济南
文章分类
- 全部博客 (303)
- c (31)
- c++ (16)
- java (18)
- c# (1)
- python (3)
- java web (6)
- oracle (7)
- sqlserver (2)
- mysql (2)
- android (24)
- android系统 (15)
- android多媒体部分 (15)
- android游戏 (12)
- linux (26)
- javaScript (1)
- ajax (1)
- node JS (2)
- html (5)
- apache (3)
- jboss (1)
- weblogic (0)
- 通信协议 (10)
- 云计算 (1)
- 分布式 (5)
- ejb (1)
- webservice (5)
- 设计模式 (16)
- JNI (6)
- swing (13)
- 版本控制 (1)
- UML (1)
- xml (4)
- spring (5)
- hibernate (5)
- struts1 (3)
- struts2 (4)
- ibatis (0)
- tomcat (2)
- 心得体会 (1)
- css (1)
- 嵌入式 (41)
- arm体系结构 (10)
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()中,保存预览回调函数,建立预览线程
在视频线程循环中,等待数据到达
发表评论
-
android系统学习笔记一
2012-09-03 15:01 9071.android的系统架构(linux2.6内核) Lin ... -
android系统学习笔记二
2012-09-03 15:03 912android的linux内核和驱动程序 Androidr专 ... -
android系统学习笔记三
2012-09-03 15:05 838第四章android的底层库和程序 知识点: And ... -
android系统学习笔记四
2012-09-03 15:07 1133Android的GUI系统 AndroidGUI系统综 ... -
android系统学习笔记六
2012-09-03 15:16 2220android的多媒体系统 ... -
android系统学习笔记七
2012-09-03 15:18 738Android电话部分综述 主 ... -
android系统学习八
2012-09-03 15:19 754Android的联接部分 Wifi部分 Wif ... -
android系统学习笔记九
2012-09-03 15:21 736蓝牙部分 蓝牙协议栈1.11.22.02.13.0 异步数 ... -
android系统学习笔记十一
2012-09-03 15:22 1501Gps(globalPositionSystem全球定位系统) ... -
android系统学习笔记十二
2012-09-03 15:23 1018Android的传感器系统 ... -
Android编译系统详解(一)
2012-09-10 13:45 829+++++++++++++++++++++++++++++ ... -
android----ServiceManager
2012-09-18 00:33 4318serviceManager 在c++层如何使用servi ... -
android 自定义核心服务
2012-09-18 23:27 796native service zygote 服务 kern ... -
android系统移植学习笔记一
2012-09-21 16:08 626系统框架 applicationjava应用程序 ...
相关推荐
Android学习笔记是Android开发者的必读书籍,书中涵盖了Android系统架构、Activity、Intent、资源管理等多方面的知识。本笔记对应的学习资源《第一行代码》是Android开发者的入门必读书籍,书中系统地介绍了Android...
Android基础学习笔记主要涵盖了一系列关于Android开发的基本概念和关键组件,以下是这些知识点的详细解析: 1. **Activity**: 是Android应用程序的基本单元,它代表用户在屏幕上看到的一个界面。每个Activity都必须...
这篇学习笔记将引导新手入门,通过创建第一个简单的案例来了解Android Studio的基本操作。 首先,让我们了解一下Android Studio的核心功能。它基于IntelliJ IDEA,具备代码自动补全、重构、调试等强大的开发特性。...
Android Activity学习笔记 Android Activity是Android系统中最基本的组件之一,它负责处理用户交互和显示用户界面。本文将深入讲解Activity的生命周期、Activity之间的数据交互、Activity启动模式、Task和BackStack...
- Android系统基于Linux系统开发,拥有开放源码。 - Android系统框架由多个组件构成,其中包括Activity、Intent、Service、ContentProvider、View和BroadcastReceiver。 - Activity作为组件容器,主要负责用户...
根据给定的信息,我们可以从Java和Android学习笔记中提取出一系列重要的知识点,下面将逐一进行详细解释。 ### Java基础知识 #### 1. 命令行基础操作 - **`javacmd`**: 这个命令是Java命令行工具的一部分,用于...
### Android学习笔记知识点详解 #### 一、简介与背景 Android作为全球最受欢迎的移动操作系统之一,自2007年谷歌发布以来,迅速占领市场并持续引领移动技术的发展。随着移动互联网的兴起和发展,Android应用开发...
### Android学习笔记——从HelloWorld开始 #### 一、Google的Android SDK介绍 自从Google发布了Android SDK以来,这款开源移动操作系统迅速吸引了众多开发者的关注。Android SDK为开发者提供了丰富的工具和API,...
Android全程学习笔记旨在提供一个详尽且全面的指南,涵盖了Android开发中的关键技术点和实践案例。以下是关于Android开发的一些核心知识点: 1. **第一个Android应用**:开发Android应用的起点通常是从创建并运行你...
这篇学习笔记主要涵盖了关于布局的一些基本概念,特别是`fill_parent`和`wrap_content`这两种尺寸指定方式,以及如何通过XML布局文件来精确控制组件的位置。 首先,`fill_parent`和`wrap_content`是Android布局中的...
这个"Android_学习笔记.zip"文件很可能包含了一个详细的Android开发学习路径和关键知识点的总结。下面将基于这个主题,详细讲解Android开发的一些核心概念和技术。 首先,Android是Google开发的一款开源操作系统,...
在Android系统相关学习笔记中,我们可以深入探讨这个广泛而复杂的移动操作系统的核心概念和技术。Android以其开源性和灵活性,吸引了大量的开发者和爱好者。以下是一些关键的知识点: 1. **Android架构**:Android...
【Android学习笔记详解】 在移动应用开发领域,Android操作系统占据着重要的地位,为开发者提供了...通过系统学习并实践其中的内容,你将能够逐步掌握Android开发的核心技能,为你的Android开发者之路打下坚实的基础。
### Android开发学习笔记知识点梳理 #### 一、Android概述与架构 - **定义与发布**:Android是由Google在2007年11月5日宣布的基于Linux平台的开源手机操作系统。它不仅用于智能手机,还广泛应用于平板电脑、可穿戴...
这篇学习笔记将深入探讨PreferenceActivity的使用方法、功能以及与源码相关的知识。 首先,PreferenceActivity是Android SDK提供的一种特殊类型的Activity,它允许开发者快速构建具有可配置选项的界面,类似于系统...
这篇Android学习笔记主要涵盖了从第五章到第十三章的内容,是Android开发者或对Android系统感兴趣的初学者的重要参考资料。笔记详细解读了Android应用开发的核心概念和技术,旨在帮助读者深入理解并掌握Android开发...