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 | |
| 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.
| -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();      }  } | 
