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 +