|
@@ -1,253 +1,254 @@
|
|
|
-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.
|
|
|
+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.
|
|
|
|
|
|
---
|
|
|
- .../0010-add-framerate-from-v4l2.patch | 234 ++++++++++++++++++
|
|
|
- 1 file changed, 234 insertions(+)
|
|
|
- create mode 100644 package/libcamera/0010-add-framerate-from-v4l2.patch
|
|
|
+ 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/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 "/etc/starfive/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
|
|
|
+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
|
|
|
|