編輯:關於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二維碼識別的過程。
我們如果自己開發新的模塊,完全可以借簽它的這個流程。
下面是配置Android開發ADB環境變量的操作步驟。工具/原料win7系統電腦+Android SDK方法/步驟1.首先右擊計算機——屬性——高級系統設置——環境變量;
Service沒有UI,因為service是後台運行如:下載,網絡I/O 等等Service的生命周期從它被創建開始,到它被銷毀為止,onCrea
1 SeekBar簡介SeekBar是進度條。我們使用進度條時,可以使用系統默認的進度條;也可以自定義進度條的圖片和滑塊圖片等。2 SeekBar示例創建一個activi
基本概念AsyncTask:異步任務,從字面上來說,就是在我們的UI主線程運行的時候,異步的完成一些操作。AsyncTask允許我們的執行一個異步的任務在後台。我們可以將