packge: stafive: Add libcamera-apps package
Sync the latest libcamera-apps from JH7100. Signed-off-by: mason.huo <mason.huo@starfivetech.com>
This commit is contained in:
@@ -6,6 +6,7 @@ source "package/starfive/codaj12/Config.in"
|
||||
source "package/starfive/sf-omx-il/Config.in"
|
||||
source "package/starfive/sf-omx-il-test/Config.in"
|
||||
source "package/starfive/v4l2_test/Config.in"
|
||||
source "package/starfive/libcamera-apps/Config.in"
|
||||
source "package/starfive/ispsdk/Config.in"
|
||||
source "package/starfive/mailbox-test/Config.in"
|
||||
source "package/starfive/e24-test/Config.in"
|
||||
|
||||
@@ -0,0 +1,489 @@
|
||||
From 6abadc7414f0fdfea160374326cea32bd2b40d7d Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Fri, 15 Oct 2021 10:55:01 +0800
|
||||
Subject: [PATCH] add starfive support
|
||||
|
||||
---
|
||||
CMakeLists.txt | 2 +-
|
||||
core/CMakeLists.txt | 2 +-
|
||||
core/libcamera_app.cpp | 38 ++++--
|
||||
core/options.hpp | 3 +
|
||||
preview/CMakeLists.txt | 9 ++
|
||||
preview/fb_preview.cpp | 289 +++++++++++++++++++++++++++++++++++++++++
|
||||
preview/preview.cpp | 7 +-
|
||||
7 files changed, 338 insertions(+), 12 deletions(-)
|
||||
create mode 100644 preview/fb_preview.cpp
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 2293211..253ec8d 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -12,7 +12,7 @@ endif()
|
||||
set (CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set (CMAKE_CXX_STANDARD 17)
|
||||
set (CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic -Wno-unused-parameter -faligned-new")
|
||||
-add_definitions(-Werror)
|
||||
+# add_definitions(-Werror)
|
||||
add_definitions(-Wfatal-errors)
|
||||
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||
|
||||
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
|
||||
index 1618541..84316b2 100644
|
||||
--- a/core/CMakeLists.txt
|
||||
+++ b/core/CMakeLists.txt
|
||||
@@ -11,6 +11,6 @@ add_library(libcamera_app libcamera_app.cpp post_processor.cpp version.cpp)
|
||||
add_dependencies(libcamera_app VersionCpp)
|
||||
|
||||
set_target_properties(libcamera_app PROPERTIES PREFIX "" IMPORT_PREFIX "")
|
||||
-target_link_libraries(libcamera_app pthread preview ${LIBCAMERA_LINK_LIBRARIES} ${Boost_LIBRARIES} post_processing_stages)
|
||||
+target_link_libraries(libcamera_app pthread preview ${LIBCAMERA_LIBRARIES} ${Boost_LIBRARIES} post_processing_stages)
|
||||
|
||||
install(TARGETS libcamera_app LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
diff --git a/core/libcamera_app.cpp b/core/libcamera_app.cpp
|
||||
index 7d4e28f..3c4d862 100644
|
||||
--- a/core/libcamera_app.cpp
|
||||
+++ b/core/libcamera_app.cpp
|
||||
@@ -134,7 +134,12 @@ void LibcameraApp::ConfigureViewfinder()
|
||||
}
|
||||
|
||||
// Now we get to override any of the default settings from the options_->
|
||||
- configuration_->at(0).pixelFormat = libcamera::formats::YUV420;
|
||||
+ std::cout << "viewfinder pixelformat: " << options_->pixelformat << std::endl;
|
||||
+ if (options_->pixelformat.length())
|
||||
+ configuration_->at(0).pixelFormat =
|
||||
+ libcamera::PixelFormat::fromString(options_->pixelformat);
|
||||
+ else
|
||||
+ configuration_->at(0).pixelFormat = libcamera::formats::YUV420;
|
||||
configuration_->at(0).size = size;
|
||||
|
||||
if (have_lores_stream)
|
||||
@@ -143,7 +148,11 @@ void LibcameraApp::ConfigureViewfinder()
|
||||
lores_size.alignDownTo(2, 2);
|
||||
if (lores_size.width > size.width || lores_size.height > size.height)
|
||||
throw std::runtime_error("Low res image larger than viewfinder");
|
||||
- configuration_->at(1).pixelFormat = libcamera::formats::YUV420;
|
||||
+ if (options_->pixelformat.length())
|
||||
+ configuration_->at(0).pixelFormat =
|
||||
+ libcamera::PixelFormat::fromString(options_->pixelformat);
|
||||
+ else
|
||||
+ configuration_->at(1).pixelFormat = libcamera::formats::YUV420;
|
||||
configuration_->at(1).size = lores_size;
|
||||
configuration_->at(1).bufferCount = configuration_->at(0).bufferCount;
|
||||
}
|
||||
@@ -186,8 +195,13 @@ void LibcameraApp::ConfigureStill(unsigned int flags)
|
||||
configuration_->at(0).pixelFormat = libcamera::formats::BGR888;
|
||||
else if (flags & FLAG_STILL_RGB)
|
||||
configuration_->at(0).pixelFormat = libcamera::formats::RGB888;
|
||||
- else
|
||||
- configuration_->at(0).pixelFormat = libcamera::formats::YUV420;
|
||||
+ else {
|
||||
+ if (options_->pixelformat.length())
|
||||
+ configuration_->at(0).pixelFormat =
|
||||
+ libcamera::PixelFormat::fromString(options_->pixelformat);
|
||||
+ else
|
||||
+ configuration_->at(0).pixelFormat = libcamera::formats::YUV420;
|
||||
+ }
|
||||
if ((flags & FLAG_STILL_BUFFER_MASK) == FLAG_STILL_DOUBLE_BUFFER)
|
||||
configuration_->at(0).bufferCount = 2;
|
||||
else if ((flags & FLAG_STILL_BUFFER_MASK) == FLAG_STILL_TRIPLE_BUFFER)
|
||||
@@ -241,7 +255,11 @@ void LibcameraApp::ConfigureVideo(unsigned int flags)
|
||||
throw std::runtime_error("failed to generate video configuration");
|
||||
|
||||
// Now we get to override any of the default settings from the options_->
|
||||
- configuration_->at(0).pixelFormat = libcamera::formats::YUV420;
|
||||
+ if (options_->pixelformat.length())
|
||||
+ configuration_->at(0).pixelFormat =
|
||||
+ libcamera::PixelFormat::fromString(options_->pixelformat);
|
||||
+ else
|
||||
+ configuration_->at(0).pixelFormat = libcamera::formats::YUV420;
|
||||
configuration_->at(0).bufferCount = 6; // 6 buffers is better than 4
|
||||
if (options_->width)
|
||||
configuration_->at(0).size.width = options_->width;
|
||||
@@ -267,7 +285,11 @@ void LibcameraApp::ConfigureVideo(unsigned int flags)
|
||||
if (lores_size.width > configuration_->at(0).size.width ||
|
||||
lores_size.height > configuration_->at(0).size.height)
|
||||
throw std::runtime_error("Low res image larger than video");
|
||||
- configuration_->at(lores_index).pixelFormat = libcamera::formats::YUV420;
|
||||
+ if (options_->pixelformat.length())
|
||||
+ configuration_->at(0).pixelFormat =
|
||||
+ libcamera::PixelFormat::fromString(options_->pixelformat);
|
||||
+ else
|
||||
+ configuration_->at(lores_index).pixelFormat = libcamera::formats::YUV420;
|
||||
configuration_->at(lores_index).size = lores_size;
|
||||
configuration_->at(lores_index).bufferCount = configuration_->at(0).bufferCount;
|
||||
}
|
||||
@@ -713,8 +735,8 @@ void LibcameraApp::previewThread()
|
||||
preview_cond_var_.wait(lock);
|
||||
}
|
||||
|
||||
- if (item.stream->configuration().pixelFormat != libcamera::formats::YUV420)
|
||||
- throw std::runtime_error("Preview windows only support YUV420");
|
||||
+ // if (item.stream->configuration().pixelFormat != libcamera::formats::YUV420)
|
||||
+ // throw std::runtime_error("Preview windows only support YUV420");
|
||||
|
||||
unsigned int w, h, stride;
|
||||
StreamDimensions(item.stream, &w, &h, &stride);
|
||||
diff --git a/core/options.hpp b/core/options.hpp
|
||||
index 447983f..5c68088 100644
|
||||
--- a/core/options.hpp
|
||||
+++ b/core/options.hpp
|
||||
@@ -43,6 +43,8 @@ struct Options
|
||||
"Set the output image width (0 = use default value)")
|
||||
("height", value<unsigned int>(&height)->default_value(0),
|
||||
"Set the output image height (0 = use default value)")
|
||||
+ ("pixelformat", value<std::string>(&pixelformat),
|
||||
+ "Set the pixelformat name")
|
||||
("timeout,t", value<uint64_t>(&timeout)->default_value(5000),
|
||||
"Time (in ms) for which program runs")
|
||||
("output,o", value<std::string>(&output),
|
||||
@@ -119,6 +121,7 @@ struct Options
|
||||
std::string post_process_file;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
+ std::string pixelformat;
|
||||
bool rawfull;
|
||||
bool nopreview;
|
||||
std::string preview;
|
||||
diff --git a/preview/CMakeLists.txt b/preview/CMakeLists.txt
|
||||
index 1a7481f..a772e14 100644
|
||||
--- a/preview/CMakeLists.txt
|
||||
+++ b/preview/CMakeLists.txt
|
||||
@@ -63,6 +63,15 @@ else()
|
||||
message(STATUS "QT display mode will be unavailable!")
|
||||
endif()
|
||||
|
||||
+set(ENABLE_FB 1)
|
||||
+if (ENABLE_FB)
|
||||
+ set(SRC ${SRC} fb_preview.cpp)
|
||||
+ set(FB_FOUND 1)
|
||||
+ message(STATUS "FB display mode enabled")
|
||||
+else()
|
||||
+ message(STATUS "FB display mode will be unavailable!")
|
||||
+endif()
|
||||
+
|
||||
add_library(preview null_preview.cpp ${SRC})
|
||||
target_link_libraries(preview ${TARGET_LIBS})
|
||||
|
||||
diff --git a/preview/fb_preview.cpp b/preview/fb_preview.cpp
|
||||
new file mode 100644
|
||||
index 0000000..1a88b79
|
||||
--- /dev/null
|
||||
+++ b/preview/fb_preview.cpp
|
||||
@@ -0,0 +1,289 @@
|
||||
+/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
+/*
|
||||
+ * Copyright (C) 2021, Raspberry Pi (Trading) Ltd.
|
||||
+ *
|
||||
+ * null_preview.cpp - dummy "show nothing" preview window.
|
||||
+ */
|
||||
+
|
||||
+#include <iostream>
|
||||
+#include <sys/mman.h>
|
||||
+#include <stdio.h>
|
||||
+#include <unistd.h>
|
||||
+#include <errno.h>
|
||||
+#include <malloc.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <linux/fb.h>
|
||||
+#include <string.h>
|
||||
+#include <malloc.h>
|
||||
+#include <linux/videodev2.h>
|
||||
+#include <libcamera/formats.h>
|
||||
+#include <chrono>
|
||||
+
|
||||
+#include "core/options.hpp"
|
||||
+
|
||||
+#include "preview.hpp"
|
||||
+
|
||||
+#define FBIOPAN_GET_PP_MODE 0x4609
|
||||
+#define FBIOPAN_SET_PP_MODE 0x460a
|
||||
+
|
||||
+enum COLOR_FORMAT {
|
||||
+ COLOR_YUV422_UYVY = 0, // 00={Y1,V0,Y0,U0}
|
||||
+ COLOR_YUV422_VYUY = 1, // 01={Y1,U0,Y0,V0}
|
||||
+ COLOR_YUV422_YUYV = 2, // 10={V0,Y1,U0,Y0}
|
||||
+ COLOR_YUV422_YVYU = 3, // 11={U0,Y1,V0,Y0}
|
||||
+
|
||||
+ COLOR_YUV420P, // 4
|
||||
+ COLOR_YUV420_NV21, // 5
|
||||
+ COLOR_YUV420_NV12, // 6
|
||||
+
|
||||
+ COLOR_RGB888_ARGB, // 7
|
||||
+ COLOR_RGB888_ABGR, // 8
|
||||
+ COLOR_RGB888_RGBA, // 9
|
||||
+ COLOR_RGB888_BGRA, // 10
|
||||
+ COLOR_RGB565, // 11
|
||||
+};
|
||||
+
|
||||
+struct pp_video_mode {
|
||||
+ enum COLOR_FORMAT format;
|
||||
+ unsigned int height;
|
||||
+ unsigned int width;
|
||||
+ unsigned int addr;
|
||||
+};
|
||||
+
|
||||
+struct pp_mode {
|
||||
+ char pp_id;
|
||||
+ bool bus_out; /*out to ddr*/
|
||||
+ bool fifo_out; /*out to lcdc*/
|
||||
+ bool inited;
|
||||
+ struct pp_video_mode src;
|
||||
+ struct pp_video_mode dst;
|
||||
+};
|
||||
+
|
||||
+class FbPreview : public Preview
|
||||
+{
|
||||
+public:
|
||||
+ FbPreview(Options const *options);
|
||||
+ ~FbPreview();
|
||||
+ void SetInfoText(const std::string &text) override
|
||||
+ {
|
||||
+ std::cout << "Camera fps: " << text << std::endl;
|
||||
+ }
|
||||
+ // Display the buffer. You get given the fd back in the BufferDoneCallback
|
||||
+ // once its available for re-use.
|
||||
+ virtual void Show(int fd, libcamera::Span<uint8_t> span, int width, int height, int stride) override;
|
||||
+ // Reset the preview window, clearing the current buffers and being ready to
|
||||
+ // show new ones.
|
||||
+ void Reset() override {}
|
||||
+ // Return the maximum image size allowed. Zeroes mean "no limit".
|
||||
+ virtual void MaxImageSize(unsigned int &w, unsigned int &h) const override { w = h = 0; }
|
||||
+
|
||||
+private:
|
||||
+ int NVResize(unsigned char *inBuf,
|
||||
+ unsigned char *outBuf, int imgWidth, int imgHeight);
|
||||
+ int g_fb_fd;
|
||||
+ int g_stfbc_fd;
|
||||
+ struct fb_var_screeninfo g_vinfo;
|
||||
+ struct fb_fix_screeninfo g_finfo;
|
||||
+ unsigned char *g_fb_buf;
|
||||
+ unsigned char *tmpBuf;
|
||||
+ unsigned int g_screensize;
|
||||
+ enum COLOR_FORMAT pixformat;
|
||||
+};
|
||||
+
|
||||
+static enum COLOR_FORMAT v4l2fmt_to_fbfmt(unsigned int format)
|
||||
+{
|
||||
+ enum COLOR_FORMAT pixformat = COLOR_RGB565;
|
||||
+
|
||||
+ switch (format) {
|
||||
+ case V4L2_PIX_FMT_RGB565:
|
||||
+ pixformat = COLOR_RGB565;
|
||||
+ break;
|
||||
+ case V4L2_PIX_FMT_RGB24:
|
||||
+ pixformat = COLOR_RGB888_ARGB;
|
||||
+ break;
|
||||
+ case V4L2_PIX_FMT_YUV420:
|
||||
+ pixformat = COLOR_YUV420P;
|
||||
+ break;
|
||||
+ case V4L2_PIX_FMT_YUYV:
|
||||
+ pixformat = COLOR_YUV422_YUYV;
|
||||
+ break;
|
||||
+ case V4L2_PIX_FMT_NV21:
|
||||
+ pixformat = COLOR_YUV420_NV21;
|
||||
+ break;
|
||||
+ case V4L2_PIX_FMT_NV12:
|
||||
+ pixformat = COLOR_YUV420_NV12;
|
||||
+ break;
|
||||
+ case V4L2_PIX_FMT_YVYU:
|
||||
+ pixformat = COLOR_YUV422_YVYU;
|
||||
+ break;
|
||||
+ default:
|
||||
+ pixformat = COLOR_RGB565;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return pixformat;
|
||||
+}
|
||||
+
|
||||
+FbPreview::FbPreview(Options const *options) : Preview(options)
|
||||
+{
|
||||
+ g_fb_fd = open("/dev/fb0", O_RDWR);
|
||||
+ if (g_fb_fd == -1)
|
||||
+ throw std::runtime_error("Couldn't open fb display");
|
||||
+ g_stfbc_fd = open("/dev/stfbcdev", O_RDWR);
|
||||
+ if (g_stfbc_fd == -1)
|
||||
+ throw std::runtime_error("Couldn't open stfbcdev display");
|
||||
+
|
||||
+ struct pp_mode pp_info[3];
|
||||
+ libcamera::PixelFormat pixelFormat =
|
||||
+ libcamera::PixelFormat::fromString(options_->pixelformat);
|
||||
+
|
||||
+ if (pixelFormat.fourcc() != V4L2_PIX_FMT_NV12)
|
||||
+ throw std::runtime_error("FB onlu support NV12 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.");
|
||||
+
|
||||
+ std::cout << "get pp format : "
|
||||
+ << pp_info[1].src.format
|
||||
+ << std::endl;
|
||||
+
|
||||
+ pp_info[1].src.format = pixformat;
|
||||
+
|
||||
+ if (-1 == ioctl(g_stfbc_fd, FBIOPAN_SET_PP_MODE, &pp_info[0]))
|
||||
+ throw std::runtime_error("Error reading variable information.");
|
||||
+
|
||||
+ if (-1 == ioctl(g_stfbc_fd, FBIOPAN_GET_PP_MODE, &pp_info[0]))
|
||||
+ throw std::runtime_error("Error reading variable information.");
|
||||
+
|
||||
+ std::cout << "get pp format : "
|
||||
+ << pp_info[1].src.format
|
||||
+ << std::endl;
|
||||
+
|
||||
+ pixformat = pp_info[1].src.format;
|
||||
+
|
||||
+ // Get fixed screen information
|
||||
+ if (-1 == ioctl(g_fb_fd, FBIOGET_FSCREENINFO, &g_finfo))
|
||||
+ throw std::runtime_error("Error reading fixed information.");
|
||||
+
|
||||
+ // Get variable screen information
|
||||
+ if (-1 == ioctl(g_fb_fd, FBIOGET_VSCREENINFO, &g_vinfo))
|
||||
+ throw std::runtime_error("Error reading variable information.");
|
||||
+
|
||||
+ std::cout << "g_vinfo.xres = " << g_vinfo.xres
|
||||
+ << ", g_vinfo.yres = " << g_vinfo.yres
|
||||
+ << ", grayscale = " << g_vinfo.grayscale
|
||||
+ << std::endl;
|
||||
+ std::cout << "g_vinfo.xoffset = " << g_vinfo.xoffset
|
||||
+ << ", g_vinfo.yoffset = " << g_vinfo.yoffset
|
||||
+ << std::endl;
|
||||
+ std::cout << "g_vinfo.bits_per_pixel = " << g_vinfo.bits_per_pixel
|
||||
+ << ", g_finfo.line_length = " << g_finfo.line_length
|
||||
+ << std::endl;
|
||||
+
|
||||
+ g_screensize = g_vinfo.xres * g_vinfo.yres * g_vinfo.bits_per_pixel / 8;
|
||||
+ g_fb_buf = (unsigned char *)mmap(NULL, g_screensize, PROT_READ | PROT_WRITE, MAP_SHARED, g_fb_fd, 0);
|
||||
+ if (g_fb_buf == (void *)(-1))
|
||||
+ throw std::runtime_error("Error: failed to map framebuffer device to memory.");
|
||||
+
|
||||
+ memset(g_fb_buf, 0x00, g_screensize);
|
||||
+ tmpBuf = static_cast<unsigned char *>(malloc(g_screensize));
|
||||
+ if (!tmpBuf)
|
||||
+ throw std::runtime_error("Error: failed to malloc memory.");
|
||||
+ memset(tmpBuf, 0x00, g_screensize);
|
||||
+
|
||||
+ if (options->verbose)
|
||||
+ std::cout << "Running fb preview window" << std::endl;
|
||||
+}
|
||||
+
|
||||
+FbPreview::~FbPreview()
|
||||
+{
|
||||
+ free(tmpBuf);
|
||||
+ munmap((void *)g_fb_buf, g_screensize);
|
||||
+ close(g_fb_fd);
|
||||
+ close(g_stfbc_fd);
|
||||
+ std::cout << "fb preview window ~FbPreview" << std::endl;
|
||||
+}
|
||||
+
|
||||
+int FbPreview::NVResize(unsigned char *inBuf,
|
||||
+ unsigned char *outBuf, int imgWidth, int imgHeight)
|
||||
+{
|
||||
+ int rows, cols;
|
||||
+ unsigned char *OutNVdata, *InNVdata;
|
||||
+ int Ypos, Upos, Vpos;
|
||||
+ 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;
|
||||
+ x_offset = (g_vinfo.xres - width) / 2;
|
||||
+ y_offset = (g_vinfo.yres - height) / 2;
|
||||
+
|
||||
+ InNVdata = inBuf;
|
||||
+ OutNVdata = tmpBuf;
|
||||
+
|
||||
+ if (imgWidth == g_vinfo.xres) {
|
||||
+ fb_Ypos = y_offset * g_vinfo.xres + x_offset;
|
||||
+ fb_Upos = (y_offset / 2 * g_vinfo.xres / 2 + x_offset / 2) * 2;
|
||||
+ fb_Upos = g_vinfo.xres * g_vinfo.yres + fb_Upos;
|
||||
+ Upos = imgWidth * imgHeight;
|
||||
+ memcpy(&tmpBuf[fb_Ypos], inBuf, imgWidth * height);
|
||||
+ memcpy(&tmpBuf[fb_Upos], &inBuf[Upos], imgWidth * height / 2);
|
||||
+ memcpy(&outBuf[fb_Ypos], &tmpBuf[fb_Ypos], imgWidth * height * 2);
|
||||
+ memcpy(&outBuf[fb_Upos], &tmpBuf[fb_Upos], imgWidth * height / 2);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* two bytes for every pixels */
|
||||
+ for(rows = 0; rows < height; rows+=2)
|
||||
+ {
|
||||
+ // g_vinfo.xres, g_vinfo.yres g_vinfo.bits_per_pixel
|
||||
+ fb_Ypos = ((rows + y_offset) * g_vinfo.xres + x_offset);
|
||||
+ fb_Upos = ((rows + y_offset) / 2 * g_vinfo.xres / 2 + x_offset / 2) * 2;
|
||||
+ fb_Upos = g_vinfo.xres * g_vinfo.yres + fb_Upos;
|
||||
+ fb_Vpos = fb_Upos + 1;
|
||||
+
|
||||
+ Ypos = rows * imgWidth;
|
||||
+ Upos = imgWidth * imgHeight + Ypos / 2;
|
||||
+ Vpos = Upos + 1;
|
||||
+ memcpy(&OutNVdata[fb_Ypos], &InNVdata[Ypos], width);
|
||||
+ memcpy(&OutNVdata[fb_Ypos+g_vinfo.xres], &InNVdata[Ypos+imgWidth], width);
|
||||
+
|
||||
+ memcpy(&OutNVdata[fb_Upos], &InNVdata[Upos], width);
|
||||
+ }
|
||||
+
|
||||
+ 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();
|
||||
+
|
||||
+ 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;
|
||||
+
|
||||
+ auto endTime = std::chrono::high_resolution_clock::now();
|
||||
+
|
||||
+ std::chrono::duration<double,std::ratio<1,1000000>> duration_mcs =
|
||||
+ std::chrono::duration_cast<std::chrono::duration<double,std::ratio<1,1000000>>>(endTime-startTime);
|
||||
+ std::cout << "FbPreview copy fps " << 1000000 / duration_mcs.count() << "." << std::endl;
|
||||
+
|
||||
+ done_callback_(fd);
|
||||
+}
|
||||
+
|
||||
+Preview *make_fb_preview(Options const *options)
|
||||
+{
|
||||
+ return new FbPreview(options);
|
||||
+}
|
||||
diff --git a/preview/preview.cpp b/preview/preview.cpp
|
||||
index 68d193a..0086d83 100644
|
||||
--- a/preview/preview.cpp
|
||||
+++ b/preview/preview.cpp
|
||||
@@ -13,6 +13,7 @@ Preview *make_null_preview(Options const *options);
|
||||
Preview *make_egl_preview(Options const *options);
|
||||
Preview *make_drm_preview(Options const *options);
|
||||
Preview *make_qt_preview(Options const *options);
|
||||
+Preview *make_fb_preview(Options const *options);
|
||||
|
||||
Preview *make_preview(Options const *options)
|
||||
{
|
||||
@@ -48,8 +49,10 @@ Preview *make_preview(Options const *options)
|
||||
}
|
||||
catch (std::exception const &e)
|
||||
{
|
||||
- std::cout << "Preview window unavailable" << std::endl;
|
||||
- return make_null_preview(options);
|
||||
+ std::cout << "FB Preview window." << std::endl;
|
||||
+ return make_fb_preview(options);
|
||||
+ // std::cout << "Preview window unavailable" << std::endl;
|
||||
+ // return make_null_preview(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
From aec56c70bdc7f037a88deaa4cc84854ec2c961e9 Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Mon, 22 Nov 2021 10:16:15 +0800
|
||||
Subject: [PATCH] add select camera options
|
||||
|
||||
---
|
||||
core/libcamera_app.cpp | 29 +++++++++++++++++++++--------
|
||||
core/options.hpp | 5 +++++
|
||||
2 files changed, 26 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/core/libcamera_app.cpp b/core/libcamera_app.cpp
|
||||
index 3c4d862..22896a7 100644
|
||||
--- a/core/libcamera_app.cpp
|
||||
+++ b/core/libcamera_app.cpp
|
||||
@@ -58,17 +58,30 @@ void LibcameraApp::OpenCamera()
|
||||
if (camera_manager_->cameras().size() == 0)
|
||||
throw std::runtime_error("no cameras available");
|
||||
|
||||
- std::string const &cam_id = camera_manager_->cameras()[0]->id();
|
||||
- camera_ = camera_manager_->get(cam_id);
|
||||
- if (!camera_)
|
||||
- throw std::runtime_error("failed to find camera " + cam_id);
|
||||
-
|
||||
- if (camera_->acquire())
|
||||
- throw std::runtime_error("failed to acquire camera " + cam_id);
|
||||
+ if (options_->camera_name.length()) {
|
||||
+ char *endptr;
|
||||
+ unsigned long index = strtoul(options_->camera_name.c_str(), &endptr, 10);
|
||||
+ std::cout << "Acquired camera name: " << options_->camera_name << std::endl;
|
||||
+ if (*endptr == '\0' && index > 0 && index <= camera_manager_->cameras().size())
|
||||
+ camera_ = camera_manager_->cameras()[index - 1];
|
||||
+ else
|
||||
+ camera_ = camera_manager_->get(options_->camera_name);
|
||||
+ if (!camera_)
|
||||
+ throw std::runtime_error("failed to find camera " + options_->camera_name);
|
||||
+ if (camera_->acquire())
|
||||
+ throw std::runtime_error("failed to acquire camera " + options_->camera_name);
|
||||
+ } else {
|
||||
+ std::string const &cam_id = camera_manager_->cameras()[0]->id();
|
||||
+ camera_ = camera_manager_->get(cam_id);
|
||||
+ if (!camera_)
|
||||
+ throw std::runtime_error("failed to find camera " + cam_id);
|
||||
+ if (camera_->acquire())
|
||||
+ throw std::runtime_error("failed to acquire camera " + cam_id);
|
||||
+ }
|
||||
camera_acquired_ = true;
|
||||
|
||||
if (options_->verbose)
|
||||
- std::cout << "Acquired camera " << cam_id << std::endl;
|
||||
+ std::cout << "Acquired camera " << camera_->id() << std::endl;
|
||||
|
||||
if (!options_->post_process_file.empty())
|
||||
post_processor_.Read(options_->post_process_file);
|
||||
diff --git a/core/options.hpp b/core/options.hpp
|
||||
index 5c68088..de49beb 100644
|
||||
--- a/core/options.hpp
|
||||
+++ b/core/options.hpp
|
||||
@@ -30,6 +30,8 @@ struct Options
|
||||
"Displays the build version number")
|
||||
("verbose,v", value<bool>(&verbose)->default_value(false)->implicit_value(true),
|
||||
"Output extra debug and diagnostics")
|
||||
+ ("camera", value<std::string>(&camera_name),
|
||||
+ "Specify which camera to operate on, by id or by index")
|
||||
("config,c", value<std::string>(&config_file)->implicit_value("config.txt"),
|
||||
"Read the options from a file. If no filename is specified, default to config.txt. "
|
||||
"In case of duplicate options, the ones provided on the command line will be used. "
|
||||
@@ -115,6 +117,7 @@ struct Options
|
||||
bool help;
|
||||
bool version;
|
||||
bool verbose;
|
||||
+ std::string camera_name;
|
||||
uint64_t timeout; // in ms
|
||||
std::string config_file;
|
||||
std::string output;
|
||||
@@ -259,12 +262,14 @@ struct Options
|
||||
{
|
||||
std::cout << "Options:" << std::endl;
|
||||
std::cout << " verbose: " << verbose << std::endl;
|
||||
+ std::cout << " camera_name: " << camera_name << std::endl;
|
||||
if (!config_file.empty())
|
||||
std::cout << " config file: " << config_file << std::endl;
|
||||
std::cout << " info_text:" << info_text << std::endl;
|
||||
std::cout << " timeout: " << timeout << std::endl;
|
||||
std::cout << " width: " << width << std::endl;
|
||||
std::cout << " height: " << height << std::endl;
|
||||
+ std::cout << " pixelformat: " << pixelformat << std::endl;
|
||||
std::cout << " output: " << output << std::endl;
|
||||
std::cout << " post_process_file: " << post_process_file << std::endl;
|
||||
std::cout << " rawfull: " << rawfull << std::endl;
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
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
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
From 30ce74f6cc34ddb310cee72280d9e1e00aa4e459 Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Thu, 25 Nov 2021 14:57:09 +0800
|
||||
Subject: [PATCH] add DrmPreview support NV12 display
|
||||
|
||||
---
|
||||
preview/drm_preview.cpp | 84 +++++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 73 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/preview/drm_preview.cpp b/preview/drm_preview.cpp
|
||||
index c444918..a969358 100644
|
||||
--- a/preview/drm_preview.cpp
|
||||
+++ b/preview/drm_preview.cpp
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <drm_mode.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <libcamera/formats.h>
|
||||
|
||||
#include "core/options.hpp"
|
||||
|
||||
@@ -50,6 +52,7 @@ private:
|
||||
void findPlane();
|
||||
int drmfd_;
|
||||
int conId_;
|
||||
+ drmModeConnector *con_;
|
||||
uint32_t crtcId_;
|
||||
int crtcIdx_;
|
||||
uint32_t planeId_;
|
||||
@@ -95,10 +98,19 @@ void DrmPreview::findCrtc()
|
||||
if (con->encoder_id)
|
||||
{
|
||||
enc = drmModeGetEncoder(drmfd_, con->encoder_id);
|
||||
- if (enc->crtc_id)
|
||||
- {
|
||||
- crtc = drmModeGetCrtc(drmfd_, enc->crtc_id);
|
||||
- }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ enc = drmModeGetEncoder(drmfd_, con->encoders[0]);
|
||||
+ }
|
||||
+
|
||||
+ if (enc->crtc_id)
|
||||
+ {
|
||||
+ crtc = drmModeGetCrtc(drmfd_, enc->crtc_id);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ crtc = drmModeGetCrtc(drmfd_, res->crtcs[0]);
|
||||
}
|
||||
|
||||
if (!conId_ && crtc)
|
||||
@@ -161,6 +173,8 @@ void DrmPreview::findCrtc()
|
||||
throw std::runtime_error("connector supports no mode");
|
||||
}
|
||||
|
||||
+ con_ = c;
|
||||
+
|
||||
if (options_->fullscreen || width_ == 0 || height_ == 0)
|
||||
{
|
||||
drmModeCrtc *crtc = drmModeGetCrtc(drmfd_, crtcId_);
|
||||
@@ -227,10 +241,13 @@ void DrmPreview::findPlane()
|
||||
|
||||
DrmPreview::DrmPreview(Options const *options) : Preview(options), last_fd_(-1)
|
||||
{
|
||||
- drmfd_ = drmOpen("vc4", NULL);
|
||||
+ // drmfd_ = drmOpen("vc4", NULL);
|
||||
+ drmfd_ = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
|
||||
if (drmfd_ < 0)
|
||||
throw std::runtime_error("drmOpen failed: " + std::string(ERRSTR));
|
||||
|
||||
+ drmSetClientCap(drmfd_, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
+
|
||||
x_ = options_->preview_x;
|
||||
y_ = options_->preview_y;
|
||||
width_ = options_->preview_width;
|
||||
@@ -245,7 +262,12 @@ DrmPreview::DrmPreview(Options const *options) : Preview(options), last_fd_(-1)
|
||||
|
||||
conId_ = 0;
|
||||
findCrtc();
|
||||
- out_fourcc_ = DRM_FORMAT_YUV420;
|
||||
+ if (options_->pixelformat.length()) {
|
||||
+ libcamera::PixelFormat pixelFormat =
|
||||
+ libcamera::PixelFormat::fromString(options_->pixelformat);
|
||||
+ out_fourcc_ = pixelFormat.fourcc();
|
||||
+ } else
|
||||
+ out_fourcc_ = DRM_FORMAT_YUV420;
|
||||
findPlane();
|
||||
}
|
||||
catch (std::exception const &e)
|
||||
@@ -281,12 +303,52 @@ void DrmPreview::makeBuffer(int fd, size_t size, unsigned int width, unsigned in
|
||||
if (drmPrimeFDToHandle(drmfd_, fd, &buffer.bo_handle))
|
||||
throw std::runtime_error("drmPrimeFDToHandle failed for fd " + std::to_string(fd));
|
||||
|
||||
- uint32_t offsets[4] = { 0, stride * height, stride * height + (stride / 2) * (height / 2) };
|
||||
- uint32_t pitches[4] = { stride, stride / 2, stride / 2 };
|
||||
- uint32_t bo_handles[4] = { buffer.bo_handle, buffer.bo_handle, buffer.bo_handle };
|
||||
-
|
||||
- if (drmModeAddFB2(drmfd_, width, height, out_fourcc_, bo_handles, pitches, offsets, &buffer.fb_handle, 0))
|
||||
+ if (out_fourcc_ == DRM_FORMAT_YUV420) {
|
||||
+ uint32_t offsets[4] = { 0, stride * height, stride * height + (stride / 2) * (height / 2) };
|
||||
+ uint32_t pitches[4] = { stride, stride / 2, stride / 2 };
|
||||
+ uint32_t bo_handles[4] = { buffer.bo_handle, buffer.bo_handle, buffer.bo_handle };
|
||||
+
|
||||
+ if (drmModeAddFB2(drmfd_, width, height, out_fourcc_, bo_handles, pitches, offsets, &buffer.fb_handle, 0))
|
||||
+ throw std::runtime_error("YUV420 drmModeAddFB2 failed: " + std::string(ERRSTR));
|
||||
+ } else if (out_fourcc_ == DRM_FORMAT_NV12 || out_fourcc_ == DRM_FORMAT_NV21) {
|
||||
+ uint32_t offsets[4] = { 0, stride * height};
|
||||
+ uint32_t pitches[4] = { stride, stride};
|
||||
+ uint32_t bo_handles[4] = { buffer.bo_handle, buffer.bo_handle};
|
||||
+
|
||||
+ if (drmModeAddFB2(drmfd_, width, height, out_fourcc_, bo_handles, pitches, offsets, &buffer.fb_handle, 0))
|
||||
+ throw std::runtime_error("NV12/21 drmModeAddFB2 failed: " + std::string(ERRSTR));
|
||||
+ } else
|
||||
throw std::runtime_error("drmModeAddFB2 failed: " + std::string(ERRSTR));
|
||||
+
|
||||
+ /* find preferred mode */
|
||||
+ drmModeModeInfo *modeptr = NULL, *preferred = NULL;
|
||||
+ for (int m = 0; m < con_->count_modes; m++) {
|
||||
+ modeptr = &con_->modes[m];
|
||||
+ if (modeptr->hdisplay == width && modeptr->vdisplay == height) {
|
||||
+ preferred = modeptr;
|
||||
+ std::cout << "find the matched mode, modes index= "
|
||||
+ << m << ", " << width << "x" << height << std::endl;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (modeptr->type & DRM_MODE_TYPE_PREFERRED) {
|
||||
+ preferred = modeptr;
|
||||
+ std::cout << "find perferred mode, modes index= " << m << std::endl;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!preferred)
|
||||
+ preferred = &con_->modes[0];
|
||||
+
|
||||
+ // set default
|
||||
+ if (drmModeSetCrtc(drmfd_, crtcId_, buffer.fb_handle, 0, 0,
|
||||
+ (uint32_t *)&conId_, 1, preferred)) {
|
||||
+ throw std::runtime_error("drmModeSetCrtc() failed");
|
||||
+ }
|
||||
+
|
||||
+ screen_width_ = preferred->hdisplay;
|
||||
+ screen_height_ = preferred->vdisplay;
|
||||
+ width_ = width;
|
||||
+ height_ = height;
|
||||
}
|
||||
|
||||
void DrmPreview::Show(int fd, libcamera::Span<uint8_t> span, int width, int height, int stride)
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
config BR2_PACKAGE_LIBCAMERA_APPS
|
||||
bool "libcamera-apps"
|
||||
depends on BR2_PACKAGE_LIBCAMERA
|
||||
select BR2_PACKAGE_GNUTLS
|
||||
select BR2_PACKAGE_BOOST
|
||||
select BR2_PACKAGE_BOOST_PROGRAM_OPTIONS
|
||||
select BR2_PACKAGE_BOOST_SYSTEM
|
||||
select BR2_PACKAGE_TIFF
|
||||
select BR2_PACKAGE_LIBEXIF
|
||||
select BR2_PACKAGE_LIBYUV
|
||||
select BR2_PACKAGE_LIBPNG
|
||||
help
|
||||
libcamera-apps provides a software stack to support
|
||||
complex devices that need heavy hardware image
|
||||
processing operations.
|
||||
|
||||
comment "libcamera-apps needs a toolchain w/ C++, threads, wchar, dynamic library, gcc >= 7"
|
||||
depends on !BR2_INSTALL_LIBSTDCPP || !BR2_TOOLCHAIN_HAS_THREADS || \
|
||||
!BR2_TOOLCHAIN_GCC_AT_LEAST_7 || BR2_STATIC_LIBS || !BR2_USE_WCHAR
|
||||
@@ -0,0 +1,3 @@
|
||||
sha256 5600c4289457c03a5062001f5942c77fabe4fcef8877b67cfaeed5bae5672756 libcamera-apps-main.tar.gz
|
||||
sha256 3fe6e9e343f268c518652a00260791c55f18cd5902fd5de578005b9c6ec9785b libcamera-apps-87f807f4eacf7d62021e3b4061348e64b2ecadc3.tar.gz
|
||||
sha256 09a169037dfba889bc9f449aaefc18c210fdf4eb7ea02cffd4a36c383b71583c libcamera-apps-87f807f4eacf7d62021e3b4061348e64b2ecadc3-br1.tar.gz
|
||||
@@ -0,0 +1,14 @@
|
||||
################################################################################
|
||||
#
|
||||
# libcamera-apps
|
||||
#
|
||||
################################################################################
|
||||
|
||||
LIBCAMERA_APPS_SITE = git@github.com:raspberrypi/libcamera-apps.git
|
||||
LIBCAMERA_APPS_VERSION = 87f807f4eacf7d62021e3b4061348e64b2ecadc3
|
||||
LIBCAMERA_APPS_SITE_METHOD = git
|
||||
LIBCAMERA_APPS_INSTALL_STAGING = YES
|
||||
|
||||
LIBCAMERA_APPS_DEPENDENCIES = libcamera libexif tiff boost host-pkgconf
|
||||
|
||||
$(eval $(cmake-package))
|
||||
Reference in New Issue
Block a user