PDA

View Full Version : Qt application with live Active X camera feed.



bitChanger
16th January 2006, 22:19
I could really use some advice. I’m using Qt 4.1 and trying to implement an Active X control.

Here is a link to the Active X – AxisMediaControl SDK
http://www.axis.com/techsup/cam_servers/dev/activex.htm

In the SDK they have sample software using this Active X app through the MFC library, which I’ve noticed that the wrapper they wrote inherits a class called CWnd and calls a function named “InvokeHelper” for all of it’s control of the Active X component. This gives me no signs that a COM object exists for this app.

This is what I did and it doesn’t seem to work:

// ---------------------------------------------------------
QAxWidget* axis = new QAxWidget(this);

// this control id was verified and is correct
axis->setControl(QString::fromUtf8(“{745395C8-D0E1-4227-8586-624CA9A10A8D}”));
axis->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
axis->setObjectName(QString::fromUtf8(“AxisMediaCo ntrol”));

// setup the MediaURL
axis->dynamicCall(“InvokeHelper(0x1, 0x4, 0, 0, “”\x0E””, http://dizco.com:81/axis-cgi/mjpg/video.cgi)”);

// setup the MediaType
axis->dynamicCall(“InvokeHelper(0x1, 0x4, 0, 0, “”\x0E””, mjpeg-unicast)”);

// press Play
axis->dynamicCall(“InvokeHelper(0x65, 0x1, 0, 0, 0, 0);
// ---------------------------------------------------------

NOTE: If you decide to download the Active X control and run the sample Visual C++ project provided by them, go to the MJPEGunicastDlg.cpp and change the media URL to the one above and you can see the live camera feed work.

Any help you may be able to give me on using this Active X app in my Qt application would be much appreciated.
Thank you.

bitChanger
17th January 2006, 16:08
I've changed my code to look more like the Qt documentation in hopes that someone might recognize what i am doing wrong.

I'm guessing the InvokeHelper is not what i should be calling.
Here's some info on the method:


Call this member function to invoke the ActiveX Control method or property specified by dwDispID, in the context specified by wFlags.

void AFX_CDECL InvokeHelper(
DISPID dwDispID,
WORD wFlags,
VARTYPE vtRet,
void* pvRet,
const BYTE* pbParamInfo,
...
);
Parameters
dwDispID
Identifies the method or property to be invoked.
wFlags
Flags describing the context of the call to IDispatch::Invoke. For possible wFlags values, see IDispatch::Invoke in the Platform SDK.
vtRet
Specifies the type of the return value. For possible values, see the Remarks section for COleDispatchDriver::InvokeHelper.
pvRet
Address of the variable that will that will receive the property value or return value. It must match the type specified by vtRet.
pbParamInfo
Pointer to a null-terminated string of bytes specifying the types of the parameters following pbParamInfo. For possible values, see the Remarks section for COleDispatchDriver::InvokeHelper.
...
Variable List of parameters, of types specified in pbParamInfo.


//-------------------------------------------------
axis = new QAxWidget();
axis->setControl(QString::fromUtf8("{745395C8-D0E1-4227-8586-624CA9A10A8D}"));
axis->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
axis->setObjectName(QString::fromUtf8("AxisMediaControl"));

QList<QVariant> params;
params << 0x1;
params << 0x4;
params << 0;
params << 0;
params << "\x0E";
params << "http://dizco.com:81/axis-cgi/mjpg/video.cgi";
axis->dynamicCall("InvokeHelper(int, uint, uint, QString, QString)", params);

QList<QVariant> params2;
params2 << 0x9;
params2 << 0x4;
params2 << 0;
params2 << 0;
params2 << "\x0E";
params2 << "mjpeg-unicast";
axis->dynamicCall("InvokeHelper(int, uint, uint, QString, QString)", params2);

QList<QVariant> params3;
params3 << 0x65;
params3 << 0x1;
params3 << 0;
params3 << 0;
params3 << 0;
axis->dynamicCall("InvokeHelper(int, uint, uint, QString, QString)", params3);

jacek
17th January 2006, 16:21
I'm guessing the InvokeHelper is not what i should be calling.
I looks more like a wrapper that just invokes methods of that COM object. Is there any specification of interfaces implemented by that AxisMediaControl object in the docs?

PS. Note that you have a space after object name in axis->setObjectName(...) line.

bitChanger
17th January 2006, 21:35
I now have a solution for my problem and would like to share with anyone interested.

dynamicCall was not the answer in this case since the COM object interface uses types that are unknown to Qt.

So the solution was to use queryInterface to get a pointer to the IDispatch handle and call invoke directly. Which by the way turns out to be the low level call made by MFC's invokeHelper method. So in stepping through the debugger on the MFC sample provided by Axis, I was able to make up a quick and dirty call in Qt to accually get this to work. Now I will clean it up and create my own Qt wrapper class for this Active X control and all will be well.

If your interested in trying this out, it's really quite a neat trick. Here is the ugly quick and dirty way of just getting a live feed to work in a Qt Application.

#include <afxwin.h>
#include <OleAuto.h>

axis = new QAxWidget();
axis->setControl(QString::fromUtf8("{745395C8-D0E1-4227-8586-624CA9A10A8D}"));
axis->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
axis->setObjectName(QString::fromUtf8("CAxisMediaControl"));

EXCEPINFO excepInfo;
memset(&excepInfo, 0, sizeof excepInfo);

UINT nArgErr = (UINT)-1; // initialize to invalid arg

DISPPARAMS dispparams;
memset(&dispparams, 0, sizeof dispparams);
dispparams.cArgs = 1;
dispparams.cNamedArgs = 1;
DISPID dispidNamed = DISPID_PROPERTYPUT;
dispparams.rgdispidNamedArgs = &dispidNamed;
VARIANT* pArg = new VARIANT[dispparams.cArgs];
dispparams.rgvarg = pArg;
memset(pArg, 0, sizeof(VARIANT) * dispparams.cArgs);
pArg->vt = 8;
pArg->bstrVal = _T("http://dizco.com:81/axis-cgi/mjpg/video.cgi");

IDispatch *iface = 0;
axis->queryInterface(QUuid(IID_IDispatch), (void**)&iface);
if (iface) {
iface->Invoke(1, IID_NULL, 0, 4, &dispparams, 0, &excepInfo, &nArgErr);
pArg->bstrVal = _T("mjpeg-unicast");
iface->Invoke(9, IID_NULL, 0, 4, &dispparams, 0, &excepInfo, &nArgErr);
dispparams.cArgs = 0;
dispparams.cNamedArgs = 0;
dispparams.rgdispidNamedArgs = 0;
dispparams.rgvarg = 0;
iface->Invoke(101, IID_NULL, 0, 1, &dispparams, 0, &excepInfo, &nArgErr);

iface->Release();

dreeves
25th January 2006, 18:02
If possible, please post the rest of the code to your solution.

Thanks,

David

bitChanger
26th January 2006, 14:43
This should be all the code you would need. Just create a basic Qt app with a custom widget. Then place the above code in the constructor for the widget.

cloclopolio
24th September 2010, 11:43
Hi, I know the last message for this thread was in 2006, but I try !

I want to do exactly the same thing. So I have created a new widget which has a QAxWidget. Here is the constructor code of my new widget class :



AxisMediaControlWidget::AxisMediaControlWidget(QWi dget *parent, Qt::WFlags flags)
: QWidget(parent, flags)
{
m_axis = new QAxWidget(this);
m_glay = new QGridLayout(this);

m_axis->setControl(QString::fromUtf8("{745395C8-D0E1-4227-8586-624CA9A10A8D}"));
m_axis->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_axis->setObjectName(QString::fromUtf8("CAxismediacontrol"));

EXCEPINFO excepInfo;
memset(&excepInfo, 0, sizeof excepInfo);

UINT nArgErr = (UINT)-1; // initialize to invalid arg

DISPPARAMS dispparams;
memset(&dispparams, 0, sizeof dispparams);
dispparams.cArgs = 1;
dispparams.cNamedArgs = 1;
DISPID dispidNamed = DISPID_PROPERTYPUT;
dispparams.rgdispidNamedArgs = &dispidNamed;
VARIANT* pArg = new VARIANT[dispparams.cArgs];
dispparams.rgvarg = pArg;
memset(pArg, 0, sizeof(VARIANT) * dispparams.cArgs);

IDispatch *iface = 0;
m_axis->queryInterface((QUuid)IID_IDispatch, (void**)&iface);
if (iface)
{
pArg->vt = VT_EMPTY;
dispparams.cArgs = 0;
dispparams.cNamedArgs = 0;
iface->Invoke(102, IID_NULL, 0, DISPATCH_METHOD, &dispparams, 0, &excepInfo, &nArgErr);

dispparams.cArgs = 1;
dispparams.cNamedArgs = 1;
// put_PTZControlURL
pArg->bstrVal = (L"http://10.67.148.30/axis-cgi/com/ptz.cgi");
iface->Invoke(0x1e, IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, 0, &excepInfo, &nArgErr);

// put_UIMode
pArg->bstrVal = _T("ptz-absolute");
iface->Invoke(0x3, IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, 0, &excepInfo, &nArgErr);

pArg->vt = VT_BOOL;
pArg->boolVal = VARIANT_TRUE;
iface->Invoke(0x12, IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, 0, &excepInfo, &nArgErr);

iface->Invoke(0x11, IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, 0, &excepInfo, &nArgErr);

iface->Invoke(0x10, IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, 0, &excepInfo, &nArgErr);

iface->Invoke(0x73, IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, 0, &excepInfo, &nArgErr);

iface->Invoke(0x75, IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, 0, &excepInfo, &nArgErr);

pArg->vt = VT_BSTR;
pArg->bstrVal = (L"default,+ptz");
iface->Invoke(0x13, IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, 0, &excepInfo, &nArgErr);

pArg->bstrVal = (L"http://10.67.148.30/axis-cgi/mjpg/video.cgi");
iface->Invoke(1, IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, 0, &excepInfo, &nArgErr);

pArg->bstrVal = (L"mjpg");
iface->Invoke(9, IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, 0, &excepInfo, &nArgErr);

// Play
pArg->vt = VT_EMPTY;
dispparams.cArgs = 0;
dispparams.cNamedArgs = 0;
dispparams.rgdispidNamedArgs = 0;
dispparams.rgvarg = 0;
iface->Invoke(101, IID_NULL, 0, DISPATCH_METHOD, &dispparams, 0, &excepInfo, &nArgErr);

iface->Release();
}
m_glay->addWidget(m_axis, 0, 0);
}


When I display my new widget in a QDialog, I have the tool bar I want to display but the frame where the video must be displayed stay white.

Do you have an idea why it doesn't work ?

shamil
9th August 2011, 17:55
Only for future readers who will find this post from google like me :-) There is more simple way to do it. My code:


#include <ActiveQt/qaxwidget.h>
#include <QtGui/qapplication.h>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QAxWidget w;
w.setControl(QString::fromUtf8("{745395C8-D0E1-4227-8586-624CA9A10A8D}"));
w.setObjectName(QString::fromUtf8("Axis Video"));
w.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
w.show();

w.dynamicCall("MediaURL", "http://10.0.0.10/axis-cgi/mjpg/video.cgi");
w.dynamicCall("MediaType", "mjpeg-unicast");
w.dynamicCall("StretchToFit", "true");
w.dynamicCall("Play()");
return a.exec();
}

Mokson
4th September 2012, 20:26
May be this software could help to you, its really awesome http://www.videocapx.com