真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Qt??祍dk回調(diào)方法是什么

這篇文章主要介紹“Qt海康sdk回調(diào)方法是什么”,在日常操作中,相信很多人在Qt??祍dk回調(diào)方法是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Qt??祍dk回調(diào)方法是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

10年積累的網(wǎng)站建設(shè)、網(wǎng)站制作經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認識你,你也不認識我。但先制作網(wǎng)站后付款的網(wǎng)站建設(shè)流程,更有蘿北免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

一、前言

??祍dk顯示實時視頻流除了支持句柄方式以外,也支持回調(diào)的方式拿到每一張圖片自己繪制處理,當然回調(diào)除了拿到視頻數(shù)據(jù),其實音頻數(shù)據(jù)也一塊拿到了,自行調(diào)用音頻設(shè)備播放就行,關(guān)于海康sdk回調(diào)這塊,還著實折騰了一陣子才搞定,可能最開始沒有參照提供的demo以及沒有徹底的搜索吧,只是單單看sdk的文檔折騰來折騰去的,搞了一星期居然沒搞定,后面找到了正確的辦法才發(fā)現(xiàn),原來就差一點點一丟丟呢,這又讓我聯(lián)想到很多事情,包括生活中的事情,不都是如此么?當你鉚足了勁,試驗搞了各種辦法,快要精疲力盡放棄的時候,其實此時離成功就差一步了,真的就差那么一丟丟,處理生活中的很多事情也是如此,所以很多時候如果方向?qū)α?,堅持過努力過,還不行的話,再努力一把估計就ok了。

折騰了很久總結(jié)失敗在哪里,調(diào)用NET_DVR_RealPlay_V40設(shè)置回調(diào)函數(shù)也是對的,回調(diào)函數(shù)里面也進去了,調(diào)用PlayM4_SetDecCallBackMend設(shè)置解碼回調(diào)函數(shù)也是對的(這地方也著實折騰了一陣子,沒想到還要用播放MP4的形式來處理),最后發(fā)現(xiàn)問題出在解碼后的數(shù)據(jù),數(shù)據(jù)也都是拿到了,默認是yv12的數(shù)據(jù),如果需要轉(zhuǎn)成image的話就需要做個轉(zhuǎn)換,這個轉(zhuǎn)換網(wǎng)上找了一堆的函數(shù)來測試,都失敗了,后面找到一個yv12轉(zhuǎn)rgb888格式的,終于可以了,我勒個去。

??祍dk回調(diào)流程:

  1. 調(diào)用NET_DVR_RealPlay_V40設(shè)置回調(diào)處理函數(shù)。

  2. 在回調(diào)處理函數(shù)RealDataCallBack中依次處理打開、播放、解碼。

  3. 調(diào)用PlayM4_GetPort獲取播放庫未使用的通道號。

  4. 調(diào)用PlayM4_OpenStream打開視頻流。

  5. 調(diào)用PlayM4_SetDecCallBackMend設(shè)置解碼回調(diào)函數(shù),只解碼不顯示。

  6. 調(diào)用PlayM4_Play播放視頻流。

  7. 調(diào)用PlayM4_InputData循環(huán)解碼數(shù)據(jù)。

  8. 在解碼回調(diào)函數(shù)DecCallBack中分別處理音視頻數(shù)據(jù)。

  9. 調(diào)用自己封裝的yv12ToRGB888函數(shù)將數(shù)據(jù)轉(zhuǎn)成QImage。

關(guān)于回調(diào)函數(shù)請注意以下幾點:

  1. 回調(diào)函數(shù)必須有關(guān)鍵詞 CALLBACK。

  2. 回調(diào)函數(shù)本身必須是全局函數(shù)或者靜態(tài)函數(shù),不可定義為某個特定的類的成員函數(shù)。

  3. 回調(diào)函數(shù)并不由開發(fā)者直接調(diào)用執(zhí)行,只是使用系統(tǒng)接口API函數(shù)作為起點。

  4. 回調(diào)函數(shù)通常作為參數(shù)傳遞給系統(tǒng)API,由該API來調(diào)用。

  5. 回調(diào)函數(shù)可能被系統(tǒng)API調(diào)用一次,也可能被循環(huán)調(diào)用多次。

二、功能特點

  1. 支持播放視頻流和本地MP4文件。

  2. 支持句柄和回調(diào)兩種模式。

  3. 多線程顯示圖像,不卡主界面。

  4. 自動重連網(wǎng)絡(luò)攝像頭。

  5. 可設(shè)置邊框大小即偏移量和邊框顏色。

  6. 可設(shè)置是否繪制OSD標簽即標簽文本或圖片和標簽位置。

  7. 可設(shè)置兩種OSD位置和風格。

  8. 可設(shè)置是否保存到文件以及文件名。

  9. 可直接拖曳文件到haikangwidget控件播放。

  10. 支持h364/h365視頻流。

  11. 可暫停播放和繼續(xù)播放。

  12. 支持存儲單個視頻文件和定時存儲視頻文件。

  13. 自定義頂部懸浮條,發(fā)送單擊信號通知,可設(shè)置是否啟用。

  14. 可設(shè)置畫面拉伸填充或者等比例填充。

  15. 可設(shè)置解碼是速度優(yōu)先、質(zhì)量優(yōu)先、均衡處理。

  16. 可對視頻進行截圖(原始圖片)和截屏(視頻窗體)。

  17. 錄像文件存儲為MP4文件。

  18. 支持焦距控制、云臺控制。

  19. 可定制功能。

三、效果圖

Qt??祍dk回調(diào)方法是什么

四、核心代碼

//yv12轉(zhuǎn)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(yData[yIdx] + 1.370705 * (vData[uIdx] - 128));
            rgb[1] = static_cast(yData[yIdx] - 0.698001 * (uData[uIdx] - 128) - 0.703125 * (vData[vIdx] - 128));
            rgb[2] = static_cast(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(rgb[k]);
                } else {
                    rgb888[idx] = (rgb[k] < 0) ? (0) : (255);
                }
            }
        }
    }
    return true;
}

//解碼回調(diào) 視頻為YUV420P數(shù)據(jù)(YV12),音頻為PCM數(shù)據(jù)
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;

    //視頻數(shù)據(jù)是 T_YV12 音頻數(shù)據(jù)是 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)
{
    //每個類都對應(yīng)自己的 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;
                }

                //設(shè)置解碼回調(diào)函數(shù) 只解碼不顯示
                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:
            //解碼數(shù)據(jù)
            if (dwBufSize > 0 && nPort != -1) {
                BOOL inData = PlayM4_InputData(nPort, pBuffer, dwBufSize);
                while (!inData) {
                    sleep(10);
                    inData = PlayM4_InputData(nPort, pBuffer, dwBufSize);
                }
            }
            break;
    }
}

到此,關(guān)于“Qt??祍dk回調(diào)方法是什么”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
本文標題:Qt??祍dk回調(diào)方法是什么
文章網(wǎng)址:http://weahome.cn/article/jscpdc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部