From be225943691178a1a31e705afd09ba4bf7e25a88 Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Fri, 10 Nov 2023 11:06:08 +0100 Subject: [PATCH] fixes and improvements, no segfaults anymore --- imagebuffer.cpp | 16 +++++++- main.cpp | 8 +++- pylonrecorder.cpp | 94 +++++++++++++++++++++++++++++------------------ pylonrecorder.h | 9 ++++- pylonwrapper.cpp | 34 +++++++++++++---- 5 files changed, 112 insertions(+), 49 deletions(-) diff --git a/imagebuffer.cpp b/imagebuffer.cpp index 424413b..bed161c 100644 --- a/imagebuffer.cpp +++ b/imagebuffer.cpp @@ -3,15 +3,25 @@ using namespace std::chrono; ImageBuffer::ImageBuffer(size_t buffer_size, QObject *parent) : QObject(parent), buffer_size(buffer_size) { - buffer.resize(buffer_size); + buffer.resize(buffer_size, nullptr); + std::cerr << "imagebuffer constructor!" << std::endl; } void ImageBuffer::clear() { + std::cerr << "Clear Image buffer!" << std::endl; + for (auto & img: buffer) { + std::cerr << "Clear Image buffer!" << std::endl; + if (img != nullptr) delete(img); + img = nullptr; } + std::cerr << "Clear Image buffer!" << std::endl; + resize(buffer_size); + std::cerr << "Clear Image buffer! done" << std::endl; + } size_t ImageBuffer::capacity() { @@ -35,10 +45,12 @@ size_t ImageBuffer::bufferLoad() { } void ImageBuffer::resize(size_t new_size) { + std::cerr << "Buffer Resize" << std::endl; mutex.lock(); + buffer_size = new_size; buffer.clear(); - buffer.resize(new_size); + buffer.resize(new_size, nullptr); current_read_index = 0; current_write_index = 0; load = 0; diff --git a/main.cpp b/main.cpp index cd828b9..9a7a189 100644 --- a/main.cpp +++ b/main.cpp @@ -4,9 +4,12 @@ #include #include #include +#include "mylogger.h" int main(int argc, char *argv[]) { + Logger::init(); + qInfo() << "PylonRecorder start"; QApplication app(argc, argv); QGuiApplication::setApplicationDisplayName(PylonRecorder::tr("Pylon Recorder")); QGuiApplication::setOrganizationName("Bendalab"); @@ -32,11 +35,14 @@ int main(int argc, char *argv[]) recorder.move(x, y); recorder.show(); int ret = app.exec(); - + QPoint pos = recorder.pos(); settings.setValue("app/width", recorder.width()); settings.setValue("app/height", recorder.height()); settings.setValue("app/pos_x", pos.x()); settings.setValue("app/pos_y", pos.y()); + qInfo() << "PylonRecorder stop"; + Logger::clean(); + return ret; } diff --git a/pylonrecorder.cpp b/pylonrecorder.cpp index 03bfdb4..e573dcc 100644 --- a/pylonrecorder.cpp +++ b/pylonrecorder.cpp @@ -33,7 +33,7 @@ #endif PylonRecorder::PylonRecorder(QWidget *parent) - : QMainWindow(parent), imageLabel(new QLabel), scrollArea(new QScrollArea) + : QMainWindow(parent), imageLabel(new QLabel), scrollArea(new QScrollArea), grabber(nullptr), writer(nullptr), buffer(nullptr), pyloncam(nullptr) { dryRun = false; imageLabel->setBackgroundRole(QPalette::Base); @@ -44,7 +44,6 @@ PylonRecorder::PylonRecorder(QWidget *parent) scrollArea->setWidget(imageLabel); scrollArea->setVisible(false); setCentralWidget(scrollArea); - std::cerr << "PylonRecorder::constructor" << std::endl; // Pylon::DeviceInfoList_t deviceList = detectCameras(); // for (auto dev : deviceList) { // std::cout << dev.GetFullName() << " " << dev.GetFriendlyName() << std::endl; @@ -63,14 +62,12 @@ PylonRecorder::PylonRecorder(QWidget *parent) // writer = new Writer(buffer); // connect(writer, &Writer::writingDone, this, &PylonRecorder::writerDone); // } -std::cerr << "PylonRecorder::constructor 1" << std::endl; frameTimer = new QTimer(this); connect(frameTimer, &QTimer::timeout, this, &PylonRecorder::displaySingleFrame); preassureTimer = new QTimer(this); - connect(preassureTimer, &QTimer::timeout, this, &PylonRecorder::displayBufferPreassure); + connect(preassureTimer, &QTimer::timeout, this, &PylonRecorder::displayBufferPressure); labelTimer = new QTimer(this); connect(labelTimer, &QTimer::timeout, this, &PylonRecorder::displayActivity); -std::cerr << "PylonRecorder::constructor 2" << std::endl; preassureBar = new QProgressBar(this); preassureBar->setRange(0, 100); preassureBar->setTextVisible(true); @@ -86,7 +83,6 @@ std::cerr << "PylonRecorder::constructor 2" << std::endl; loadBar->setFixedSize(200, 25); QLabel *loadLabel = new QLabel("Load:", this); loadLabel->setStyleSheet("QLabel{font-size: 11pt;font-family: Arial;font-weight: Bold}"); -std::cerr << "PylonRecorder::constructor 3" << std::endl; writingLabel = new QLabel("writing"); writingLabel->setEnabled(false); writingLabel->setStyleSheet("QLabel{font-size: 11pt;font-family: Arial;}"); @@ -97,7 +93,6 @@ std::cerr << "PylonRecorder::constructor 3" << std::endl; cameraConnectedLabel = new QLabel("not connected"); cameraConnectedLabel->setStyleSheet("QLabel { color : red; }"); cameraConnectedLabel->setStyleSheet("QLabel{font-size: 11pt;font-family: Arial;}"); -std::cerr << "PylonRecorder::constructor 4" << std::endl; fileLabel = new QLabel(); fileLabel->setStyleSheet("QLabel{font-size: 11pt;font-family: Arial;}"); @@ -107,7 +102,6 @@ std::cerr << "PylonRecorder::constructor 4" << std::endl; statusHeader->setStyleSheet("QLabel{font-size: 11pt;font-family: Arial; font-weight: Bold}"); QLabel *fileHeader = new QLabel("Output file:"); fileHeader->setStyleSheet("QLabel{font-size: 11pt;font-family: Arial; font-weight: Bold}"); -std::cerr << "PylonRecorder::constructor 5" << std::endl; statusBar()->addWidget(camHeader); statusBar()->addWidget(cameraConnectedLabel); statusBar()->addWidget(preassureLabel); @@ -120,15 +114,10 @@ std::cerr << "PylonRecorder::constructor 5" << std::endl; statusBar()->addWidget(fileHeader); statusBar()->addWidget(fileLabel); resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5); -std::cerr << "PylonRecorder::constructor 6" << std::endl; detectCameras(); -std::cerr << "PylonRecorder::constructor 7" << std::endl; createActions(); -std::cerr << "PylonRecorder::constructor 8 " << std::endl; updateActions(); -std::cerr << "PylonRecorder::constructor 9" << std::endl; applySettings(); -std::cerr << "PylonRecorder::constructor done" << std::endl; } void PylonRecorder::setupCameras(){ @@ -140,13 +129,14 @@ void PylonRecorder::setupCameras(){ std::cout << "peng\n"; if (deviceList.size() == 0) { - std::cout << "device list is empty!" << std::endl; + qWarning() << "device list is empty!"; QErrorMessage message(this); message.showMessage("No camera detected!"); } else { std::cout << "peng\n"; // std::string cname = (std::string)deviceList[0].GetFullName(); // pyloncam = new PylonWrapper(cname); + qDebug() << "Creating buffer, grabber, and writer"; buffer = new ImageBuffer(defaultBufferSize); grabber = new Grabber(pyloncam, buffer, defaultFrameRate); writer = new Writer(buffer); @@ -155,27 +145,37 @@ void PylonRecorder::setupCameras(){ } void PylonRecorder::detectCameras() { - Pylon::PylonAutoInitTerm autoInitTerm; Pylon::CTlFactory& TlFactory = Pylon::CTlFactory::GetInstance(); TlFactory.EnumerateDevices(deviceList); } PylonRecorder::~PylonRecorder(){ - if (grabber->isRunning()) { + qDebug() << "Destructing PylonRecorder"; + if (grabber != nullptr && grabber->isRunning()) { grabber->requestStop(); grabber->wait(1000); } - if (writer->isRunning()) { + if (writer != nullptr && writer->isRunning()) { writer->forceStop(); writer->wait(1000); } storeSettings(); - std::cerr << "recorder::destructor" << std::endl; - delete pyloncam; - std::cerr << "recorder::destructor" << std::endl; - delete buffer; + if (pyloncam != nullptr) { + qDebug() << "Deleting pyloncam"; + delete pyloncam; + pyloncam = nullptr; + } + + if (buffer != nullptr) { + qDebug() << "Deleting buffer"; + delete buffer; + buffer = nullptr; + } + qDebug() << "Deleting grabber"; delete grabber; + qDebug() << "Deleting writer"; delete writer; + qDebug() << "Deleting setting"; delete settings; } @@ -556,7 +556,7 @@ void PylonRecorder::updateActions() { disconnect_camera_action->setEnabled(deviceList.size() > 0); connect_camera_action->setEnabled(true); grab_still_action->setEnabled(deviceList.size() > 0); - grab_continuous_action->setEnabled(deviceList.size() > 0 && pyloncam->isOpen() && !grabbing); + //grab_continuous_action->setEnabled(deviceList.size() > 0 && pyloncam->isOpen() && !grabbing); grab_stop_action->setEnabled(grabbing); } @@ -582,15 +582,14 @@ void PylonRecorder::applyScaling(){ void PylonRecorder::quitApplication() { std::cerr << "Quit Application!" << std::endl; - if (pyloncam->isOpen()) { - std::cerr << "Cam is open!" << std::endl; + // if (pyloncam->isOpen()) { + // std::cerr << "Cam is open!" << std::endl; + std::cerr << "Stop grabbing" << std::endl; - if (grabbing) { - stopRecording(); - buffer->clear(); - } - pyloncam->closeCamera(); + if (grabbing) { + stopRecording(); } + std::cerr << "done!" << std::endl; this->close(); } @@ -601,10 +600,16 @@ void PylonRecorder::adjustScrollBar(QScrollBar *scrollBar, double factor) { } void PylonRecorder::cameraConfiguration(){ - CamConfigurator d(this); - // QObject::connect(&d, SIGNAL(recent_file_changed(QStringList)), this, SLOT(recent_file_update(QStringList))); + d = new CamConfigurator(deviceList, this); + connect(d, SIGNAL(accepted()), SLOT(camerasetup())); // QObject::connect(&d, SIGNAL(column_visibility_changed(QString, QString,bool)), this, SLOT(visible_columns_update(QString, QString,bool))); - d.exec(); + d->exec(); +} + +void PylonRecorder::camerasetup() { + std::cerr << "camera settings accepted" << std::endl; + std::cerr << d->result() << std::endl; + delete d; } void PylonRecorder::connectCamera() { @@ -695,22 +700,37 @@ void PylonRecorder::startRecording() { void PylonRecorder::stopRecording() { + std::cerr << "StopRecording!" << std::endl; + if (!stopRequest) { + std::cerr << "StopRecording2!" << std::endl; + frameTimer->stop(); - grabber->requestStop(); - writer->requestStop(); + std::cerr << "StopRecording3!" << std::endl; + if (grabber !=nullptr) + grabber->requestStop(); + std::cerr << "StopRecording4!" << std::endl; + if (writer != nullptr) + writer->requestStop(); + std::cerr << "StopRecording5!" << std::endl; grabbing = false; stopRequest = true; grab_stop_action->setEnabled(false); - if(dryRun) { + std::cerr << "stop recording buffer" << buffer << std::endl; + if(buffer != nullptr) { + std::cerr << "stop recording buffer" << buffer << std::endl; buffer->clear(); writerDone(); } } + std::cerr << "StopRecording done!" << std::endl; + } void PylonRecorder::writerDone() { + std::cerr << "writerDone slot!" << std::endl; + preassureTimer->stop(); preassureBar->reset(); loadBar->reset(); @@ -721,6 +741,8 @@ void PylonRecorder::writerDone() { writer->wait(10000); writing = false; updateActions(); + std::cerr << "writerDone slot done!" << std::endl; + } @@ -770,7 +792,7 @@ std::string PylonRecorder::createFilename() { } -void PylonRecorder::displayBufferPreassure() { +void PylonRecorder::displayBufferPressure() { int value = static_cast(round(buffer->bufferPreassure())); preassureBar->setValue(value); QColor color = progressColor(value); diff --git a/pylonrecorder.h b/pylonrecorder.h index 3563ba4..351fe51 100644 --- a/pylonrecorder.h +++ b/pylonrecorder.h @@ -12,6 +12,7 @@ #include "grabber.h" #include "writer.h" #include "projectsettings.h" +#include "camconfig.h" #include #if defined(QT_PRINTSUPPORT_LIB) @@ -60,10 +61,11 @@ private slots: void stopRecording(); void quitApplication(); void displaySingleFrame(); - void displayBufferPreassure(); + void displayBufferPressure(); void displayActivity(); void writerDone(); void selectStorageLocation(); + void camerasetup(); private: void createActions(); @@ -110,7 +112,10 @@ private: QString storageLocation = ""; ProjectMetadata mdata; Pylon::DeviceInfoList_t deviceList; - + CamConfigurator *d; + Pylon::PylonAutoInitTerm autoInitTerm; + + #if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer) QPrinter printer; #endif diff --git a/pylonwrapper.cpp b/pylonwrapper.cpp index b7a437c..1c614ef 100644 --- a/pylonwrapper.cpp +++ b/pylonwrapper.cpp @@ -1,20 +1,34 @@ #include "pylonwrapper.h" PylonWrapper::PylonWrapper(const std::string &fullName): - valid(false), fullName(fullName) { + valid(false), fullName(fullName), camera(nullptr) { Pylon::PylonInitialize(); - camera = new Pylon::CInstantCamera(); + // camera = new Pylon::CInstantCamera(); // std::cerr << "Wrapper:camera is open" << camera->IsOpen() << std::endl; // std::cerr << "Wrapper:is valid" << valid << std::endl; } PylonWrapper::~PylonWrapper() { - Pylon::PylonTerminate(); + std::cerr << "wrapper destructor" << std::endl; + if (camera != nullptr){ + std::cerr << "check camera!" << std::endl; + if (camera->IsOpen()) { + std::cerr << "close camera!" << std::endl; + camera->Close(); + // std::cerr << "terminate pylon" << std::endl; + // terminate(); + } + std::cerr << "delete camera!" << std::endl; + + delete camera; + camera = nullptr; + } + std::cerr << "wrapper: deleted camera" << std::endl; } void PylonWrapper::terminate() { try { - //Pylon::PylonTerminate(); + Pylon::PylonTerminate(); } catch (const Pylon::GenericException &e) { std::cerr << e.GetDescription() << std::endl; } @@ -136,15 +150,17 @@ bool PylonWrapper::grabFrame(MyImage &img) { } bool PylonWrapper::openCamera(std::string &message) { - std::cerr << "open Camera" << std::endl; try { + camera = new Pylon::CInstantCamera(); + // Pylon::CInstantCamera camera( pTl->CreateDevice( lstDevices[0] ); - camera->Attach(Pylon::CTlFactory::GetInstance().CreateFirstDevice()); + // Pylon::IPylonDevice *pDevice = Pylon::CTlFactory::GetInstance().CreateFirstDevice(); + Pylon::String_t fname(fullName.c_str()); + Pylon::IPylonDevice *pDevice = Pylon::CTlFactory::GetInstance().CreateDevice(fname); + camera->Attach(pDevice); camera->Open(); valid = camera->IsOpen(); message = "Successfully opened camera!"; - std::cerr << message << std::endl; - } catch (const Pylon::GenericException &e) { message = e.GetDescription(); std::cerr << "An exception occurred." << std::endl << e.GetDescription() << std::endl; @@ -159,6 +175,8 @@ void PylonWrapper::closeCamera() { try { camera->Close(); valid = false; + delete camera; + camera = nullptr; } catch (const Pylon::GenericException &e) { std::cerr << "An exception occurred." << std::endl << e.GetDescription() << std::endl; }