From 4c4ac467c90972c1a4bbd5c71b834b44b5ed00db Mon Sep 17 00:00:00 2001 From: "zejian.su" Date: Wed, 15 Nov 2023 11:54:58 +0800 Subject: [PATCH] Make the qt preview work in SDK/VF2/DEVDIT. 1. Fill the NV12 data into the QT buffer. 2. For the low performance of QWidget, reduce the FPS to 15. 3. Remove the EGL preview option because its code can't work well. The qt supported patch has been verified on the VF2 with qt5 (linuxfb plugin). Signed-off-by: zejian.su --- ...6-Make-the-qt-preview-work-in-debian.patch | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 package/starfive/libcamera-apps/0006-Make-the-qt-preview-work-in-debian.patch diff --git a/package/starfive/libcamera-apps/0006-Make-the-qt-preview-work-in-debian.patch b/package/starfive/libcamera-apps/0006-Make-the-qt-preview-work-in-debian.patch new file mode 100644 index 00000000..9aec34b4 --- /dev/null +++ b/package/starfive/libcamera-apps/0006-Make-the-qt-preview-work-in-debian.patch @@ -0,0 +1,148 @@ +From 0327a137e069e0cfbdd775f7c40f03e088b765d6 Mon Sep 17 00:00:00 2001 +From: "zejian.su" +Date: Wed, 8 Nov 2023 09:23:01 +0800 +Subject: [PATCH 2/2] Make the qt preview work in debian. 1. Fill the NV12 data + into the QT buffer. 2. For the low performance of QWidget, reduce the FPS to + 15. + +Signed-off-by: zejian.su +--- + preview/preview.cpp | 37 ++++++++++++++----------------------- + preview/qt_preview.cpp | 20 ++++++++++++++++---- + 2 files changed, 30 insertions(+), 27 deletions(-) + +diff --git a/preview/preview.cpp b/preview/preview.cpp +index b67edb3..d2c511a 100644 +--- a/preview/preview.cpp ++++ b/preview/preview.cpp +@@ -19,47 +19,38 @@ Preview *make_preview(Options const *options) + if (options->nopreview) + return make_null_preview(options); + #if QT_PRESENT +- else if (options->qt_preview) ++ else + { + Preview *p = make_qt_preview(options); + if (p) + LOG(1, "Made QT preview window"); + return p; + } +-#endif +- else ++#else ++ try ++ { ++ throw std::runtime_error("qt5 libraries unavailable."); ++ } ++ catch(std::exception const &e) + { + try + { +-#if LIBEGL_PRESENT +- Preview *p = make_egl_preview(options); ++#if LIBDRM_PRESENT ++ Preview *p = make_drm_preview(options); + if (p) +- LOG(1, "Made X/EGL preview window"); ++ LOG(1, "Made DRM preview window"); + return p; + #else +- throw std::runtime_error("egl libraries unavailable."); ++ throw std::runtime_error("drm libraries unavailable."); + #endif + } + catch (std::exception const &e) + { +- try +- { +-#if LIBDRM_PRESENT +- Preview *p = make_drm_preview(options); +- if (p) +- LOG(1, "Made DRM preview window"); +- return p; +-#else +- throw std::runtime_error("drm libraries unavailable."); +-#endif +- } +- catch (std::exception const &e) +- { +- LOG(1, "Preview window unavailable"); +- return make_null_preview(options); +- } ++ LOG(1, "Preview window unavailable"); ++ return make_null_preview(options); + } + } ++#endif + + return nullptr; // prevents compiler warning in debug builds + } +diff --git a/preview/qt_preview.cpp b/preview/qt_preview.cpp +index f595db7..8196a8e 100644 +--- a/preview/qt_preview.cpp ++++ b/preview/qt_preview.cpp +@@ -58,7 +58,7 @@ protected: + class QtPreview : public Preview + { + public: +- QtPreview(Options const *options) : Preview(options) ++ QtPreview(Options const *options) : Preview(options), frame_counter_(0) + { + window_width_ = options->preview_width; + window_height_ = options->preview_height; +@@ -83,6 +83,12 @@ public: + void SetInfoText(const std::string &text) override { main_window_->setWindowTitle(QString::fromStdString(text)); } + virtual void Show(int fd, libcamera::Span span, StreamInfo const &info) override + { ++ if((frame_counter_++) & 1) { ++ // Return the buffer to the camera system. ++ done_callback_(fd); ++ return; ++ } ++ + // Quick and simple nearest-neighbour-ish resampling is used here. + // We further share U,V samples between adjacent output pixel pairs + // (even when downscaling) to speed up the conversion. +@@ -131,6 +137,7 @@ public: + // take a copy of each row used. This is a speedup provided memcpy() is vectorized. + tmp_stripe_.resize(2 * info.stride); + uint8_t const *Y_start = span.data(); ++ uint8_t const *UV_start = Y_start + info.height * info.stride; + uint8_t *Y_row = &tmp_stripe_[0]; + uint8_t *U_row = Y_row + info.stride; + uint8_t *V_row = U_row + (info.stride >> 1); +@@ -146,8 +153,11 @@ public: + unsigned x_pos = x_step >> 1; + + memcpy(Y_row, Y_start + row * info.stride, info.stride); +- memcpy(U_row, Y_start + ((4 * info.height + row) >> 1) * (info.stride >> 1), info.stride >> 1); +- memcpy(V_row, Y_start + ((5 * info.height + row) >> 1) * (info.stride >> 1), info.stride >> 1); ++ //memcpy(U_row, Y_start + ((4 * info.height + row) >> 1) * (info.stride >> 1), info.stride >> 1); ++ //memcpy(V_row, Y_start + ((5 * info.height + row) >> 1) * (info.stride >> 1), info.stride >> 1); ++ uint8_t const *cur_uv = UV_start + (row >> 1) * info.width; ++ for(unsigned int uv_idx = 0; uv_idx < info.width >> 1; uv_idx++, cur_uv += 2) ++ U_row[uv_idx] = cur_uv[0], V_row[uv_idx] = cur_uv[1]; + + for (unsigned int x = 0; x < window_width_; x += 2) + { +@@ -183,7 +193,7 @@ public: + } + // Reset the preview window, clearing the current buffers and being ready to + // show new ones. +- void Reset() override {} ++ void Reset() override {frame_counter_ = 0;} + // Check if preview window has been shut down. + bool Quit() override { return main_window_->quit; } + // There is no particular limit to image sizes, though large images will be very slow. +@@ -218,6 +228,8 @@ private: + std::mutex mutex_; + std::condition_variable cond_var_; + std::vector tmp_stripe_; ++ ++ unsigned int frame_counter_; + }; + + Preview *make_qt_preview(Options const *options) +-- +2.34.1 +