android系统学习笔记五

  android 中的audio系统

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

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

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

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

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

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 .javaaudio,

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

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

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

                android_media_AudioRecord.cpp     系统输入控制

                android_media_AudioTrack.cpp      系统输出控制

Audiojava代码

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.hiCamera.h分别定义了CameraiCamera两个类,两个类接口形式不同,但功能类似

功能如下:

    预览功能(preview

    视频获取功能(recording

    拍照照片(takePicture)

    参数设置

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

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

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

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

  

1 camera

    代码路径为:\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    //所有消息

};

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.hICameraClient.h 中定义了   ICameraServiceICameraClient两个类

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

ICameraClientCamera类继承,

代码如下:

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

    }

}

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

        需要复制数据

        不需要复制数据

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

CameraJNI 代码

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

    }

}

Camerajava代码:

  代码的路径为:

\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硬件抽像层的“桩”,可以根据宏来进行配置

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

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

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

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()中,保存预览回调函数 ,建立预览线程

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

你可能感兴趣的:(java,android,callback,audio,frameworks,照片)