Bladeren bron

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 <zejian.su@starfivetech.com>

zejian.su 6 maanden geleden
bovenliggende
commit
4c4ac467c9
1 gewijzigde bestanden met toevoegingen van 148 en 0 verwijderingen
  1. 148 0
      package/starfive/libcamera-apps/0006-Make-the-qt-preview-work-in-debian.patch

+ 148 - 0
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" <zejian.su@starfivetech.com>
+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 <zejian.su@starfivetech.com>
+---
+ 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<uint8_t> 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<uint8_t> tmp_stripe_;
++
++	unsigned int frame_counter_;
+ };
+ 
+ Preview *make_qt_preview(Options const *options)
+-- 
+2.34.1
+