0010-libcamera-add-framerate-for-request-pad-src.patch 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. From 4d84bab2e88580bb96a24343051f2ea8132dc4e3 Mon Sep 17 00:00:00 2001
  2. From: sw.multimedia <sw.multimedia@starfivetech.com>
  3. Date: Thu, 13 Jan 2022 14:44:18 +0800
  4. Subject: [PATCH 10/10] libcamera: add framerate for request pad src.
  5. ---
  6. include/libcamera/internal/v4l2_videodevice.h | 7 +-
  7. include/libcamera/stream.h | 8 +++
  8. src/gstreamer/gstlibcamera-utils.cpp | 16 +++--
  9. src/libcamera/pipeline/starfive/starfive.cpp | 37 ++++++++++
  10. src/libcamera/v4l2_videodevice.cpp | 68 +++++++++++++++++++
  11. 5 files changed, 131 insertions(+), 5 deletions(-)
  12. diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h
  13. index a1c458e4..650da22d 100644
  14. --- a/include/libcamera/internal/v4l2_videodevice.h
  15. +++ b/include/libcamera/internal/v4l2_videodevice.h
  16. @@ -35,6 +35,11 @@ class FileDescriptor;
  17. class MediaDevice;
  18. class MediaEntity;
  19. +struct V4L2Framerate {
  20. + uint32_t num = 0;
  21. + uint32_t denom = 0;
  22. +};
  23. +
  24. struct V4L2Capability final : v4l2_capability {
  25. const char *driver() const
  26. {
  27. @@ -215,7 +220,7 @@ public:
  28. static std::unique_ptr<V4L2VideoDevice>
  29. fromEntityName(const MediaDevice *media, const std::string &entity);
  30. -
  31. + std::vector<V4L2Framerate> getFramerates(uint32_t pixelformat, uint32_t width, uint32_t height);
  32. protected:
  33. std::string logPrefix() const override;
  34. diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h
  35. index 0c55e716..2e06d7d8 100644
  36. --- a/include/libcamera/stream.h
  37. +++ b/include/libcamera/stream.h
  38. @@ -36,6 +36,11 @@ private:
  39. std::map<PixelFormat, std::vector<SizeRange>> formats_;
  40. };
  41. +struct Framerate {
  42. + uint32_t num = 0;
  43. + uint32_t denom = 0;
  44. +};
  45. +
  46. struct StreamConfiguration {
  47. StreamConfiguration();
  48. StreamConfiguration(const StreamFormats &formats);
  49. @@ -51,11 +56,14 @@ struct StreamConfiguration {
  50. void setStream(Stream *stream) { stream_ = stream; }
  51. const StreamFormats &formats() const { return formats_; }
  52. + void setframeRates(std::vector<Framerate> framerates) { rates = framerates; }
  53. + const std::vector<Framerate> getframeRates() const { return rates; }
  54. std::string toString() const;
  55. private:
  56. Stream *stream_;
  57. StreamFormats formats_;
  58. + std::vector<Framerate> rates;
  59. };
  60. enum StreamRole {
  61. diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
  62. index bce4960a..4cd07508 100644
  63. --- a/src/gstreamer/gstlibcamera-utils.cpp
  64. +++ b/src/gstreamer/gstlibcamera-utils.cpp
  65. @@ -140,10 +140,18 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg
  66. "height", G_TYPE_INT, stream_cfg.size.height,
  67. nullptr);
  68. - // Add framerate negotiation support
  69. - // the range will be [ 0/1, 2147483647/1 ] as there is not any args
  70. - // required from driver for the time being.
  71. - gst_structure_set(s, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
  72. + std::vector<libcamera::Framerate> rates = stream_cfg.getframeRates();
  73. + guint index = 0;
  74. + for (libcamera::Framerate it : rates) {
  75. + libcamera::Framerate rate = it;
  76. + gst_structure_set (s, "framerate", GST_TYPE_FRACTION, rate.denom, rate.num, NULL);
  77. + //truncate rates. only remain the first one.
  78. + if ( index == 0)
  79. + {
  80. + break;
  81. + }
  82. + index++;
  83. + }
  84. gst_caps_append_structure(caps, s);
  85. diff --git a/src/libcamera/pipeline/starfive/starfive.cpp b/src/libcamera/pipeline/starfive/starfive.cpp
  86. index 61a2ddc6..997d9835 100644
  87. --- a/src/libcamera/pipeline/starfive/starfive.cpp
  88. +++ b/src/libcamera/pipeline/starfive/starfive.cpp
  89. @@ -43,6 +43,9 @@
  90. #define PIPELINE_CONFIG_FILENAME "/etc/starfive/sensors_pipeline.yaml"
  91. +#define DEFAULT_FRAMERATE_NUM 25;
  92. +#define DEFAULT_FRAMERATE_DENOM 1;
  93. +
  94. namespace {
  95. typedef enum {
  96. @@ -225,6 +228,8 @@ public:
  97. std::vector<SizeRange> sensorSizes() const;
  98. std::vector<PixelFormat> sensorFormats() const;
  99. std::vector<PixelFormat> videoFormats() const;
  100. + std::vector<Framerate> videoFrameRates(unsigned int pixelformat, unsigned int width, unsigned int height) const;
  101. +
  102. void paramsFilled(unsigned int id){}
  103. int ispLoadFW(const char *filename);
  104. @@ -269,6 +274,24 @@ std::vector<PixelFormat> StarFiveCameraData::videoFormats() const
  105. return formats;
  106. }
  107. +std::vector<Framerate> StarFiveCameraData::videoFrameRates(unsigned int pixelformat, unsigned int width, unsigned int height) const
  108. +{
  109. + if (!video_)
  110. + return {};
  111. +
  112. + std::vector<Framerate> framerates;
  113. + for (auto it : video_->getFramerates(pixelformat, width, height)) {
  114. + V4L2Framerate v4l2_framerate = (V4L2Framerate)it;
  115. + libcamera::Framerate rate;
  116. + rate.num = v4l2_framerate.num;
  117. + rate.denom = v4l2_framerate.denom;
  118. + LOG(STARFIVE, Debug) << "videoFrameRates framerate: rate.num=" << rate.num << " rate.denom= " << rate.denom;
  119. + framerates.push_back(rate);
  120. + }
  121. +
  122. + return framerates;
  123. +}
  124. +
  125. std::vector<PixelFormat> StarFiveCameraData::sensorFormats() const
  126. {
  127. if (!sensor_)
  128. @@ -480,6 +503,20 @@ CameraConfiguration::Status StarFiveCameraConfiguration::validate()
  129. cfg.size.height = std::max(OUTPUT_MIN_SIZE.height,
  130. std::min(OUTPUT_MAX_SIZE.height, cfg.size.height));
  131. + std::vector<Framerate> rates;
  132. + rates = data_->videoFrameRates(cfg.pixelFormat,size.width, size.height);
  133. + if (rates.size() > 0){
  134. + cfg.setframeRates(rates);
  135. + } else {
  136. + LOG(STARFIVE, Debug)
  137. + << "fail to obtian framerate, use default one ";
  138. + Framerate rate;
  139. + rate.num = DEFAULT_FRAMERATE_NUM;
  140. + rate.denom = DEFAULT_FRAMERATE_DENOM;
  141. + rates.emplace_back(rate);
  142. + cfg.setframeRates(rates);
  143. + }
  144. +
  145. if (cfg.size != size) {
  146. LOG(STARFIVE, Debug)
  147. << "Adjusting size to " << cfg.size.toString();
  148. diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
  149. index 4f04212d..5ccf70d9 100644
  150. --- a/src/libcamera/v4l2_videodevice.cpp
  151. +++ b/src/libcamera/v4l2_videodevice.cpp
  152. @@ -31,6 +31,7 @@
  153. #include "libcamera/internal/framebuffer.h"
  154. #include "libcamera/internal/media_device.h"
  155. #include "libcamera/internal/media_object.h"
  156. +#include <limits.h>
  157. /**
  158. * \file v4l2_videodevice.h
  159. @@ -1847,6 +1848,73 @@ V4L2VideoDevice::fromEntityName(const MediaDevice *media,
  160. return std::make_unique<V4L2VideoDevice>(mediaEntity);
  161. }
  162. +std::vector<V4L2Framerate> V4L2VideoDevice::getFramerates(uint32_t pixelformat, uint32_t width, uint32_t height)
  163. +{
  164. + struct v4l2_frmivalenum ival;
  165. + uint32_t num, denom;
  166. +
  167. + memset (&ival, 0, sizeof (struct v4l2_frmivalenum));
  168. + ival.index = 0;
  169. + ival.pixel_format = pixelformat;
  170. + ival.width = width;
  171. + ival.height = height;
  172. + std::vector<V4L2Framerate> rates;
  173. + LOG(V4L2, Debug) << "getFramerates: width: " << width << " height: " << height << " pixelformat " << pixelformat;
  174. +
  175. + if (ioctl (VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0){
  176. + LOG(V4L2, Error) << "fail to ioctl: VIDIOC_ENUM_FRAMEINTERVALS";
  177. + goto enum_frameintervals_failed;
  178. + }
  179. +
  180. + if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
  181. + struct V4L2Framerate rate;
  182. + do {
  183. + num = ival.discrete.numerator;
  184. + denom = ival.discrete.denominator;
  185. +
  186. + if (num > INT_MAX || denom > INT_MAX) {
  187. + /* let us hope we don't get here... */
  188. + LOG(V4L2, Error) << "num or denom is beyond INT_MAX";
  189. + goto enum_frameintervals_failed;
  190. + }
  191. +
  192. + // /* swap to get the framerate */
  193. + // gst_value_set_fraction (&rate, denom, num);
  194. + rate.denom = denom;
  195. + rate.num = num;
  196. + LOG(V4L2, Debug) << "gstFramerates adding discrete framerate: " << denom << "/" << num;
  197. + rates.emplace_back(rate);
  198. + ival.index++;
  199. + } while (ioctl (VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0);
  200. + } else if (ival.type == V4L2_FRMIVAL_TYPE_STEPWISE){
  201. + //TODO
  202. + goto enum_frameintervals_unimplemented;
  203. + } else if (ival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
  204. + num = ival.stepwise.min.numerator;
  205. + denom = ival.stepwise.min.denominator;
  206. + if (num > INT_MAX || denom > INT_MAX) {
  207. + LOG(V4L2, Error) << "continuous frame interval: num or denom is beyond INT_MAX";
  208. + goto enum_frameintervals_failed;
  209. + }
  210. +
  211. + struct V4L2Framerate rate;
  212. + rate.denom = denom;
  213. + rate.num = num;
  214. + LOG(V4L2, Debug) << "gstFramerates continuous frame interval: " << denom << "/" <<num;
  215. + rates.emplace_back(rate);
  216. + }
  217. +
  218. + return rates;
  219. +
  220. +enum_frameintervals_failed:
  221. +enum_frameintervals_unimplemented:
  222. +{
  223. + LOG(V4L2, Error) << "fail to obtain framerate !!!";
  224. + return rates;
  225. +}
  226. +
  227. +}
  228. +
  229. /**
  230. * \class V4L2M2MDevice
  231. * \brief Memory-to-Memory video device
  232. --
  233. 2.25.1