#include "video-widget.hpp" #include void cv_video_widget::update_image(const cv::Mat& frame) { QMutexLocker l(&mtx); if (freshp) return; if (W < 1 || H < 1 || frame.rows < 1 || frame.cols < 1) return; cv::Mat const* __restrict frame_scaled = nullptr; if (frame3.cols != W || frame3.rows != H) { frame3 = cv::Mat(H, W, frame.type()); frame2 = cv::Mat(H, W, CV_8UC4); if (!frame2.isContinuous() || !frame3.isContinuous()) std::abort(); } if (frame.cols != W || frame.rows != H) { cv::resize(frame, frame3, { W, H }, 0, 0, cv::INTER_NEAREST); frame_scaled = &frame3; } else if (!frame.isContinuous()) { frame.copyTo(frame3); frame_scaled = &frame3; } else frame_scaled = &frame; freshp = true; int color_cvt = 0; constexpr int nchannels = 4; switch (frame_scaled->channels()) { case 1: color_cvt = cv::COLOR_GRAY2BGRA; break; case 3: color_cvt = cv::COLOR_BGR2BGRA; break; case nchannels: break; default: unreachable(); break; } cv::Mat const* frame_color; if (color_cvt != cv::COLOR_COLORCVT_MAX) { cv::cvtColor(*frame_scaled, frame2, color_cvt); frame_color = &frame2; } else frame_color = frame_scaled; int stride = frame_color->step.p[0], rows = frame_color->rows; unsigned nbytes = (unsigned)(rows * stride); vec.resize(nbytes); vec.shrink_to_fit(); std::memcpy(vec.data(), frame_color->data, nbytes); texture = QImage((const unsigned char*) vec.data(), W, H, stride, QImage::Format_ARGB32); texture.setDevicePixelRatio(devicePixelRatioF()); } cv_video_widget::cv_video_widget(QWidget* parent) : video_widget(parent) {}