Camera HAL层代码分析2

来源:互联网 发布:jsp加载时调用js 编辑:程序博客网 时间:2024/05/30 20:07

camera open之后,可以调用startPreview函数进行preview,今天主要讲解Camera HAL层startPreview的follow。

先判定camera是否打开,没有打开则直接返回。

status_t CameraHardware:: startPreview(){    status_t ret = NO_ERROR;    int PreviewFrameSize;    if (mCameraOpened == false)        return UNKNOWN_ERROR;

HAL层有提供函数判定Camera是否打开:

bool CameraHardware::isCameraOpened(){    return mCameraOpened;};

camera打开后,先判定是否已经在preview,如果已经preview,直接返回

 ALOGI("startPreview");    Mutex::Autolock lock(mPreviewLock);    if (mPreviewEnabled) {        ALOGE("Preview already running");        return ALREADY_EXISTS;    }

根据preview的格式,计算previewFramesize:

if (strcmp(mParameters.getPreviewFormat(), CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 ||        strcmp(mParameters.getPreviewFormat(), CameraParameters::PIXEL_FORMAT_YUV420P) == 0 ) {        // YUV420SP        mPreviewFrameSize = mWidth * mHeight * 3 / 2;    } else {        // YUV422        mPreviewFrameSize = mWidth * mHeight * 2;    }

最后进行JpegDecoder初始化以及开启decoder和preview thread

 mJpegDecoder.Init();    usleep(1000 * 1000 );    mPreviewEnabled = true;    mDecodeThread = new DecodeThread(this);    mPreviewThread = new PreviewThread(this);

在CameraHardWare.h中定义DecodeThread:

    class DecodeThread : public Thread {        CameraHardware* mHal;    public:        DecodeThread(CameraHardware* hal) :#ifdef SINGLE_PROCESS        // In single process mode this thread needs to be a java thread,        // since we won't be calling through the binder.        Thread(true),#else        Thread(false),#endif        mHal(hal) {}        virtual void onFirstRef() {            run("CameraDecodeThread", PRIORITY_URGENT_DISPLAY);        }        virtual bool threadLoop() {            mHal->decodeThread();            // loop until we need to quit            return true;        }    };

可以看到,此线程一直在执行mHal->decodeThread();,即调用CameraHardware::decodeThread()

在CameraHardWare.h中定义PreviewThread:

    class PreviewThread : public Thread {        CameraHardware* mHal;    public:        PreviewThread(CameraHardware* hal) :#ifdef SINGLE_PROCESS        // In single process mode this thread needs to be a java thread,        // since we won't be calling through the binder.        Thread(true),#else        Thread(false),#endif        mHal(hal) {}        virtual void onFirstRef() {            run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY);        }        virtual bool threadLoop() {            mHal->previewThread();            // loop until we need to quit            return true;        }    };

同decodeThread,最终调用到CameraHardware::previewThread()。

 

int CameraHardware::decodeThread(){    if (mPreviewEnabled && mImageFormat == V4L2_PIX_FMT_MJPEG        &&( mANativeWindow != NULL || mRecordingEnabled)) {        void* buf = mJpegDecoder.GetEmptyYuvBuffer();        if (buf == NULL)            return NO_ERROR;        char *rawFramePointer = mCamera->GrabRawFrame();        if (rawFramePointer) {            if (mJpegDecoder.Decode(mPreviewBufs, rawFramePointer, mCamera->videoIn->buf.bytesused, buf))                mJpegDecoder.SetYuvBufferState(buf, false);        } else if (!rawFramePointer) {            ALOGE("Got EMPTY raw data !!!!!");            usleep(1000 * 50 );            return UNKNOWN_ERROR;        }#if DUMP_JPEG        char fname[50];        FILE *file;        static int nCapture = 0;        sprintf(fname, "/var/tmp/media/capture-%06u.jpg", nCapture);        nCapture++;        if (nCapture >= 5)            nCapture = 0;        file = fopen(fname, "wb");        if (file != NULL) {            fwrite(rawFramePointer, mCamera->videoIn->buf.bytesused, 1, file);            fclose(file);        }#endif        mCamera->ProcessRawFrameDone();    }    return NO_ERROR;}

主要是对camera获取的buffer数据进行decode,可以通过DUMP_JPEG查看preview的图片。

同样在previewThread中可以打印出当前preview的fps:

#if COUNT_FPS            static time_t start, end;            static int totalframe = 0;            if (totalframe == 0)                time(&start);            time(&end);            totalframe ++;            if (difftime (end,start) >= 1) {                ALOGI("FPS(%d, %d) ::::::::::::::::: %d", mWidth, mHeight, totalframe);                totalframe = 0;            }#endif


 

 


 


 


 



 




 

 

0 0
原创粉丝点击