I have a mini PCI capture card (MPX-6864) which i want to use for grabbing video stream from a surveillance camera giving composite (PAL/NTSC) standard output. I have already included the DLL provided with the hardware SDK in my project. Though i am able to detect/read details about the card and device interfaced with the card through the API, I am not able to take the video stream output using the API's callback function. Please refer to the function below.
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);
My doubt is:
- How to call these function and acquire the data stream.
- How callback and callback_register functions are used in a closed API
- What is context pointer of callback function used in both the functions
Your help will be very much appreciated.
Please refer the code below
/* 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, ¶Value);
// int width = paraValue;
qDebug() << "Video Width: " << paraValue;
TwGetVideoPara(chHandle, vpHeight, ¶Value);
// int height = paraValue;
qDebug() << "Video Height: " << paraValue;
TwGetVideoPara(chHandle, vpFrameRate, ¶Value);
qDebug() << "Video Frame Rate: " << paraValue;
TwGetVideoPara(chHandle, vpPixelFormat, ¶Value);
qDebug() << "Video PIXEL Format: " << paraValue;
TwGetVideoPara(chHandle, vpStandard, ¶Value);
qDebug() << "Video Video Standard: " << paraValue;
TwGetVideoPara(chHandle, vpBufferType, ¶Value);
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();
}
and the callback function is
__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;
}
TwRegisterVideoStreamCallback(some_function, nullptr)
and see ifsome_function
is called) theContext
you pass will be passed ascontext
to the callback. You can use it to store data that the callback needs for that stream. – BotjeTwRegisterVideoCallback
has an input of typeTwVideoCallback
so i don't know whether it will be callable or not. I am new to this concept. – Rohit Kalia