Merge branch 'CR_6612_libcamera_mm_zejian.su' into 'jh7110-mm-devel'
CR_6612: Update the libcamera and the libcamera-apps See merge request sdk/buildroot!139
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,182 +0,0 @@
|
||||
From a3756db6257742587da7e97546aa330ad363bfd1 Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Tue, 26 Oct 2021 12:29:30 +0800
|
||||
Subject: [PATCH 02/10] add sensor ctrls
|
||||
|
||||
---
|
||||
src/libcamera/pipeline/starfive/starfive.cpp | 118 ++++++++++++++++---
|
||||
1 file changed, 99 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
index 8797bdcb..f63af910 100644
|
||||
--- a/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
+++ b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
@@ -370,7 +370,7 @@ public:
|
||||
bool match(DeviceEnumerator *enumerator) override;
|
||||
|
||||
private:
|
||||
- int processControls(StarFiveCameraData *data, Request *request);
|
||||
+ int processControls(StarFiveCameraData *data, const ControlList &controls);
|
||||
|
||||
StarFiveCameraData *cameraData(Camera *camera)
|
||||
{
|
||||
@@ -620,6 +620,13 @@ int PipelineHandlerStarFive::start(Camera *camera, const ControlList *controls)
|
||||
|
||||
LOG(STARFIVE, Debug) << __func__ << " bufferCount: " << count;
|
||||
|
||||
+ if (controls != nullptr) {
|
||||
+ ret = processControls(data, *controls);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ } else
|
||||
+ LOG(STARFIVE, Debug) << __func__ << " start no controls";
|
||||
+
|
||||
ret = data->video_->importBuffers(count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -672,43 +679,116 @@ void PipelineHandlerStarFive::stop(Camera *camera)
|
||||
}
|
||||
}
|
||||
|
||||
-int PipelineHandlerStarFive::processControls(StarFiveCameraData *data, Request *request)
|
||||
+int PipelineHandlerStarFive::processControls(StarFiveCameraData *data, const ControlList &controls)
|
||||
{
|
||||
- LOG(STARFIVE, Debug) << __func__;
|
||||
+ LOG(STARFIVE, Debug) << __func__ << ": test1 controls";
|
||||
+ const ControlInfoMap &SensorControlsInfoMap = data->sensor_->controls();
|
||||
+ ControlList SensorControls(SensorControlsInfoMap);
|
||||
|
||||
- ControlList controls(data->sensor_->controls());
|
||||
-
|
||||
- for (auto it : request->controls()) {
|
||||
+ for (auto it : controls) {
|
||||
unsigned int id = it.first;
|
||||
- unsigned int offset;
|
||||
- uint32_t cid;
|
||||
+ unsigned int offset = 0;
|
||||
+ uint32_t cid = 0;
|
||||
+ int32_t value = 0;
|
||||
|
||||
- if (id == controls::Brightness) {
|
||||
+ switch (id) {
|
||||
+ case controls::BRIGHTNESS:
|
||||
cid = V4L2_CID_BRIGHTNESS;
|
||||
offset = 128;
|
||||
- } else if (id == controls::Contrast) {
|
||||
+ value = lroundf(it.second.get<float>() * 128 + offset);
|
||||
+ LOG(STARFIVE, Debug) << "Brightness controls: " << id
|
||||
+ << ", value: " << value;
|
||||
+ break;
|
||||
+ case controls::CONTRAST:
|
||||
cid = V4L2_CID_CONTRAST;
|
||||
offset = 0;
|
||||
- } else if (id == controls::Saturation) {
|
||||
+ value = lroundf(it.second.get<float>() * 128 + offset);
|
||||
+ LOG(STARFIVE, Debug) << "Contrast controls: " << id
|
||||
+ << ", value: " << value;
|
||||
+ break;
|
||||
+ case controls::SATURATION:
|
||||
cid = V4L2_CID_SATURATION;
|
||||
offset = 0;
|
||||
- } else {
|
||||
- continue;
|
||||
+ value = lroundf(it.second.get<float>() * 128 + offset);
|
||||
+ LOG(STARFIVE, Debug) << "Saturation controls: " << id
|
||||
+ << ", value: " << value;
|
||||
+ break;
|
||||
+ case controls::SHARPNESS:
|
||||
+ cid = V4L2_CID_SHARPNESS;
|
||||
+ offset = 0;
|
||||
+ value = lroundf(it.second.get<float>() * 128 + offset);
|
||||
+ LOG(STARFIVE, Debug) << "Sharpness controls: " << id
|
||||
+ << ", value: " << value;
|
||||
+ break;
|
||||
+ case controls::COLOUR_GAINS:
|
||||
+ cid = V4L2_CID_RED_BALANCE;
|
||||
+ offset = 0;
|
||||
+ value = lroundf(it.second.get<Span<const float>>()[0]);
|
||||
+ LOG(STARFIVE, Debug) << "ColourGains controls: " << id
|
||||
+ << ", COLOUR_GAINS RED value: " << value;
|
||||
+ if (SensorControlsInfoMap.find(cid) != SensorControlsInfoMap.end())
|
||||
+ SensorControls.set(cid, value);
|
||||
+ else
|
||||
+ LOG(STARFIVE, Debug)
|
||||
+ << "SensorControls not supported controls: " << id;
|
||||
+ cid = V4L2_CID_BLUE_BALANCE;
|
||||
+ value = lroundf(it.second.get<Span<const float>>()[1]);
|
||||
+ LOG(STARFIVE, Debug) << "COLOUR_GAINS BLUE value: " << value;
|
||||
+ break;
|
||||
+ case controls::AWB_ENABLE:
|
||||
+ cid = V4L2_CID_AUTO_WHITE_BALANCE;
|
||||
+ value = it.second.get<bool>();
|
||||
+ LOG(STARFIVE, Debug) << "AwbMode controls: " << id
|
||||
+ << ", value: " << value;
|
||||
+ break;
|
||||
+ case controls::EXPOSURE_VALUE:
|
||||
+ cid = V4L2_CID_EXPOSURE;
|
||||
+ offset = 0;
|
||||
+ value = lroundf(it.second.get<float>());
|
||||
+ LOG(STARFIVE, Debug) << "ExposureValue controls: " << id
|
||||
+ << ", value: " << value;
|
||||
+ break;
|
||||
+ case controls::AE_ENABLE:
|
||||
+ cid = V4L2_CID_EXPOSURE_AUTO;
|
||||
+ value = it.second.get<bool>();
|
||||
+ LOG(STARFIVE, Debug) << "AeExposureMode controls: " << id
|
||||
+ << ", value: " << value;
|
||||
+ break;
|
||||
+ case controls::ANALOGUE_GAIN:
|
||||
+ cid = V4L2_CID_ANALOGUE_GAIN;
|
||||
+ offset = 0;
|
||||
+ value = lroundf(it.second.get<float>());
|
||||
+ LOG(STARFIVE, Debug) << "AnalogueGain controls: " << id
|
||||
+ << ", value: " << value;
|
||||
+ break;
|
||||
+ case controls::DIGITAL_GAIN:
|
||||
+ cid = V4L2_CID_GAIN;
|
||||
+ offset = 0;
|
||||
+ value = lroundf(it.second.get<float>());
|
||||
+ LOG(STARFIVE, Debug) << "AnalogueGain controls: " << id
|
||||
+ << ", value: " << value;
|
||||
+ break;
|
||||
+ default:
|
||||
+ LOG(STARFIVE, Debug) << "default controls: " << id;
|
||||
+ break;
|
||||
}
|
||||
|
||||
- int32_t value = lroundf(it.second.get<float>() * 128 + offset);
|
||||
- controls.set(cid, std::clamp(value, 0, 255));
|
||||
+ if (SensorControlsInfoMap.find(cid) != SensorControlsInfoMap.end())
|
||||
+ SensorControls.set(cid, value);
|
||||
+ else
|
||||
+ LOG(STARFIVE, Debug) << "SensorControls not supported controls: " << id;
|
||||
+
|
||||
}
|
||||
|
||||
- for (const auto &ctrl : controls)
|
||||
+ for (const auto &ctrl : SensorControls)
|
||||
LOG(STARFIVE, Debug)
|
||||
<< "Setting control " << utils::hex(ctrl.first)
|
||||
<< " to " << ctrl.second.toString();
|
||||
|
||||
- int ret = data->sensor_->setControls(&controls);
|
||||
+ int ret = data->sensor_->setControls(&SensorControls);
|
||||
if (ret) {
|
||||
LOG(STARFIVE, Debug)
|
||||
- << "Failed to set controls: " << ret;
|
||||
+ << "Failed to set sensor controls: " << ret;
|
||||
return ret < 0 ? ret : -EINVAL;
|
||||
}
|
||||
|
||||
@@ -721,7 +801,7 @@ int PipelineHandlerStarFive::queueRequestDevice(Camera *camera, Request *request
|
||||
int error = 0;
|
||||
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
- int ret = processControls(data, request);
|
||||
+ int ret = processControls(data, request->controls());
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,537 +0,0 @@
|
||||
From 26127511bf0b6d2f016c16956d04332858bd8d7f Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Thu, 13 Jan 2022 13:52:11 +0800
|
||||
Subject: [PATCH 03/10] libcamera: 1. add caps for src templ 2. add
|
||||
starfive ipa (dummy)
|
||||
|
||||
---
|
||||
include/libcamera/ipa/meson.build | 1 +
|
||||
include/libcamera/ipa/starfive.mojom | 45 +++++
|
||||
meson_options.txt | 2 +-
|
||||
src/gstreamer/gstlibcamerasrc.cpp | 11 +-
|
||||
src/ipa/starfive/data/meson.build | 8 +
|
||||
src/ipa/starfive/data/starfive.conf | 3 +
|
||||
src/ipa/starfive/meson.build | 23 +++
|
||||
src/ipa/starfive/starfive.cpp | 200 +++++++++++++++++++
|
||||
src/libcamera/ipa_manager.cpp | 4 +-
|
||||
src/libcamera/pipeline/starfive/starfive.cpp | 56 +++++-
|
||||
src/meson.build | 1 +
|
||||
11 files changed, 350 insertions(+), 4 deletions(-)
|
||||
create mode 100644 include/libcamera/ipa/starfive.mojom
|
||||
create mode 100644 src/ipa/starfive/data/meson.build
|
||||
create mode 100644 src/ipa/starfive/data/starfive.conf
|
||||
create mode 100644 src/ipa/starfive/meson.build
|
||||
create mode 100644 src/ipa/starfive/starfive.cpp
|
||||
|
||||
diff --git a/include/libcamera/ipa/meson.build b/include/libcamera/ipa/meson.build
|
||||
index 6ea94fb5..b84358a6 100644
|
||||
--- a/include/libcamera/ipa/meson.build
|
||||
+++ b/include/libcamera/ipa/meson.build
|
||||
@@ -65,6 +65,7 @@ ipa_mojom_files = [
|
||||
'raspberrypi.mojom',
|
||||
'rkisp1.mojom',
|
||||
'vimc.mojom',
|
||||
+ 'starfive.mojom',
|
||||
]
|
||||
|
||||
ipa_mojoms = []
|
||||
diff --git a/include/libcamera/ipa/starfive.mojom b/include/libcamera/ipa/starfive.mojom
|
||||
new file mode 100644
|
||||
index 00000000..b302b609
|
||||
--- /dev/null
|
||||
+++ b/include/libcamera/ipa/starfive.mojom
|
||||
@@ -0,0 +1,45 @@
|
||||
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
+
|
||||
+/*
|
||||
+ * \todo Document the interface and remove the related EXCLUDE_PATTERNS entry.
|
||||
+ */
|
||||
+
|
||||
+module ipa.starfive;
|
||||
+
|
||||
+import "include/libcamera/ipa/core.mojom";
|
||||
+
|
||||
+const string StarfiveIPAFIFOPath = "/tmp/libcamera_ipa_starfive_fifo";
|
||||
+
|
||||
+enum IPAOperationCode {
|
||||
+ IPAOperationNone,
|
||||
+ IPAOperationInit,
|
||||
+ IPAOperationStart,
|
||||
+ IPAOperationStop,
|
||||
+};
|
||||
+
|
||||
+interface IPAStarfiveInterface {
|
||||
+ init(libcamera.IPASettings settings) => (int32 ret);
|
||||
+
|
||||
+ configure(libcamera.IPACameraSensorInfo sensorInfo,
|
||||
+ map<uint32, libcamera.IPAStream> streamConfig,
|
||||
+ map<uint32, libcamera.ControlInfoMap> entityControls) => (int32 ret);
|
||||
+
|
||||
+ start() => (int32 ret);
|
||||
+ stop();
|
||||
+
|
||||
+ mapBuffers(array<libcamera.IPABuffer> buffers);
|
||||
+ unmapBuffers(array<uint32> ids);
|
||||
+
|
||||
+ /*
|
||||
+ * The starfive driver doesn't use parameters buffers. To maximize coverage
|
||||
+ * of unit tests that rely on the starfive pipeline handler, we still define
|
||||
+ * interface functions that mimick how other pipeline handlers typically
|
||||
+ * handle parameters at runtime.
|
||||
+ */
|
||||
+ [async] fillParams(uint32 frame, uint32 bufferId);
|
||||
+ [async] processControls(uint32 frame, libcamera.ControlList controls);
|
||||
+};
|
||||
+
|
||||
+interface IPAStarfiveEventInterface {
|
||||
+ paramsFilled(uint32 bufferId);
|
||||
+};
|
||||
diff --git a/meson_options.txt b/meson_options.txt
|
||||
index 14baa7ef..ba4ecb0b 100644
|
||||
--- a/meson_options.txt
|
||||
+++ b/meson_options.txt
|
||||
@@ -27,7 +27,7 @@ option('gstreamer',
|
||||
|
||||
option('ipas',
|
||||
type : 'array',
|
||||
- choices : ['ipu3', 'raspberrypi', 'rkisp1', 'vimc'],
|
||||
+ choices : ['ipu3', 'raspberrypi', 'rkisp1', 'vimc' ,'starfive'],
|
||||
description : 'Select which IPA modules to build')
|
||||
|
||||
option('lc-compliance',
|
||||
diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
|
||||
index 1dd0e807..6329b01a 100644
|
||||
--- a/src/gstreamer/gstlibcamerasrc.cpp
|
||||
+++ b/src/gstreamer/gstlibcamerasrc.cpp
|
||||
@@ -140,9 +140,18 @@ G_DEFINE_TYPE_WITH_CODE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT,
|
||||
|
||||
#define TEMPLATE_CAPS GST_STATIC_CAPS("video/x-raw; image/jpeg")
|
||||
|
||||
+#define TEMPLATE_CAPS_SRC GST_STATIC_CAPS("video/x-raw, "\
|
||||
+ "format = { (string)BG24,(string)RG24,(string)BA24, \
|
||||
+ (string)NV12, (string)NV21, (string)NV16, \
|
||||
+ (string)NV61, (string)NV24, (string)UYVY, \
|
||||
+ (string)VYUY, (string)YUYV, (string)YVYU}, "\
|
||||
+ "width = " GST_VIDEO_SIZE_RANGE ", "\
|
||||
+ "height = " GST_VIDEO_SIZE_RANGE ", "\
|
||||
+ "framerate = " GST_VIDEO_FPS_RANGE ";"\
|
||||
+)
|
||||
/* For the simple case, we have a src pad that is always present. */
|
||||
GstStaticPadTemplate src_template = {
|
||||
- "src", GST_PAD_SRC, GST_PAD_ALWAYS, TEMPLATE_CAPS
|
||||
+ "src", GST_PAD_SRC, GST_PAD_ALWAYS, TEMPLATE_CAPS_SRC
|
||||
};
|
||||
|
||||
/* More pads can be requested in state < PAUSED */
|
||||
diff --git a/src/ipa/starfive/data/meson.build b/src/ipa/starfive/data/meson.build
|
||||
new file mode 100644
|
||||
index 00000000..0ce6a9b4
|
||||
--- /dev/null
|
||||
+++ b/src/ipa/starfive/data/meson.build
|
||||
@@ -0,0 +1,8 @@
|
||||
+# SPDX-License-Identifier: CC0-1.0
|
||||
+
|
||||
+conf_files = files([
|
||||
+ 'starfive.conf',
|
||||
+])
|
||||
+
|
||||
+install_data(conf_files,
|
||||
+ install_dir : ipa_data_dir / 'starfive')
|
||||
diff --git a/src/ipa/starfive/data/starfive.conf b/src/ipa/starfive/data/starfive.conf
|
||||
new file mode 100644
|
||||
index 00000000..6b74f622
|
||||
--- /dev/null
|
||||
+++ b/src/ipa/starfive/data/starfive.conf
|
||||
@@ -0,0 +1,3 @@
|
||||
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
+#
|
||||
+# Dummy configuration file for the starfive IPA.
|
||||
diff --git a/src/ipa/starfive/meson.build b/src/ipa/starfive/meson.build
|
||||
new file mode 100644
|
||||
index 00000000..c93bd058
|
||||
--- /dev/null
|
||||
+++ b/src/ipa/starfive/meson.build
|
||||
@@ -0,0 +1,23 @@
|
||||
+# SPDX-License-Identifier: CC0-1.0
|
||||
+
|
||||
+ipa_name = 'ipa_starfive'
|
||||
+
|
||||
+mod = shared_module(ipa_name,
|
||||
+ ['starfive.cpp', libcamera_generated_ipa_headers],
|
||||
+ name_prefix : '',
|
||||
+ include_directories : [ipa_includes, libipa_includes],
|
||||
+ dependencies : libcamera_private,
|
||||
+ link_with : libipa,
|
||||
+ install : true,
|
||||
+ install_dir : ipa_install_dir)
|
||||
+
|
||||
+if ipa_sign_module
|
||||
+ custom_target(ipa_name + '.so.sign',
|
||||
+ input : mod,
|
||||
+ output : ipa_name + '.so.sign',
|
||||
+ command : [ipa_sign, ipa_priv_key, '@INPUT@', '@OUTPUT@'],
|
||||
+ install : false,
|
||||
+ build_by_default : true)
|
||||
+endif
|
||||
+
|
||||
+subdir('data')
|
||||
diff --git a/src/ipa/starfive/starfive.cpp b/src/ipa/starfive/starfive.cpp
|
||||
new file mode 100644
|
||||
index 00000000..e1207606
|
||||
--- /dev/null
|
||||
+++ b/src/ipa/starfive/starfive.cpp
|
||||
@@ -0,0 +1,200 @@
|
||||
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
+/*
|
||||
+ * Copyright (C) 2019, Google Inc.
|
||||
+ *
|
||||
+ * ipa_starfive.cpp - Starfive Image Processing Algorithm module
|
||||
+ */
|
||||
+#include <libcamera/ipa/starfive_ipa_interface.h>
|
||||
+
|
||||
+#include <fcntl.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include <iostream>
|
||||
+
|
||||
+#include <libcamera/base/file.h>
|
||||
+#include <libcamera/base/log.h>
|
||||
+
|
||||
+#include <libcamera/ipa/ipa_interface.h>
|
||||
+#include <libcamera/ipa/ipa_module_info.h>
|
||||
+
|
||||
+#include "libcamera/internal/mapped_framebuffer.h"
|
||||
+
|
||||
+namespace libcamera {
|
||||
+
|
||||
+LOG_DEFINE_CATEGORY(IPAStarfive)
|
||||
+
|
||||
+class IPAStarfive : public ipa::starfive::IPAStarfiveInterface
|
||||
+{
|
||||
+public:
|
||||
+ IPAStarfive();
|
||||
+ ~IPAStarfive();
|
||||
+
|
||||
+ int init(const IPASettings &settings) override;
|
||||
+
|
||||
+ int start() override;
|
||||
+ void stop() override;
|
||||
+
|
||||
+ int configure(const IPACameraSensorInfo &sensorInfo,
|
||||
+ const std::map<unsigned int, IPAStream> &streamConfig,
|
||||
+ const std::map<unsigned int, ControlInfoMap> &entityControls) override;
|
||||
+
|
||||
+ void mapBuffers(const std::vector<IPABuffer> &buffers) override;
|
||||
+ void unmapBuffers(const std::vector<unsigned int> &ids) override;
|
||||
+
|
||||
+ void fillParams(uint32_t frame, uint32_t bufferId) override;
|
||||
+ void processControls(uint32_t frame, const ControlList &controls) override;
|
||||
+
|
||||
+private:
|
||||
+ void initTrace();
|
||||
+ void trace(enum ipa::starfive::IPAOperationCode operation);
|
||||
+
|
||||
+ int fd_;
|
||||
+ std::map<unsigned int, MappedFrameBuffer> buffers_;
|
||||
+};
|
||||
+
|
||||
+IPAStarfive::IPAStarfive()
|
||||
+ : fd_(-1)
|
||||
+{
|
||||
+ initTrace();
|
||||
+}
|
||||
+
|
||||
+IPAStarfive::~IPAStarfive()
|
||||
+{
|
||||
+ if (fd_ != -1)
|
||||
+ ::close(fd_);
|
||||
+}
|
||||
+
|
||||
+int IPAStarfive::init(const IPASettings &settings)
|
||||
+{
|
||||
+ trace(ipa::starfive::IPAOperationInit);
|
||||
+
|
||||
+ LOG(IPAStarfive, Debug)
|
||||
+ << "initializing starfive IPA with configuration file "
|
||||
+ << settings.configurationFile;
|
||||
+
|
||||
+ File conf(settings.configurationFile);
|
||||
+ if (!conf.open(File::OpenModeFlag::ReadOnly)) {
|
||||
+ LOG(IPAStarfive, Error) << "Failed to open configuration file";
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int IPAStarfive::start()
|
||||
+{
|
||||
+ trace(ipa::starfive::IPAOperationStart);
|
||||
+
|
||||
+ LOG(IPAStarfive, Debug) << "start starfive IPA!";
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void IPAStarfive::stop()
|
||||
+{
|
||||
+ trace(ipa::starfive::IPAOperationStop);
|
||||
+
|
||||
+ LOG(IPAStarfive, Debug) << "stop starfive IPA!";
|
||||
+}
|
||||
+
|
||||
+int IPAStarfive::configure([[maybe_unused]] const IPACameraSensorInfo &sensorInfo,
|
||||
+ [[maybe_unused]] const std::map<unsigned int, IPAStream> &streamConfig,
|
||||
+ [[maybe_unused]] const std::map<unsigned int, ControlInfoMap> &entityControls)
|
||||
+{
|
||||
+ LOG(IPAStarfive, Debug) << "configure()";
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void IPAStarfive::mapBuffers(const std::vector<IPABuffer> &buffers)
|
||||
+{
|
||||
+ LOG(IPAStarfive, Debug) << "mapBuffers()";
|
||||
+ for (const IPABuffer &buffer : buffers) {
|
||||
+ const FrameBuffer fb(buffer.planes);
|
||||
+ buffers_.emplace(std::piecewise_construct,
|
||||
+ std::forward_as_tuple(buffer.id),
|
||||
+ std::forward_as_tuple(&fb, MappedFrameBuffer::MapFlag::Read));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void IPAStarfive::unmapBuffers(const std::vector<unsigned int> &ids)
|
||||
+{
|
||||
+ LOG(IPAStarfive, Debug) << "unmapBuffers()";
|
||||
+ for (unsigned int id : ids) {
|
||||
+ auto it = buffers_.find(id);
|
||||
+ if (it == buffers_.end())
|
||||
+ continue;
|
||||
+
|
||||
+ buffers_.erase(it);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void IPAStarfive::fillParams([[maybe_unused]] uint32_t frame, uint32_t bufferId)
|
||||
+{
|
||||
+ auto it = buffers_.find(bufferId);
|
||||
+ if (it == buffers_.end()) {
|
||||
+ LOG(IPAStarfive, Error) << "Could not find parameter buffer";
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ paramsFilled.emit(bufferId);
|
||||
+}
|
||||
+
|
||||
+void IPAStarfive::processControls([[maybe_unused]] uint32_t frame,
|
||||
+ [[maybe_unused]] const ControlList &controls)
|
||||
+{
|
||||
+ LOG(IPAStarfive,Debug) << "IPA ProcessControl";
|
||||
+}
|
||||
+
|
||||
+void IPAStarfive::initTrace()
|
||||
+{
|
||||
+ struct stat fifoStat;
|
||||
+ int ret = stat(ipa::starfive::StarfiveIPAFIFOPath.c_str(), &fifoStat);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ ret = ::open(ipa::starfive::StarfiveIPAFIFOPath.c_str(), O_WRONLY);
|
||||
+ if (ret < 0) {
|
||||
+ ret = errno;
|
||||
+ LOG(IPAStarfive, Error) << "Failed to open starfive IPA test FIFO: "
|
||||
+ << strerror(ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ fd_ = ret;
|
||||
+}
|
||||
+
|
||||
+void IPAStarfive::trace(enum ipa::starfive::IPAOperationCode operation)
|
||||
+{
|
||||
+ if (fd_ < 0)
|
||||
+ return;
|
||||
+
|
||||
+ int ret = ::write(fd_, &operation, sizeof(operation));
|
||||
+ if (ret < 0) {
|
||||
+ ret = errno;
|
||||
+ LOG(IPAStarfive, Error) << "Failed to write to starfive IPA test FIFO: "
|
||||
+ << strerror(ret);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * External IPA module interface
|
||||
+ */
|
||||
+
|
||||
+extern "C" {
|
||||
+const struct IPAModuleInfo ipaModuleInfo = {
|
||||
+ IPA_MODULE_API_VERSION,
|
||||
+ 0,
|
||||
+ "PipelineHandlerStarFive",
|
||||
+ "starfive",
|
||||
+};
|
||||
+
|
||||
+IPAInterface *ipaCreate()
|
||||
+{
|
||||
+ return new IPAStarfive();
|
||||
+}
|
||||
+}
|
||||
+
|
||||
+} /* namespace libcamera */
|
||||
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
|
||||
index ec966045..634cbb8d 100644
|
||||
--- a/src/libcamera/ipa_manager.cpp
|
||||
+++ b/src/libcamera/ipa_manager.cpp
|
||||
@@ -276,7 +276,9 @@ IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,
|
||||
|
||||
bool IPAManager::isSignatureValid([[maybe_unused]] IPAModule *ipa) const
|
||||
{
|
||||
-#if HAVE_IPA_PUBKEY
|
||||
+#if SKIP_SIGN_VERIFY
|
||||
+ return true;
|
||||
+#elif HAVE_IPA_PUBKEY
|
||||
char *force = utils::secure_getenv("LIBCAMERA_IPA_FORCE_ISOLATION");
|
||||
if (force && force[0] != '\0') {
|
||||
LOG(IPAManager, Debug)
|
||||
diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
index f63af910..bc82a062 100644
|
||||
--- a/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
+++ b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
@@ -23,6 +23,10 @@
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/v4l2-subdev.h>
|
||||
|
||||
+#include <libcamera/ipa/ipa_interface.h>
|
||||
+#include <libcamera/ipa/ipa_module_info.h>
|
||||
+#include <libcamera/ipa/starfive_ipa_interface.h>
|
||||
+#include <libcamera/ipa/starfive_ipa_proxy.h>
|
||||
#include "libcamera/internal/camera.h"
|
||||
#include "libcamera/internal/camera_sensor.h"
|
||||
#include "libcamera/internal/device_enumerator.h"
|
||||
@@ -189,6 +193,7 @@ public:
|
||||
std::vector<SizeRange> sensorSizes() const;
|
||||
std::vector<PixelFormat> sensorFormats() const;
|
||||
std::vector<PixelFormat> videoFormats() const;
|
||||
+ void paramsFilled(unsigned int id){}
|
||||
|
||||
MediaDevice *media_;
|
||||
V4L2VideoDevice *video_;
|
||||
@@ -197,6 +202,8 @@ public:
|
||||
CameraSensor *sensor_;
|
||||
Stream outStream_;
|
||||
Stream rawStream_;
|
||||
+ std::unique_ptr<ipa::starfive::IPAProxyStarfive> ipa_;
|
||||
+ std::vector<std::unique_ptr<FrameBuffer>> mockIPABufs_;
|
||||
|
||||
private:
|
||||
bool haveRaw_;
|
||||
@@ -591,6 +598,22 @@ int PipelineHandlerStarFive::configure(Camera *camera, CameraConfiguration *c)
|
||||
data->video_->toV4L2PixelFormat(cfg.pixelFormat))
|
||||
return -EINVAL;
|
||||
}
|
||||
+
|
||||
+ if (data->ipa_) {
|
||||
+ /* Inform IPA of stream configuration and sensor controls. */
|
||||
+ std::map<unsigned int, IPAStream> streamConfig;
|
||||
+ streamConfig.emplace(std::piecewise_construct,
|
||||
+ std::forward_as_tuple(0),
|
||||
+ std::forward_as_tuple(cfg.pixelFormat, cfg.size));
|
||||
+
|
||||
+ std::map<unsigned int, ControlInfoMap> entityControls;
|
||||
+ entityControls.emplace(0, data->sensor_->controls());
|
||||
+
|
||||
+ IPACameraSensorInfo sensorInfo;
|
||||
+ data->sensor_->sensorInfo(&sensorInfo);
|
||||
+
|
||||
+ data->ipa_->configure(sensorInfo, streamConfig, entityControls);
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -630,6 +653,17 @@ int PipelineHandlerStarFive::start(Camera *camera, const ControlList *controls)
|
||||
ret = data->video_->importBuffers(count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
+
|
||||
+ /* Map the mock IPA buffers to VIMC IPA to exercise IPC code paths. */
|
||||
+ std::vector<IPABuffer> ipaBuffers;
|
||||
+ for (auto [i, buffer] : utils::enumerate(data->mockIPABufs_)) {
|
||||
+ buffer->setCookie(i + 1);
|
||||
+ ipaBuffers.emplace_back(buffer->cookie(), buffer->planes());
|
||||
+ }
|
||||
+ data->ipa_->mapBuffers(ipaBuffers);
|
||||
+ ret = data->ipa_->start();
|
||||
+ if(ret < 0)
|
||||
+ goto error;
|
||||
|
||||
ret = data->video_->streamOn();
|
||||
if (ret < 0)
|
||||
@@ -661,6 +695,7 @@ int PipelineHandlerStarFive::start(Camera *camera, const ControlList *controls)
|
||||
|
||||
return ret;
|
||||
error:
|
||||
+ data->ipa_->stop();
|
||||
data->video_->releaseBuffers();
|
||||
return ret;
|
||||
}
|
||||
@@ -671,6 +706,12 @@ void PipelineHandlerStarFive::stop(Camera *camera)
|
||||
|
||||
StarFiveCameraData *data = cameraData(camera);
|
||||
data->video_->streamOff();
|
||||
+ std::vector<unsigned int> ids;
|
||||
+ for (const std::unique_ptr<FrameBuffer> &buffer : data->mockIPABufs_)
|
||||
+ ids.push_back(buffer->cookie());
|
||||
+ data->ipa_->unmapBuffers(ids);
|
||||
+ data->ipa_->stop();
|
||||
+
|
||||
data->video_->releaseBuffers();
|
||||
if (data->rawActive()) {
|
||||
data->raw_->streamOff();
|
||||
@@ -813,8 +854,11 @@ int PipelineHandlerStarFive::queueRequestDevice(Camera *camera, Request *request
|
||||
LOG(STARFIVE, Debug)
|
||||
<< "stream queueBuffer : " << stream->configuration().toString();
|
||||
|
||||
- if (stream == &data->outStream_)
|
||||
+ if (stream == &data->outStream_){
|
||||
ret = data->video_->queueBuffer(buffer);
|
||||
+ data->ipa_->processControls(request->sequence(), request->controls());
|
||||
+ }
|
||||
+
|
||||
else if (stream == &data->rawStream_)
|
||||
ret = data->raw_->queueBuffer(buffer);
|
||||
else
|
||||
@@ -918,6 +962,16 @@ int PipelineHandlerStarFive::registerCameras()
|
||||
if (data->init())
|
||||
continue;
|
||||
|
||||
+ /*create ipa module*/
|
||||
+ data->ipa_ = IPAManager::createIPA<ipa::starfive::IPAProxyStarfive>(this, 0, 0);
|
||||
+ if (!data->ipa_) {
|
||||
+ LOG(STARFIVE, Error) << "no matching IPA found";
|
||||
+ return false;
|
||||
+ }
|
||||
+ data->ipa_->paramsFilled.connect(data.get(), &StarFiveCameraData::paramsFilled);
|
||||
+ std::string conf = data->ipa_->configurationFile("starfive.conf");
|
||||
+ data->ipa_->init(IPASettings{ conf, data->sensor_->model() });
|
||||
+
|
||||
/* Create and register the camera. */
|
||||
LOG(STARFIVE, Debug) << "register deviceName: "
|
||||
<< videoEntiryName;
|
||||
diff --git a/src/meson.build b/src/meson.build
|
||||
index e0ea9c35..8ae89b5b 100644
|
||||
--- a/src/meson.build
|
||||
+++ b/src/meson.build
|
||||
@@ -20,6 +20,7 @@ if openssl.found()
|
||||
output : ['ipa-priv-key.pem'],
|
||||
command : [gen_ipa_priv_key, '@OUTPUT@'])
|
||||
config_h.set('HAVE_IPA_PUBKEY', 1)
|
||||
+ config_h.set('SKIP_SIGN_VERIFY',1)
|
||||
ipa_sign_module = true
|
||||
else
|
||||
ipa_sign_module = false
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
From eb7bd9dc15d8a2636d12d4e8cec219946fea353d Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Tue, 16 Nov 2021 17:23:17 +0800
|
||||
Subject: [PATCH 04/10] update toV4L2PixelFormat
|
||||
|
||||
---
|
||||
src/libcamera/pipeline/starfive/starfive.cpp | 18 ++++++++++++------
|
||||
1 file changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
index bc82a062..58e1f55a 100644
|
||||
--- a/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
+++ b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
@@ -440,7 +440,8 @@ CameraConfiguration::Status StarFiveCameraConfiguration::validate()
|
||||
&& data_->haveRaw()) {
|
||||
V4L2DeviceFormat format = {};
|
||||
format.fourcc =
|
||||
- data_->raw_->toV4L2PixelFormat(cfg.pixelFormat);
|
||||
+ V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat,
|
||||
+ data_->raw_->caps().isMultiplanar());
|
||||
format.size = cfg.size;
|
||||
|
||||
int ret = data_->raw_->tryFormat(&format);
|
||||
@@ -454,7 +455,8 @@ CameraConfiguration::Status StarFiveCameraConfiguration::validate()
|
||||
} else {
|
||||
V4L2DeviceFormat format = {};
|
||||
format.fourcc =
|
||||
- data_->video_->toV4L2PixelFormat(cfg.pixelFormat);
|
||||
+ V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat,
|
||||
+ data_->video_->caps().isMultiplanar());
|
||||
format.size = cfg.size;
|
||||
|
||||
int ret = data_->video_->tryFormat(&format);
|
||||
@@ -571,7 +573,8 @@ int PipelineHandlerStarFive::configure(Camera *camera, CameraConfiguration *c)
|
||||
if (stream == &data->rawStream_) {
|
||||
V4L2DeviceFormat format = {};
|
||||
format.fourcc =
|
||||
- data->raw_->toV4L2PixelFormat(cfg.pixelFormat);
|
||||
+ V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat,
|
||||
+ data->raw_->caps().isMultiplanar());
|
||||
format.size = cfg.size;
|
||||
|
||||
ret = data->raw_->setFormat(&format);
|
||||
@@ -580,13 +583,15 @@ int PipelineHandlerStarFive::configure(Camera *camera, CameraConfiguration *c)
|
||||
|
||||
if (format.size != cfg.size ||
|
||||
format.fourcc !=
|
||||
- data->raw_->toV4L2PixelFormat(cfg.pixelFormat))
|
||||
+ V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat,
|
||||
+ data->raw_->caps().isMultiplanar()))
|
||||
return -EINVAL;
|
||||
|
||||
} else if (stream == &data->outStream_) {
|
||||
V4L2DeviceFormat format = {};
|
||||
format.fourcc =
|
||||
- data->video_->toV4L2PixelFormat(cfg.pixelFormat);
|
||||
+ V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat,
|
||||
+ data->video_->caps().isMultiplanar());
|
||||
format.size = cfg.size;
|
||||
|
||||
ret = data->video_->setFormat(&format);
|
||||
@@ -595,7 +600,8 @@ int PipelineHandlerStarFive::configure(Camera *camera, CameraConfiguration *c)
|
||||
|
||||
if (format.size != cfg.size ||
|
||||
format.fourcc !=
|
||||
- data->video_->toV4L2PixelFormat(cfg.pixelFormat))
|
||||
+ V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat,
|
||||
+ data->video_->caps().isMultiplanar()))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
From 4810d94989891c7bb825ab5847b7e01e9db5e14d Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Wed, 17 Nov 2021 10:07:35 +0800
|
||||
Subject: [PATCH 05/10] fix build gen version error
|
||||
|
||||
---
|
||||
utils/gen-version.sh | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/utils/gen-version.sh b/utils/gen-version.sh
|
||||
index eb7c7268..ef548100 100755
|
||||
--- a/utils/gen-version.sh
|
||||
+++ b/utils/gen-version.sh
|
||||
@@ -3,6 +3,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Generate a version string using git describe
|
||||
|
||||
+workdir=$PWD
|
||||
+cd ../../../../buildroot/dl/libcamera/git/
|
||||
build_dir="$1"
|
||||
src_dir="$2"
|
||||
|
||||
@@ -48,3 +50,4 @@ git diff-index --quiet HEAD || version="$version-dirty ($(date --iso-8601=second
|
||||
version=$(echo "$version" | sed -e 's/-/+/' | sed -e 's/-g/-/' | cut -c 2-)
|
||||
|
||||
echo "$version"
|
||||
+cd $workdir
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
From 652fa5837d0c54c4b850b6b2a2171dc94aab3c1f Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Thu, 13 Jan 2022 13:57:12 +0800
|
||||
Subject: [PATCH 06/10] libcamera: pixel formats supported should move to
|
||||
request pads
|
||||
|
||||
---
|
||||
src/gstreamer/gstlibcamerasrc.cpp | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
|
||||
index 6329b01a..53247c3f 100644
|
||||
--- a/src/gstreamer/gstlibcamerasrc.cpp
|
||||
+++ b/src/gstreamer/gstlibcamerasrc.cpp
|
||||
@@ -151,12 +151,12 @@ G_DEFINE_TYPE_WITH_CODE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT,
|
||||
)
|
||||
/* For the simple case, we have a src pad that is always present. */
|
||||
GstStaticPadTemplate src_template = {
|
||||
- "src", GST_PAD_SRC, GST_PAD_ALWAYS, TEMPLATE_CAPS_SRC
|
||||
+ "src", GST_PAD_SRC, GST_PAD_ALWAYS, TEMPLATE_CAPS
|
||||
};
|
||||
|
||||
/* More pads can be requested in state < PAUSED */
|
||||
GstStaticPadTemplate request_src_template = {
|
||||
- "src_%u", GST_PAD_SRC, GST_PAD_REQUEST, TEMPLATE_CAPS
|
||||
+ "src_%u", GST_PAD_SRC, GST_PAD_REQUEST, TEMPLATE_CAPS_SRC
|
||||
};
|
||||
|
||||
void
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,318 +0,0 @@
|
||||
From 5e558d4454fa476cc9e0670a30d631a1174b55a2 Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Tue, 23 Nov 2021 10:44:04 +0800
|
||||
Subject: [PATCH 07/10] add list controls and properties
|
||||
|
||||
---
|
||||
src/libcamera/pipeline/starfive/starfive.cpp | 219 ++++++++++++++-----
|
||||
1 file changed, 165 insertions(+), 54 deletions(-)
|
||||
|
||||
diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
index 58e1f55a..b91a85a4 100644
|
||||
--- a/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
+++ b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
@@ -185,7 +185,9 @@ public:
|
||||
delete ispSubDev_;
|
||||
}
|
||||
|
||||
- int init();
|
||||
+ int init(MediaDevice *media);
|
||||
+ void addControl(uint32_t cid, const ControlInfo &v4l2Info,
|
||||
+ ControlInfoMap::Map *ctrls);
|
||||
void bufferReady(FrameBuffer *buffer);
|
||||
bool haveRaw() const { return haveRaw_; }
|
||||
bool rawActive() const { return rawActive_; }
|
||||
@@ -298,7 +300,7 @@ private:
|
||||
StarFiveCameraData *data_;
|
||||
};
|
||||
|
||||
-int StarFiveCameraData::init()
|
||||
+int StarFiveCameraData::init(MediaDevice *media)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -353,7 +355,38 @@ int StarFiveCameraData::init()
|
||||
&StarFiveCameraData::bufferReady);
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
+ // properties_.set(properties::Location, properties::CameraLocationExternal);
|
||||
+ properties_.set(properties::Model, utils::toAscii(media->model()));
|
||||
+
|
||||
+ /*
|
||||
+ * Get the current format in order to initialize the sensor array
|
||||
+ * properties.
|
||||
+ */
|
||||
+ Size resolution;
|
||||
+ for (const auto &it : video_->formats()) {
|
||||
+ const std::vector<SizeRange> &sizeRanges = it.second;
|
||||
+ for (const SizeRange &sizeRange : sizeRanges) {
|
||||
+ if (sizeRange.max > resolution)
|
||||
+ resolution = sizeRange.max;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ properties_.set(properties::PixelArraySize, resolution);
|
||||
+ properties_.set(properties::PixelArrayActiveAreas, { Rectangle(resolution) });
|
||||
+
|
||||
+ /* Initialise the supported controls. */
|
||||
+ ControlInfoMap::Map ctrls;
|
||||
+
|
||||
+ for (const auto &ctrl : sensor_->controls()) {
|
||||
+ uint32_t cid = ctrl.first->id();
|
||||
+ const ControlInfo &info = ctrl.second;
|
||||
+
|
||||
+ addControl(cid, info, &ctrls);
|
||||
+ }
|
||||
+
|
||||
+ controlInfo_ = ControlInfoMap(std::move(ctrls), controls::controls);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -734,97 +767,89 @@ int PipelineHandlerStarFive::processControls(StarFiveCameraData *data, const Con
|
||||
|
||||
for (auto it : controls) {
|
||||
unsigned int id = it.first;
|
||||
- unsigned int offset = 0;
|
||||
uint32_t cid = 0;
|
||||
int32_t value = 0;
|
||||
|
||||
switch (id) {
|
||||
case controls::BRIGHTNESS:
|
||||
cid = V4L2_CID_BRIGHTNESS;
|
||||
- offset = 128;
|
||||
- value = lroundf(it.second.get<float>() * 128 + offset);
|
||||
- LOG(STARFIVE, Debug) << "Brightness controls: " << id
|
||||
- << ", value: " << value;
|
||||
break;
|
||||
case controls::CONTRAST:
|
||||
cid = V4L2_CID_CONTRAST;
|
||||
- offset = 0;
|
||||
- value = lroundf(it.second.get<float>() * 128 + offset);
|
||||
- LOG(STARFIVE, Debug) << "Contrast controls: " << id
|
||||
- << ", value: " << value;
|
||||
break;
|
||||
case controls::SATURATION:
|
||||
cid = V4L2_CID_SATURATION;
|
||||
- offset = 0;
|
||||
- value = lroundf(it.second.get<float>() * 128 + offset);
|
||||
- LOG(STARFIVE, Debug) << "Saturation controls: " << id
|
||||
- << ", value: " << value;
|
||||
break;
|
||||
case controls::SHARPNESS:
|
||||
cid = V4L2_CID_SHARPNESS;
|
||||
- offset = 0;
|
||||
- value = lroundf(it.second.get<float>() * 128 + offset);
|
||||
- LOG(STARFIVE, Debug) << "Sharpness controls: " << id
|
||||
- << ", value: " << value;
|
||||
break;
|
||||
case controls::COLOUR_GAINS:
|
||||
cid = V4L2_CID_RED_BALANCE;
|
||||
- offset = 0;
|
||||
- value = lroundf(it.second.get<Span<const float>>()[0]);
|
||||
- LOG(STARFIVE, Debug) << "ColourGains controls: " << id
|
||||
- << ", COLOUR_GAINS RED value: " << value;
|
||||
- if (SensorControlsInfoMap.find(cid) != SensorControlsInfoMap.end())
|
||||
- SensorControls.set(cid, value);
|
||||
- else
|
||||
- LOG(STARFIVE, Debug)
|
||||
- << "SensorControls not supported controls: " << id;
|
||||
- cid = V4L2_CID_BLUE_BALANCE;
|
||||
- value = lroundf(it.second.get<Span<const float>>()[1]);
|
||||
- LOG(STARFIVE, Debug) << "COLOUR_GAINS BLUE value: " << value;
|
||||
break;
|
||||
case controls::AWB_ENABLE:
|
||||
cid = V4L2_CID_AUTO_WHITE_BALANCE;
|
||||
- value = it.second.get<bool>();
|
||||
- LOG(STARFIVE, Debug) << "AwbMode controls: " << id
|
||||
- << ", value: " << value;
|
||||
break;
|
||||
case controls::EXPOSURE_VALUE:
|
||||
cid = V4L2_CID_EXPOSURE;
|
||||
- offset = 0;
|
||||
- value = lroundf(it.second.get<float>());
|
||||
- LOG(STARFIVE, Debug) << "ExposureValue controls: " << id
|
||||
- << ", value: " << value;
|
||||
break;
|
||||
case controls::AE_ENABLE:
|
||||
cid = V4L2_CID_EXPOSURE_AUTO;
|
||||
- value = it.second.get<bool>();
|
||||
- LOG(STARFIVE, Debug) << "AeExposureMode controls: " << id
|
||||
- << ", value: " << value;
|
||||
break;
|
||||
case controls::ANALOGUE_GAIN:
|
||||
cid = V4L2_CID_ANALOGUE_GAIN;
|
||||
- offset = 0;
|
||||
- value = lroundf(it.second.get<float>());
|
||||
- LOG(STARFIVE, Debug) << "AnalogueGain controls: " << id
|
||||
- << ", value: " << value;
|
||||
break;
|
||||
case controls::DIGITAL_GAIN:
|
||||
- cid = V4L2_CID_GAIN;
|
||||
- offset = 0;
|
||||
- value = lroundf(it.second.get<float>());
|
||||
- LOG(STARFIVE, Debug) << "AnalogueGain controls: " << id
|
||||
- << ", value: " << value;
|
||||
+ cid = V4L2_CID_DIGITAL_GAIN;
|
||||
break;
|
||||
default:
|
||||
- LOG(STARFIVE, Debug) << "default controls: " << id;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (SensorControlsInfoMap.find(cid) == SensorControlsInfoMap.end()) {
|
||||
+ LOG(STARFIVE, Debug) << "SensorControls not supported controls: " << id;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ const ControlInfo &v4l2Info = SensorControlsInfoMap.at(cid);
|
||||
+ int32_t min = v4l2Info.min().get<int32_t>();
|
||||
+ int32_t def = v4l2Info.def().get<int32_t>();
|
||||
+ int32_t max = v4l2Info.max().get<int32_t>();
|
||||
+
|
||||
+ switch (id) {
|
||||
+ case controls::SATURATION:
|
||||
+ case controls::SHARPNESS:
|
||||
+ case controls::CONTRAST:
|
||||
+ case controls::EXPOSURE_VALUE:
|
||||
+ case controls::ANALOGUE_GAIN:
|
||||
+ case controls::DIGITAL_GAIN:
|
||||
+ case controls::BRIGHTNESS: {
|
||||
+ value = static_cast<int32_t>(lroundf(it.second.get<float>()));
|
||||
+ break;
|
||||
+ }
|
||||
+ case controls::COLOUR_GAINS: {
|
||||
+ value = static_cast<int32_t>(lroundf(it.second.get<float>()));
|
||||
+ LOG(STARFIVE, Debug) << "ColourGains controls: " << id
|
||||
+ << ", COLOUR_GAINS RED value: " << value;
|
||||
+ SensorControls.set(cid, value);
|
||||
+ cid = V4L2_CID_BLUE_BALANCE;
|
||||
+ value = static_cast<int32_t>(lroundf(it.second.get<float>()));
|
||||
+ LOG(STARFIVE, Debug) << "COLOUR_GAINS BLUE value: " << value;
|
||||
+ break;
|
||||
+ }
|
||||
+ case controls::AWB_ENABLE:
|
||||
+ case controls::AE_ENABLE:
|
||||
+ value = it.second.get<bool>();
|
||||
break;
|
||||
+ default:
|
||||
+ LOG(STARFIVE, Debug) << "default controls: " << id;
|
||||
+ continue;
|
||||
}
|
||||
|
||||
+ LOG(STARFIVE, Debug) << "controls: " << id << ", value: " << value;
|
||||
if (SensorControlsInfoMap.find(cid) != SensorControlsInfoMap.end())
|
||||
SensorControls.set(cid, value);
|
||||
else
|
||||
LOG(STARFIVE, Debug) << "SensorControls not supported controls: " << id;
|
||||
-
|
||||
}
|
||||
|
||||
for (const auto &ctrl : SensorControls)
|
||||
@@ -965,7 +990,7 @@ int PipelineHandlerStarFive::registerCameras()
|
||||
videoEntiryName, sensorEntityName);
|
||||
|
||||
/* Locate and open the capture video node. */
|
||||
- if (data->init())
|
||||
+ if (data->init(starFiveMediaDev_))
|
||||
continue;
|
||||
|
||||
/*create ipa module*/
|
||||
@@ -1075,6 +1100,92 @@ void StarFiveCameraData::bufferReady(FrameBuffer *buffer)
|
||||
pipe->completeRequest(request);
|
||||
}
|
||||
|
||||
+void StarFiveCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,
|
||||
+ ControlInfoMap::Map *ctrls)
|
||||
+{
|
||||
+ const ControlId *id;
|
||||
+ ControlInfo info;
|
||||
+
|
||||
+ LOG(STARFIVE, Debug) << __func__ << " cid: " << utils::hex(cid);
|
||||
+ /* Map the control ID. */
|
||||
+ switch (cid) {
|
||||
+ case V4L2_CID_BRIGHTNESS:
|
||||
+ id = &controls::Brightness;
|
||||
+ break;
|
||||
+ case V4L2_CID_CONTRAST:
|
||||
+ id = &controls::Contrast;
|
||||
+ break;
|
||||
+ case V4L2_CID_SATURATION:
|
||||
+ id = &controls::Saturation;
|
||||
+ break;
|
||||
+ case V4L2_CID_SHARPNESS:
|
||||
+ id = &controls::Sharpness;
|
||||
+ break;
|
||||
+ case V4L2_CID_RED_BALANCE:
|
||||
+ case V4L2_CID_BLUE_BALANCE:
|
||||
+ id = &controls::ColourGains;
|
||||
+ break;
|
||||
+ case V4L2_CID_AUTO_WHITE_BALANCE:
|
||||
+ id = &controls::AwbMode;
|
||||
+ break;
|
||||
+ case V4L2_CID_EXPOSURE:
|
||||
+ id = &controls::ExposureValue;
|
||||
+ break;
|
||||
+ case V4L2_CID_EXPOSURE_AUTO:
|
||||
+ id = &controls::AeExposureMode;
|
||||
+ break;
|
||||
+ case V4L2_CID_ANALOGUE_GAIN:
|
||||
+ id = &controls::AnalogueGain;
|
||||
+ break;
|
||||
+ case V4L2_CID_DIGITAL_GAIN:
|
||||
+ id = &controls::DigitalGain;
|
||||
+ break;
|
||||
+ default:
|
||||
+ LOG(STARFIVE, Debug) << __func__ << " unsupport cid: " << utils::hex(cid);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Map the control info. */
|
||||
+ int32_t min = v4l2Info.min().get<int32_t>();
|
||||
+ int32_t max = v4l2Info.max().get<int32_t>();
|
||||
+ int32_t def = v4l2Info.def().get<int32_t>();
|
||||
+
|
||||
+ switch (cid) {
|
||||
+ case V4L2_CID_SATURATION:
|
||||
+ case V4L2_CID_SHARPNESS:
|
||||
+ case V4L2_CID_CONTRAST:
|
||||
+ case V4L2_CID_EXPOSURE:
|
||||
+ case V4L2_CID_ANALOGUE_GAIN:
|
||||
+ case V4L2_CID_DIGITAL_GAIN:
|
||||
+ case V4L2_CID_BRIGHTNESS: {
|
||||
+ info = ControlInfo{
|
||||
+ { static_cast<float>(min) },
|
||||
+ { static_cast<float>(max) },
|
||||
+ { static_cast<float>(def) },
|
||||
+ };
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ case V4L2_CID_EXPOSURE_AUTO:
|
||||
+ info = ControlInfo{ false, true, true };
|
||||
+ break;
|
||||
+
|
||||
+ case V4L2_CID_EXPOSURE_ABSOLUTE:
|
||||
+ info = ControlInfo{
|
||||
+ { min * 100 },
|
||||
+ { max * 100 },
|
||||
+ { def * 100 }
|
||||
+ };
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ info = v4l2Info;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ ctrls->emplace(id, info);
|
||||
+}
|
||||
+
|
||||
REGISTER_PIPELINE_HANDLER(PipelineHandlerStarFive)
|
||||
|
||||
} /* namespace libcamera */
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
From 4c51694d5f3fbb23423f60165f928e50e7d9c3a3 Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Wed, 15 Dec 2021 17:13:58 +0800
|
||||
Subject: [PATCH 08/10] support use yaml file to config sensor pipeline
|
||||
|
||||
---
|
||||
src/libcamera/meson.build | 3 +
|
||||
.../pipeline/starfive/sensors_pipeline.yaml | 35 ++++++
|
||||
src/libcamera/pipeline/starfive/starfive.cpp | 106 ++++++++++++++++--
|
||||
3 files changed, 132 insertions(+), 12 deletions(-)
|
||||
create mode 100644 src/libcamera/pipeline/starfive/sensors_pipeline.yaml
|
||||
|
||||
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
|
||||
index 6727a777..39c44d42 100644
|
||||
--- a/src/libcamera/meson.build
|
||||
+++ b/src/libcamera/meson.build
|
||||
@@ -113,6 +113,8 @@ if ipa_sign_module
|
||||
libcamera_sources += ipa_pub_key_cpp
|
||||
endif
|
||||
|
||||
+libyamlcpp = cc.find_library('yaml-cpp', required : true)
|
||||
+
|
||||
libcamera_deps = [
|
||||
libatomic,
|
||||
libcamera_base,
|
||||
@@ -121,6 +123,7 @@ libcamera_deps = [
|
||||
libgnutls,
|
||||
liblttng,
|
||||
libudev,
|
||||
+ libyamlcpp,
|
||||
]
|
||||
|
||||
# We add '/' to the build_rpath as a 'safe' path to act as a boolean flag.
|
||||
diff --git a/src/libcamera/pipeline/starfive/sensors_pipeline.yaml b/src/libcamera/pipeline/starfive/sensors_pipeline.yaml
|
||||
new file mode 100644
|
||||
index 00000000..3446b0ac
|
||||
--- /dev/null
|
||||
+++ b/src/libcamera/pipeline/starfive/sensors_pipeline.yaml
|
||||
@@ -0,0 +1,35 @@
|
||||
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
+#
|
||||
+# Copyright (C) 2020, Google Inc.
|
||||
+#
|
||||
+%YAML 1.2
|
||||
+# description:
|
||||
+# sensors:
|
||||
+# - sensorentity: "imx219 0-0010"
|
||||
+# ispfwimage: "stf_isp0_fw_dump.bin" isp fw image name
|
||||
+# sensortype: 4
|
||||
+#
|
||||
+# sensortype value:
|
||||
+# {
|
||||
+# DVP_YUV = 0,
|
||||
+# MIPICSI0_YUV = 1,
|
||||
+# MIPICSI1_YUV = 2,
|
||||
+# DVP_ISP0 = 3, // ISP0
|
||||
+# MIPICSI0_ISP0 = 4,
|
||||
+# MIPICSI1_ISP0 = 5,
|
||||
+# DVP_ISP1 = 6, // ISP1
|
||||
+# MIPICSI0_ISP1 = 7,
|
||||
+# MIPICSI1_ISP1 = 8,
|
||||
+# SENSORTYPE_MAX
|
||||
+# }
|
||||
+#
|
||||
+---
|
||||
+sensors:
|
||||
+ - sensorentity: "imx219 0-0010"
|
||||
+ ispfwimage: "stf_isp0_fw_dump.bin"
|
||||
+ sensortype: 4
|
||||
+
|
||||
+ - sensorentity: "imx219 2-0010"
|
||||
+ ispfwimage: "stf_isp0_fw_dump.bin"
|
||||
+ sensortype: 8
|
||||
+...
|
||||
diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
index b91a85a4..864addfa 100644
|
||||
--- a/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
+++ b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <queue>
|
||||
#include <sys/mman.h>
|
||||
#include <math.h>
|
||||
+#include <yaml-cpp/yaml.h>
|
||||
+#include <yaml-cpp/node/parse.h>
|
||||
|
||||
#include <libcamera/camera.h>
|
||||
#include <libcamera/control_ids.h>
|
||||
@@ -39,14 +41,7 @@
|
||||
|
||||
#define STF_MAX_CAMERAS 3
|
||||
|
||||
-namespace libcamera {
|
||||
-
|
||||
-LOG_DEFINE_CATEGORY(STARFIVE)
|
||||
-
|
||||
-static constexpr unsigned int BUFFER_COUNT = 4;
|
||||
-static constexpr unsigned int MAX_STREAMS = 2;
|
||||
-static const Size OUTPUT_MIN_SIZE = { 8, 8 };
|
||||
-static const Size OUTPUT_MAX_SIZE = { 8192, 8192 };
|
||||
+#define PIPELINE_CONFIG_FILENAME "/etc/starfive/sensors_pipeline.yaml"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -66,14 +61,16 @@ typedef enum {
|
||||
typedef struct {
|
||||
std::string sensorEntityName_;
|
||||
std::string sensorFwImageName_;
|
||||
- SensorType sensorType_;
|
||||
+ int sensorType_;
|
||||
} SensorConfig;
|
||||
|
||||
-const std::vector<SensorConfig> sensorConfigs = {
|
||||
+const std::vector<SensorConfig> defaultSensorConfigs = {
|
||||
{ "imx219 0-0010", "stf_isp0_fw_dump.bin", MIPICSI0_ISP0 },
|
||||
{ "imx219 2-0010", "stf_isp0_fw_dump.bin", MIPICSI1_ISP1 },
|
||||
};
|
||||
|
||||
+std::vector<SensorConfig> sensorConfigs;
|
||||
+
|
||||
typedef struct {
|
||||
std::string source;
|
||||
std::string link;
|
||||
@@ -139,6 +136,40 @@ const std::vector<PipelineConfigLink> pipelineConfigs[SENSORTYPE_MAX] = {
|
||||
mipicsi1raw1Config,
|
||||
};
|
||||
|
||||
+} /* namespace */
|
||||
+
|
||||
+namespace YAML {
|
||||
+ template<>
|
||||
+ struct convert<SensorConfig> {
|
||||
+ static Node encode(const SensorConfig& sensor) {
|
||||
+ Node node;
|
||||
+ node.push_back(sensor.sensorEntityName_);
|
||||
+ node.push_back(sensor.sensorFwImageName_);
|
||||
+ node.push_back(sensor.sensorType_);
|
||||
+ return node;
|
||||
+ }
|
||||
+
|
||||
+ static bool decode(const Node& node, SensorConfig& sensor) {
|
||||
+ if(node.size() != 3)
|
||||
+ return false;
|
||||
+
|
||||
+ sensor.sensorEntityName_ = node["sensorentity"].as<std::string>();
|
||||
+ sensor.sensorFwImageName_ = node["ispfwimage"].as<std::string>();
|
||||
+ sensor.sensorType_ = node["sensortype"].as<int>();
|
||||
+ return true;
|
||||
+ }
|
||||
+ };
|
||||
+}
|
||||
+
|
||||
+namespace libcamera {
|
||||
+
|
||||
+LOG_DEFINE_CATEGORY(STARFIVE)
|
||||
+
|
||||
+static constexpr unsigned int BUFFER_COUNT = 4;
|
||||
+static constexpr unsigned int MAX_STREAMS = 2;
|
||||
+static const Size OUTPUT_MIN_SIZE = { 8, 8 };
|
||||
+static const Size OUTPUT_MAX_SIZE = { 8192, 8192 };
|
||||
+
|
||||
const std::map<uint32_t, PixelFormat> mbusCodesToPixelFormat = {
|
||||
{ MEDIA_BUS_FMT_SBGGR10_1X10, formats::SBGGR12 },
|
||||
{ MEDIA_BUS_FMT_SGBRG10_1X10, formats::SGBRG12 },
|
||||
@@ -146,8 +177,6 @@ const std::map<uint32_t, PixelFormat> mbusCodesToPixelFormat = {
|
||||
{ MEDIA_BUS_FMT_SRGGB10_1X10, formats::SRGGB12 },
|
||||
};
|
||||
|
||||
-} /* namespace */
|
||||
-
|
||||
class StarFiveCameraData : public Camera::Private
|
||||
{
|
||||
public:
|
||||
@@ -423,6 +452,7 @@ private:
|
||||
int enableLinks(std::vector<PipelineConfigLink> config);
|
||||
|
||||
MediaDevice *starFiveMediaDev_;
|
||||
+ int parserPipelineConfig(const char *filename);
|
||||
};
|
||||
|
||||
StarFiveCameraConfiguration::StarFiveCameraConfiguration(StarFiveCameraData *data)
|
||||
@@ -1042,6 +1072,56 @@ int PipelineHandlerStarFive::enableLinks(std::vector<PipelineConfigLink> config)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static void loaddefaultSensorConfig(void)
|
||||
+{
|
||||
+ LOG(STARFIVE, Debug) << __func__;
|
||||
+ sensorConfigs.clear();
|
||||
+ for (SensorConfig it : defaultSensorConfigs)
|
||||
+ sensorConfigs.push_back(it);
|
||||
+}
|
||||
+
|
||||
+static void printSensorConfig(void)
|
||||
+{
|
||||
+ for (SensorConfig it : sensorConfigs)
|
||||
+ LOG(STARFIVE, Debug)
|
||||
+ << " sensorEntityName: " << it.sensorEntityName_
|
||||
+ << ", ispLoadFW: " << it.sensorFwImageName_
|
||||
+ << ", sensorType: " << it.sensorType_;
|
||||
+}
|
||||
+
|
||||
+int PipelineHandlerStarFive::parserPipelineConfig(const char *filename)
|
||||
+{
|
||||
+ LOG(STARFIVE, Debug) << __func__;
|
||||
+ try {
|
||||
+ YAML::Node config = YAML::LoadFile(PIPELINE_CONFIG_FILENAME);
|
||||
+
|
||||
+ if (config["sensors"]) {
|
||||
+ std::vector<SensorConfig> sensors =
|
||||
+ config["sensors"].as<std::vector<SensorConfig>>();
|
||||
+ int found = 0;
|
||||
+
|
||||
+ for (SensorConfig it : sensors) {
|
||||
+ found = 0;
|
||||
+ for (SensorConfig its : sensorConfigs) {
|
||||
+ if (its.sensorEntityName_ == it.sensorEntityName_) {
|
||||
+ found = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!found)
|
||||
+ sensorConfigs.push_back(it);
|
||||
+ }
|
||||
+ }
|
||||
+ } catch(std::exception const & e) {
|
||||
+ LOG(STARFIVE, Debug) << PIPELINE_CONFIG_FILENAME
|
||||
+ << " yaml file error, use default config!!!";
|
||||
+ loaddefaultSensorConfig();
|
||||
+ }
|
||||
+
|
||||
+ printSensorConfig();
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
bool PipelineHandlerStarFive::match(DeviceEnumerator *enumerator)
|
||||
{
|
||||
int numCameras = 0;
|
||||
@@ -1059,6 +1139,8 @@ bool PipelineHandlerStarFive::match(DeviceEnumerator *enumerator)
|
||||
if (starFiveMediaDev_->disableLinks())
|
||||
return false;
|
||||
|
||||
+ parserPipelineConfig(PIPELINE_CONFIG_FILENAME);
|
||||
+
|
||||
for (SensorConfig it : sensorConfigs) {
|
||||
MediaEntity *sensorEntity =
|
||||
starFiveMediaDev_->getEntityByName(it.sensorEntityName_);
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,271 +0,0 @@
|
||||
From a24624e164f041e86d9c864a4eb83ab8c2befee4 Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Thu, 16 Dec 2021 17:46:03 +0800
|
||||
Subject: [PATCH 09/10] csi0/csi1 can be configured to the same ISP
|
||||
|
||||
---
|
||||
src/libcamera/pipeline/starfive/starfive.cpp | 146 +++++++++++--------
|
||||
1 file changed, 89 insertions(+), 57 deletions(-)
|
||||
|
||||
diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
index 864addfa..61a2ddc6 100644
|
||||
--- a/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
+++ b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
@@ -182,11 +182,11 @@ class StarFiveCameraData : public Camera::Private
|
||||
public:
|
||||
StarFiveCameraData(PipelineHandler *pipe, MediaDevice *media,
|
||||
std::string entityName,
|
||||
- std::string sensorEntityName)
|
||||
+ SensorConfig sensorConfig)
|
||||
: Camera::Private(pipe), media_(media)
|
||||
{
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
- sensorEntityName_ = sensorEntityName;
|
||||
+ sensorConfig_ = sensorConfig;
|
||||
videoEntityName_ = entityName;
|
||||
if ( videoEntityName_ == "stf_vin0_isp0_video1")
|
||||
ispEntityName_ = "stf_isp0";
|
||||
@@ -221,10 +221,12 @@ public:
|
||||
bool haveRaw() const { return haveRaw_; }
|
||||
bool rawActive() const { return rawActive_; }
|
||||
void setRawActive(bool val) { rawActive_ = val; }
|
||||
+ SensorConfig getSensorConfig() {return sensorConfig_; }
|
||||
std::vector<SizeRange> sensorSizes() const;
|
||||
std::vector<PixelFormat> sensorFormats() const;
|
||||
std::vector<PixelFormat> videoFormats() const;
|
||||
void paramsFilled(unsigned int id){}
|
||||
+ int ispLoadFW(const char *filename);
|
||||
|
||||
MediaDevice *media_;
|
||||
V4L2VideoDevice *video_;
|
||||
@@ -240,8 +242,8 @@ private:
|
||||
bool haveRaw_;
|
||||
bool rawActive_;
|
||||
std::string videoEntityName_;
|
||||
- std::string sensorEntityName_;
|
||||
std::string ispEntityName_;
|
||||
+ SensorConfig sensorConfig_;
|
||||
std::string getRawVideoEntityName()
|
||||
{
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
@@ -252,7 +254,6 @@ private:
|
||||
else
|
||||
return "unknow";
|
||||
}
|
||||
- int ispLoadFW(const char *filename);
|
||||
};
|
||||
|
||||
std::vector<PixelFormat> StarFiveCameraData::videoFormats() const
|
||||
@@ -334,17 +335,12 @@ int StarFiveCameraData::init(MediaDevice *media)
|
||||
int ret;
|
||||
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
- if (sensorEntityName_ != "unknow") {
|
||||
- sensor_ =
|
||||
- new CameraSensor(media_->getEntityByName(sensorEntityName_));
|
||||
- ret = sensor_->init();
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- LOG(STARFIVE, Debug) << "sensor id: " << sensor_->id();
|
||||
- } else {
|
||||
- LOG(STARFIVE, Debug) << " Can't find sensorEntityName!";
|
||||
- return -ENODEV;
|
||||
- }
|
||||
+ sensor_ =
|
||||
+ new CameraSensor(media_->getEntityByName(sensorConfig_.sensorEntityName_));
|
||||
+ ret = sensor_->init();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ LOG(STARFIVE, Debug) << "sensor id: " << sensor_->id();
|
||||
|
||||
if (ispEntityName_ != "unknow") {
|
||||
ispSubDev_ =
|
||||
@@ -352,13 +348,6 @@ int StarFiveCameraData::init(MediaDevice *media)
|
||||
LOG(STARFIVE, Debug) << "ispEntityName: " << ispEntityName_;
|
||||
if (ispSubDev_->open())
|
||||
return -ENODEV;
|
||||
-
|
||||
- for (SensorConfig it : sensorConfigs) {
|
||||
- if (it.sensorEntityName_ == sensorEntityName_) {
|
||||
- ispLoadFW(it.sensorFwImageName_.c_str());
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
}
|
||||
|
||||
video_ = new V4L2VideoDevice(media_->getEntityByName(videoEntityName_));
|
||||
@@ -550,10 +539,20 @@ PipelineHandlerStarFive::generateConfiguration(Camera *camera,
|
||||
StarFiveCameraData *data = cameraData(camera);
|
||||
StarFiveCameraConfiguration *config =
|
||||
new StarFiveCameraConfiguration(data);
|
||||
+ SensorConfig sensorConfig = data->getSensorConfig();
|
||||
|
||||
if (roles.empty())
|
||||
return config;
|
||||
|
||||
+ int ret = enableLinks(pipelineConfigs[sensorConfig.sensorType_]);
|
||||
+ if (ret < 0) {
|
||||
+ LOG(STARFIVE, Error)
|
||||
+ << sensorConfig.sensorEntityName_
|
||||
+ << " enableLinks failed!";
|
||||
+ return config;
|
||||
+ }
|
||||
+ data->ispLoadFW(sensorConfig.sensorFwImageName_.c_str());
|
||||
+
|
||||
for (const StreamRole role : roles) {
|
||||
std::map<PixelFormat, std::vector<SizeRange>> streamFormats;
|
||||
unsigned int bufferCount;
|
||||
@@ -1002,9 +1001,43 @@ int PipelineHandlerStarFive::registerCameras()
|
||||
unsigned int numCameras = 0;
|
||||
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
- for (unsigned int id = 0;
|
||||
- id < STF_MAX_CAMERAS
|
||||
- && numCameras < STF_MAX_CAMERAS; ++id) {
|
||||
+ for (SensorConfig it : sensorConfigs) {
|
||||
+ std::string cameraName;
|
||||
+ int id = 0;
|
||||
+
|
||||
+ switch (it.sensorType_) {
|
||||
+ case DVP_YUV:
|
||||
+ case MIPICSI0_YUV:
|
||||
+ case MIPICSI1_YUV:
|
||||
+ id = 0;
|
||||
+ break;
|
||||
+ case DVP_ISP0:
|
||||
+ case MIPICSI0_ISP0:
|
||||
+ case MIPICSI1_ISP0:
|
||||
+ id = 1;
|
||||
+ break;
|
||||
+ case DVP_ISP1:
|
||||
+ case MIPICSI0_ISP1:
|
||||
+ case MIPICSI1_ISP1:
|
||||
+ id = 2;
|
||||
+ break;
|
||||
+ default:
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ MediaEntity *sensorEntity =
|
||||
+ starFiveMediaDev_->getEntityByName(it.sensorEntityName_);
|
||||
+ if (sensorEntity != nullptr) {
|
||||
+ int ret = enableLinks(pipelineConfigs[it.sensorType_]);
|
||||
+ if (ret < 0) {
|
||||
+ LOG(STARFIVE, Error)
|
||||
+ << it.sensorEntityName_
|
||||
+ << " enableLinks failed!";
|
||||
+ continue;
|
||||
+ }
|
||||
+ } else
|
||||
+ continue;
|
||||
+
|
||||
std::string videoEntiryName;
|
||||
videoEntiryName = getVideoEntityNameById(id);
|
||||
if (videoEntiryName == "unknow")
|
||||
@@ -1012,12 +1045,17 @@ int PipelineHandlerStarFive::registerCameras()
|
||||
|
||||
std::string sensorEntityName;
|
||||
sensorEntityName = findSensorEntityName(videoEntiryName);
|
||||
- if (sensorEntityName == "unknow")
|
||||
- continue;
|
||||
+ if (sensorEntityName != it.sensorEntityName_)
|
||||
+ continue;
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ cameraName = it.sensorEntityName_ + " isp" + std::to_string(id - 1);
|
||||
+ else
|
||||
+ cameraName = it.sensorEntityName_ + " wr";
|
||||
|
||||
std::unique_ptr<StarFiveCameraData> data =
|
||||
std::make_unique<StarFiveCameraData>(this, starFiveMediaDev_,
|
||||
- videoEntiryName, sensorEntityName);
|
||||
+ videoEntiryName, it);
|
||||
|
||||
/* Locate and open the capture video node. */
|
||||
if (data->init(starFiveMediaDev_))
|
||||
@@ -1034,18 +1072,17 @@ int PipelineHandlerStarFive::registerCameras()
|
||||
data->ipa_->init(IPASettings{ conf, data->sensor_->model() });
|
||||
|
||||
/* Create and register the camera. */
|
||||
- LOG(STARFIVE, Debug) << "register deviceName: "
|
||||
- << videoEntiryName;
|
||||
+ LOG(STARFIVE, Debug) << "register deviceName: " << cameraName;
|
||||
if (data->haveRaw()) {
|
||||
std::set<Stream *> streams{ &data->outStream_,
|
||||
&data->rawStream_ };
|
||||
std::shared_ptr<Camera> camera =
|
||||
- Camera::create(std::move(data), videoEntiryName, streams);
|
||||
+ Camera::create(std::move(data), cameraName, streams);
|
||||
registerCamera(std::move(camera));
|
||||
} else {
|
||||
std::set<Stream *> streams{ &data->outStream_ };
|
||||
std::shared_ptr<Camera> camera =
|
||||
- Camera::create(std::move(data), videoEntiryName, streams);
|
||||
+ Camera::create(std::move(data), cameraName, streams);
|
||||
registerCamera(std::move(camera));
|
||||
}
|
||||
numCameras++;
|
||||
@@ -1064,9 +1101,26 @@ int PipelineHandlerStarFive::enableLinks(std::vector<PipelineConfigLink> config)
|
||||
if (!link)
|
||||
return -ENODEV;
|
||||
|
||||
- ret = link->setEnabled(true);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
+ MediaEntity *remote = link->sink()->entity();
|
||||
+ for (MediaPad *pad : remote->pads()) {
|
||||
+ for (MediaLink *e : pad->links()) {
|
||||
+ if (link == e)
|
||||
+ continue;
|
||||
+
|
||||
+ if ((e->flags() & MEDIA_LNK_FL_ENABLED) &&
|
||||
+ !(e->flags() & MEDIA_LNK_FL_IMMUTABLE)) {
|
||||
+ ret = e->setEnabled(false);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!(link->flags() & MEDIA_LNK_FL_ENABLED)) {
|
||||
+ ret = link->setEnabled(true);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1136,30 +1190,8 @@ bool PipelineHandlerStarFive::match(DeviceEnumerator *enumerator)
|
||||
if (!starFiveMediaDev_)
|
||||
return false;
|
||||
|
||||
- if (starFiveMediaDev_->disableLinks())
|
||||
- return false;
|
||||
-
|
||||
parserPipelineConfig(PIPELINE_CONFIG_FILENAME);
|
||||
|
||||
- for (SensorConfig it : sensorConfigs) {
|
||||
- MediaEntity *sensorEntity =
|
||||
- starFiveMediaDev_->getEntityByName(it.sensorEntityName_);
|
||||
- int ret;
|
||||
-
|
||||
- if (sensorEntity != nullptr) {
|
||||
- if (it.sensorType_ < DVP_YUV
|
||||
- || it.sensorType_ >= SENSORTYPE_MAX)
|
||||
- continue;
|
||||
- ret = enableLinks(pipelineConfigs[it.sensorType_]);
|
||||
- if (ret < 0) {
|
||||
- LOG(STARFIVE, Error)
|
||||
- << it.sensorEntityName_
|
||||
- << " enableLinks failed!";
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
numCameras = registerCameras();
|
||||
if (numCameras)
|
||||
LOG(STARFIVE, Debug)
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,254 +0,0 @@
|
||||
From 4d84bab2e88580bb96a24343051f2ea8132dc4e3 Mon Sep 17 00:00:00 2001
|
||||
From: sw.multimedia <sw.multimedia@starfivetech.com>
|
||||
Date: Thu, 13 Jan 2022 14:44:18 +0800
|
||||
Subject: [PATCH 10/10] libcamera: add framerate for request pad src.
|
||||
|
||||
---
|
||||
include/libcamera/internal/v4l2_videodevice.h | 7 +-
|
||||
include/libcamera/stream.h | 8 +++
|
||||
src/gstreamer/gstlibcamera-utils.cpp | 16 +++--
|
||||
src/libcamera/pipeline/starfive/starfive.cpp | 37 ++++++++++
|
||||
src/libcamera/v4l2_videodevice.cpp | 68 +++++++++++++++++++
|
||||
5 files changed, 131 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h
|
||||
index a1c458e4..650da22d 100644
|
||||
--- a/include/libcamera/internal/v4l2_videodevice.h
|
||||
+++ b/include/libcamera/internal/v4l2_videodevice.h
|
||||
@@ -35,6 +35,11 @@ class FileDescriptor;
|
||||
class MediaDevice;
|
||||
class MediaEntity;
|
||||
|
||||
+struct V4L2Framerate {
|
||||
+ uint32_t num = 0;
|
||||
+ uint32_t denom = 0;
|
||||
+};
|
||||
+
|
||||
struct V4L2Capability final : v4l2_capability {
|
||||
const char *driver() const
|
||||
{
|
||||
@@ -215,7 +220,7 @@ public:
|
||||
|
||||
static std::unique_ptr<V4L2VideoDevice>
|
||||
fromEntityName(const MediaDevice *media, const std::string &entity);
|
||||
-
|
||||
+ std::vector<V4L2Framerate> getFramerates(uint32_t pixelformat, uint32_t width, uint32_t height);
|
||||
protected:
|
||||
std::string logPrefix() const override;
|
||||
|
||||
diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h
|
||||
index 0c55e716..2e06d7d8 100644
|
||||
--- a/include/libcamera/stream.h
|
||||
+++ b/include/libcamera/stream.h
|
||||
@@ -36,6 +36,11 @@ private:
|
||||
std::map<PixelFormat, std::vector<SizeRange>> formats_;
|
||||
};
|
||||
|
||||
+struct Framerate {
|
||||
+ uint32_t num = 0;
|
||||
+ uint32_t denom = 0;
|
||||
+};
|
||||
+
|
||||
struct StreamConfiguration {
|
||||
StreamConfiguration();
|
||||
StreamConfiguration(const StreamFormats &formats);
|
||||
@@ -51,11 +56,14 @@ struct StreamConfiguration {
|
||||
void setStream(Stream *stream) { stream_ = stream; }
|
||||
const StreamFormats &formats() const { return formats_; }
|
||||
|
||||
+ void setframeRates(std::vector<Framerate> framerates) { rates = framerates; }
|
||||
+ const std::vector<Framerate> getframeRates() const { return rates; }
|
||||
std::string toString() const;
|
||||
|
||||
private:
|
||||
Stream *stream_;
|
||||
StreamFormats formats_;
|
||||
+ std::vector<Framerate> rates;
|
||||
};
|
||||
|
||||
enum StreamRole {
|
||||
diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
|
||||
index bce4960a..4cd07508 100644
|
||||
--- a/src/gstreamer/gstlibcamera-utils.cpp
|
||||
+++ b/src/gstreamer/gstlibcamera-utils.cpp
|
||||
@@ -140,10 +140,18 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg
|
||||
"height", G_TYPE_INT, stream_cfg.size.height,
|
||||
nullptr);
|
||||
|
||||
- // Add framerate negotiation support
|
||||
- // the range will be [ 0/1, 2147483647/1 ] as there is not any args
|
||||
- // required from driver for the time being.
|
||||
- gst_structure_set(s, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
|
||||
+ std::vector<libcamera::Framerate> rates = stream_cfg.getframeRates();
|
||||
+ guint index = 0;
|
||||
+ for (libcamera::Framerate it : rates) {
|
||||
+ libcamera::Framerate rate = it;
|
||||
+ gst_structure_set (s, "framerate", GST_TYPE_FRACTION, rate.denom, rate.num, NULL);
|
||||
+ //truncate rates. only remain the first one.
|
||||
+ if ( index == 0)
|
||||
+ {
|
||||
+ break;
|
||||
+ }
|
||||
+ index++;
|
||||
+ }
|
||||
|
||||
gst_caps_append_structure(caps, s);
|
||||
|
||||
diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
index 61a2ddc6..997d9835 100644
|
||||
--- a/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
+++ b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
@@ -43,6 +43,9 @@
|
||||
|
||||
#define PIPELINE_CONFIG_FILENAME "/etc/starfive/sensors_pipeline.yaml"
|
||||
|
||||
+#define DEFAULT_FRAMERATE_NUM 25;
|
||||
+#define DEFAULT_FRAMERATE_DENOM 1;
|
||||
+
|
||||
namespace {
|
||||
|
||||
typedef enum {
|
||||
@@ -225,6 +228,8 @@ public:
|
||||
std::vector<SizeRange> sensorSizes() const;
|
||||
std::vector<PixelFormat> sensorFormats() const;
|
||||
std::vector<PixelFormat> videoFormats() const;
|
||||
+ std::vector<Framerate> videoFrameRates(unsigned int pixelformat, unsigned int width, unsigned int height) const;
|
||||
+
|
||||
void paramsFilled(unsigned int id){}
|
||||
int ispLoadFW(const char *filename);
|
||||
|
||||
@@ -269,6 +274,24 @@ std::vector<PixelFormat> StarFiveCameraData::videoFormats() const
|
||||
return formats;
|
||||
}
|
||||
|
||||
+std::vector<Framerate> StarFiveCameraData::videoFrameRates(unsigned int pixelformat, unsigned int width, unsigned int height) const
|
||||
+{
|
||||
+ if (!video_)
|
||||
+ return {};
|
||||
+
|
||||
+ std::vector<Framerate> framerates;
|
||||
+ for (auto it : video_->getFramerates(pixelformat, width, height)) {
|
||||
+ V4L2Framerate v4l2_framerate = (V4L2Framerate)it;
|
||||
+ libcamera::Framerate rate;
|
||||
+ rate.num = v4l2_framerate.num;
|
||||
+ rate.denom = v4l2_framerate.denom;
|
||||
+ LOG(STARFIVE, Debug) << "videoFrameRates framerate: rate.num=" << rate.num << " rate.denom= " << rate.denom;
|
||||
+ framerates.push_back(rate);
|
||||
+ }
|
||||
+
|
||||
+ return framerates;
|
||||
+}
|
||||
+
|
||||
std::vector<PixelFormat> StarFiveCameraData::sensorFormats() const
|
||||
{
|
||||
if (!sensor_)
|
||||
@@ -480,6 +503,20 @@ CameraConfiguration::Status StarFiveCameraConfiguration::validate()
|
||||
cfg.size.height = std::max(OUTPUT_MIN_SIZE.height,
|
||||
std::min(OUTPUT_MAX_SIZE.height, cfg.size.height));
|
||||
|
||||
+ std::vector<Framerate> rates;
|
||||
+ rates = data_->videoFrameRates(cfg.pixelFormat,size.width, size.height);
|
||||
+ if (rates.size() > 0){
|
||||
+ cfg.setframeRates(rates);
|
||||
+ } else {
|
||||
+ LOG(STARFIVE, Debug)
|
||||
+ << "fail to obtian framerate, use default one ";
|
||||
+ Framerate rate;
|
||||
+ rate.num = DEFAULT_FRAMERATE_NUM;
|
||||
+ rate.denom = DEFAULT_FRAMERATE_DENOM;
|
||||
+ rates.emplace_back(rate);
|
||||
+ cfg.setframeRates(rates);
|
||||
+ }
|
||||
+
|
||||
if (cfg.size != size) {
|
||||
LOG(STARFIVE, Debug)
|
||||
<< "Adjusting size to " << cfg.size.toString();
|
||||
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
|
||||
index 4f04212d..5ccf70d9 100644
|
||||
--- a/src/libcamera/v4l2_videodevice.cpp
|
||||
+++ b/src/libcamera/v4l2_videodevice.cpp
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "libcamera/internal/framebuffer.h"
|
||||
#include "libcamera/internal/media_device.h"
|
||||
#include "libcamera/internal/media_object.h"
|
||||
+#include <limits.h>
|
||||
|
||||
/**
|
||||
* \file v4l2_videodevice.h
|
||||
@@ -1847,6 +1848,73 @@ V4L2VideoDevice::fromEntityName(const MediaDevice *media,
|
||||
return std::make_unique<V4L2VideoDevice>(mediaEntity);
|
||||
}
|
||||
|
||||
+std::vector<V4L2Framerate> V4L2VideoDevice::getFramerates(uint32_t pixelformat, uint32_t width, uint32_t height)
|
||||
+{
|
||||
+ struct v4l2_frmivalenum ival;
|
||||
+ uint32_t num, denom;
|
||||
+
|
||||
+ memset (&ival, 0, sizeof (struct v4l2_frmivalenum));
|
||||
+ ival.index = 0;
|
||||
+ ival.pixel_format = pixelformat;
|
||||
+ ival.width = width;
|
||||
+ ival.height = height;
|
||||
+ std::vector<V4L2Framerate> rates;
|
||||
+ LOG(V4L2, Debug) << "getFramerates: width: " << width << " height: " << height << " pixelformat " << pixelformat;
|
||||
+
|
||||
+ if (ioctl (VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0){
|
||||
+ LOG(V4L2, Error) << "fail to ioctl: VIDIOC_ENUM_FRAMEINTERVALS";
|
||||
+ goto enum_frameintervals_failed;
|
||||
+ }
|
||||
+
|
||||
+ if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
|
||||
+ struct V4L2Framerate rate;
|
||||
+ do {
|
||||
+ num = ival.discrete.numerator;
|
||||
+ denom = ival.discrete.denominator;
|
||||
+
|
||||
+ if (num > INT_MAX || denom > INT_MAX) {
|
||||
+ /* let us hope we don't get here... */
|
||||
+ LOG(V4L2, Error) << "num or denom is beyond INT_MAX";
|
||||
+ goto enum_frameintervals_failed;
|
||||
+ }
|
||||
+
|
||||
+ // /* swap to get the framerate */
|
||||
+ // gst_value_set_fraction (&rate, denom, num);
|
||||
+ rate.denom = denom;
|
||||
+ rate.num = num;
|
||||
+ LOG(V4L2, Debug) << "gstFramerates adding discrete framerate: " << denom << "/" << num;
|
||||
+ rates.emplace_back(rate);
|
||||
+ ival.index++;
|
||||
+ } while (ioctl (VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0);
|
||||
+ } else if (ival.type == V4L2_FRMIVAL_TYPE_STEPWISE){
|
||||
+ //TODO
|
||||
+ goto enum_frameintervals_unimplemented;
|
||||
+ } else if (ival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
|
||||
+ num = ival.stepwise.min.numerator;
|
||||
+ denom = ival.stepwise.min.denominator;
|
||||
+ if (num > INT_MAX || denom > INT_MAX) {
|
||||
+ LOG(V4L2, Error) << "continuous frame interval: num or denom is beyond INT_MAX";
|
||||
+ goto enum_frameintervals_failed;
|
||||
+ }
|
||||
+
|
||||
+ struct V4L2Framerate rate;
|
||||
+ rate.denom = denom;
|
||||
+ rate.num = num;
|
||||
+ LOG(V4L2, Debug) << "gstFramerates continuous frame interval: " << denom << "/" <<num;
|
||||
+ rates.emplace_back(rate);
|
||||
+ }
|
||||
+
|
||||
+ return rates;
|
||||
+
|
||||
+enum_frameintervals_failed:
|
||||
+enum_frameintervals_unimplemented:
|
||||
+{
|
||||
+ LOG(V4L2, Error) << "fail to obtain framerate !!!";
|
||||
+ return rates;
|
||||
+}
|
||||
+
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* \class V4L2M2MDevice
|
||||
* \brief Memory-to-Memory video device
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
From 43ac4b2e62f6998a24b6b42e2ce25917f674b18b Mon Sep 17 00:00:00 2001
|
||||
From: liuxl0327 <liuxl0327@starfivetech.com>
|
||||
Date: Fri, 8 Apr 2022 09:27:55 +0800
|
||||
Subject: [PATCH] libcamera support isp driver
|
||||
|
||||
---
|
||||
src/libcamera/pipeline/starfive/starfive.cpp | 94 ++++++++++++++------
|
||||
1 file changed, 65 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
index 0de22f2c..1689ad9d 100644
|
||||
--- a/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
+++ b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
@@ -73,55 +73,61 @@ std::vector<SensorConfig> sensorConfigs;
|
||||
|
||||
typedef struct {
|
||||
std::string source;
|
||||
- std::string link;
|
||||
+ unsigned int sourceIdx;
|
||||
+ std::string sink;
|
||||
+ unsigned int sinkIdx;
|
||||
} PipelineConfigLink;
|
||||
|
||||
const std::vector<PipelineConfigLink> dvpyuvConfig = {
|
||||
- {"stf_dvp0", "stf_vin0_wr"},
|
||||
+ {"stf_dvp0", 1, "stf_vin0_wr", 0},
|
||||
};
|
||||
|
||||
const std::vector<PipelineConfigLink> mipicsi0yuvConfig = {
|
||||
- {"stf_csiphy0", "stf_csi0"},
|
||||
- {"stf_csi0", "stf_vin0_wr"}
|
||||
+ {"stf_csiphy0", 1, "stf_csi0", 0},
|
||||
+ {"stf_csi0", 1, "stf_vin0_wr", 0}
|
||||
};
|
||||
|
||||
const std::vector<PipelineConfigLink> mipicsi1yuvConfig = {
|
||||
- {"stf_csiphy1", "stf_csi1"},
|
||||
- {"stf_csi1", "stf_vin0_wr"}
|
||||
+ {"stf_csiphy1", 1, "stf_csi1", 0},
|
||||
+ {"stf_csi1", 1, "stf_vin0_wr", 0}
|
||||
};
|
||||
|
||||
const std::vector<PipelineConfigLink> dvpraw0Config = {
|
||||
- {"stf_dvp0", "stf_isp0"},
|
||||
- {"stf_isp0", "stf_vin0_isp0"}
|
||||
+ {"stf_dvp0", 1, "stf_isp0", 0},
|
||||
};
|
||||
|
||||
const std::vector<PipelineConfigLink> mipicsi0raw0Config = {
|
||||
- {"stf_csiphy0", "stf_csi0"},
|
||||
- {"stf_csi0", "stf_isp0"},
|
||||
- {"stf_isp0", "stf_vin0_isp0"}
|
||||
+ {"stf_csiphy0", 1, "stf_csi0", 0},
|
||||
+ {"stf_csi0", 1, "stf_isp0", 0},
|
||||
};
|
||||
|
||||
const std::vector<PipelineConfigLink> mipicsi1raw0Config = {
|
||||
- {"stf_csiphy1", "stf_csi1"},
|
||||
- {"stf_csi1", "stf_isp0"},
|
||||
- {"stf_isp0", "stf_vin0_isp0"}
|
||||
+ {"stf_csiphy1", 1, "stf_csi1", 0},
|
||||
+ {"stf_csi1", 1, "stf_isp0", 0},
|
||||
};
|
||||
|
||||
const std::vector<PipelineConfigLink> dvpraw1Config = {
|
||||
- {"stf_dvp0", "stf_isp1"},
|
||||
- {"stf_isp1", "stf_vin0_isp1"}
|
||||
+ {"stf_dvp0", 1, "stf_isp1", 0},
|
||||
};
|
||||
|
||||
const std::vector<PipelineConfigLink> mipicsi0raw1Config = {
|
||||
- {"stf_csiphy0", "stf_csi0"},
|
||||
- {"stf_csi0", "stf_isp1"},
|
||||
- {"stf_isp1", "stf_vin0_isp1"}
|
||||
+ {"stf_csiphy0", 1, "stf_csi0", 0},
|
||||
+ {"stf_csi0", 1, "stf_isp1", 0},
|
||||
};
|
||||
|
||||
const std::vector<PipelineConfigLink> mipicsi1raw1Config = {
|
||||
- {"stf_csiphy1", "stf_csi1"},
|
||||
- {"stf_csi1", "stf_isp1"},
|
||||
- {"stf_isp1", "stf_vin0_isp1"}
|
||||
+ {"stf_csiphy1", 1, "stf_csi1", 0},
|
||||
+ {"stf_csi1", 1, "stf_isp1", 0},
|
||||
+};
|
||||
+
|
||||
+const std::vector<PipelineConfigLink> isp0Config = {
|
||||
+ {"stf_isp0", 1, "stf_vin0_isp0", 0},
|
||||
+ {"stf_isp0", 6, "stf_vin0_isp0_raw", 0}
|
||||
+};
|
||||
+
|
||||
+const std::vector<PipelineConfigLink> isp1Config = {
|
||||
+ {"stf_isp1", 1, "stf_vin0_isp1", 0},
|
||||
+ {"stf_isp1", 6, "stf_vin0_isp1_raw", 0}
|
||||
};
|
||||
|
||||
const std::vector<PipelineConfigLink> pipelineConfigs[SENSORTYPE_MAX] = {
|
||||
@@ -248,9 +254,9 @@ private:
|
||||
{
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
if ( videoEntityName_ == "stf_vin0_isp0_video1")
|
||||
- return "stf_vin0_isp0_raw_video3";
|
||||
+ return "stf_vin0_isp0_raw_video11";
|
||||
else if (videoEntityName_ == "stf_vin0_isp1_video2")
|
||||
- return "stf_vin0_isp1_raw_video4";
|
||||
+ return "stf_vin0_isp1_raw_video12";
|
||||
else
|
||||
return "unknow";
|
||||
}
|
||||
@@ -438,6 +444,7 @@ private:
|
||||
int registerCameras();
|
||||
std::string getVideoEntityNameById(unsigned int id);
|
||||
std::string findSensorEntityName(std::string entityName);
|
||||
+ int enableLinks(int sensorType);
|
||||
int enableLinks(std::vector<PipelineConfigLink> config);
|
||||
|
||||
MediaDevice *starFiveMediaDev_;
|
||||
@@ -544,7 +551,7 @@ PipelineHandlerStarFive::generateConfiguration(Camera *camera,
|
||||
if (roles.empty())
|
||||
return config;
|
||||
|
||||
- int ret = enableLinks(pipelineConfigs[sensorConfig.sensorType_]);
|
||||
+ int ret = enableLinks(sensorConfig.sensorType_);
|
||||
if (ret < 0) {
|
||||
LOG(STARFIVE, Error)
|
||||
<< sensorConfig.sensorEntityName_
|
||||
@@ -942,9 +949,9 @@ std::string PipelineHandlerStarFive::getVideoEntityNameById(unsigned int id)
|
||||
case 2:
|
||||
return "stf_vin0_isp1_video2";
|
||||
case 3:
|
||||
- return "stf_vin0_isp0_raw_video3";
|
||||
+ return "stf_vin0_isp0_raw_video11";
|
||||
case 4:
|
||||
- return "stf_vin0_isp1_raw_video4";
|
||||
+ return "stf_vin0_isp1_raw_video12";
|
||||
default:
|
||||
return "unknow";
|
||||
}
|
||||
@@ -1028,7 +1035,7 @@ int PipelineHandlerStarFive::registerCameras()
|
||||
MediaEntity *sensorEntity =
|
||||
starFiveMediaDev_->getEntityByName(it.sensorEntityName_);
|
||||
if (sensorEntity != nullptr) {
|
||||
- int ret = enableLinks(pipelineConfigs[it.sensorType_]);
|
||||
+ int ret = enableLinks(it.sensorType_);
|
||||
if (ret < 0) {
|
||||
LOG(STARFIVE, Error)
|
||||
<< it.sensorEntityName_
|
||||
@@ -1097,7 +1104,7 @@ int PipelineHandlerStarFive::enableLinks(std::vector<PipelineConfigLink> config)
|
||||
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
for (PipelineConfigLink it : config) {
|
||||
- MediaLink *link = starFiveMediaDev_->link(it.source, 1, it.link, 0);
|
||||
+ MediaLink *link = starFiveMediaDev_->link(it.source, it.sourceIdx, it.sink, it.sinkIdx);
|
||||
if (!link)
|
||||
return -ENODEV;
|
||||
|
||||
@@ -1126,6 +1133,35 @@ int PipelineHandlerStarFive::enableLinks(std::vector<PipelineConfigLink> config)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int PipelineHandlerStarFive::enableLinks(int sensorType)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ LOG(STARFIVE, Debug) << __func__;
|
||||
+ if (sensorType > SENSORTYPE_MAX || sensorType < DVP_YUV)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ ret = enableLinks(pipelineConfigs[sensorType]);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ switch (sensorType) {
|
||||
+ case DVP_ISP0:
|
||||
+ case MIPICSI0_ISP0:
|
||||
+ case MIPICSI1_ISP0:
|
||||
+ ret = enableLinks(isp0Config);
|
||||
+ break;
|
||||
+ case DVP_ISP1:
|
||||
+ case MIPICSI0_ISP1:
|
||||
+ case MIPICSI1_ISP1:
|
||||
+ ret = enableLinks(isp1Config);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void loaddefaultSensorConfig(void)
|
||||
{
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
From 6d4c962f44084b0e01ec49d37818fcdd10e9c01d Mon Sep 17 00:00:00 2001
|
||||
From: "Kevin.xie" <kevin.xie@starfivetech.com>
|
||||
Date: Wed, 8 Jun 2022 14:38:08 +0800
|
||||
Subject: [PATCH] Adjust StarFive pipeline video device entity name
|
||||
|
||||
Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
|
||||
---
|
||||
src/libcamera/pipeline/starfive/starfive.cpp | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
index 7f02baf..03f0949 100755
|
||||
--- a/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
+++ b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
@@ -199,7 +199,7 @@ public:
|
||||
videoEntityName_ = entityName;
|
||||
if ( videoEntityName_ == "stf_vin0_isp0_video1")
|
||||
ispEntityName_ = "stf_isp0";
|
||||
- else if (videoEntityName_ == "stf_vin0_isp1_video2")
|
||||
+ else if (videoEntityName_ == "stf_vin0_isp1_video8")
|
||||
ispEntityName_ = "stf_isp1";
|
||||
else
|
||||
ispEntityName_ = "unknow";
|
||||
@@ -258,9 +258,9 @@ private:
|
||||
{
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
if ( videoEntityName_ == "stf_vin0_isp0_video1")
|
||||
- return "stf_vin0_isp0_raw_video11";
|
||||
- else if (videoEntityName_ == "stf_vin0_isp1_video2")
|
||||
- return "stf_vin0_isp1_raw_video12";
|
||||
+ return "stf_vin0_isp0_raw_video6";
|
||||
+ else if (videoEntityName_ == "stf_vin0_isp1_video8")
|
||||
+ return "stf_vin0_isp1_raw_video13";
|
||||
else
|
||||
return "unknow";
|
||||
}
|
||||
@@ -983,11 +983,11 @@ std::string PipelineHandlerStarFive::getVideoEntityNameById(unsigned int id)
|
||||
case 1:
|
||||
return "stf_vin0_isp0_video1";
|
||||
case 2:
|
||||
- return "stf_vin0_isp1_video2";
|
||||
+ return "stf_vin0_isp1_video8";
|
||||
case 3:
|
||||
- return "stf_vin0_isp0_raw_video11";
|
||||
+ return "stf_vin0_isp0_raw_video6";
|
||||
case 4:
|
||||
- return "stf_vin0_isp1_raw_video12";
|
||||
+ return "stf_vin0_isp1_raw_video13";
|
||||
default:
|
||||
return "unknow";
|
||||
}
|
||||
@@ -1255,7 +1255,7 @@ bool PipelineHandlerStarFive::match(DeviceEnumerator *enumerator)
|
||||
DeviceMatch dm("stf-vin");
|
||||
dm.add("stf_vin0_wr_video0");
|
||||
dm.add("stf_vin0_isp0_video1");
|
||||
- dm.add("stf_vin0_isp1_video2");
|
||||
+ dm.add("stf_vin0_isp1_video8");
|
||||
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
starFiveMediaDev_ = acquireMediaDevice(enumerator, dm);
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
From 3c0db39c0acd04c9ddfd37279efb9bf47bf1f74c Mon Sep 17 00:00:00 2001
|
||||
From: "Kevin.xie" <kevin.xie@starfivetech.com>
|
||||
Date: Thu, 9 Jun 2022 19:08:14 +0800
|
||||
Subject: [PATCH] Removed isp1 config from pipeline & modified imx219 config
|
||||
|
||||
Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
|
||||
---
|
||||
.../pipeline/starfive/sensors_pipeline.yaml | 6 +--
|
||||
src/libcamera/pipeline/starfive/starfive.cpp | 47 +------------------
|
||||
2 files changed, 2 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/src/libcamera/pipeline/starfive/sensors_pipeline.yaml b/src/libcamera/pipeline/starfive/sensors_pipeline.yaml
|
||||
index 3446b0a..dc4fc63 100644
|
||||
--- a/src/libcamera/pipeline/starfive/sensors_pipeline.yaml
|
||||
+++ b/src/libcamera/pipeline/starfive/sensors_pipeline.yaml
|
||||
@@ -25,11 +25,7 @@
|
||||
#
|
||||
---
|
||||
sensors:
|
||||
- - sensorentity: "imx219 0-0010"
|
||||
+ - sensorentity: "imx219 6-0010"
|
||||
ispfwimage: "stf_isp0_fw_dump.bin"
|
||||
sensortype: 4
|
||||
-
|
||||
- - sensorentity: "imx219 2-0010"
|
||||
- ispfwimage: "stf_isp0_fw_dump.bin"
|
||||
- sensortype: 8
|
||||
...
|
||||
diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
index cc4cd1e..7f97069 100644
|
||||
--- a/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
+++ b/src/libcamera/pipeline/starfive/starfive.cpp
|
||||
@@ -55,9 +55,6 @@ typedef enum {
|
||||
DVP_ISP0, // ISP0
|
||||
MIPICSI0_ISP0,
|
||||
MIPICSI1_ISP0,
|
||||
- DVP_ISP1, // ISP1
|
||||
- MIPICSI0_ISP1,
|
||||
- MIPICSI1_ISP1,
|
||||
SENSORTYPE_MAX
|
||||
} SensorType;
|
||||
|
||||
@@ -68,8 +65,7 @@ typedef struct {
|
||||
} SensorConfig;
|
||||
|
||||
const std::vector<SensorConfig> defaultSensorConfigs = {
|
||||
- { "imx219 0-0010", "stf_isp0_fw_dump.bin", MIPICSI0_ISP0 },
|
||||
- { "imx219 2-0010", "stf_isp0_fw_dump.bin", MIPICSI1_ISP1 },
|
||||
+ { "imx219 6-0010", "stf_isp0_fw_dump.bin", MIPICSI0_ISP0 },
|
||||
};
|
||||
|
||||
std::vector<SensorConfig> sensorConfigs;
|
||||
@@ -109,30 +105,11 @@ const std::vector<PipelineConfigLink> mipicsi1raw0Config = {
|
||||
{"stf_csi1", 1, "stf_isp0", 0},
|
||||
};
|
||||
|
||||
-const std::vector<PipelineConfigLink> dvpraw1Config = {
|
||||
- {"stf_dvp0", 1, "stf_isp1", 0},
|
||||
-};
|
||||
-
|
||||
-const std::vector<PipelineConfigLink> mipicsi0raw1Config = {
|
||||
- {"stf_csiphy0", 1, "stf_csi0", 0},
|
||||
- {"stf_csi0", 1, "stf_isp1", 0},
|
||||
-};
|
||||
-
|
||||
-const std::vector<PipelineConfigLink> mipicsi1raw1Config = {
|
||||
- {"stf_csiphy1", 1, "stf_csi1", 0},
|
||||
- {"stf_csi1", 1, "stf_isp1", 0},
|
||||
-};
|
||||
-
|
||||
const std::vector<PipelineConfigLink> isp0Config = {
|
||||
{"stf_isp0", 1, "stf_vin0_isp0", 0},
|
||||
{"stf_isp0", 6, "stf_vin0_isp0_raw", 0}
|
||||
};
|
||||
|
||||
-const std::vector<PipelineConfigLink> isp1Config = {
|
||||
- {"stf_isp1", 1, "stf_vin0_isp1", 0},
|
||||
- {"stf_isp1", 6, "stf_vin0_isp1_raw", 0}
|
||||
-};
|
||||
-
|
||||
const std::vector<PipelineConfigLink> pipelineConfigs[SENSORTYPE_MAX] = {
|
||||
dvpyuvConfig,
|
||||
mipicsi0yuvConfig,
|
||||
@@ -140,9 +117,6 @@ const std::vector<PipelineConfigLink> pipelineConfigs[SENSORTYPE_MAX] = {
|
||||
dvpraw0Config,
|
||||
mipicsi0raw0Config,
|
||||
mipicsi1raw0Config,
|
||||
- dvpraw1Config,
|
||||
- mipicsi0raw1Config,
|
||||
- mipicsi1raw1Config,
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
@@ -199,8 +173,6 @@ public:
|
||||
videoEntityName_ = entityName;
|
||||
if ( videoEntityName_ == "stf_vin0_isp0_video1")
|
||||
ispEntityName_ = "stf_isp0";
|
||||
- else if (videoEntityName_ == "stf_vin0_isp1_video8")
|
||||
- ispEntityName_ = "stf_isp1";
|
||||
else
|
||||
ispEntityName_ = "unknow";
|
||||
|
||||
@@ -260,8 +232,6 @@ private:
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
if ( videoEntityName_ == "stf_vin0_isp0_video1")
|
||||
return "stf_vin0_isp0_raw_video6";
|
||||
- else if (videoEntityName_ == "stf_vin0_isp1_video8")
|
||||
- return "stf_vin0_isp1_raw_video13";
|
||||
else
|
||||
return "unknow";
|
||||
}
|
||||
@@ -984,11 +954,7 @@ std::string PipelineHandlerStarFive::getVideoEntityNameById(unsigned int id)
|
||||
case 1:
|
||||
return "stf_vin0_isp0_video1";
|
||||
case 2:
|
||||
- return "stf_vin0_isp1_video8";
|
||||
- case 3:
|
||||
return "stf_vin0_isp0_raw_video6";
|
||||
- case 4:
|
||||
- return "stf_vin0_isp1_raw_video13";
|
||||
default:
|
||||
return "unknow";
|
||||
}
|
||||
@@ -1060,11 +1026,6 @@ int PipelineHandlerStarFive::registerCameras()
|
||||
case MIPICSI1_ISP0:
|
||||
id = 1;
|
||||
break;
|
||||
- case DVP_ISP1:
|
||||
- case MIPICSI0_ISP1:
|
||||
- case MIPICSI1_ISP1:
|
||||
- id = 2;
|
||||
- break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@@ -1187,11 +1148,6 @@ int PipelineHandlerStarFive::enableLinks(int sensorType)
|
||||
case MIPICSI1_ISP0:
|
||||
ret = enableLinks(isp0Config);
|
||||
break;
|
||||
- case DVP_ISP1:
|
||||
- case MIPICSI0_ISP1:
|
||||
- case MIPICSI1_ISP1:
|
||||
- ret = enableLinks(isp1Config);
|
||||
- break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1256,7 +1212,6 @@ bool PipelineHandlerStarFive::match(DeviceEnumerator *enumerator)
|
||||
DeviceMatch dm("stf-vin");
|
||||
dm.add("stf_vin0_wr_video0");
|
||||
dm.add("stf_vin0_isp0_video1");
|
||||
- dm.add("stf_vin0_isp1_video8");
|
||||
|
||||
LOG(STARFIVE, Debug) << __func__;
|
||||
starFiveMediaDev_ = acquireMediaDevice(enumerator, dm);
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
From b04b58f1eea0b2fe417205846beef663c89275b7 Mon Sep 17 00:00:00 2001
|
||||
From: "Kevin.xie" <kevin.xie@starfivetech.com>
|
||||
Date: Wed, 3 Aug 2022 16:26:26 +0800
|
||||
Subject: [PATCH] libcamera: Open drm device by module name 'starfive'
|
||||
|
||||
Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
|
||||
---
|
||||
src/cam/drm.cpp | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/cam/drm.cpp b/src/cam/drm.cpp
|
||||
index f253009..72c64c9 100644
|
||||
--- a/src/cam/drm.cpp
|
||||
+++ b/src/cam/drm.cpp
|
||||
@@ -393,8 +393,8 @@ Device::~Device()
|
||||
|
||||
int Device::init()
|
||||
{
|
||||
- constexpr size_t NODE_NAME_MAX = sizeof("/dev/dri/card255");
|
||||
- char name[NODE_NAME_MAX];
|
||||
+ //constexpr size_t NODE_NAME_MAX = sizeof("/dev/dri/card255");
|
||||
+ //char name[NODE_NAME_MAX];
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -404,8 +404,10 @@ int Device::init()
|
||||
* from drmOpen() is of no practical use as any modern system will
|
||||
* handle that through udev or an equivalent component.
|
||||
*/
|
||||
- snprintf(name, sizeof(name), "/dev/dri/card%u", 0);
|
||||
- fd_ = open(name, O_RDWR | O_CLOEXEC);
|
||||
+ //snprintf(name, sizeof(name), "/dev/dri/card%u", 0);
|
||||
+ //fd_ = open(name, O_RDWR | O_CLOEXEC);
|
||||
+ const char *name = "starfive";
|
||||
+ fd_ = drmOpen(name, NULL);
|
||||
if (fd_ < 0) {
|
||||
ret = -errno;
|
||||
std::cerr
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -38,12 +38,14 @@ config BR2_PACKAGE_LIBCAMERA_HAS_PIPELINE
|
||||
|
||||
config BR2_PACKAGE_LIBCAMERA_PIPELINE_IPU3
|
||||
bool "ipu3 pipeline"
|
||||
depends on BR2_i386 || BR2_x86_64
|
||||
select BR2_PACKAGE_LIBCAMERA_HAS_PIPELINE
|
||||
help
|
||||
Pipeline for Intel IPU3.
|
||||
|
||||
config BR2_PACKAGE_LIBCAMERA_PIPELINE_RASPBERRYPI
|
||||
bool "raspberrypi pipeline"
|
||||
depends on BR2_arm || BR2_aarch64
|
||||
depends on BR2_USE_WCHAR # boost (already enforced for gnutls)
|
||||
select BR2_PACKAGE_BOOST
|
||||
select BR2_PACKAGE_LIBCAMERA_HAS_PIPELINE
|
||||
@@ -52,6 +54,7 @@ config BR2_PACKAGE_LIBCAMERA_PIPELINE_RASPBERRYPI
|
||||
|
||||
config BR2_PACKAGE_LIBCAMERA_PIPELINE_RKISP1
|
||||
bool "rkisp1 pipeline"
|
||||
depends on BR2_arm || BR2_aarch64
|
||||
select BR2_PACKAGE_LIBCAMERA_HAS_PIPELINE
|
||||
help
|
||||
Pipeline for Rockchip ISP1.
|
||||
@@ -80,6 +83,24 @@ config BR2_PACKAGE_LIBCAMERA_PIPELINE_STARFIVE
|
||||
help
|
||||
Pipeline for the starfive device.
|
||||
|
||||
config BR2_PACKAGE_LIBCAMERA_COMPLIANCE
|
||||
bool "lc-compliance test application"
|
||||
depends on BR2_USE_WCHAR # gtest
|
||||
depends on BR2_TOOLCHAIN_HAS_THREADS # gtest
|
||||
depends on BR2_INSTALL_LIBSTDCPP # gtest
|
||||
depends on BR2_TOOLCHAIN_GCC_AT_LEAST_4_9 # gtest
|
||||
depends on BR2_USE_MMU # gtest
|
||||
select BR2_PACKAGE_GTEST
|
||||
select BR2_PACKAGE_LIBEVENT
|
||||
help
|
||||
lc-compliance test application
|
||||
|
||||
comment "lc-compliance test application needs a toolchain w/ C++, wchar, threads, gcc >= 4.9"
|
||||
depends on BR2_USE_MMU
|
||||
depends on !BR2_USE_WCHAR || !BR2_TOOLCHAIN_HAS_THREADS || \
|
||||
!BR2_INSTALL_LIBSTDCPP || \
|
||||
!BR2_TOOLCHAIN_GCC_AT_LEAST_4_9
|
||||
|
||||
endif # BR2_PACKAGE_LIBCAMERA
|
||||
|
||||
comment "libcamera needs a toolchain w/ C++, threads, wchar, dynamic library, gcc >= 7"
|
||||
|
||||
@@ -1,15 +1,2 @@
|
||||
sha256 a7800b54584dee321874610ef70b1b7690c79d8340c5b134ea35176657681e29 libcamera-e59713c68678f3eb6b6ebe97cabdc88c7042567f.tar.gz
|
||||
sha256 5bca8bc504318da05fd238ca48a2519e71721d3417ff6f014b42146d270281a8 libcamera-06e53199c2563105030bda4c72752b853da7edc8.tar.gz
|
||||
sha256 9369e7cbc138cd31f782325a4361f4163909d09c7475a1f99e938504c191d5f2 libcamera-d6f4abeead1e86d89dc376e8a303849bdb98d5fd.tar.gz
|
||||
sha256 111c99661b1c04bd1f6d0630caf910f36f213ab74a0c1966f0592547d3a86b41 libcamera-d6f4abeead1e86d89dc376e8a303849bdb98d5fd-br1.tar.gz
|
||||
sha256 f66c16878e335012f0ce5ba1cd47296aa69392bf449b90a1098a16723d1d0ac7 libcamera-a10863152a7ca4b98304e345db3c9f9e0034d8f9-br1.tar.gz
|
||||
|
||||
# license files
|
||||
sha256 fd38b2c053c0cce46d9c5ef3545a6e34d157a240ba99c9b8dca5d37a8147da6c LICENSES/BSD-2-Clause.txt
|
||||
sha256 e11af671c491efac2f94c1d752bea92f4308ca2450c7d11e582e4b48c40e4de1 LICENSES/BSD-3-Clause.txt
|
||||
sha256 6a573fb2f9082662978cf21fb153096df0a1981deaea7dbc10a11046fe005d9f LICENSES/CC0-1.0.txt
|
||||
sha256 ec3732087acf8c52429a020d6bba362ff578705bdb53365a21744485ec15b0e6 LICENSES/CC-BY-SA-4.0.txt
|
||||
sha256 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643 LICENSES/GPL-2.0-only.txt
|
||||
sha256 606aa26338f69ce178f1cbc648b7574aec4b5bbaeb20f4df36ff49010cb8fbbd LICENSES/GPL-2.0-or-later.txt
|
||||
sha256 1ccf09bf2f598308df4bed9cd8e9657dc5cd0973d2800318f2e241486e2edf3f LICENSES/LGPL-2.1-or-later.txt
|
||||
sha256 3f9e477523febab58de8b716ccfbcf02e6ef1c8e7728953905e8558637abe2a9 LICENSES/Linux-syscall-note.txt
|
||||
sha256 8f25018489d6fe0dec34a352314c38dc146247b7de65735790f4398a92afa84b LICENSES/MIT.txt
|
||||
|
||||
Regular → Executable
+35
-8
@@ -4,11 +4,10 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
LIBCAMERA_SITE = https://git.linuxtv.org/libcamera.git
|
||||
# LIBCAMERA_VERSION = e59713c68678f3eb6b6ebe97cabdc88c7042567f
|
||||
# LIBCAMERA_VERSION = 06e53199c2563105030bda4c72752b853da7edc8
|
||||
LIBCAMERA_VERSION = d6f4abeead1e86d89dc376e8a303849bdb98d5fd
|
||||
LIBCAMERA_VERSION = a10863152a7ca4b98304e345db3c9f9e0034d8f9
|
||||
LIBCAMERA_SITE = https://github.com/starfive-tech/libcamera
|
||||
LIBCAMERA_SITE_METHOD = git
|
||||
|
||||
LIBCAMERA_DEPENDENCIES = \
|
||||
host-openssl \
|
||||
host-pkgconf \
|
||||
@@ -64,6 +63,13 @@ LIBCAMERA_PIPELINES-$(BR2_PACKAGE_LIBCAMERA_PIPELINE_STARFIVE) += starfive
|
||||
|
||||
LIBCAMERA_CONF_OPTS += -Dpipelines=$(subst $(space),$(comma),$(LIBCAMERA_PIPELINES-y))
|
||||
|
||||
ifeq ($(BR2_PACKAGE_LIBCAMERA_COMPLIANCE),y)
|
||||
LIBCAMERA_DEPENDENCIES += gtest libevent
|
||||
LIBCAMERA_CONF_OPTS += -Dlc-compliance=enabled
|
||||
else
|
||||
LIBCAMERA_CONF_OPTS += -Dlc-compliance=disabled
|
||||
endif
|
||||
|
||||
# gstreamer-video-1.0, gstreamer-allocators-1.0
|
||||
ifeq ($(BR2_PACKAGE_GSTREAMER1)$(BR2_PACKAGE_GST1_PLUGINS_BASE),yy)
|
||||
LIBCAMERA_CONF_OPTS += -Dgstreamer=enabled
|
||||
@@ -96,10 +102,31 @@ ifeq ($(BR2_PACKAGE_LIBCAMERA_PIPELINE_STARFIVE),y)
|
||||
LIBCAMERA_DEPENDENCIES += yaml-cpp
|
||||
endif
|
||||
|
||||
define LIBCAMERA_HOOK_EXTRA
|
||||
mkdir -p $(TARGET_DIR)/etc/starfive
|
||||
$(INSTALL) -D -m 0644 $(@D)/src/libcamera/pipeline/starfive/sensors_pipeline.yaml $(TARGET_DIR)/etc/starfive/sensors_pipeline.yaml
|
||||
|
||||
## replace with the starfive full feature ipa library which is closed source when post build
|
||||
define LIBCAMERA_BUILD_REPLACE_STARFIVE_IPA
|
||||
@echo "LIBCAMERA_POST_BUILD_HOOKS !!!!"
|
||||
$(if $(wildcard $(@D)/starfive_post_script/replace_and_sign_ipa_starfive_lib.sh),
|
||||
$(@D)/starfive_post_script/replace_and_sign_ipa_starfive_lib.sh)
|
||||
endef
|
||||
LIBCAMERA_POST_INSTALL_TARGET_HOOKS = LIBCAMERA_HOOK_EXTRA
|
||||
LIBCAMERA_POST_BUILD_HOOKS += LIBCAMERA_BUILD_REPLACE_STARFIVE_IPA
|
||||
|
||||
|
||||
## replace with the starfive full feature ipa library which is closed source when post install to stage
|
||||
define LIBCAMERA_INSTALL_STAGING_REPLACE_STARFIVE_IPA
|
||||
@echo "LIBCAMERA_POST_INSTALL_STAGING_HOOKS !!!!"
|
||||
$(if $(wildcard $(@D)/starfive_post_script/replace_and_sign_ipa_starfive_lib.sh),
|
||||
$(@D)/starfive_post_script/replace_and_sign_ipa_starfive_lib.sh $(STAGING_DIR)/usr/lib/libcamera)
|
||||
endef
|
||||
LIBCAMERA_POST_INSTALL_STAGING_HOOKS += LIBCAMERA_INSTALL_STAGING_REPLACE_STARFIVE_IPA
|
||||
|
||||
## replace with the starfive full feature ipa library which is closed source when post install to target
|
||||
define LIBCAMERA_TARGET_INSTALL_REPLACE_STARFIVE_IPA
|
||||
@echo "LIBCAMERA_POST_INSTALL_TARGET_HOOKS !!!!"
|
||||
$(if $(wildcard $(@D)/starfive_post_script/replace_and_sign_ipa_starfive_lib.sh),
|
||||
$(@D)/starfive_post_script/replace_and_sign_ipa_starfive_lib.sh $(TARGET_DIR)/usr/lib/libcamera; \
|
||||
$(@D)/starfive_post_script/replace_and_sign_ipa_starfive_lib.sh)
|
||||
endef
|
||||
LIBCAMERA_POST_INSTALL_TARGET_HOOKS += LIBCAMERA_TARGET_INSTALL_REPLACE_STARFIVE_IPA
|
||||
|
||||
$(eval $(meson-package))
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
From 2982813d58c13077c06d1c3c44cd60b0b93d1f4e Mon Sep 17 00:00:00 2001
|
||||
From: "zejian.su" <zejian.su@starfivetech.com>
|
||||
Date: Thu, 12 Oct 2023 11:54:09 +0800
|
||||
Subject: [PATCH 1/4] Make libcamera-hello run normally
|
||||
|
||||
---
|
||||
core/libcamera_app.cpp | 53 ++++++++++++++------------
|
||||
preview/drm_preview.cpp | 84 +++++++++++++++++++++++++++++++++++------
|
||||
2 files changed, 100 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/core/libcamera_app.cpp b/core/libcamera_app.cpp
|
||||
index d3a6b63..cc76e9b 100644
|
||||
--- a/core/libcamera_app.cpp
|
||||
+++ b/core/libcamera_app.cpp
|
||||
@@ -247,23 +247,24 @@ void LibcameraApp::ConfigureViewfinder()
|
||||
if (!configuration_)
|
||||
throw std::runtime_error("failed to generate viewfinder configuration");
|
||||
|
||||
- Size size(1280, 960);
|
||||
- auto area = camera_->properties().get(properties::PixelArrayActiveAreas);
|
||||
+ //Size size(1280, 960);
|
||||
+ Size size = configuration_->at(0).size;
|
||||
+ //auto area = camera_->properties().get(properties::PixelArrayActiveAreas);
|
||||
if (options_->viewfinder_width && options_->viewfinder_height)
|
||||
size = Size(options_->viewfinder_width, options_->viewfinder_height);
|
||||
- else if (area)
|
||||
- {
|
||||
- // The idea here is that most sensors will have a 2x2 binned mode that
|
||||
- // we can pick up. If it doesn't, well, you can always specify the size
|
||||
- // you want exactly with the viewfinder_width/height options_->
|
||||
- size = (*area)[0].size() / 2;
|
||||
- // If width and height were given, we might be switching to capture
|
||||
- // afterwards - so try to match the field of view.
|
||||
- if (options_->width && options_->height)
|
||||
- size = size.boundedToAspectRatio(Size(options_->width, options_->height));
|
||||
- size.alignDownTo(2, 2); // YUV420 will want to be even
|
||||
- LOG(2, "Viewfinder size chosen is " << size.toString());
|
||||
- }
|
||||
+ //else if (area)
|
||||
+ //{
|
||||
+ // // The idea here is that most sensors will have a 2x2 binned mode that
|
||||
+ // // we can pick up. If it doesn't, well, you can always specify the size
|
||||
+ // // you want exactly with the viewfinder_width/height options_->
|
||||
+ // size = (*area)[0].size() / 2;
|
||||
+ // // If width and height were given, we might be switching to capture
|
||||
+ // // afterwards - so try to match the field of view.
|
||||
+ // if (options_->width && options_->height)
|
||||
+ // size = size.boundedToAspectRatio(Size(options_->width, options_->height));
|
||||
+ // size.alignDownTo(2, 2); // YUV420 will want to be even
|
||||
+ // LOG(2, "Viewfinder size chosen is " << size.toString());
|
||||
+ //}
|
||||
|
||||
// Finally trim the image size to the largest that the preview can handle.
|
||||
Size max_size;
|
||||
@@ -275,7 +276,7 @@ void LibcameraApp::ConfigureViewfinder()
|
||||
}
|
||||
|
||||
// Now we get to override any of the default settings from the options_->
|
||||
- configuration_->at(0).pixelFormat = libcamera::formats::YUV420;
|
||||
+ //configuration_->at(0).pixelFormat = libcamera::formats::YUV420;
|
||||
configuration_->at(0).size = size;
|
||||
if (options_->viewfinder_buffer_count > 0)
|
||||
configuration_->at(0).bufferCount = options_->viewfinder_buffer_count;
|
||||
@@ -286,7 +287,7 @@ 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(lores_stream_num).pixelFormat = libcamera::formats::YUV420;
|
||||
+ //configuration_->at(lores_stream_num).pixelFormat = libcamera::formats::YUV420;
|
||||
configuration_->at(lores_stream_num).size = lores_size;
|
||||
configuration_->at(lores_stream_num).bufferCount = configuration_->at(0).bufferCount;
|
||||
}
|
||||
@@ -297,7 +298,7 @@ void LibcameraApp::ConfigureViewfinder()
|
||||
if (have_raw_stream)
|
||||
{
|
||||
configuration_->at(raw_stream_num).size = options_->viewfinder_mode.Size();
|
||||
- configuration_->at(raw_stream_num).pixelFormat = mode_to_pixel_format(options_->viewfinder_mode);
|
||||
+ //configuration_->at(raw_stream_num).pixelFormat = mode_to_pixel_format(options_->viewfinder_mode);
|
||||
configuration_->at(raw_stream_num).bufferCount = configuration_->at(0).bufferCount;
|
||||
}
|
||||
|
||||
@@ -335,8 +336,9 @@ 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 {
|
||||
+ //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)
|
||||
@@ -358,8 +360,8 @@ void LibcameraApp::ConfigureStill(unsigned int flags)
|
||||
configuration_->at(1).pixelFormat = mode_to_pixel_format(options_->mode);
|
||||
}
|
||||
configuration_->at(1).bufferCount = configuration_->at(0).bufferCount;
|
||||
-
|
||||
configureDenoise(options_->denoise == "auto" ? "cdn_hq" : options_->denoise);
|
||||
+
|
||||
setupCapture();
|
||||
|
||||
streams_["still"] = configuration_->at(0).stream();
|
||||
@@ -392,7 +394,7 @@ void LibcameraApp::ConfigureVideo(unsigned int flags)
|
||||
|
||||
// Now we get to override any of the default settings from the options_->
|
||||
StreamConfiguration &cfg = configuration_->at(0);
|
||||
- cfg.pixelFormat = libcamera::formats::YUV420;
|
||||
+ //cfg.pixelFormat = libcamera::formats::YUV420;
|
||||
cfg.bufferCount = 6; // 6 buffers is better than 4
|
||||
if (options_->buffer_count > 0)
|
||||
cfg.bufferCount = options_->buffer_count;
|
||||
@@ -431,7 +433,7 @@ 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;
|
||||
+ //configuration_->at(lores_index).pixelFormat = libcamera::formats::YUV420;
|
||||
configuration_->at(lores_index).size = lores_size;
|
||||
configuration_->at(lores_index).bufferCount = configuration_->at(0).bufferCount;
|
||||
}
|
||||
@@ -959,8 +961,9 @@ 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 &&
|
||||
+ item.stream->configuration().pixelFormat != libcamera::formats::NV12)
|
||||
+ throw std::runtime_error("Preview windows only support YUV420 and NV12");
|
||||
|
||||
StreamInfo info = GetStreamInfo(item.stream);
|
||||
FrameBuffer *buffer = item.completed_request->buffers[item.stream];
|
||||
diff --git a/preview/drm_preview.cpp b/preview/drm_preview.cpp
|
||||
index 4d6cf0d..38fc6a2 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"
|
||||
|
||||
@@ -48,6 +50,7 @@ private:
|
||||
void findPlane();
|
||||
int drmfd_;
|
||||
int conId_;
|
||||
+ drmModeConnector *con_;
|
||||
uint32_t crtcId_;
|
||||
int crtcIdx_;
|
||||
uint32_t planeId_;
|
||||
@@ -93,10 +96,21 @@ void DrmPreview::findCrtc()
|
||||
if (con->encoder_id)
|
||||
{
|
||||
enc = drmModeGetEncoder(drmfd_, con->encoder_id);
|
||||
- if (enc->crtc_id)
|
||||
- {
|
||||
- crtc = drmModeGetCrtc(drmfd_, enc->crtc_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)
|
||||
@@ -158,6 +172,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_);
|
||||
@@ -225,10 +241,13 @@ void DrmPreview::findPlane()
|
||||
|
||||
DrmPreview::DrmPreview(Options const *options) : Preview(options), last_fd_(-1), first_time_(true)
|
||||
{
|
||||
- drmfd_ = drmOpen("vc4", NULL);
|
||||
+ //drmfd_ = drmOpen("vc4", NULL);
|
||||
+ drmfd_ = drmOpen("starfive", NULL);
|
||||
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;
|
||||
@@ -243,7 +262,8 @@ DrmPreview::DrmPreview(Options const *options) : Preview(options), last_fd_(-1),
|
||||
|
||||
conId_ = 0;
|
||||
findCrtc();
|
||||
- out_fourcc_ = DRM_FORMAT_YUV420;
|
||||
+ //out_fourcc_ = DRM_FORMAT_YUV420;
|
||||
+ out_fourcc_ = DRM_FORMAT_NV12;
|
||||
findPlane();
|
||||
}
|
||||
catch (std::exception const &e)
|
||||
@@ -347,6 +367,7 @@ static void setup_colour_space(int fd, int plane_id, std::optional<libcamera::Co
|
||||
|
||||
void DrmPreview::makeBuffer(int fd, size_t size, StreamInfo const &info, Buffer &buffer)
|
||||
{
|
||||
+ unsigned int width = info.width, height = info.height, stride = info.stride;
|
||||
if (first_time_)
|
||||
{
|
||||
first_time_ = false;
|
||||
@@ -361,13 +382,52 @@ void DrmPreview::makeBuffer(int fd, size_t size, StreamInfo const &info, Buffer
|
||||
if (drmPrimeFDToHandle(drmfd_, fd, &buffer.bo_handle))
|
||||
throw std::runtime_error("drmPrimeFDToHandle failed for fd " + std::to_string(fd));
|
||||
|
||||
- uint32_t offsets[4] =
|
||||
- { 0, info.stride * info.height, info.stride * info.height + (info.stride / 2) * (info.height / 2) };
|
||||
- uint32_t pitches[4] = { info.stride, info.stride / 2, info.stride / 2 };
|
||||
- uint32_t bo_handles[4] = { buffer.bo_handle, buffer.bo_handle, buffer.bo_handle };
|
||||
-
|
||||
- if (drmModeAddFB2(drmfd_, info.width, info.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, StreamInfo const &info)
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,489 +0,0 @@
|
||||
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,222 @@
|
||||
From d02d3b3a6c0abdfd8a89ee92447df7d8d48639d5 Mon Sep 17 00:00:00 2001
|
||||
From: "zejian.su" <zejian.su@starfivetech.com>
|
||||
Date: Thu, 12 Oct 2023 11:55:47 +0800
|
||||
Subject: [PATCH 2/4] Make libcamera-jpeg run normally
|
||||
|
||||
---
|
||||
apps/libcamera_jpeg.cpp | 28 +++++----
|
||||
core/CMakeLists.txt | 2 +-
|
||||
core/cvt_color_format.cpp | 119 ++++++++++++++++++++++++++++++++++++++
|
||||
image/jpeg.cpp | 1 +
|
||||
4 files changed, 134 insertions(+), 16 deletions(-)
|
||||
create mode 100755 core/cvt_color_format.cpp
|
||||
|
||||
diff --git a/apps/libcamera_jpeg.cpp b/apps/libcamera_jpeg.cpp
|
||||
index 05a632b..b791960 100644
|
||||
--- a/apps/libcamera_jpeg.cpp
|
||||
+++ b/apps/libcamera_jpeg.cpp
|
||||
@@ -15,6 +15,8 @@
|
||||
using namespace std::placeholders;
|
||||
using libcamera::Stream;
|
||||
|
||||
+void NV12ToYUV420(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &yuv420, StreamInfo &info);
|
||||
+
|
||||
class LibcameraJpegApp : public LibcameraApp
|
||||
{
|
||||
public:
|
||||
@@ -61,10 +63,19 @@ static void event_loop(LibcameraJpegApp &app)
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
if (options->timeout && now - start_time > std::chrono::milliseconds(options->timeout))
|
||||
{
|
||||
+ Stream *stream = app.ViewfinderStream();
|
||||
+ StreamInfo info = app.GetStreamInfo(stream);
|
||||
+ CompletedRequestPtr &payload = std::get<CompletedRequestPtr>(msg.payload);
|
||||
+ const std::vector<libcamera::Span<uint8_t>> mem = app.Mmap(payload->buffers[stream]);
|
||||
+ std::vector<libcamera::Span<uint8_t>> yuv420;
|
||||
+
|
||||
+ NV12ToYUV420(mem[0], yuv420, info);
|
||||
app.StopCamera();
|
||||
app.Teardown();
|
||||
- app.ConfigureStill();
|
||||
- app.StartCamera();
|
||||
+
|
||||
+ jpeg_save(yuv420, info, payload->metadata, options->output, app.CameraModel(), options);
|
||||
+ delete[] yuv420[0].data();
|
||||
+ return;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -72,19 +83,6 @@ static void event_loop(LibcameraJpegApp &app)
|
||||
app.ShowPreview(completed_request, app.ViewfinderStream());
|
||||
}
|
||||
}
|
||||
- // In still capture mode, save a jpeg and quit.
|
||||
- else if (app.StillStream())
|
||||
- {
|
||||
- app.StopCamera();
|
||||
- LOG(1, "Still capture image received");
|
||||
-
|
||||
- Stream *stream = app.StillStream();
|
||||
- StreamInfo info = app.GetStreamInfo(stream);
|
||||
- CompletedRequestPtr &payload = std::get<CompletedRequestPtr>(msg.payload);
|
||||
- const std::vector<libcamera::Span<uint8_t>> mem = app.Mmap(payload->buffers[stream]);
|
||||
- jpeg_save(mem, info, payload->metadata, options->output, app.CameraModel(), options);
|
||||
- return;
|
||||
- }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
|
||||
index b601538..5d9ee30 100644
|
||||
--- a/core/CMakeLists.txt
|
||||
+++ b/core/CMakeLists.txt
|
||||
@@ -7,7 +7,7 @@ find_package(Boost REQUIRED COMPONENTS program_options)
|
||||
add_custom_target(VersionCpp ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR} -P ${CMAKE_CURRENT_LIST_DIR}/version.cmake)
|
||||
set_source_files_properties(version.cpp PROPERTIES GENERATED 1)
|
||||
|
||||
-add_library(libcamera_app libcamera_app.cpp post_processor.cpp version.cpp options.cpp)
|
||||
+add_library(libcamera_app libcamera_app.cpp post_processor.cpp version.cpp options.cpp cvt_color_format.cpp)
|
||||
add_dependencies(libcamera_app VersionCpp)
|
||||
|
||||
set_target_properties(libcamera_app PROPERTIES PREFIX "" IMPORT_PREFIX "" VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR})
|
||||
diff --git a/core/cvt_color_format.cpp b/core/cvt_color_format.cpp
|
||||
new file mode 100755
|
||||
index 0000000..9ff2b6b
|
||||
--- /dev/null
|
||||
+++ b/core/cvt_color_format.cpp
|
||||
@@ -0,0 +1,119 @@
|
||||
+/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
+/*
|
||||
+ * Copyright (C) 2023, Starfive Technology Co., Ltd.
|
||||
+ *
|
||||
+ * cvt_color_format.cpp - convert other format to yuv420.
|
||||
+ */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/types.h>
|
||||
+#include "core/still_options.hpp"
|
||||
+
|
||||
+void NV12ToYUV420(const uint8_t *mem, uint8_t *dst, const StreamInfo &info)
|
||||
+{
|
||||
+ const uint8_t *src = mem;
|
||||
+ uint32_t width = info.width, height = info.height, stride = info.stride;
|
||||
+ uint8_t *u = dst + height * stride;
|
||||
+ uint8_t *v = u + ((height * width) >> 2);
|
||||
+ uint32_t i;
|
||||
+
|
||||
+ memcpy(dst, src, height * stride);
|
||||
+
|
||||
+ src += height * stride;
|
||||
+ for(i = 0; i < (height * width) >> 2; i++, src += 2)
|
||||
+ u[i] = src[0], v[i] = src[1];
|
||||
+}
|
||||
+
|
||||
+void NV12ToYUV420(const libcamera::Span<uint8_t> &mem, uint8_t *dst, const StreamInfo &info)
|
||||
+{
|
||||
+ NV12ToYUV420((const uint8_t *)(mem.data()), dst, info);
|
||||
+/*
|
||||
+ const uint8_t *src = mem.data();
|
||||
+ uint32_t width = info.width, height = info.height, stride = info.stride;
|
||||
+ uint8_t *u = dst + height * stride;
|
||||
+ uint8_t *v = u + ((height * width) >> 2);
|
||||
+ uint32_t i;
|
||||
+
|
||||
+ memcpy(dst, src, height * stride);
|
||||
+
|
||||
+ src += height * stride;
|
||||
+ for(i = 0; i < (height * width) >> 2; i++, src += 2)
|
||||
+ u[i] = src[0], v[i] = src[1];
|
||||
+*/
|
||||
+}
|
||||
+
|
||||
+void NV12ToYUV420(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &yuv420, StreamInfo &info)
|
||||
+{
|
||||
+ uint32_t imgBufSize = info.height * info.stride + ((info.height * info.width) >> 1);
|
||||
+ uint8_t * yuv420Buf = new uint8_t[imgBufSize];
|
||||
+
|
||||
+ if(!yuv420Buf)
|
||||
+ throw std::runtime_error("fail to apply memory");
|
||||
+
|
||||
+ yuv420.push_back(libcamera::Span<uint8_t>(yuv420Buf, imgBufSize));
|
||||
+
|
||||
+ NV12ToYUV420(mem, yuv420Buf, info);
|
||||
+ info.pixel_format = libcamera::formats::YUV420;
|
||||
+}
|
||||
+
|
||||
+template<int R>
|
||||
+void NV12ToRGB888(const libcamera::Span<uint8_t> &mem, uint8_t *dst, const StreamInfo &info)
|
||||
+{
|
||||
+ uint32_t width = info.width, height = info.height, stride = info.stride;
|
||||
+ const uint8_t *yRow = mem.data();
|
||||
+ const uint8_t *uv = yRow + height * stride;
|
||||
+ int ri = R ? 2 : 0;
|
||||
+
|
||||
+ for(uint32_t i = 0; i < height; i++, yRow += stride, dst += 3 * width)
|
||||
+ {
|
||||
+ const uint8_t * curUV = uv;
|
||||
+ uint8_t * curDst = dst;
|
||||
+ for(uint32_t j = 0; j < width; j++, curDst += 3)
|
||||
+ {
|
||||
+ int32_t y = (int32_t)yRow[j] - 16;
|
||||
+ int32_t u = (int32_t)curUV[0] - 128;
|
||||
+ int32_t v = (int32_t)curUV[1] - 128;
|
||||
+ int32_t val;
|
||||
+
|
||||
+ val = (1192 * y + 2066 * u - v) >> 10;
|
||||
+ curDst[ri] = val < 0 ? 0 : (val > 255 ? 255 : (uint8_t)val);
|
||||
+ val = (1192 * y - 401 * u - 833 * v) >> 10;
|
||||
+ curDst[1] = val < 0 ? 0 : (val > 255 ? 255 : (uint8_t)val);
|
||||
+ val = (1192 * y - 2 * u + 1634 * v) >> 10;
|
||||
+ curDst[2 - ri] = val < 0 ? 0 : (val > 255 ? 255 : (uint8_t)val);
|
||||
+
|
||||
+ if(j & 1)
|
||||
+ curUV += 2;
|
||||
+ }
|
||||
+ if(i & 1)
|
||||
+ uv += width;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+template<int R>
|
||||
+void RGB888FromNV12(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &rgb888, StreamInfo &info)
|
||||
+{
|
||||
+ uint32_t imgBufSize = info.height * info.width * 3;
|
||||
+ uint8_t * rgb888Buf = new uint8_t[imgBufSize];
|
||||
+
|
||||
+ if(!rgb888Buf)
|
||||
+ throw std::runtime_error("fail to apply memory");
|
||||
+
|
||||
+ rgb888.push_back(libcamera::Span<uint8_t>(rgb888Buf, imgBufSize));
|
||||
+
|
||||
+ NV12ToRGB888<R>(mem, rgb888Buf, info);
|
||||
+ info.stride = 3 * info.width;
|
||||
+}
|
||||
+
|
||||
+void NV12ToRGB888(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &rgb888, StreamInfo &info)
|
||||
+{
|
||||
+ RGB888FromNV12<0>(mem, rgb888, info);
|
||||
+ info.pixel_format = libcamera::formats::RGB888;
|
||||
+}
|
||||
+
|
||||
+void NV12ToBGR888(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &rgb888, StreamInfo &info)
|
||||
+{
|
||||
+ RGB888FromNV12<2>(mem, rgb888, info);
|
||||
+ info.pixel_format = libcamera::formats::BGR888;
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/image/jpeg.cpp b/image/jpeg.cpp
|
||||
index e3516ef..872f5c6 100644
|
||||
--- a/image/jpeg.cpp
|
||||
+++ b/image/jpeg.cpp
|
||||
@@ -447,6 +447,7 @@ static void create_exif_data(std::vector<libcamera::Span<uint8_t>> const &mem, S
|
||||
exif = exif_data_new();
|
||||
if (!exif)
|
||||
throw std::runtime_error("failed to allocate EXIF data");
|
||||
+
|
||||
exif_data_set_byte_order(exif, exif_byte_order);
|
||||
|
||||
// First add some fixed EXIF tags.
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
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,204 @@
|
||||
From f79f0914c3f8e740cf653da0dd14e5664760188d Mon Sep 17 00:00:00 2001
|
||||
From: "zejian.su" <zejian.su@starfivetech.com>
|
||||
Date: Thu, 12 Oct 2023 11:56:48 +0800
|
||||
Subject: [PATCH 3/4] Make libcamera-still run normally
|
||||
|
||||
---
|
||||
apps/libcamera_still.cpp | 137 +++++++++++++++++++++++++--------------
|
||||
image/dng.cpp | 1 -
|
||||
2 files changed, 88 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/apps/libcamera_still.cpp b/apps/libcamera_still.cpp
|
||||
index 856f1be..bd44818 100644
|
||||
--- a/apps/libcamera_still.cpp
|
||||
+++ b/apps/libcamera_still.cpp
|
||||
@@ -74,22 +74,79 @@ static void update_latest_link(std::string const &filename, StillOptions const *
|
||||
}
|
||||
}
|
||||
|
||||
+void cvtRawData(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &packRaw, StreamInfo &info)
|
||||
+{
|
||||
+ const uint8_t *src = (uint8_t *)mem.data();
|
||||
+ uint32_t width = info.width, height = info.height;
|
||||
+ uint32_t bufSize = (width * height) + ((width * height) >> 1);
|
||||
+ uint8_t * dstBuf = new uint8_t[bufSize];
|
||||
+ uint8_t * dst = dstBuf;
|
||||
+ uint32_t srcStride = ((width * 12 / 8 + 8 * 16 - 1) / (8 * 16)) * 128;
|
||||
+
|
||||
+ if(!dst)
|
||||
+ throw std::runtime_error("fail to apply memory");
|
||||
+
|
||||
+ for(uint32_t i = 0; i < height; i++, src += srcStride, dst += (3 * width) >> 1) {
|
||||
+ const uint8_t *srcRow = src;
|
||||
+ uint8_t * dstRow = dst;
|
||||
+ for(uint32_t j = 0; j < width; j += 2, srcRow += 3, dstRow += 3) {
|
||||
+ dstRow[0] = ((srcRow[1] & 0xf) << 4) | (srcRow[0] >> 4);
|
||||
+ dstRow[1] = srcRow[2];
|
||||
+ dstRow[2] = (srcRow[1] & 0xf0) | (srcRow[0] & 0xf);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ packRaw.push_back(libcamera::Span<uint8_t>(dstBuf, bufSize));
|
||||
+
|
||||
+ if(libcamera::formats::SRGGB12 == info.pixel_format)
|
||||
+ info.pixel_format = libcamera::formats::SRGGB12_CSI2P;
|
||||
+ else if(libcamera::formats::SGRBG12 == info.pixel_format)
|
||||
+ info.pixel_format = libcamera::formats::SGRBG12_CSI2P;
|
||||
+ else if(libcamera::formats::SBGGR12 == info.pixel_format)
|
||||
+ info.pixel_format = libcamera::formats::SBGGR12_CSI2P;
|
||||
+ else if(libcamera::formats::SGBRG12 == info.pixel_format)
|
||||
+ info.pixel_format = libcamera::formats::SGBRG12_CSI2P;
|
||||
+ else
|
||||
+ throw std::runtime_error("unsupported Bayer format");
|
||||
+ info.stride = (3 * width) >> 1;
|
||||
+}
|
||||
+
|
||||
+void NV12ToYUV420(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &yuv420, StreamInfo &info);
|
||||
+void NV12ToRGB888(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &rgb888, StreamInfo &info);
|
||||
+void NV12ToBGR888(const libcamera::Span<uint8_t> &mem, std::vector<libcamera::Span<uint8_t>> &rgb888, StreamInfo &info);
|
||||
+
|
||||
static void save_image(LibcameraStillApp &app, CompletedRequestPtr &payload, Stream *stream,
|
||||
std::string const &filename)
|
||||
{
|
||||
StillOptions const *options = app.GetOptions();
|
||||
StreamInfo info = app.GetStreamInfo(stream);
|
||||
const std::vector<libcamera::Span<uint8_t>> mem = app.Mmap(payload->buffers[stream]);
|
||||
- if (stream == app.RawStream())
|
||||
- dng_save(mem, info, payload->metadata, filename, app.CameraModel(), options);
|
||||
- else if (options->encoding == "jpg")
|
||||
- jpeg_save(mem, info, payload->metadata, filename, app.CameraModel(), options);
|
||||
- else if (options->encoding == "png")
|
||||
- png_save(mem, info, filename, options);
|
||||
- else if (options->encoding == "bmp")
|
||||
- bmp_save(mem, info, filename, options);
|
||||
- else
|
||||
- yuv_save(mem, info, filename, options);
|
||||
+ if (stream == app.RawStream()) {
|
||||
+ std::vector<libcamera::Span<uint8_t>> packRaw;
|
||||
+ cvtRawData(mem[0], packRaw, info);
|
||||
+ dng_save(packRaw, info, payload->metadata, filename, app.CameraModel(), options);
|
||||
+ delete[] packRaw[0].data();
|
||||
+ } else if (options->encoding == "jpg") {
|
||||
+ std::vector<libcamera::Span<uint8_t>> yuv420;
|
||||
+ NV12ToYUV420(mem[0], yuv420, info);
|
||||
+ jpeg_save(yuv420, info, payload->metadata, filename, app.CameraModel(), options);
|
||||
+ delete[] yuv420[0].data();
|
||||
+ } else if (options->encoding == "png") {
|
||||
+ std::vector<libcamera::Span<uint8_t>> rgb888;
|
||||
+ NV12ToBGR888(mem[0], rgb888, info);
|
||||
+ png_save(rgb888, info, filename, options);
|
||||
+ delete[] rgb888[0].data();
|
||||
+ } else if (options->encoding == "bmp") {
|
||||
+ std::vector<libcamera::Span<uint8_t>> rgb888;
|
||||
+ NV12ToRGB888(mem[0], rgb888, info);
|
||||
+ bmp_save(rgb888, info, filename, options);
|
||||
+ delete[] rgb888[0].data();
|
||||
+ } else {
|
||||
+ std::vector<libcamera::Span<uint8_t>> yuv420;
|
||||
+ NV12ToYUV420(mem[0], yuv420, info);
|
||||
+ yuv_save(yuv420, info, filename, options);
|
||||
+ delete[] yuv420[0].data();
|
||||
+ }
|
||||
LOG(2, "Saved image " << info.width << " x " << info.height << " to file " << filename);
|
||||
}
|
||||
|
||||
@@ -193,7 +250,7 @@ static void event_loop(LibcameraStillApp &app)
|
||||
}
|
||||
}
|
||||
else
|
||||
- app.ConfigureViewfinder();
|
||||
+ app.ConfigureStill();
|
||||
app.StartCamera();
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
auto timelapse_time = start_time;
|
||||
@@ -234,7 +291,7 @@ static void event_loop(LibcameraStillApp &app)
|
||||
// In viewfinder mode, run until the timeout or keypress. When that happens,
|
||||
// if the "--autofocus-on-capture" option was set, trigger an AF scan and wait
|
||||
// for it to complete. Then switch to capture mode if an output was requested.
|
||||
- if (app.ViewfinderStream())
|
||||
+ if (app.StillStream())
|
||||
{
|
||||
LOG(2, "Viewfinder frame " << count);
|
||||
timelapse_frames++;
|
||||
@@ -280,47 +337,29 @@ static void event_loop(LibcameraStillApp &app)
|
||||
keypressed = false;
|
||||
af_wait_state = AF_WAIT_NONE;
|
||||
timelapse_time = std::chrono::high_resolution_clock::now();
|
||||
+
|
||||
+ save_images(app, completed_request);
|
||||
+ if (!options->metadata.empty())
|
||||
+ save_metadata(options, completed_request->metadata);
|
||||
+
|
||||
app.StopCamera();
|
||||
app.Teardown();
|
||||
- app.ConfigureStill(still_flags);
|
||||
- if (options->af_on_capture)
|
||||
- {
|
||||
- libcamera::ControlList cl;
|
||||
- cl.set(libcamera::controls::AfMode, libcamera::controls::AfModeAuto);
|
||||
- cl.set(libcamera::controls::AfTrigger, libcamera::controls::AfTriggerCancel);
|
||||
- app.SetControls(cl);
|
||||
- }
|
||||
- app.StartCamera();
|
||||
- }
|
||||
- else
|
||||
- app.ShowPreview(completed_request, app.ViewfinderStream());
|
||||
- }
|
||||
- // In still capture mode, save a jpeg. Go back to viewfinder if in timelapse mode,
|
||||
- // otherwise quit.
|
||||
- else if (app.StillStream())
|
||||
- {
|
||||
- app.StopCamera();
|
||||
- LOG(1, "Still capture image received");
|
||||
- save_images(app, completed_request);
|
||||
- if (!options->metadata.empty())
|
||||
- save_metadata(options, completed_request->metadata);
|
||||
- timelapse_frames = 0;
|
||||
- if (!options->immediate && (options->timelapse || options->signal || options->keypress))
|
||||
- {
|
||||
- app.Teardown();
|
||||
- app.ConfigureViewfinder();
|
||||
- if (options->af_on_capture && options->afMode_index == -1)
|
||||
- {
|
||||
- libcamera::ControlList cl;
|
||||
- cl.set(libcamera::controls::AfMode, libcamera::controls::AfModeAuto);
|
||||
- cl.set(libcamera::controls::AfTrigger, libcamera::controls::AfTriggerCancel);
|
||||
- app.SetControls(cl);
|
||||
- }
|
||||
- app.StartCamera();
|
||||
- af_wait_state = AF_WAIT_NONE;
|
||||
+ if (!options->immediate && (options->timelapse || options->signal || options->keypress)){
|
||||
+ app.ConfigureStill(still_flags);
|
||||
+ if (options->af_on_capture)
|
||||
+ {
|
||||
+ libcamera::ControlList cl;
|
||||
+ cl.set(libcamera::controls::AfMode, libcamera::controls::AfModeAuto);
|
||||
+ cl.set(libcamera::controls::AfTrigger, libcamera::controls::AfTriggerCancel);
|
||||
+ app.SetControls(cl);
|
||||
+ }
|
||||
+ app.StartCamera();
|
||||
+ }
|
||||
+ else
|
||||
+ return;
|
||||
}
|
||||
else
|
||||
- return;
|
||||
+ app.ShowPreview(completed_request, app.StillStream());
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/image/dng.cpp b/image/dng.cpp
|
||||
index fbc02bb..98cb5e7 100644
|
||||
--- a/image/dng.cpp
|
||||
+++ b/image/dng.cpp
|
||||
@@ -151,7 +151,6 @@ void dng_save(std::vector<libcamera::Span<uint8_t>> const &mem, StreamInfo const
|
||||
std::string const &filename, std::string const &cam_model, StillOptions const *options)
|
||||
{
|
||||
// Check the Bayer format and unpack it to u16.
|
||||
-
|
||||
auto it = bayer_formats.find(info.pixel_format);
|
||||
if (it == bayer_formats.end())
|
||||
throw std::runtime_error("unsupported Bayer format");
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,153 +0,0 @@
|
||||
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
|
||||
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
From 5021e32ddc68459c1d96a5ddb8c4225e82023130 Mon Sep 17 00:00:00 2001
|
||||
From: "Kevin.xie" <kevin.xie@starfivetech.com>
|
||||
Date: Thu, 4 Aug 2022 13:55:56 +0800
|
||||
Subject: [PATCH] libcamera-apps: Open drm device by module name 'starfive'
|
||||
|
||||
Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
|
||||
---
|
||||
preview/drm_preview.cpp | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/preview/drm_preview.cpp b/preview/drm_preview.cpp
|
||||
index a969358..df6bfb5 100644
|
||||
--- a/preview/drm_preview.cpp
|
||||
+++ b/preview/drm_preview.cpp
|
||||
@@ -241,8 +241,8 @@ void DrmPreview::findPlane()
|
||||
|
||||
DrmPreview::DrmPreview(Options const *options) : Preview(options), last_fd_(-1)
|
||||
{
|
||||
- // drmfd_ = drmOpen("vc4", NULL);
|
||||
- drmfd_ = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
|
||||
+ drmfd_ = drmOpen("starfive", NULL);
|
||||
+ // drmfd_ = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
|
||||
if (drmfd_ < 0)
|
||||
throw std::runtime_error("drmOpen failed: " + std::string(ERRSTR));
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
sha256 5600c4289457c03a5062001f5942c77fabe4fcef8877b67cfaeed5bae5672756 libcamera-apps-main.tar.gz
|
||||
sha256 3fe6e9e343f268c518652a00260791c55f18cd5902fd5de578005b9c6ec9785b libcamera-apps-87f807f4eacf7d62021e3b4061348e64b2ecadc3.tar.gz
|
||||
sha256 09a169037dfba889bc9f449aaefc18c210fdf4eb7ea02cffd4a36c383b71583c libcamera-apps-87f807f4eacf7d62021e3b4061348e64b2ecadc3-br1.tar.gz
|
||||
sha256 add2d80450f3b61de275c6505689b0984d29c9dde94f0cf381c4209620c96263 libcamera-apps-54a781dffdd101954dcfa6acd0bd80006f67da83-br1.tar.gz
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
################################################################################
|
||||
|
||||
LIBCAMERA_APPS_SITE = https://github.com/raspberrypi/libcamera-apps.git
|
||||
LIBCAMERA_APPS_VERSION = 87f807f4eacf7d62021e3b4061348e64b2ecadc3
|
||||
LIBCAMERA_APPS_VERSION = 54a781dffdd101954dcfa6acd0bd80006f67da83
|
||||
LIBCAMERA_APPS_SITE_METHOD = git
|
||||
LIBCAMERA_APPS_INSTALL_STAGING = YES
|
||||
|
||||
LIBCAMERA_APPS_DEPENDENCIES = libcamera libexif tiff boost host-pkgconf
|
||||
LIBCAMERA_APPS_DEPENDENCIES = libcamera libexif tiff boost host-pkgconf jpeg libpng sf-omx-il
|
||||
|
||||
$(eval $(cmake-package))
|
||||
|
||||
Reference in New Issue
Block a user