Unsolved setPixmap crash
-
I would like to capture images from my webcam, process the images, and then display them in a window. Whenever I try to set a pixmap obtained from the camera on a control I get a deeply nested null pointer error during (I suppose) the event handler. Note that when I call save() on the QPixmap object, the save works. The image is upside down but otherwise a good image.
Also note that all crashes and breakpoints that I've seen or set, always include WinMain in the stack trace. To my knowledge there is only one thread. Additionally, before I used the label, I tried a pixmap item in a graphic scene. I tried both resetting the pixmap item's pixmap as well as deleting the pixmap item and adding a fresh one to the scene. All attempts result in the same crash in the same place.
Can anyone spot what I'm doing wrong? I feel like it must be something very basic that most documentation assumes one already knows.
Windows 10, MSVC 2015 64 bit.
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), frame(640, 480), pix_no(0) { ui->setupUi(this); QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); cam = new QCamera(cameras.first(), this); cam->load(); frame_grabber = new CameraFrameGrabber(); cam->setViewfinder(frame_grabber); cam->setCaptureMode(QCamera::CaptureViewfinder); connect(frame_grabber, SIGNAL(frameAvailable(QImage)), this, SLOT(handleFrame(QImage))); cam->start(); frame_timer.start(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::handleFrame(const QImage& img) { frame_times.push_back(frame_timer.elapsed()); frame_timer.restart(); if (frame_times.size() > 10) frame_times.pop_front(); int frame_count = frame_times.size(); int frame_total = 0; for(int i = 0; i < frame_count; ++i) { frame_total += frame_times[i]; } double fps = 0; if (frame_count) { fps = (frame_total / frame_count); } ui->sb_fps->setValue(fps); frame = QPixmap::fromImage(img); QString fname("campix"); fname += QString::number(++pix_no); fname += ".jpg"; bool success = frame.save(fname); ui->label->setPixmap(frame); this->update(); }
bool CameraFrameGrabber::present(const QVideoFrame &frame) { if (frame.isValid()) { QVideoFrame cloneFrame(frame); cloneFrame.map(QAbstractVideoBuffer::ReadOnly); const QImage image(cloneFrame.bits(), cloneFrame.width(), cloneFrame.height(), QVideoFrame::imageFormatFromPixelFormat(cloneFrame .pixelFormat())); emit frameAvailable(image); cloneFrame.unmap(); return true; } return false; }
1 memcpy VCRUNTIME140D 0x7ffc23ad1e10 2 qt_blend_rgb32_on_rgb32 qblendfunctions.cpp 399 0x7ffbfd00bb85 3 qt_blend_rgb32_on_rgb32_sse2 qdrawhelper_sse2.cpp 139 0x7ffbfd3bc17d 4 QRasterPaintEnginePrivate::drawImage qpaintengine_raster.cpp 1021 0x7ffbfd0cb9bd 5 QRasterPaintEngine::drawImage qpaintengine_raster.cpp 2412 0x7ffbfd0c4248 6 QRasterPaintEngine::drawPixmap qpaintengine_raster.cpp 2063 0x7ffbfd0c1b72 7 QPainter::drawPixmap qpainter.cpp 5200 0x7ffbfd0e7170 8 QPainter::drawPixmap qpainter.h 803 0x7ffbfcc9474c 9 QStyle::drawItemPixmap qstyle.cpp 630 0x5d96c830 10 QLabel::paintEvent qlabel.cpp 1117 0x5db15bb8 11 QWidget::event qwidget.cpp 8931 0x5d910fb1 12 QFrame::event qframe.cpp 550 0x5db0c62f 13 QLabel::event qlabel.cpp 1000 0x5db14d48 14 QApplicationPrivate::notify_helper qapplication.cpp 3799 0x5d8a5e8e 15 QApplication::notify qapplication.cpp 3762 0x5d8a34c9 16 QCoreApplication::notifyInternal2 qcoreapplication.cpp 988 0x5d0f78c6 17 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 234 0x5d264c3b 18 QWidgetPrivate::sendPaintEvent qwidget.cpp 5699 0x5d91af5d 19 QWidgetPrivate::drawWidget qwidget.cpp 5640 0x5d91aa57 20 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5832 0x5d91b4a7 21 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5819 0x5d91b374 22 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5819 0x5d91b374 23 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5819 0x5d91b374 24 QWidgetPrivate::drawWidget qwidget.cpp 5690 0x5d91aef4 25 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5832 0x5d91b4a7 26 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5819 0x5d91b374 27 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5819 0x5d91b374 28 QWidgetPrivate::paintSiblingsRecursive qwidget.cpp 5819 0x5d91b374 29 QWidgetPrivate::drawWidget qwidget.cpp 5690 0x5d91aef4 30 QWidgetBackingStore::doSync qwidgetbackingstore.cpp 1365 0x5d8bf8c4 31 QWidgetBackingStore::sync qwidgetbackingstore.cpp 1152 0x5d8bc8a3 32 QWidgetPrivate::syncBackingStore qwidget.cpp 1957 0x5d91d650 33 QWidget::event qwidget.cpp 9084 0x5d911617 34 QMainWindow::event qmainwindow.cpp 1544 0x5db380b1 35 QApplicationPrivate::notify_helper qapplication.cpp 3799 0x5d8a5e8e 36 QApplication::notify qapplication.cpp 3762 0x5d8a34c9 37 QCoreApplication::notifyInternal2 qcoreapplication.cpp 988 0x5d0f78c6 38 QCoreApplication::sendEvent qcoreapplication.h 231 0x5d1027f2 39 QCoreApplicationPrivate::sendPostedEvents qcoreapplication.cpp 1649 0x5d0f9112 40 QEventDispatcherWin32::sendPostedEvents qeventdispatcher_win.cpp 1295 0x5d1b180a 41 QWindowsGuiEventDispatcher::sendPostedEvents qwindowsguieventdispatcher.cpp 82 0x7ffbfc8cc204 42 qt_internal_proc qeventdispatcher_win.cpp 445 0x5d1af521 43 CallWindowProcW USER32 0x7ffc29f41c24 44 DispatchMessageW USER32 0x7ffc29f4156c 45 QEventDispatcherWin32::processEvents qeventdispatcher_win.cpp 845 0x5d1aff2b 46 QWindowsGuiEventDispatcher::processEvents qwindowsguieventdispatcher.cpp 74 0x7ffbfc8cc1c4 47 QEventLoop::processEvents qeventloop.cpp 135 0x5d0f24e8 48 QEventLoop::exec qeventloop.cpp 210 0x5d0f272e 49 QCoreApplication::exec qcoreapplication.cpp 1261 0x5d0f55ff 50 QGuiApplication::exec qguiapplication.cpp 1640 0x7ffbfccf3208 51 QApplication::exec qapplication.cpp 2976 0x5d8a021a 52 main main.cpp 10 0x7ff609d72749 53 WinMain qtmain_win.cpp 123 0x7ff609d7afbd 54 invoke_main exe_common.inl 109 0x7ff609d78bed 55 __scrt_common_main_seh exe_common.inl 264 0x7ff609d78a8e 56 __scrt_common_main exe_common.inl 309 0x7ff609d7894e 57 WinMainCRTStartup exe_winmain.cpp 17 0x7ff609d78c09 58 BaseThreadInitThunk KERNEL32 0x7ffc2a4a8364 59 RtlUserThreadStart ntdll 0x7ffc2c1a5e91
-
Hi,
When using the QImage constructor you are using, you have to ensure that the data pointed to are available for as long as you are using the image. Hence, you are likely trying to access the data after the unmap happened which means that you are trying to access data that are not there anymore.
You should emit a copy of the QImage.