Android摄像头采集Demo

定义MyCameraContext类,该类必须继承CameraListener,采集到数据时,将会触发该类内部定义的回调函数:postData。注意android2.3,和2.2在构造函数上是有区别的

 

//MyCameraContext.h 


#ifndef MY_CAMERA_H

#define  MY_CAMERA_H

#include "jni.h"

//#include "JNIHelp.h"

#include "android_runtime/AndroidRuntime.h"



#include <utils/Vector.h>



#include <surfaceflinger/Surface.h>

#include <camera/Camera.h>

#include <binder/IMemory.h>

#include <stdint.h>

using namespace android;

class MyCameraContext: public CameraListener

{

public:

    MyCameraContext(const sp<Camera>& camera);

    ~MyCameraContext() { ; }

    //特殊事件通知回调,包括错误之类....目前在Demo中未使用

    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);

    //采集数据回调....

    virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr);

    //获取时间回调........目前在Demo中未使用

    virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);

    void setCallbackMode();

    void getcallbackfunc(void(*p)(void* lpdata,int len) ){mcallbackfunc=p; };

    sp<Camera> getCamera() { return mCamera; }

private:

        void(*mcallbackfunc)(void* lpdata,int len) ;

    void copyAndPost(const sp<IMemory>& dataPtr, int msgType);

    sp<Camera>  mCamera;                // strong reference to native object

   // Mutex       mLock;



};



sp<Camera> CreateCamera();



sp<MyCameraContext> CreateCameraContext(sp<Camera>& spCamera);



int setPreviewDisplaysurface(sp<Camera>& spCamera, sp<Surface>& surface);


#endif




//MyCameraContext.cpp 


#include "MyCamera.h"





MyCameraContext::MyCameraContext(const sp<Camera>& camera)

{



    mCamera = camera;

}







void MyCameraContext::notify(int32_t msgType, int32_t ext1, int32_t ext2)

{



}



void MyCameraContext::copyAndPost( const sp<IMemory>& dataPtr, int msgType)

{

    jbyteArray obj = NULL;

    if (dataPtr != NULL) {

        ssize_t offset;

        size_t size;

        sp<IMemoryHeap> heap = dataPtr->getMemory(&offset, &size);

        mcallbackfunc((void*)(heap->getBase()+offset),size);

        uint8_t *heapBase = (uint8_t*)heap->base();

        }

}



void MyCameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr)

{

    copyAndPost(dataPtr, msgType);



}



void MyCameraContext::postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)

{

    postData(msgType, dataPtr);

}



void MyCameraContext::setCallbackMode()

{

    mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_CAMERA);

}

#ifdef ANDROID2_3  //android2.3

sp<Camera> CreateCamera()

{

        int NumberOfCameras=Camera::getNumberOfCameras();

        CameraInfo cameraInfo;

        for (int i = 0; i < NumberOfCameras; i++) {

                    status_t rc = Camera::getCameraInfo(i, &cameraInfo);

                    if (rc != NO_ERROR) {                

                        break;

                     }

                if(cameraInfo.facing==CAMERA_FACING_BACK) {

                        sp<Camera> camera = Camera::connect(i);

                        return camera;

                }

        }

        return NULL;

}

#else //android 2.2

sp<Camera> CreateCamera()

{



        sp<Camera> camera = Camera::connect();

        if(camera->get())

                return camera;

        return NULL;

}

#endif



sp<MyCameraContext> CreateCameraContext(sp<Camera>& spCamera)

{

    sp<MyCameraContext> context = new MyCameraContext(spCamera);

    spCamera->setListener(context);

    return context;

}



int setPreviewDisplaysurface(sp<Camera>& spCamera, sp<Surface>& surface)

{

        if (spCamera->setPreviewDisplay(surface) != NO_ERROR)

                return -1;

        return 1;

}





//测试demo:


#include "MyCamera.h"

void databackfunc(void *base,int size);



void databackfunc(void *base,int size)

{

  //注意数据格式的处理

  //spCamera->getParameters(); 获取各种采集参数包括格式

   //数据处理

}



JNIEXPORT  jint Java_lpc_bairui_android_lpc_camera(JNIEnv* env, jclass clazz)

{



        sp<Surface> sps;

        sp<Camera> spCamera=CreateCamera();

        if(spCamera.get()){        

                spCameraContext=CreateCameraContext(spCamera);

                if(spCameraContext.get()){

                        /*并没有为sps赋值,所以它不指向任何Surface,所以将不会创建预览格式,仅仅获取数据

                        setPreviewDisplaysurface函数在*/

                        if( setPreviewDisplaysurface(spCamera,sps)==1){

                                //String8  str("preview-size=240x320");

                                //spCamera->setParameters(str);

                                //spCamera->getParameters().string();

                                spCameraContext->setCallbackMode();

                                //设置处理采集到数据的回调函数

                                spCameraContext->getcallbackfunc(databackfunc);

                                //开始采集

                                spCamera->startPreview();

                                

                                return 1;

                        }

                        

                }

        }

        return 0;

}

 

你可能感兴趣的:(android,jni)