PDA

View Full Version : trying to call Xlib inside qt app



phixx
11th February 2008, 19:15
Hi!

Im trying to access Xlib directly to paint Xv overlays inside subwindows of a QT4 MDI app.
Now Im getting some strange errors. I'm pretty sure I'm missing some basic concepts of XLib programming here...

I started with a basic QT app and included code from this example:
http://www.wedesoft.demon.co.uk/downloads/testxv2.cc

I made an Xvideo class for all Xlib specific code. Before theres any data to display, I'd like to know if Xv is going to work. So I splitted the code in the example in "initialization part" and "code that can be used as base for the actual painting routine".

Initialization is done in the constructor(which throws an exception on errors... some todos here)
The rest is kept inside "setup()" for now.

A stripped down version of my code looks like this:


Xvideo::Xvideo()
{
m_nAdaptor = ~0; // equals -1
m_pDisplay = NULL;
m_pAdaptorInfo = NULL;
m_nPort = 0;
m_nColorkey = 0;

// --- start initialization ---

m_pDisplay = QX11Info::display () ;
//alternatively: m_pDisplay = XOpenDisplay ( NULL );

// get version and release information about X video extension
unsigned int nVersion, nRelease, nRequest_base, nEvent_base, nError_base;
XvQueryExtension ( m_pDisplay, &nVersion, &nRelease, &nRequest_base,
&nEvent_base, &nError_base );

// get video adaptor list for default display
unsigned int nAdaptors;
XvQueryAdaptors ( m_pDisplay, DefaultRootWindow ( m_pDisplay ), &nAdaptors,
&m_pAdaptorInfo );

// search list for Xv-capable adaptor and try to grab a port
for ( unsigned int i=0; i<nAdaptors; i++ )
{
// call XvGrabPort in some loop until its successfull...
...
XvGrabPort ( m_pDisplay, p, CurrentTime )
...
}

// get and set ColorKey data/config
XvGetPortAttribute ( m_pDisplay, m_nPort,... );
XvSetPortAttribute ( m_pDisplay, m_nPort, ...);
}

bool Xvideo::setup ( Drawable window, int width, int height )
{
unsigned int formats;
XvImageFormatValues *fo;
// next call ends in segmentation fault
fo = XvListImageFormats ( m_pDisplay, m_nPort, ( int * ) &formats );
...
}


the constructor is called from the constructor of my "QT UI class":



CamWindow() : QWidget()
{
setupUi ( this );
Xvideo *m_pXvPort = NULL;
try
{
m_pXvPort = new Xvideo();
}
catch ( QString strErr )
{
QMessageBox::warning(this, tr("x video extension"),
strErr, QMessageBox::Ok);
}

}


And setup is called directly after this window has been displayed (through a wrapper function in the "CamWindow" class:)



CamWindow *w = new CamWindow();
m_pWorkspace->addWindow(w);
w->show();
w->setup();



This may look a bit confusing, but the important points are:

- Im doing some screen/adaptor specific calls in the constructor of a qwidget-derived class
Also XvGrabPort is called here to grab a Port for future use.
Returned data ( Display Pointer, AdaptorInfo Struct, Port handle, Colorkey ) is stored in member variables.

- directly after the window is shown, I call XvListImageFormats with Display and Port read from member variables, which ends in a segmentation fault.

- if i move XvListImageFormats to the constructor (to have it called in the same block as XvGrabPort), no errors occur.

I dont use any extra threads yet. All XLib code is called from a signal function triggered by a QMenu action.

Any idea what's goin wrong?
Obviously my main problem is missing knowledge about Xlib programming and Qt internals. Are there any good references for platform dependent hacks in qt? Or 'modern' Xlib programming (besides man pages and 20 yo standards...)?

phixx
12th February 2008, 19:46
I made further tests. I'm able to crash the program without any Xlib calls at all:

I found out, that writing a simple member variable in (my class) Xvideo break things when its not inside the constructor ...?
I commented out the whole constructor code of Xvideo. I placed
>m_pDisplay = NULL;
as first command in setup(), which is enough to let it crash.

No I've even less ideas.... looks a bit like "we called the function of a deleted object"

relevant code:

class CamWindow :

class CamWindow : public QWidget, private Ui::CamWindow
{
Q_OBJECT;
protected:
Xvideo *m_pXvPort;
public:
CamWindow() : QWidget()
{
setupUi ( this );
Xvideo *m_pXvPort = NULL;
try
{
m_pXvPort = new Xvideo();
}
catch ( QString strErr )
{
QMessageBox::warning ( this, tr ( "x video extension" ),
strErr, QMessageBox::Ok );
}

}
~CamWindow()
{
;
}
void setup()
{
m_pXvPort->setup ( winId(), 100, 100 );
}
};

called functions of class Xvideo:

Xvideo::Xvideo()
{

}

bool Xvideo::setup ( Drawable window, int width, int height )
{
// next command crashes
m_pDisplay = NULL;
....


}


"main code":

CamWindow *w = new CamWindow();
m_pWorkspace->addWindow(w);
w->show();
w->setup();

jpn
12th February 2008, 20:00
What does gdb and/or valgrind have to say about it?

jacek
12th February 2008, 20:07
class CamWindow : public QWidget, private Ui::CamWindow
{
Q_OBJECT;
protected:
Xvideo *m_pXvPort;
public:
CamWindow() : QWidget()
{
setupUi ( this );
Xvideo *m_pXvPort = NULL;
...
You have two m_pXvPort variables and you leave the member variable uninitialized.

phixx
12th February 2008, 20:28
thanks a lot !!!
now all my code runs through
i dont see any results on the screen yet, but thats another story.