联咏科技MS300二维码识别在android平台上实现流程二
novatek实现底层的时候,它将实现细节封装成一个库了,留出来一个头文件。
路径:mediatek/source/external/novatek/Novatek_Special_function_0.h
我们引用的时候,包含该头文件,编译连接其共享库就可以使用头文件中提供的方法。我们大概看一下其库提供的方法如下:
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二维码识别的过程。
我们如果自己开发新的模块,完全可以借签它的这个流程。