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