diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2019-02-11 16:00:07 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2019-02-11 18:44:03 +0100 |
commit | 2e946e830ae52b19973745b8d67915cd0d8c767b (patch) | |
tree | 39b02f52f8f64faad543fb4a5875339554cb4b32 /cv | |
parent | ec506192a7a0739a862568cc8bb8c904e702db78 (diff) |
cv/video-widget: fixes
- don't copy pointlessly on ARGB32 input.
- add stride argument to QImage.
- don't do pointless stuff during painting on the main thread.
Diffstat (limited to 'cv')
-rw-r--r-- | cv/video-widget.cpp | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/cv/video-widget.cpp b/cv/video-widget.cpp index da9972f5..f2da8da7 100644 --- a/cv/video-widget.cpp +++ b/cv/video-widget.cpp @@ -6,10 +6,13 @@ * copyright notice and this permission notice appear in all copies. */ +// XXX TODO remove hard opencv dependency -sh 20190210 + #include "video-widget.hpp" #include "compat/check-visible.hpp" #include "compat/math.hpp" +#include <cstddef> #include <cstring> #include <opencv2/imgproc.hpp> @@ -27,6 +30,12 @@ void cv_video_widget::update_image(const cv::Mat& frame) { QMutexLocker l(&mtx); + if (texture.width() != W || texture.height() != H) + { + frame2 = cv::Mat(); + frame3 = cv::Mat(); + } + if (!freshp) { if (W < 1 || H < 1 || frame.rows < 1 || frame.cols < 1) @@ -40,6 +49,8 @@ void cv_video_widget::update_image(const cv::Mat& frame) if (frame3.cols != W || frame3.rows != H) frame3 = cv::Mat(H, W, CV_8UC4); + const cv::Mat* argb = &frame2; + switch (frame.channels()) { case 1: @@ -49,28 +60,32 @@ void cv_video_widget::update_image(const cv::Mat& frame) cv::cvtColor(frame, frame2, cv::COLOR_BGR2BGRA); break; case 4: - frame2.setTo(frame); + argb = &frame; break; default: - *(volatile int*)nullptr = 0; // NOLINT(clang-analyzer-core.NullDereference) unreachable(); } const cv::Mat* img; - if (frame2.cols != W || frame2.rows != H) + if (argb->cols != W || argb->rows != H) { - cv::resize(frame2, frame3, cv::Size(W, H), 0, 0, cv::INTER_NEAREST); + cv::resize(*argb, frame3, cv::Size(W, H), 0, 0, cv::INTER_NEAREST); img = &frame3; } else - img = &frame2; + img = argb; + + int stride = (int)img->step.p[0]; - const unsigned nbytes = unsigned(4 * img->rows * img->cols); - vec.resize(nbytes); + if (stride < img->cols) + std::abort(); + + unsigned nbytes = (unsigned)(4 * img->rows * stride); + vec.resize(nbytes); vec.shrink_to_fit(); std::memcpy(vec.data(), img->data, nbytes); - texture = QImage((const unsigned char*) vec.data(), W, H, QImage::Format_ARGB32); + texture = QImage((const unsigned char*) vec.data(), W, H, stride, QImage::Format_ARGB32); texture.setDevicePixelRatio(devicePixelRatioF()); } } @@ -83,18 +98,17 @@ void cv_video_widget::update_image(const QImage& img) return; freshp = true; - const unsigned nbytes = unsigned(img.bytesPerLine() * img.height()); - vec.resize(nbytes); + unsigned nbytes = unsigned(img.bytesPerLine() * img.height()); + vec.resize(nbytes); vec.shrink_to_fit(); std::memcpy(vec.data(), img.constBits(), nbytes); - texture = QImage((const unsigned char*) vec.data(), img.width(), img.height(), img.format()); + texture = QImage((const unsigned char*) vec.data(), img.width(), img.height(), img.bytesPerLine(), img.format()); texture.setDevicePixelRatio(devicePixelRatioF()); } void cv_video_widget::paintEvent(QPaintEvent*) { QMutexLocker foo(&mtx); - QPainter painter(this); double dpr = devicePixelRatioF(); @@ -106,10 +120,8 @@ void cv_video_widget::paintEvent(QPaintEvent*) if (texture.width() != W || texture.height() != H) { texture = QImage(W, H, QImage::Format_ARGB32); + texture.fill(Qt::gray); texture.setDevicePixelRatio(dpr); - - frame2 = cv::Mat(); - frame3 = cv::Mat(); } } |