android 中的audio系统
Audo系统主要分如下几个层次:
1.Media库提供的Audio系统本地部分接口
2.audioFlinger作为audio系统的中间层
3.audio的硬件层提供底层支持
4.audio接口通过JNI和java框架提供给上层
Audio的系统结构如下图
代码分布如下:
1 audio 的java部分
路径为:/frameworks/base/media/java/android/media 例: audioManager
2 Audio 的JNI 部分 (最终生成库libandroid_runtime.so)
/frameworks/base/core/jni
3 audio的框架部分
头文件部分:/frameworks/base/include/media
源代码部分:/frameworks/base/media/libmedia
是media库的一部分,最终被编译成libmedia.so 提供audio部分接口
4 audio Flinger
代码路径:/frameworks/base/libs/surfaceflinger_client
最终被编译成:libaudioflinger.so audio系统的本地服务部分
5 audo 的硬件抽像层接口
代码路径:/hardware/libhardware_legacy/include/hardware_legacy
作为本地框架层和驱动程序的接口
Audio系统和上层接口 一般以pcm作为输入和输出格式
Audio自上而下:
1 .java的audio类,
2 . audio本地框架类 libmedia.so的一部分,对上层提供接口,由本地代码实现
3 .audioFlinger 继承libmeida接口,提供libaudiofilnger.so
4 .audio的硬件抽像层
各个层次之间的对应关系
Media库中的框架部分
主要实现三个类:audioSystem audioTrack audioRecorder
IaudioFlinger audioTrack 实现 IaudioTrack 播放
audioRecorder 实现 IaudioRecorder 录制
Audio系统的头文件
路径是:/frameworks/base/include/media
AudioSystem.h 对上层的总管接口
IAudioFlinger.h 需要下层实现的总管接口
audioTrack.h 放音部分对上接口
IaudioTrack.h 放音部分需要下层实现的接口
audioRecorder 录音部分对上接口
IaudioRecorder 录音部分需要下层实现接口
audioFlinger本地代码
代码路径:
/frameworks/base/libs/audioFlinger audio系统的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 系统处理的宏观逻辑是:
上层通过调用控制接口来控制下层,并设置回调函数,下层通过回调函数向上层传递数据
1 camera类
代码路径为:\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 //所有消息
};
class CameraListener: virtual public RefBase
{
public:
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;//消息通知
virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr) = 0;//传递没有时间戳的帧数据
virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0; //传递有时间戳的帧数据
};
//回调函数rawCallback jpegCallback previewCallback recordingCallback 等回调函数均可以用
// postData()和postDataTimestamp() 用枚举值进行区分
class Camera : public BnCameraClient, public IBinder::DeathRecipient
{
public:
// construct a camera client from an existing remote
static sp<Camera> create(const sp<ICamera>& camera);
static int32_t getNumberOfCameras();
static status_t getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo);
static sp<Camera> connect(int cameraId);
~Camera();
//核心按制部分
void init();
status_t reconnect();
void disconnect();
status_t lock();
status_t unlock();
status_t getStatus() { return mStatus; }
// pass the buffered ISurface to the camera service
// 预览部分
status_t setPreviewDisplay(const sp<Surface>& surface);
status_t setPreviewDisplay(const sp<ISurface>& surface);
// start preview mode, must call setPreviewDisplay first
status_t startPreview();
// stop preview mode
void stopPreview();
// get preview state
bool previewEnabled();
// start recording mode, must call setPreviewDisplay first
//记录视频部分
status_t startRecording();
// stop recording mode
void stopRecording();
// get recording state
bool recordingEnabled();
// release a recording frame
void releaseRecordingFrame(const sp<IMemory>& mem);
// autoFocus - status returned from callback
//拍照和辅助功能
status_t autoFocus();
// cancel auto focus
status_t cancelAutoFocus();
// take a picture - picture returned from callback
status_t takePicture();
// set preview/capture parameters - key/value pairs
status_t setParameters(const String8& params);
// get preview/capture parameters - key/value pairs
String8 getParameters() const;
// send command to camera driver
status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
void setListener(const sp<CameraListener>& listener);
void setPreviewCallbackFlags(int preview_callback_flag);
// ICameraClient interface
//数据流的传输是通过回调函数来实现
virtual void notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
virtual void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr);
virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
sp<ICamera> remote();
private:
Camera();
Camera(const Camera&);
Camera& operator=(const Camera);
virtual void binderDied(const wp<IBinder>& who);
class DeathNotifier: public IBinder::DeathRecipient
{
public:
DeathNotifier() {
}
virtual void binderDied(const wp<IBinder>& who);
};
static sp<DeathNotifier> mDeathNotifier;
// helper function to obtain camera service handle
static const sp<ICameraService>& getCameraService();
sp<ICamera> mCamera;
status_t mStatus;
sp<CameraListener> mListener;
friend class DeathNotifier;
static Mutex mLock;
static sp<ICameraService> mCameraService;
};
};
预览功能的两种方式:
一、不设预览设备,设置回调函数setPreviewCallback().可以得到取景器预览的数据流,自行输出到指定设备
二、设置预览设备setPreviewDisplay(),不设回调函数,由C ameraService会进行取景器输出,
数据流不通过上层,
一般使用第二种方式,他又分为:使用overlay和不使用overlay
视频录制功能
使用startRecording()和stopRecording()为起点和终点,通过设置回调函数setRecordingCallbak()来接受视频录制的数据,releaseRecordingFrame()函数是调用者通知下层“当前帧已结束”camera 的照片功能使用takePicture()接口setRawCallback 或者setJpegCallBack回调函数来取数据
2 ICamera类
ICamera.h中定义了ICamera 和BnCamera类.,要求CameraService 进行实现,
代码如下:
class ICamera: public IInterface
{
public:
DECLARE_META_INTERFACE(Camera);
virtual void disconnect() = 0;
// connect new client with existing camera remote
virtual status_t connect(const sp<ICameraClient>& client) = 0;
// prevent other processes from using this ICamera interface
virtual status_t lock() = 0;
// allow other processes to use this ICamera interface
virtual status_t unlock() = 0;
// pass the buffered ISurface to the camera service
virtual status_t setPreviewDisplay(const sp<ISurface>& surface) = 0;
// set the preview callback flag to affect how the received frames from
// preview are handled.
virtual void setPreviewCallbackFlag(int flag) = 0;
// start preview mode, must call setPreviewDisplay first
virtual status_t startPreview() = 0;
// stop preview mode
virtual void stopPreview() = 0;
// get preview state
virtual bool previewEnabled() = 0;
// start recording mode
virtual status_t startRecording() = 0;
// stop recording mode
virtual void stopRecording() = 0;
// get recording state
virtual bool recordingEnabled() = 0;
// release a recording frame
virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0;
// auto focus
virtual status_t autoFocus() = 0;
// cancel auto focus
virtual status_t cancelAutoFocus() = 0;
// take a picture
virtual status_t takePicture() = 0;
// set preview/capture parameters - key/value pairs
virtual status_t setParameters(const String8& params) = 0;
// get preview/capture parameters - key/value pairs
virtual String8 getParameters() const = 0;
// send command to camera driver
virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0;
};
// ----------------------------------------------------------------------------
class BnCamera: public BnInterface<ICamera>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
};
3 ICameraService.h和ICameraClient.h 中定义了 ICameraService和ICameraClient两个类
ICameraService类需要下层去实现
代码如下:
class ICameraService : public IInterface
{
public:
enum {
GET_NUMBER_OF_CAMERAS = IBinder::FIRST_CALL_TRANSACTION,
GET_CAMERA_INFO,
CONNECT
};
public:
DECLARE_META_INTERFACE(CameraService);
virtual int32_t getNumberOfCameras() = 0;
virtual status_t getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo) = 0;
virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient,
int cameraId) = 0;
};
// ----------------------------------------------------------------------------
class BnCameraService: public BnInterface<ICameraService>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
};
ICameraService通过传入一个ICameraClient作为参数,来取得一个ICamera 类型的接口, 这个接口是实际的camera实现
ICameraClient被Camera类继承,
代码如下:
class ICameraClient: public IInterface
{
public:
DECLARE_META_INTERFACE(CameraClient);
virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
virtual void dataCallback(int32_t msgType, const sp<IMemory>& data) = 0;
virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& data) = 0;
};
//以上函数均可调用postData()和postDataTimestamp()
// ----------------------------------------------------------------------------
class BnCameraClient: public BnInterface<ICameraClient>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
};
该类型的功能主要是起回调作用,通过被继承将回调函数传给Camaera的下层cameraService
Camera.cpp 1.6以后增加的cameraListener相当于1.5之前的回调函数
代码路径为:\frameworks\base\libs\camera
该类实现了ICameraClient 中的几个函数,代码如下:
void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
{
sp<CameraListener> listener;
{
Mutex::Autolock _l(mLock);
listener = mListener;
}
if (listener != NULL) {
listener->postDataTimestamp(timestamp, msgType, dataPtr);
} else {
LOGW("No listener was set. Drop a recording frame.");
releaseRecordingFrame(dataPtr);
}
}
CameraService :他是camera系统中的中间层实现,继承libui提供的接口,没有对外的API
CameraService.cpp中定义类CameraService,它继承BnCameraService的实现
基运作过程中:cameraService:connect()函数用来得到cameraService:client,主要调用这个类的接口来实现camera功能.
cameraService具体实现是通过Camera的硬件抽像层来完成,以下是拍照的接口
status_t CameraService::Client::takePicture() {
LOG1("takePicture (pid %d)", getCallingPid());
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
enableMsgType(CAMERA_MSG_SHUTTER |
CAMERA_MSG_POSTVIEW_FRAME |
CAMERA_MSG_RAW_IMAGE |
CAMERA_MSG_COMPRESSED_IMAGE);
return mHardware->takePicture();
}
cameraService需要处理的一个逻辑是取景器的预览问题
如果上层设置了预览输出设备,预览在cameraService以下处理,
如果使用overlay数据流在camera的硬件抽像层处理,
如果不使用overlay数据流在cameraService中处理
预览功能是从以下函数开始
status_t CameraService::Client::startPreview() {
LOG1("startPreview (pid %d)", getCallingPid());
return startCameraMode(CAMERA_PREVIEW_MODE);
}
之后调用以下:
status_t CameraService::Client::startPreviewMode() {
LOG1("startPreviewMode");
status_t result = NO_ERROR;
// if preview has been enabled, nothing needs to be done
if (mHardware->previewEnabled()) {
return NO_ERROR;
}
if (mUseOverlay) {//如果mUseOverlay为真,则表示使用overlay
// If preview display has been set, set overlay now.
if (mSurface != 0) {
result = setOverlay();
}
if (result != NO_ERROR) return result;
result = mHardware->startPreview();
} else {//不使用overlay的情况
enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
result = mHardware->startPreview();
if (result != NO_ERROR) return result;
// If preview display has been set, register preview buffers now.
if (mSurface != 0) {
// Unregister here because the surface may be previously registered
// with the raw (snapshot) heap.
mSurface->unregisterBuffers();
result = registerPreviewBuffers();
}
}
return result;
}
对于使用overlay 的情况,取景器的预览是在camera的硬件层中处理,cameraService 只需要调用setoverlay()把overlay设备设置到其中即可.
对于不合用overlay的情况,需要从camera的硬件抽像层中得到预览内容的数据,并调用iSurface的registerBuffers()将内存注册到输出设备(ISurface)中
设置到Camera硬件抽像层中的回调函数,他会调用handlePreviewData(),将视频发送到输出设备
void CameraService::Client::dataCallback(int32_t msgType,
const sp<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("Null data returned in data callback");
client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
return;
}
switch (msgType) {
case CAMERA_MSG_PREVIEW_FRAME:
client->handlePreviewData(dataPtr);//将数据发送到输出设备
break;
case CAMERA_MSG_POSTVIEW_FRAME:
client->handlePostview(dataPtr);
break;
case CAMERA_MSG_RAW_IMAGE:
client->handleRawPicture(dataPtr);
break;
case CAMERA_MSG_COMPRESSED_IMAGE:
client->handleCompressedPicture(dataPtr);
break;
default:
client->handleGenericData(msgType, dataPtr);
break;
}
}
handlePreviewData()用来处理surface输出情况,
void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) {
ssize_t offset;
size_t size;
sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
if (!mUseOverlay) {
if (mSurface != 0) {
mSurface->postBuffer(offset);//将视频数据送出
}
}
// local copy of the callback flags
int flags = mPreviewCallbackFlag;
// is callback enabled?
if (!(flags & FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
// If the enable bit is off, the copy-out and one-shot bits are ignored
LOG2("frame callback is disabled");
mLock.unlock();
return;
}
// hold a strong pointer to the client
sp<ICameraClient> c = mCameraClient;
// clear callback flags if no client or one-shot mode
if (c == 0 || (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
LOG2("Disable preview callback");
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) {
// Is the received frame copied out or not?
//进行ICameraClient的回调函数的处理,
if (flags & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
LOG2("frame is copied");
//复制传递内存
copyFrameAndPostCopiedFrame(c, heap, offset, size);
} else {
LOG2("frame is forwarded");
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部分代码
static JNINativeMethod camMethods[] = {
...
{ "setPreviewDisplay",
"(Landroid/view/Surface;)V",
(void *)android_hardware_Camera_setPreviewDisplay }
...
}
setPreviewDisplay函数的处理过程如下(以serviceView为参数,将一个外部的surface设置给camera的本地接口,由本地进行取景器的输出处理)
static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz, jobject jSurface)
{
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", "setPreviewDisplay failed");
}
}
仅当设置时才会使用:
static void android_hardware_Camera_setHasPreviewCallback(JNIEnv *env, jobject thiz, jboolean installed, jboolean manualBuffer)
{
LOGV("setHasPreviewCallback: installed:%d, manualBuffer:%d", (int)installed, (int)manualBuffer);
// Important: Only install preview_callback if the Java code has called
// setPreviewCallback() with a non-null value, otherwise we'd pay to memcpy
// each preview frame for nothing.
JNICameraContext* context;
sp<Camera> camera = get_native_camera(env, thiz, &context);
if (camera == 0) return;
// setCallbackMode will take care of setting the context flags and calling
// camera->setPreviewCallbackFlags within a mutex for us.
context->setCallbackMode(env, installed, manualBuffer);
}
previewCallback ()可以将预览数据传达递到java层。
由于视频流的数据量很大,所以不会送到java 层进行处理,只通过设置输出设备(surface),在本地处理;
照片处理的函数:这个函数没有参数,可以通过java层的回调函数实现
static JNINativeMethod camMethods[] = {
。。。
{ "native_takePicture",
"()V",
(void *)android_hardware_Camera_takePicture },
。。。
}
函数的实现
static void android_hardware_Camera_takePicture(JNIEnv *env, jobject thiz)
{
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", "takePicture failed");
return;
}
}
Camera的java代码:
代码的路径为:
\frameworks\base\core\java\android\hardware
部分代码如下:
public class Camera {
//对应的本地方法
public native final void startPreview();
public native final void stopPreview();
public native final boolean previewEnabled();
//拍照函数的定义
public final void takePicture(ShutterCallback shutter, PictureCallback raw,
PictureCallback postview, PictureCallback jpeg) {
mShutterCallback = shutter;
mRawImageCallback = raw;
mPostviewCallback = postview;
mJpegCallback = jpeg;
native_takePicture();
}
}
外部接口的takePicture 将调用本地方法private native final void native_takePicture();
public interface PictureCallback {
/**
* Called when image data is available after a picture is taken.
* The format of the data depends on the context of the callback
* and {@link Camera.Parameters} settings.
*
* @param data a byte array of the picture data
* @param camera the Camera service object
*/
void onPictureTaken(byte[] data, Camera camera);
};
得到的是内存中的照片数据
Camera 的硬件抽像层
是android 中camera系统最底层部分,直接负责控制硬件
其接口在CameraHardwareInterface.h头文件中进行定义,代码路径为:
\frameworks\base\include\camera
其接口类型与上层接口类型类似, 包含:取景器预览,视频录制,照片拍摄
Camera硬件抽像层需要实现这个类,最终编译生成libcamera.so
其代码如下
namespace android {
class Overlay;
//指针
typedef struct image_rect_struct
{
uint32_t width; /* Image width */
uint32_t height; /* Image height */
} image_rect_type;
typedef void (*notify_callback)(int32_t msgType,
int32_t ext1,
int32_t ext2,
void* user);
typedef void (*data_callback)(int32_t msgType,
const sp<IMemory>& dataPtr,
void* user);
typedef void (*data_callback_timestamp)(nsecs_t timestamp,
int32_t msgType,
const sp<IMemory>& dataPtr,
void* user);
class CameraHardwareInterface : public virtual RefBase {
public:
virtual ~CameraHardwareInterface() { }
/** Return the IMemoryHeap for the preview image heap */
virtual sp<IMemoryHeap> getPreviewHeap() const = 0;
/** Return the IMemoryHeap for the raw image heap */
virtual sp<IMemoryHeap> getRawHeap() const = 0;
/** Set the notification and data callbacks */
virtual void setCallbacks(notify_callback notify_cb,
data_callback data_cb,
data_callback_timestamp data_cb_timestamp,
void* user) = 0;
virtual void enableMsgType(int32_t msgType) = 0;
virtual void disableMsgType(int32_t msgType) = 0;
virtual bool msgTypeEnabled(int32_t msgType) = 0;
virtual status_t startPreview() = 0;
virtual bool useOverlay() {return false;}
virtual status_t setOverlay(const sp<Overlay> &overlay) {return BAD_VALUE;}
/**
* Stop a previously started preview.
*/
virtual void stopPreview() = 0;
/**
* Returns true if preview is enabled.
*/
virtual bool previewEnabled() = 0;
virtual status_t startRecording() = 0;
virtual void stopRecording() = 0;
virtual bool recordingEnabled() = 0;
virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0;
virtual status_t autoFocus() = 0;
virtual status_t cancelAutoFocus() = 0;
virtual status_t takePicture() = 0;
virtual status_t cancelPicture() = 0;
virtual status_t setParameters(const CameraParameters& params) = 0;
virtual CameraParameters getParameters() const = 0;
virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0;
virtual void release() = 0;
virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
};
extern "C" int HAL_getNumberOfCameras();
extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo);
/* HAL should return NULL if it fails to open camera hardware. */
extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId);
};
cameraHardsareInterface 中的startPreview() stopRecording() takePicture()直接传入回调函数的支持,
函数中定义的回调函数指针,用于数据的传输和信息的传递
CameraParameters.h这个类是用于定义camera系统参数的类,在cameraHardwareInterface中通过setParameter()和getParameter()
部分代码如下:
class CameraParameters
{
public:
CameraParameters();
CameraParameters(const String8 ¶ms) { unflatten(params); }
~CameraParameters();
String8 flatten() const;
void unflatten(const String8 ¶ms);
void set(const char *key, const char *value);//设置键和键值
void set(const char *key, int value);
void setFloat(const char *key, float value);
const char *get(const char *key) const; //取得键和键值
int getInt(const char *key) const;
float getFloat(const char *key) const;
void remove(const char *key);
void setPreviewSize(int width, int height);
void getPreviewSize(int *width, int *height) const;
void getSupportedPreviewSizes(Vector<Size> &sizes) const;
void setPreviewFrameRate(int fps);
int getPreviewFrameRate() const;
void getPreviewFpsRange(int *min_fps, int *max_fps) const;
void setPreviewFormat(const char *format);
const char *getPreviewFormat() const;
void setPictureSize(int width, int height);
void getPictureSize(int *width, int *height) const;
void getSupportedPictureSizes(Vector<Size> &sizes) const;
void setPictureFormat(const char *format);
const char *getPictureFormat() const;
void dump() const;
status_t dump(int fd, const Vector<String16>& args) const;
}
该函数中除了预览大小、格式、照片大小、格式等,还可以使作键和键值来进行任意设置,
Camera中默认不使用overlay(),如果想使用可以通过setOverlay() 进行设置
Camera硬功夫件抽像层的桩实现
cameraService 中,实现了一个camera硬件抽像层的“桩”,可以根据宏来进行配置
这个桩使用假的方式,可以实现一个取景器预览等功能,他用黑白相间的格子来代码来自硬件的视频流,这样就能在不接触硬件的情况下,可以让android的camera系统在没有硬件的情况下运行起来
cameraService 的.mk文件
文件的路径是:\frameworks\base\services\camera\libcameraservice
代码内容是:
LOCAL_PATH:= $(call my-dir)
# Set USE_CAMERA_STUB if you don't want to use the hardware camera.
# force these builds to use camera stub only
ifneq ($(filter sooner generic sim,$(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中实现
头文件的部分代码如下:
class FakeCamera {
public:
FakeCamera(int width, int height);
~FakeCamera();
void setSize(int width, int height);
void getNextFrameAsYuv420(uint8_t *buffer);//颜色空间格式
// Write to the fd a string representing the current state.
void dump(int fd) const;
private:
// TODO: remove the uint16_t buffer param everywhere since it is a field of
// this class.
void getNextFrameAsRgb565(uint16_t *buffer);//颜色空间格式
void drawSquare(uint16_t *buffer, int x, int y, int size, int color, int shadow);
void drawCheckerboard(uint16_t *buffer, int size);
static const int kRed = 0xf800;
static const int kGreen = 0x07c0;
static const int kBlue = 0x003e;
int mWidth, mHeight;
int mCounter;
int mCheckX, mCheckY;
uint16_t *mTmpRgb16Buffer;
};
};
CameraHardwareStub.ht和CameraHardwareStub.cpp继承CameraHardwareInterface
initHeapLocked函数在CameraHardwareStub.cpp中,代码如下:
void CameraHardwareStub::initHeapLocked()
{
// Create raw heap.
int picture_width, picture_height;
mParameters.getPictureSize(&picture_width, &picture_height);
mRawHeap = new MemoryHeapBase(picture_width * picture_height * 3 / 2);
int preview_width, preview_height;
mParameters.getPreviewSize(&preview_width, &preview_height);
LOGD("initHeapLocked: preview size=%dx%d", preview_width, preview_height);
// Note that we enforce yuv420sp in setParameters().
int how_big = preview_width * preview_height * 3 / 2;
// If we are being reinitialized to the same size as before, no
// work needs to be done.
if (how_big == mPreviewFrameSize)
return;
mPreviewFrameSize = how_big;
// Make a new mmap'ed heap that can be shared across processes.
// use code below to test with pmem
mPreviewHeap = new MemoryHeapBase(mPreviewFrameSize * kBufferCount);
// Make an IMemory for each frame so that we can reuse them in callbacks.
for (int i = 0; i < kBufferCount; i++) {
mBuffers[i] = new MemoryBase(mPreviewHeap, i * mPreviewFrameSize, mPreviewFrameSize);
}
// Recreate the fake camera to reflect the current size.
delete mFakeCamera;
mFakeCamera = new FakeCamera(preview_width, preview_height);
}
在这个过程中开辟两块内存
一个是拍照照片的内存mRawHeap
一个是取景器预览的内存mPreviewHeap
由于mPreviewHeap是一个序列,所以在mPreviewHeap中实现kBufferCount个MemoryBase
status_t CameraHardwareStub::startPreview()
{
Mutex::Autolock lock(mLock);
if (mPreviewThread != 0) {
// already running
return INVALID_OPERATION;
}
mPreviewThread = new PreviewThread(this);
return NO_ERROR;
}
Camera硬功夫件抽像层的硬件实现
取景器预览的主要步骤:
初始化的过程中,建立预览数据的内存队列
在startPreview()中,保存预览回调函数 ,建立预览线程
在视频线程循环中,等待数据到达