Setting QPixmap to Qlabel gives segmentation fault and app crashes
-
GstFlowReturn MainWindow::newSample1(GstAppSink *sink1, gpointer gSelf) { GstSample* sample = NULL; GstBuffer* sampleBuffer = NULL; GstMapInfo bufferInfo; MainWindow* self = static_cast<MainWindow* >(gSelf); sample = gst_app_sink_pull_sample(GST_APP_SINK(sink1)); QImage image ; QPixmap image1 ; if(sample != NULL) { sampleBuffer = gst_sample_get_buffer(sample); if(sampleBuffer != NULL) { gst_buffer_map(sampleBuffer, &bufferInfo, GST_MAP_READ); image = QImage(bufferInfo.data, 640, 480, QImage::Format_Grayscale8); image1 = QPixmap::fromImage(image); if(!image1.isNull()) { self->ui->CAM_VDO->setPixmap(image1); } gst_buffer_unmap(sampleBuffer, &bufferInfo); } gst_sample_unref(sample); } return GST_FLOW_OK; }
This application crashes and gives segmentation fault error.
But when i remove or comment this line :
self->ui->CAM_VDO->setPixmap(image1);
it runs fine.Can anyone please let me know why it's happening.
-
@vicky_mac said in Setting QPixmap to Qlabel gives segmentation fault and app crashes:
self->ui->CAM_VDO
is CAM_VDO a valid pointer?
-
WTH is
self->ui->
? -
-
@vicky_mac said in Setting QPixmap to Qlabel gives segmentation fault and app crashes:
it's an instance to the UI app running ... it access the coponent from mainwindowui and then access CAM_VDO label and displays image on it
I smell a very very big potential error source here.
Children should not know of object instanced of their parents! One is supposed to use Signal & Slots.
Please show how you designed this
-
@J-Hilk i am using gstreamer for decoding a video ... and appsink to capture the data and display it into qt label..
this the signal emitted by gstreamer when new sample is ready.
g_signal_connect(appsink,"new-sample",G_CALLBACK(newSample1),(gpointer)this);
and it calls above given function.
-
Hi,
Beside what was already said, you might also be hitting a life time issue. Unless bufferInfo.data is const you are triggering this QImage constructor which requires the buffer to be valid as long as the QImage built with it.
In any case, you should not update GUI elements directly from a callback as it might be running in a different thread. You can use QMetaObject::invokeMethod with a queued connection to call a slot that will do the QLabel work. Just create the proper QImage in your callback.
Note that with recent version of Qt, you can use custom pipeline with QMediaPlayer which might be way simpler to use.
-
@SGaist thank for suggestion ...
AS i am running qt version 5.11.3 and due to some resctrictions i cannot update it.
So i think QMetaObject::invokeMethod approch i'll have to follow . But i don't know how to use it.
Do you have any example code or any link where i can get some more details on this.*i tried copying the bufferInfo.data into another buffer and then did the image building and display. Then it works .. Don't know wther i should do this or not.
As suggested above i must not update UI from call back function . I'll try to use QMetaObject::invokeMethod and come back to you.
-
Do you have a slot on your widget to set the QPixmap on the label ?
-
Which code exactly ?
-
@SGaist
In the question it self I have given code where I am updating the label.As I receive a frame in gst reamer thread I update it.
But how to do it in signal slot mechanism I am not able to feagure out. As you suggested above using qmetaobject how to use it in code.?
-
@vicky_mac said in Setting QPixmap to Qlabel gives segmentation fault and app crashes:
As I receive a frame in gst reamer thread I update it.
You are not allowed to modify the GUI from any thread except the main thread (better: the thread where QApplication lives in). Use signals/slots to update your ui.
-
Something like:
QMetaObject::invokeMethod(ui->label, "setPixmap", Qt::QueuedConnection, Q_ARG(pixmap));
-
@SGaist hi thanx for advise..
I did Qmetaobject::Invokemethod(self-ui->vdolabel, "setPixel", qtqueuedconnection, Q_Args(Qpixmap, P)) :And updating qlabel from setPixmap function in mainwidown.cpp its working fine.
Is it ok now or should have to anything else.
Is this OK passing the object reference and derefenrecing it like this?
MainWindow* self = static_cast<MainWindow* >(gSelf); -
Do you mean pass your MainWindow instance as the opaque data to your callback ?
-
@SGaist yes, because without that we would not Abe able to invoke method.
MainWindow* self = static_cast<MainWindow* >(gSelf);
This line...Because now by using Invokemethod I am updating qlabel in main thread and not child or gstreamer thread that seems OK.
-
I'd go a step further and pass directly the pointer to the QLabel object, it's even less instructions to use.