summaryrefslogtreecommitdiffhomepage
path: root/cv/video-widget.cpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2019-02-11 16:00:07 +0100
committerStanislaw Halik <sthalik@misaki.pl>2019-02-11 18:44:03 +0100
commit2e946e830ae52b19973745b8d67915cd0d8c767b (patch)
tree39b02f52f8f64faad543fb4a5875339554cb4b32 /cv/video-widget.cpp
parentec506192a7a0739a862568cc8bb8c904e702db78 (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/video-widget.cpp')
-rw-r--r--cv/video-widget.cpp42
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();
}
}