Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 聯詠科技MS300二維碼識別在android平台上實現流程二

聯詠科技MS300二維碼識別在android平台上實現流程二

編輯:關於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二維碼識別的過程。
我們如果自己開發新的模塊,完全可以借簽它的這個流程。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved