Files
fml13v01-buildroot/package/starfive/libcamera-apps/0003-add-FbPreview-support-YUYV-YVYU-display.patch
T
mason.huo c0584b271e packge: stafive: Add libcamera-apps package
Sync the latest libcamera-apps from JH7100.

Signed-off-by: mason.huo <mason.huo@starfivetech.com>
2022-10-28 22:14:41 +08:00

225 lines
6.5 KiB
Diff

From 4fd0d73ae92f4e0f49c9d0f9f7e559e55e4fe2a8 Mon Sep 17 00:00:00 2001
From: sw.multimedia <sw.multimedia@starfivetech.com>
Date: Mon, 22 Nov 2021 15:28:17 +0800
Subject: [PATCH] add FbPreview support YUYV/YVYU display
---
preview/fb_preview.cpp | 123 +++++++++++++++++++++++++++++++++++------
preview/preview.cpp | 15 +++--
2 files changed, 118 insertions(+), 20 deletions(-)
diff --git a/preview/fb_preview.cpp b/preview/fb_preview.cpp
index 1a88b79..0b42ad1 100644
--- a/preview/fb_preview.cpp
+++ b/preview/fb_preview.cpp
@@ -44,6 +44,7 @@ enum COLOR_FORMAT {
COLOR_RGB888_RGBA, // 9
COLOR_RGB888_BGRA, // 10
COLOR_RGB565, // 11
+ COLOR_UNKOWN, // unkown
};
struct pp_video_mode {
@@ -83,6 +84,10 @@ public:
private:
int NVResize(unsigned char *inBuf,
unsigned char *outBuf, int imgWidth, int imgHeight);
+ int YUYVResize(unsigned char *inBuf,
+ unsigned char *outBuf, int imgWidth, int imgHeight);
+ void setPixformat(unsigned int format);
+ unsigned int getPixformat(void);
int g_fb_fd;
int g_stfbc_fd;
struct fb_var_screeninfo g_vinfo;
@@ -93,10 +98,8 @@ private:
enum COLOR_FORMAT pixformat;
};
-static enum COLOR_FORMAT v4l2fmt_to_fbfmt(unsigned int format)
+void FbPreview::setPixformat(unsigned int format)
{
- enum COLOR_FORMAT pixformat = COLOR_RGB565;
-
switch (format) {
case V4L2_PIX_FMT_RGB565:
pixformat = COLOR_RGB565;
@@ -120,11 +123,43 @@ static enum COLOR_FORMAT v4l2fmt_to_fbfmt(unsigned int format)
pixformat = COLOR_YUV422_YVYU;
break;
default:
- pixformat = COLOR_RGB565;
+ pixformat = COLOR_UNKOWN;
break;
}
+}
- return pixformat;
+unsigned int FbPreview::getPixformat(void)
+{
+ unsigned int format;
+
+ switch (pixformat) {
+ case COLOR_RGB565:
+ format = V4L2_PIX_FMT_RGB565;
+ break;
+ case COLOR_RGB888_ARGB:
+ format = V4L2_PIX_FMT_RGB24;
+ break;
+ case COLOR_YUV420P:
+ format = V4L2_PIX_FMT_YUV420;
+ break;
+ case COLOR_YUV422_YUYV:
+ format = V4L2_PIX_FMT_YUYV;
+ break;
+ case COLOR_YUV420_NV21:
+ format = V4L2_PIX_FMT_NV21;
+ break;
+ case COLOR_YUV420_NV12:
+ format = V4L2_PIX_FMT_NV12;
+ break;
+ case COLOR_YUV422_YVYU:
+ format = V4L2_PIX_FMT_YVYU;
+ break;
+ default:
+ format = 0;
+ break;
+ }
+
+ return format;
}
FbPreview::FbPreview(Options const *options) : Preview(options)
@@ -140,10 +175,10 @@ FbPreview::FbPreview(Options const *options) : Preview(options)
libcamera::PixelFormat pixelFormat =
libcamera::PixelFormat::fromString(options_->pixelformat);
- if (pixelFormat.fourcc() != V4L2_PIX_FMT_NV12)
- throw std::runtime_error("FB onlu support NV12 display");
+ setPixformat(pixelFormat.fourcc());
+ if (pixformat == COLOR_UNKOWN)
+ throw std::runtime_error("FB unsupport format display.");
- pixformat = v4l2fmt_to_fbfmt(pixelFormat.fourcc());
if (-1 == ioctl(g_stfbc_fd, FBIOPAN_GET_PP_MODE, &pp_info[0]))
throw std::runtime_error("Error reading variable information.");
@@ -217,9 +252,6 @@ int FbPreview::NVResize(unsigned char *inBuf,
int fb_Ypos, fb_Upos, fb_Vpos;
int width, height;
int x_offset, y_offset;
- unsigned int start_timems;
- unsigned int end_timems;
- struct timeval ts_start, ts_end;
width = imgWidth > g_vinfo.xres ? g_vinfo.xres : imgWidth;
height = imgHeight > g_vinfo.yres ? g_vinfo.yres : imgHeight;
@@ -264,15 +296,74 @@ int FbPreview::NVResize(unsigned char *inBuf,
return 0;
}
+int FbPreview::YUYVResize(unsigned char *inBuf,
+ unsigned char *outBuf, int imgWidth, int imgHeight)
+{
+ int rows, cols;
+ unsigned char *OutNVdata, *InNVdata;
+ int Ypos, fb_Ypos;
+ int width, height;
+ int x_offset, y_offset;
+
+ width = imgWidth > g_vinfo.xres ? g_vinfo.xres : imgWidth;
+ height = imgHeight > g_vinfo.yres ? g_vinfo.yres : imgHeight;
+ x_offset = (g_vinfo.xres - width) / 2;
+ y_offset = (g_vinfo.yres - height) / 2;
+ x_offset &= ~0x1;
+
+ InNVdata = inBuf;
+ OutNVdata = tmpBuf;
+
+ if (imgWidth == g_vinfo.xres) {
+ fb_Ypos = y_offset * g_vinfo.xres + x_offset;
+ memcpy(&tmpBuf[fb_Ypos], inBuf, imgWidth * height * 2);
+ memcpy(&outBuf[fb_Ypos], &tmpBuf[fb_Ypos], imgWidth * height * 2);
+ return 0;
+ }
+
+ /* two bytes for every pixels */
+ for(rows = 0; rows < height; rows++)
+ {
+ // g_vinfo.xres, g_vinfo.yres g_vinfo.bits_per_pixel
+ fb_Ypos = ((rows + y_offset) * g_vinfo.xres + x_offset) * 2;
+ Ypos = rows * imgWidth * 2;
+ memcpy(&OutNVdata[fb_Ypos], &InNVdata[Ypos], width * 2);
+ }
+
+ memcpy(outBuf, tmpBuf, g_screensize);
+
+ return 0;
+}
+
void FbPreview::Show(int fd, libcamera::Span<uint8_t> span, int width, int height, int stride)
{
- int imgsize = stride * height + stride * height / 2;
auto startTime = std::chrono::high_resolution_clock::now();
+ int size_valid = 0;
+ int imgsize;
+
+ if (pixformat == COLOR_YUV420_NV21 || pixformat == COLOR_YUV420_NV12) {
+ imgsize = stride * height + stride * height / 2;
+ if (imgsize == span.size()) {
+ size_valid = 1;
+ NVResize(span.data(), g_fb_buf, width, height);
+ }
+ } else if (pixformat == COLOR_YUV422_YVYU || pixformat == COLOR_YUV422_YUYV) {
+ imgsize = stride * height;
+ if (imgsize == span.size()) {
+ size_valid = 1;
+ YUYVResize(span.data(), g_fb_buf, width, height);
+ }
+ }
- if (pixformat == COLOR_YUV420_NV21 || pixformat == COLOR_YUV420_NV12)
- NVResize(span.data(), g_fb_buf, width, height);
- else
- std::cout << "FbPreview unsupport pixformat: " << pixformat << std::endl;
+ if (!size_valid) {
+ std::cout << "FbPreview unsupport pixformat: " << pixformat
+ << " fb need size: " << imgsize
+ << " width: " << width
+ << " height: " << height
+ << " stride: " << stride
+ << " size: " << span.size() << std::endl;
+ throw std::runtime_error("Error FbPreview unsupport pixformat.");
+ }
auto endTime = std::chrono::high_resolution_clock::now();
diff --git a/preview/preview.cpp b/preview/preview.cpp
index 0086d83..17118d4 100644
--- a/preview/preview.cpp
+++ b/preview/preview.cpp
@@ -49,10 +49,17 @@ Preview *make_preview(Options const *options)
}
catch (std::exception const &e)
{
- std::cout << "FB Preview window." << std::endl;
- return make_fb_preview(options);
- // std::cout << "Preview window unavailable" << std::endl;
- // return make_null_preview(options);
+ try {
+ std::cout << "FB Preview window." << std::endl;
+ return make_fb_preview(options);
+ if (options->verbose)
+ std::cout << "Made FB Preview window." << std::endl;
+ }
+ catch (std::exception const &e)
+ {
+ std::cout << "Preview window unavailable" << std::endl;
+ return make_null_preview(options);
+ }
}
}
}
--
2.17.1