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
- Camera HAL层代码分析2
- Camera HAL层代码分析1
- Android5.0 MTk Camera HAL层代码分析
- camera GC0339 Rawdata hal层分析
- camera GC0339 Rawdata hal层分析
- android TIF HAL层代码分析
- hal层代码
- android HAL层代码
- HAL层代码
- Android HAL层分析
- mx53 camera HAL preview(接口层)
- Android Camera porting(HAL层移植)
- mx53 camera HAL preview(接口层)
- mx53 camera HAL preview(接口层)
- Android Camera porting(HAL层移植)
- Android Camera porting(HAL层移植)
- Android camera子系统HAL层介绍集锦
- Android camera子系统HAL层介绍集锦
- android.view.WindowLeaked的问题解决
- 生命的长度
- ICML 2014
- 第22章、OnItemSelectedListener事件与二级联动(从零开始学Android)
- VS折叠和展开代码快捷键
- Camera HAL层代码分析2
- ngni-x conf 配置
- GDB调试大型工程
- PL/SQL Developer如何连接64位的Oracle数据库
- new和delete
- 安装GCC 问题解决
- Java Swing 常识篇之EDT
- Access自定义函数(人民币大写)
- 第23章、OnFocuChangeListener焦点事件(从零开始学Android)