Устройство захвата кадров камеры на основе Mini PCI для сбора данных видеопотока с использованием функции обратного вызова в API - PullRequest
0 голосов
/ 19 марта 2020

У меня есть карта захвата mini PCI ( MPX-6864 ), которую я хочу использовать для захвата видеопотока с камеры наблюдения, дающей композитный сигнал ( PAL / NTS C) стандартный вывод. Я уже включил в свой проект DLL , поставляемый с аппаратным SDK. Хотя я могу обнаружить / прочитать сведения о карте и устройстве, подключенном к карте через API, я не могу получить видеопоток, используя функцию обратного вызова API . Пожалуйста, обратитесь к функции ниже.

typedef int (__stdcall *TwVideoStreamCallback)(int nChannel, VOID *DataBuf, int width, int height, BOOL bField2, void *context, __int64 pts);
TW68XX_API BOOL   __stdcall TwRegisterVideoStreamCallback(TwVideoStreamCallback VideoStreamCallback, VOID *Context);

Я сомневаюсь:

  1. Как вызвать эти функции и получить поток данных.
  2. Как функции обратного вызова и callback_register используются в закрытом API
  3. Что такое указатель контекста функции обратного вызова, используемый в обеих функциях

Вот windows SDK и драйвер для конкретного оборудования. Документация, представленная в нем, не очень помогает.

Ваша помощь будет высоко оценена.

Пожалуйста, используйте код ниже

/* intialise SDK */
        BOOL init = TwInitSDK();
        if (init == 1){
            qDebug() << "Initialization Successfull";
        }
    /* Get board details */
        qDebug() << endl;
        int noOfBoard = TwGetBoardCount();
        qDebug() << "Number of Boards: " << noOfBoard;
        HANDLE bHandle = TwGetBoardHandle(noOfBoard-1);
        qDebug() << "Board Handle is: " << bHandle;
        TBoardDesc pBoardDesc;
        qDebug() << endl;
        qDebug() << "Fetching Board Details....";
        BOOL bDetails = TwGetBoardDetail(bHandle, &pBoardDesc);
        if (bDetails == 1){
            qDebug() << "\t Successful in Fetching Details: ";
            qDebug() << "\t Board Index: " << pBoardDesc.nBoardId;
            qDebug() << "\t Slot no. of board: " << pBoardDesc.nSlot;
            qDebug() << "\t Devices on board: " << pBoardDesc.nDeviceCount;
            qDebug() << "\t Index of first device: " << pBoardDesc.nFirstDevice;
        }
        else{
            qDebug() << "\t Could not Fetch details...";
            qDebug() << "\t Please refer error code: " << TwGetLastError();
        }
    /* Get Device details */
        qDebug() << endl;
        int deviceCount = TwGetDeviceCount();
        qDebug() << "Number of Device: " << deviceCount;
        HANDLE dHandle = TwGetDeviceHandle(deviceCount-1);
        qDebug() << "Device Handle: " << dHandle;
        TDeviceDesc pDevDesc;
        qDebug() << endl;
        qDebug() << "Fetching Device details....";
        BOOL devDetails = TwGetDeviceDetail(dHandle, &pDevDesc);
        if (devDetails == 1){
            qDebug() << "\t Successfull in Fetching Details.... ";
            qDebug() << "\t Device Index: " << pDevDesc.nDeviceId;
            qDebug() << "\t Index of Board where device is: " << pDevDesc.nBoardId;
            qDebug() << "\t Bus number of Board: " << pDevDesc.nBus;
            qDebug() << "\t Device Hardware ID: " << pDevDesc.HardwareId;
            qDebug() << "\t Device Number: " << pDevDesc.DeviceNumber;
            qDebug() << "\t Total dub-device number in device: " << pDevDesc.nSubDevice;
            qDebug() << "\t Index of first sub-device in device: " << pDevDesc.nFirstSubDevice;
        }
        else{
            qDebug() << "\t Could not Fetch details...";
            qDebug() << "\t Please refer error code: " << TwGetLastError();
        }
    /* Get sub-device details */
        qDebug() << endl;
        int subDeviceCount = TwGetSubDeviceCount();
        qDebug() << "Number of Sub-Device: " << subDeviceCount;
        HANDLE sdHandle = TwGetSubDeviceHandle(subDeviceCount-1);
        qDebug() << "Sub-Device Handle: " << sdHandle;
        TSubDeviceDesc pSubDevDesc;
        qDebug() << endl;
        qDebug() << "Fetching Device details....";
        BOOL subDevDetails = TwGetSubDeviceDetail(sdHandle, &pSubDevDesc);
        if (subDevDetails == 1){
            qDebug() << "\t Successfull in Fetching Details.... ";
            qDebug() << "\t Device index where sub-device is: " << pSubDevDesc.nDeviceId;
            qDebug() << "\t Index of Board where sub-device is: " << pSubDevDesc.nBoardId;
            qDebug() << "\t Whether audio is included:" << pSubDevDesc.nAudio;
            qDebug() << "\t The max channel number of non real time switching supported by sub-device: " << pSubDevDesc.iSwitch;
            qDebug() << "\t Total channel number contained by sub-device: " << pSubDevDesc.nChannels;
            qDebug() << "\t Index of the first channel by sub-device: " << pSubDevDesc.nFirstChannel;
            qDebug() << "\t Whether capture odd / even field seperately: " << pSubDevDesc.bField2;
            qDebug() << "\t Video input mask: " << pSubDevDesc.VideoInputMask;
        }
        else{
            qDebug() << "\t Could not Fetch details...";
            qDebug() << "\t Please refer error code: " << TwGetLastError();
        }
    /* Enable input video channel */
        qDebug() << endl;
        BOOL enable = TwEnableVideoInput(sdHandle, viCompositeVideo1, TRUE);
        if (enable == TRUE){
            qDebug() << "Enableing video successfull....";
        }
        else{
            qDebug() << "Enabling Video failed....";
            qDebug() << "Please refer error code: " << TwGetLastError();
        }
    /* Video parameter set before Channel details */
        TVideoPara vPara;
        vPara = vpBufferType;
        BOOL prevSetPara = TwSetVideoPara(NULL, vPara, vbtD1);
        if(prevSetPara == 1){
            qDebug() << "Parameter set before channel details is successfull....";
        }
        else{
            qDebug() << "Parameter setting failed....";
            qDebug() << "Please refer error code: " << TwGetLastError();
        }
    /* Get channel details */
        qDebug() << endl;
        int chCount = TwGetChannelCount();
        qDebug() << "Number of Channels: " << chCount;
        int nChannel = chCount-4; // modify to a typedef struct for nChannel index
        HANDLE chHandle = TwChannelOpen(nChannel);
        qDebug() << "Channel Handle: " << chHandle;
        TChannelDesc pChannelDesc;
        qDebug() << endl;
        qDebug() << "Fetching Channel Details....";
        BOOL chDetails = TwGetChannelDetail(chHandle, &pChannelDesc);
        if (chDetails == 1){
            qDebug() << "\t Successfull in Fetching Details.... ";
            qDebug() << "\t Index of board where channel is: " << pChannelDesc.nBoardId;
            qDebug() << "\t Index of devic where device is: " << pChannelDesc.nDeviceId;
            qDebug() << "\t Index of device where sub-device is: " << pChannelDesc.nSubDeviceId;
            qDebug() << "\t Max frame rate of channel: " << pChannelDesc.nMaxFrameRate;
            qDebug() << "\t Whether audio is contained in channel: " << pChannelDesc.nAudio;
        }
        else{
            qDebug() << "\t Could not Fetch details....";
            qDebug() << "\t Please refer error code: " << TwGetLastError();
        }
    /* Set Video Parameters */
        LONG paraValue;
        TwSetVideoPara(chHandle, vpWidth, 720);
        TwSetVideoPara(chHandle, vpHeight, 576);
        TwSetVideoPara(chHandle, vpFrameRate, 25);
        TwSetVideoPara(chHandle, vpPixelFormat, vpfYUV422Interspersed);
        TwSetVideoPara(chHandle, vpStandard, vsStandardPAL);
        TwSetVideoPara(chHandle, vpBufferType, vbtD1);
    /* Get Video Parameters */
        qDebug() << "\nGetting Video Parameter....";
        TwGetVideoPara(chHandle, vpWidth, &paraValue);
//        int width = paraValue;
        qDebug() << "Video Width: " << paraValue;
        TwGetVideoPara(chHandle, vpHeight, &paraValue);
//        int height = paraValue;
        qDebug() << "Video Height: " << paraValue;
        TwGetVideoPara(chHandle, vpFrameRate, &paraValue);
        qDebug() << "Video Frame Rate: " << paraValue;
        TwGetVideoPara(chHandle, vpPixelFormat, &paraValue);
        qDebug() << "Video PIXEL Format: " << paraValue;
        TwGetVideoPara(chHandle, vpStandard, &paraValue);
        qDebug() << "Video Video Standard: " << paraValue;
        TwGetVideoPara(chHandle, vpBufferType, &paraValue);
        qDebug() << "Video Buffer Type: " << paraValue;
    /* Start Video Capture */
        qDebug() << endl;
        BOOL captureEnable = TwStartVideoCapture(chHandle);
        if (captureEnable == 1){
            qDebug() << "Video Capture Started....";
        }
        else{
            qDebug() << "Could not start video capture...";
            qDebug() << "Please refer error code: " << TwGetLastError();
        }
    /* Obtain Data Stream */

        int extra_context = 42;
        TwVideoStreamCallback my_callback;
        BOOL ret = TwRegisterVideoStreamCallback(my_callback, (void*)&extra_context);
        if (ret) {
            qDebug() << "Data stream available...";
        }
//        qDebug() << extra_context;
//        TwVideoStreamCallback videoStream;
//        VOID *Context;
//        BOOL data = TwRegisterVideoStreamCallback(videoStream, &Context);
//        if (data == 1){
//            qDebug() << "Data stream available...";
//        }
//        else{
//            qDebug() << "Data stream not available...";
//            qDebug() << "Please refer error code: " << TwGetLastError();
//        }
//        videoStream(nChannel, &DataBuf, width, height, FALSE, &context, 0);
//        qDebug() << videoStream;
//        qDebug() << Context;

    /* Stop channel */
        TwChannelClose(chHandle);
    /* Stop Video Capture */
        qDebug() << endl;
        BOOL captureDisable = TwStopVideoCapture(chHandle);
        if (captureDisable == 1){
            qDebug() << "Video Capture Stoped....";
        }
        else{
            qDebug() << "Could not stop video capture...";
            qDebug() << "Please refer error code: " << TwGetLastError();
        }

и функция обратного вызова

__stdcall int MainWindow::my_callback(int nChannel, VOID *DataBuf, int width, int height, BOOL bField2, void *context, __int64 pts) {
    qDebug() << "Callback with image of " << width << "x" << height << " pixels. from channel number: "<< nChannel << " @ timestamp: " << pts;
    qDebug() << "Address: " << DataBuf << endl;
    int extra_context = *reinterpret_cast<int*>(context); // will be 42.
    return extra_context;
}

1 Ответ

1 голос
/ 19 марта 2020

От вас ожидает, что этот SDK определит и предоставит вашу собственную функцию, соответствующую типу обратного вызова:

typedef int (__stdcall *TwVideoStreamCallback)(int nChannel, VOID *DataBuf, int width, int height, BOOL bField2, void *context, __int64 pts);

__stdcall int my_callback(int nChannel, VOID *DataBuf, int width, int height, BOOL bField2, void *context, __int64 pts) {
  std::cout << "Callback with image of " << width << "x" << height << " pixels. Address: " << std::hex << DataBuf << std::endl;
  int extra_context = *reinterpret_cast<int*>(context); // will be 42.
}

int main() { // or wherever
  int extra_context = 42;
  BOOL ret = TwRegisterVideoStreamCallback(my_callback, (void*)&extra_context);
  if (!ret) {
    std::cerr << "Something went wrong" << std::endl;
  }
  SleepEx(INFINITE, false);
}
...