|
@@ -0,0 +1,253 @@
|
|
|
+From d93fba5044e5688df377b8f1087d22b0357c36ba Mon Sep 17 00:00:00 2001
|
|
|
+From: chenhb3487 <chenhb3487@thundersoft.com>
|
|
|
+Date: Tue, 11 Jan 2022 10:24:26 +0800
|
|
|
+Subject: [PATCH] libcamera: add framerate for request pad src.
|
|
|
+
|
|
|
+---
|
|
|
+ .../0010-add-framerate-from-v4l2.patch | 234 ++++++++++++++++++
|
|
|
+ 1 file changed, 234 insertions(+)
|
|
|
+ create mode 100644 package/libcamera/0010-add-framerate-from-v4l2.patch
|
|
|
+
|
|
|
+diff --git a/package/libcamera/0010-add-framerate-from-v4l2.patch b/package/libcamera/0010-add-framerate-from-v4l2.patch
|
|
|
+new file mode 100644
|
|
|
+index 00000000..b2a558aa
|
|
|
+--- /dev/null
|
|
|
++++ b/package/libcamera/0010-add-framerate-from-v4l2.patch
|
|
|
+@@ -0,0 +1,234 @@
|
|
|
++diff -Naur a/include/libcamera/internal/v4l2_videodevice.h libcamera-d6f4abeead1e86d89dc376e8a303849bdb98d5fd/include/libcamera/internal/v4l2_videodevice.h
|
|
|
++--- a/include/libcamera/internal/v4l2_videodevice.h 2022-01-10 22:03:08.131869823 +0800
|
|
|
+++++ b/include/libcamera/internal/v4l2_videodevice.h 2022-01-11 10:12:46.551963256 +0800
|
|
|
++@@ -35,6 +35,11 @@
|
|
|
++ 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 @@
|
|
|
++
|
|
|
++ 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 -Naur a/include/libcamera/stream.h b/include/libcamera/stream.h
|
|
|
++--- a/include/libcamera/stream.h 2022-01-10 22:03:08.131869823 +0800
|
|
|
+++++ b/include/libcamera/stream.h 2022-01-11 10:12:56.020027708 +0800
|
|
|
++@@ -36,6 +36,11 @@
|
|
|
++ 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,15 @@
|
|
|
++ 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 -Naur a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
|
|
|
++--- a/src/gstreamer/gstlibcamera-utils.cpp 2022-01-10 22:03:08.135869864 +0800
|
|
|
+++++ b/src/gstreamer/gstlibcamera-utils.cpp 2022-01-11 10:13:11.952135908 +0800
|
|
|
++@@ -140,10 +140,18 @@
|
|
|
++ "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 -Naur a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
|
|
|
++--- a/src/libcamera/pipeline/starfive/starfive.cpp 2022-01-10 22:03:08.139869906 +0800
|
|
|
+++++ b/src/libcamera/pipeline/starfive/starfive.cpp 2022-01-11 10:13:31.200266219 +0800
|
|
|
++@@ -44,6 +44,9 @@
|
|
|
++
|
|
|
++ #define PIPELINE_CONFIG_FILENAME "/root/sensors_pipeline.yaml"
|
|
|
++
|
|
|
+++#define DEFAULT_FRAMERATE_NUM 25;
|
|
|
+++#define DEFAULT_FRAMERATE_DENOM 1;
|
|
|
+++
|
|
|
++ namespace {
|
|
|
++
|
|
|
++ typedef enum {
|
|
|
++@@ -226,6 +229,8 @@
|
|
|
++ 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);
|
|
|
++
|
|
|
++@@ -270,6 +275,24 @@
|
|
|
++ 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_)
|
|
|
++@@ -481,6 +504,20 @@
|
|
|
++ 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 -Naur a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
|
|
|
++--- a/src/libcamera/v4l2_videodevice.cpp 2022-01-10 22:03:08.135869864 +0800
|
|
|
+++++ b/src/libcamera/v4l2_videodevice.cpp 2022-01-11 10:13:42.444342141 +0800
|
|
|
++@@ -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 @@
|
|
|
++ 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
|
|
|
+
|