diff --git a/grabber.cpp b/grabber.cpp index 295fb83..884ea66 100644 --- a/grabber.cpp +++ b/grabber.cpp @@ -1,6 +1,8 @@ #include "grabber.h" #include #include +#include +using namespace std::chrono; void Grabber::run() { stop_request = false; @@ -13,10 +15,15 @@ void Grabber::run() { Pylon::CInstantCamera *cam = camera->getCamera(); cam->StartGrabbing(); while (camera->isOpen() && !stop_request) { - MyImage img; + MyImage *img = new MyImage(); + auto start = high_resolution_clock::now(); cam->RetrieveResult( 5000, frame, Pylon::TimeoutHandling_ThrowException); - img.setFrame(frame); + auto stop1 = high_resolution_clock::now(); + img->setFrame(frame); + auto stop2 = high_resolution_clock::now(); buffer->push(img); + auto duration1 = duration_cast(stop1 - start); + auto duration2 = duration_cast(stop2 - stop1); count += 1; } cam->StopGrabbing(); diff --git a/imagebuffer.cpp b/imagebuffer.cpp index a489e4d..424413b 100644 --- a/imagebuffer.cpp +++ b/imagebuffer.cpp @@ -1,10 +1,16 @@ #include "imagebuffer.h" +#include +using namespace std::chrono; ImageBuffer::ImageBuffer(size_t buffer_size, QObject *parent) : QObject(parent), buffer_size(buffer_size) { buffer.resize(buffer_size); } void ImageBuffer::clear() { + for (auto & img: buffer) { + if (img != nullptr) + delete(img); + } resize(buffer_size); } @@ -20,8 +26,8 @@ double ImageBuffer::bufferPreassure() { return preassure * 100; } -int64_t ImageBuffer::bufferLoad() { - int64_t l; +size_t ImageBuffer::bufferLoad() { + size_t l; mutex.lock(); l = load; mutex.unlock(); @@ -34,17 +40,32 @@ void ImageBuffer::resize(size_t new_size) { buffer.clear(); buffer.resize(new_size); current_read_index = 0; - current_write_index = -1; + current_write_index = 0; load = 0; mutex.unlock(); } -void ImageBuffer::push(const MyImage &img) { +void ImageBuffer::push(MyImage *img) { mutex.lock(); - static_cast(current_write_index) < (buffer.size() - 1) ? current_write_index += 1 : current_write_index = 0; - buffer[static_cast(current_write_index)] = img; - if (load < static_cast(buffer.capacity())) - load += 1; + if (buffer[current_write_index] != nullptr) { + std::cerr << "possible frame drop detected!!" << std::endl; + std::cerr << "buffer.push write: " << current_write_index << " read: " << current_read_index << " load: " << load << std::endl; + + delete(buffer[current_write_index]); + } + buffer[current_write_index] = img; + current_write_index += 1; + load += 1; + if (current_write_index >= buffer_size){ + current_write_index = 0; + } + if (load >= buffer_size){ + load = buffer_size; + if (current_read_index == current_write_index) + current_read_index = current_write_index < buffer_size - 1 ? current_write_index + 1 : 0; + } + // std::cout << "Buffer.afterpush: load = " << load << " write index =" << current_write_index << " read index = " << current_read_index << std::endl; + mutex.unlock(); } @@ -56,33 +77,38 @@ bool ImageBuffer::bufferNotEmpty() { return res; } -bool ImageBuffer::pop(MyImage &img) { +MyImage* ImageBuffer::pop() { bool ret = false; + MyImage * img; mutex.lock(); if (load > 0) { - // std::cerr << "Buffer.pop, load: " << load << " read_idx: " << current_read_index << " write_idx: " << current_write_index << std::endl; - img = buffer[static_cast(current_read_index)]; - static_cast(current_read_index) < (buffer.capacity() - 1) ? current_read_index += 1 : current_read_index = 0; + img = buffer[current_read_index]; + current_read_index < (buffer_size - 1) ? current_read_index += 1 : current_read_index = 0; load -= 1; - ret = true; } mutex.unlock(); - return ret; + std::cerr << "buffer.pop write: " << current_write_index << " read: " << current_read_index << " load: " << load << std::endl; + + return img; } -bool ImageBuffer::readLast(MyImage &img) { - bool ret = false; +MyImage* ImageBuffer::readLast() { + MyImage *img; mutex.lock(); if (load > 0) { - size_t idx; - if (current_write_index != 0) { - idx = static_cast(current_write_index) - 1; - } else { - idx = buffer.capacity() -1; + size_t idx = current_write_index - 1; + + if (idx < 0) { + std::cerr << "Bank" << std::endl; + idx = buffer_size - 1; } img = buffer[idx]; - ret = true; } mutex.unlock(); - return ret; + return img; } + +ImageBuffer::~ImageBuffer(){ + std::cerr << "Image buffer destructor" << std::endl; + clear(); +} \ No newline at end of file diff --git a/imagebuffer.h b/imagebuffer.h index 2c8fad9..3d11ef0 100644 --- a/imagebuffer.h +++ b/imagebuffer.h @@ -12,25 +12,26 @@ class ImageBuffer : public QObject Q_OBJECT public: explicit ImageBuffer(size_t buffer_size=100, QObject *parent = nullptr); + ~ImageBuffer(); void clear(); void resize(size_t new_size); - void push(const MyImage &img); - bool pop(MyImage &img); - bool readLast(MyImage &img); + void push(MyImage *img); + MyImage* pop(); + MyImage* readLast(); size_t capacity(); double bufferPreassure(); - int64_t bufferLoad(); + size_t bufferLoad(); bool bufferNotEmpty(); private: QMutex mutex; int numUsedBytes = 0; - std::vector buffer; - int64_t current_write_index = -1; - int64_t current_read_index = 0; - int64_t load = 0; + std::vector buffer; + size_t current_write_index = 0; + size_t current_read_index = 0; + size_t load = 0; size_t buffer_size; signals: diff --git a/myimage.cpp b/myimage.cpp index 0625002..d50ab77 100644 --- a/myimage.cpp +++ b/myimage.cpp @@ -9,7 +9,7 @@ MyImage::MyImage(Pylon::CGrabResultPtr ptr) { } bool MyImage::setFrame(Pylon::CGrabResultPtr ptr) { - bool valid = ptr.IsValid() && ptr->GetWidth() <= max_width && ptr->GetHeight() <= max_height; + bool valid = ptr.IsValid() && ptr->GetWidth() <= max_width && ptr->GetHeight() <= max_height; if (valid) { img_index = ptr->GetID(); img_width = ptr->GetWidth(); diff --git a/pylonrecorder.cpp b/pylonrecorder.cpp index eff2690..20910f3 100644 --- a/pylonrecorder.cpp +++ b/pylonrecorder.cpp @@ -251,19 +251,20 @@ void PylonRecorder::saveAs() { void PylonRecorder::print() { - Q_ASSERT(imageLabel->pixmap()); -#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog) + QPixmap map = imageLabel->pixmap(Qt::ReturnByValue); + Q_ASSERT(!map.isNull()); + #if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog) QPrintDialog dialog(&printer, this); if (dialog.exec()) { QPainter painter(&printer); QRect rect = painter.viewport(); - QSize size = imageLabel->pixmap()->size(); + QSize size = map.size(); size.scale(rect.size(), Qt::KeepAspectRatio); painter.setViewport(rect.x(), rect.y(), size.width(), size.height()); - painter.setWindow(imageLabel->pixmap()->rect()); - painter.drawPixmap(0, 0, *imageLabel->pixmap()); + painter.setWindow(map.rect()); + painter.drawPixmap(0, 0, map); } #endif } @@ -512,9 +513,10 @@ void PylonRecorder::updateActions() { void PylonRecorder::scaleImage(double factor) { - Q_ASSERT(imageLabel->pixmap()); + QPixmap map = imageLabel->pixmap(Qt::ReturnByValue); + Q_ASSERT(!map.isNull()); scaleFactor *= factor; - imageLabel->resize(scaleFactor * imageLabel->pixmap()->size()); + imageLabel->resize(scaleFactor * map.size()); adjustScrollBar(scrollArea->horizontalScrollBar(), factor); adjustScrollBar(scrollArea->verticalScrollBar(), factor); @@ -525,14 +527,16 @@ void PylonRecorder::scaleImage(double factor) { void PylonRecorder::applyScaling(){ - imageLabel->resize(scaleFactor * imageLabel->pixmap()->size()); + imageLabel->resize(scaleFactor * imageLabel->pixmap(Qt::ReturnByValue).size()); } void PylonRecorder::quitApplication() { + std::cerr << "Quit Application!" << std::endl; if (pylon->isOpen()) { if (grabbing) { stopRecording(); + buffer->clear(); } pylon->closeCamera(); } @@ -604,12 +608,12 @@ void PylonRecorder::startRecording() { writer->setProjectMetadata(mdata); buffer->clear(); - grabber->start(); if (!dryRunCheckBox->isChecked()) { writer->start(); writing = true; } dryRun = dryRunCheckBox->isChecked(); + grabber->start(); grabbing = true; stopRequest = false; @@ -658,15 +662,14 @@ void PylonRecorder::displayActivity() { void PylonRecorder::displaySingleFrame() { - MyImage img; - bool valid = buffer->readLast(img); - if (valid) { - QImage qimg(static_cast(img.data()), img.width(), img.height(), + MyImage *img = buffer->readLast(); + if (img != nullptr){ + QImage qimg(static_cast(img->data()), img->width(), img->height(), QImage::Format::Format_Grayscale8); setImage(qimg); - }/* else { - std::cerr << "Error reading last image" << std::endl; - }*/ + }/* else { + std::cerr << "Error reading last image" << std::endl; + }*/ } @@ -686,7 +689,7 @@ std::string PylonRecorder::createFilename() { QDateTime dt(QDateTime::currentDateTimeUtc()); QDate date = dt.date(); std::string base = (date.toString("yyyy.MM.dd") + "_").toStdString(); - std::string extension = ".mp4"; + std::string extension = ".avi"; QString idx = QString::number(movieCount); std::string fname = base + idx.toStdString() + extension; while (QFile::exists(QString::fromStdString(fname))) {