基于微型PCI的摄像机帧抓取器,用于使用API中的回调函数获取视频流数据



我有一个迷你PCI采集卡(MPX-6864(,我想用它从提供复合(PAL/NTSC。我已经在我的项目中包含了硬件SDK附带的DLL。虽然我能够通过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. 如何在已关闭的API中使用回调和callback_register函数
  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;
}

这个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);
}

最新更新