您好,登錄后才能下訂單哦!
這篇文章主要介紹“Qt海康sdk回調方法是什么”,在日常操作中,相信很多人在Qt海康sdk回調方法是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Qt海康sdk回調方法是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
海康sdk顯示實時視頻流除了支持句柄方式以外,也支持回調的方式拿到每一張圖片自己繪制處理,當然回調除了拿到視頻數據,其實音頻數據也一塊拿到了,自行調用音頻設備播放就行,關于海康sdk回調這塊,還著實折騰了一陣子才搞定,可能最開始沒有參照提供的demo以及沒有徹底的搜索吧,只是單單看sdk的文檔折騰來折騰去的,搞了一星期居然沒搞定,后面找到了正確的辦法才發現,原來就差一點點一丟丟呢,這又讓我聯想到很多事情,包括生活中的事情,不都是如此么?當你鉚足了勁,試驗搞了各種辦法,快要精疲力盡放棄的時候,其實此時離成功就差一步了,真的就差那么一丟丟,處理生活中的很多事情也是如此,所以很多時候如果方向對了,堅持過努力過,還不行的話,再努力一把估計就ok了。
折騰了很久總結失敗在哪里,調用NET_DVR_RealPlay_V40設置回調函數也是對的,回調函數里面也進去了,調用PlayM4_SetDecCallBackMend設置解碼回調函數也是對的(這地方也著實折騰了一陣子,沒想到還要用播放MP4的形式來處理),最后發現問題出在解碼后的數據,數據也都是拿到了,默認是yv12的數據,如果需要轉成image的話就需要做個轉換,這個轉換網上找了一堆的函數來測試,都失敗了,后面找到一個yv12轉rgb888格式的,終于可以了,我勒個去。
海康sdk回調流程:
調用NET_DVR_RealPlay_V40設置回調處理函數。
在回調處理函數RealDataCallBack中依次處理打開、播放、解碼。
調用PlayM4_GetPort獲取播放庫未使用的通道號。
調用PlayM4_OpenStream打開視頻流。
調用PlayM4_SetDecCallBackMend設置解碼回調函數,只解碼不顯示。
調用PlayM4_Play播放視頻流。
調用PlayM4_InputData循環解碼數據。
在解碼回調函數DecCallBack中分別處理音視頻數據。
調用自己封裝的yv12ToRGB888函數將數據轉成QImage。
關于回調函數請注意以下幾點:
回調函數必須有關鍵詞 CALLBACK。
回調函數本身必須是全局函數或者靜態函數,不可定義為某個特定的類的成員函數。
回調函數并不由開發者直接調用執行,只是使用系統接口API函數作為起點。
回調函數通常作為參數傳遞給系統API,由該API來調用。
回調函數可能被系統API調用一次,也可能被循環調用多次。
支持播放視頻流和本地MP4文件。
支持句柄和回調兩種模式。
多線程顯示圖像,不卡主界面。
自動重連網絡攝像頭。
可設置邊框大小即偏移量和邊框顏色。
可設置是否繪制OSD標簽即標簽文本或圖片和標簽位置。
可設置兩種OSD位置和風格。
可設置是否保存到文件以及文件名。
可直接拖曳文件到haikangwidget控件播放。
支持h364/h365視頻流。
可暫停播放和繼續播放。
支持存儲單個視頻文件和定時存儲視頻文件。
自定義頂部懸浮條,發送單擊信號通知,可設置是否啟用。
可設置畫面拉伸填充或者等比例填充。
可設置解碼是速度優先、質量優先、均衡處理。
可對視頻進行截圖(原始圖片)和截屏(視頻窗體)。
錄像文件存儲為MP4文件。
支持焦距控制、云臺控制。
可定制功能。
//yv12轉RGB888 static bool yv12ToRGB888(const unsigned char *yv12, unsigned char *rgb888, int width, int height) { if ((width < 1) || (height < 1) || (yv12 == NULL) || (rgb888 == NULL)) { return false; } int len = width * height; unsigned char const *yData = yv12; unsigned char const *vData = &yData[len]; unsigned char const *uData = &vData[len >> 2]; int rgb[3]; int yIdx, uIdx, vIdx, idx; for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { yIdx = i * width + j; vIdx = (i / 2) * (width / 2) + (j / 2); uIdx = vIdx; rgb[0] = static_cast<int>(yData[yIdx] + 1.370705 * (vData[uIdx] - 128)); rgb[1] = static_cast<int>(yData[yIdx] - 0.698001 * (uData[uIdx] - 128) - 0.703125 * (vData[vIdx] - 128)); rgb[2] = static_cast<int>(yData[yIdx] + 1.732446 * (uData[vIdx] - 128)); for (int k = 0; k < 3; ++k) { idx = (i * width + j) * 3 + k; if ((rgb[k] >= 0) && (rgb[k] <= 255)) { rgb888[idx] = static_cast<unsigned char>(rgb[k]); } else { rgb888[idx] = (rgb[k] < 0) ? (0) : (255); } } } } return true; } //解碼回調 視頻為YUV420P數據(YV12),音頻為PCM數據 static void CALLBACK DecCallBack(qport nPort, char *pBuf, qport nSize, FRAME_INFO *pFrameInfo, quser luser, quser nReserved2) { HaiKangThread *thread = (HaiKangThread *)luser; long frameType = pFrameInfo->nType; //視頻數據是 T_YV12 音頻數據是 T_AUDIO16 if (frameType == T_YV12) { //qDebug() << TIMEMS << width << height << thread; int width = pFrameInfo->nWidth; int height = pFrameInfo->nHeight; QImage image(width, height, QImage::Format_RGB888); if (yv12ToRGB888((unsigned char *)pBuf, image.bits(), width, height)) { thread->setImage(image); } } else if (frameType == T_AUDIO16) { //qDebug() << TIMEMS << "T_AUDIO16" << thread; } } static void CALLBACK RealDataCallBack(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, void *dwUser) { //每個類都對應自己的 port HaiKangThread *thread = (HaiKangThread *)dwUser; qport nPort = thread->port; DWORD dRet; switch (dwDataType) { case NET_DVR_SYSHEAD: //獲取播放庫未使用的通道號 if (!PlayM4_GetPort(&nPort)) { break; } if (dwBufSize > 0) { thread->port = nPort; if (!PlayM4_OpenStream(nPort, pBuffer, dwBufSize, 1024 * 1024)) { dRet = PlayM4_GetLastError(nPort); break; } //設置解碼回調函數 只解碼不顯示 if (!PlayM4_SetDecCallBackMend(nPort, DecCallBack, (quser)dwUser)) { dRet = PlayM4_GetLastError(nPort); break; } //打開視頻解碼 if (!PlayM4_Play(nPort, NULL)) { dRet = PlayM4_GetLastError(nPort); break; } //打開音頻解碼, 需要碼流是復合流 if (!PlayM4_PlaySound(nPort)) { dRet = PlayM4_GetLastError(nPort); break; } } break; case NET_DVR_STREAMDATA: //解碼數據 if (dwBufSize > 0 && nPort != -1) { BOOL inData = PlayM4_InputData(nPort, pBuffer, dwBufSize); while (!inData) { sleep(10); inData = PlayM4_InputData(nPort, pBuffer, dwBufSize); } } break; } }
到此,關于“Qt海康sdk回調方法是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。