TAG:
novatek实现底层的时候,它将实现细节封装成一个库了,留出来一个头文件。 我们引用的时候,包含该头文件,编译连接其共享库就可以使用头文件中提供的方法。我们大概看一下其库提供的方法如下:
(qq345260600)extern "C" unsigned int NovatekCustomSpecial_init(unsigned int cameraId, unsigned int flag); extern "C" void NovatekCustomSpecial_SetResolution(unsigned int nvtSpecial_0, unsigned int width, unsigned int height); //added by albert on20120424 extern "C" void NovatekCustomSpecial_SetFlag(unsigned int nvtSpecial_0, unsigned int flag); extern "C" int NovatekCustomSpecial_Process(unsigned int nvtSpecial_0, unsigned int dataPtr, unsigned int ext1, unsigned int ext2); extern "C" void NovatekCustomSpecial_Close(unsigned int nvtSpecial_0); 从名字上我们就可以略窥一斑,大概就知道其方法的功能了。 一,jni传下来的命令是怎么处理的 我们找到sendcommand,其命令处理部分: case CAMERA_CMD_DO_NOVATEKSPEC: m_NovatekSpecialEn = arg1; break; 赋值给m_NovatekSpecialEn变量。 这个变量的作用就是,每次要解析二维码时,会先判断该变量是否为1,若为1再进行处理解析,否则放弃。所以就有了一个开关的作用了。 二,preview中设置和处理 status_t MTKCameraHardware::startPreviewInternal() { ...... if((m_NovatekSpecial==0) && (m_NovatekSpecialEn==1))//判断是否打开 { m_NovatekSpecial = NovatekCustomSpecial_init(mCameraId, 0);//初始化 if(m_NovatekSpecial==0) { CAM_LOG("[NovatekCustomSpecial_init]: Fail \n"); } else//如果没失败,则申请内存 { g_pMTKCameraHwObj->mNVTSpecialMemPool = NULL; g_pMTKCameraHwObj->mNVTSpecialMemPool = new CamMemPool(0x5000, "novatek", 1, 0x5000, PMEM_TYPE); if (g_pMTKCameraHwObj->mNVTSpecialMemPool->mMemHeapBase == NULL)//申请失败 { CAM_LOG("[allocCamNovatekMem] Err Not enough MEMORY for mNVTSpecialMemPool \n\n"); g_pMTKCameraHwObj->mNVTSpecialMemPool = NULL; NovatekCustomSpecial_Close(m_NovatekSpecial);//close m_NovatekSpecial = 0; } } } { int qvW, qvH; mParameters.getPreviewSize(&qvW, &qvH); NovatekCustomSpecial_SetResolution(m_NovatekSpecial, qvW, qvH);//设置preview时的解析度 } } 上面为preview中的关于二维码的设置,下面看一下preview中处理二维码: void* MTKCameraHardware::previewThread(void *arg) { ...... if ( (g_pMTKCameraHwObj->mNVTSpecialMemPool != NULL) && (g_pMTKCameraHwObj->m_NovatekSpecial != 0) && (g_pMTKCameraHwObj->m_NovatekSpecialEn==1))//判断部分 { NovatekCustomSpecial_SetFlag(g_pMTKCameraHwObj->m_NovatekSpecial,0);//设置标记 data_len=0; Process_ret = NovatekCustomSpecial_Process(g_pMTKCameraHwObj->m_NovatekSpecial, //二维码的处理部分 g_pMTKCameraHwObj->mPreviewMemPool->mVirtAddr + g_pMTKCameraHwObj->mPreviewMemPool->mBufferSize * g_pMTKCameraHwObj->mDispBufNo, (int32_t) g_pMTKCameraHwObj->mNVTSpecialMemPool->mVirtAddr, (int32_t) &data_len); if ( Process_ret == QRCODE_DETECT_OK)//如果处理OK { //to be continued... sp<MemoryHeapBase> NovatekHeap = new MemoryHeapBase(1); sp<MemoryBase> NovatekMem = new MemoryBase(NovatekHeap, 0, 1); tempbuf[0]=0x30; memcpy(NovatekHeap->base(), tempbuf, 1); //sp<MemoryBase> NovatekMem = new MemoryBase(g_pMTKCameraHwObj->mNVTSpecialMemPool->mMemHeapBase, 0, data_len); g_pMTKCameraHwObj->mDataCb(CAMERA_MSG_CUSTOMSPECIAL1, NovatekMem, g_pMTKCameraHwObj->mCallbackCookie); //发送msg1,包含数据,在分析一中,知道frameworks层收到改消息会调用app层的callback,将msg中的数据取出来 NovatekHeap=NULL; NovatekMem=NULL; //CAM_LOG(" Albert QRCODE_DETECT_OK Send Out: %d \n", Process_ret); } else { //CAM_LOG(" Albert No data: %d \n", Process_ret); } } ...... } 三,capture中处理 status_t MTKCameraHardware::takePictureProc() { if ( (g_pMTKCameraHwObj->mNVTSpecialMemPool != NULL) && (g_pMTKCameraHwObj->m_NovatekSpecial != 0) && (g_pMTKCameraHwObj->m_NovatekSpecialEn==1))//同样是判断部分 { NovatekCustomSpecial_SetFlag(g_pMTKCameraHwObj->m_NovatekSpecial, 1);//设置标记,要主要到跟preview是有区别的,0应该是指定芯片preview的时候进行侦测,1应该是指定芯片capture时进行解析 data_len=0; Process_ret= NovatekCustomSpecial_Process(g_pMTKCameraHwObj->m_NovatekSpecial, //进行解析二维码 g_pMTKCameraHwObj->mQvMemPool->mVirtAddr, (int32_t) g_pMTKCameraHwObj->mNVTSpecialMemPool->mVirtAddr, (int32_t) &data_len); //CAM_LOG("albert Process result: [%d] %d\n", data_len, Process_ret); if ( Process_ret == QRCODE_DECODE_OK)//如果解析ok { //to be continued... sp<MemoryHeapBase> NovatekHeap = new MemoryHeapBase(data_len+1); sp<MemoryBase> NovatekMem = new MemoryBase(NovatekHeap, 0, data_len+1); tempbuf[0] = 0x30; memcpy(NovatekHeap->base(), tempbuf, 1); memcpy((uint8_t *)NovatekHeap->base()+1, (uint8_t *)g_pMTKCameraHwObj->mNVTSpecialMemPool->mMemHeapBase->base(), data_len);//将数据拷贝出来 //sp<MemoryBase> NovatekMem = new MemoryBase(g_pMTKCameraHwObj->mNVTSpecialMemPool->mMemHeapBase, 0, data_len); g_pMTKCameraHwObj->mDataCb(CAMERA_MSG_CUSTOMSPECIAL2, NovatekMem, g_pMTKCameraHwObj->mCallbackCookie);//发送消息给frameworks NovatekHeap=NULL; NovatekMem=NULL; // CAM_LOG(" Albert QRCODE_DECODE_OK Send Out \n"); } ...... } } 至此,我们详细分析了从app到framework到jni到hal二维码识别的过程。 我们如果自己开发新的模块,完全可以借签它的这个流程。 |