diff options
-rw-r--r-- | src/libcamera/pipeline/rkisp1/rkisp1.cpp | 122 | ||||
-rw-r--r-- | src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 94 | ||||
-rw-r--r-- | src/libcamera/pipeline/rkisp1/rkisp1_path.h | 19 |
3 files changed, 119 insertions, 116 deletions
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 857c9330..86a8fd4f 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -20,7 +20,6 @@ #include <libcamera/formats.h> #include <libcamera/ipa/rkisp1.h> #include <libcamera/request.h> -#include <libcamera/span.h> #include <libcamera/stream.h> #include "libcamera/internal/camera_sensor.h" @@ -40,34 +39,6 @@ namespace libcamera { LOG_DEFINE_CATEGORY(RkISP1) -namespace { -constexpr Size RKISP1_RSZ_MP_SRC_MIN{ 32, 16 }; -constexpr Size RKISP1_RSZ_MP_SRC_MAX{ 4416, 3312 }; -constexpr std::array<PixelFormat, 7> RKISP1_RSZ_MP_FORMATS{ - formats::YUYV, - formats::YVYU, - formats::VYUY, - formats::NV16, - formats::NV61, - formats::NV21, - formats::NV12, - /* \todo Add support for 8-bit greyscale to DRM formats */ -}; - -constexpr Size RKISP1_RSZ_SP_SRC_MIN{ 32, 16 }; -constexpr Size RKISP1_RSZ_SP_SRC_MAX{ 1920, 1920 }; -constexpr std::array<PixelFormat, 7> RKISP1_RSZ_SP_FORMATS{ - formats::YUYV, - formats::YVYU, - formats::VYUY, - formats::NV16, - formats::NV61, - formats::NV21, - formats::NV12, - /* \todo Add support for BGR888 and RGB565 */ -}; -} /* namespace */ - class PipelineHandlerRkISP1; class RkISP1ActionQueueBuffers; class RkISP1CameraData; @@ -194,14 +165,6 @@ public: const V4L2SubdeviceFormat &sensorFormat() { return sensorFormat_; } private: - static constexpr unsigned int RKISP1_BUFFER_COUNT = 4; - - CameraConfiguration::Status validatePath(StreamConfiguration *cfg, - const Span<const PixelFormat> &formats, - const Size &min, const Size &max, - V4L2VideoDevice *video); - CameraConfiguration::Status validateMainPath(StreamConfiguration *cfg); - CameraConfiguration::Status validateSelfPath(StreamConfiguration *cfg); bool fitsAllPaths(const StreamConfiguration &cfg); /* @@ -514,64 +477,16 @@ RkISP1CameraConfiguration::RkISP1CameraConfiguration(Camera *camera, data_ = data; } -CameraConfiguration::Status RkISP1CameraConfiguration::validatePath( - StreamConfiguration *cfg, const Span<const PixelFormat> &formats, - const Size &min, const Size &max, V4L2VideoDevice *video) -{ - const StreamConfiguration reqCfg = *cfg; - Status status = Valid; - - if (std::find(formats.begin(), formats.end(), cfg->pixelFormat) == - formats.end()) - cfg->pixelFormat = formats::NV12; - - cfg->size.boundTo(max); - cfg->size.expandTo(min); - cfg->bufferCount = RKISP1_BUFFER_COUNT; - - V4L2DeviceFormat format = {}; - format.fourcc = video->toV4L2PixelFormat(cfg->pixelFormat); - format.size = cfg->size; - - int ret = video->tryFormat(&format); - if (ret) - return Invalid; - - cfg->stride = format.planes[0].bpl; - cfg->frameSize = format.planes[0].size; - - if (cfg->pixelFormat != reqCfg.pixelFormat || cfg->size != reqCfg.size) { - LOG(RkISP1, Debug) - << "Adjusting format from " << reqCfg.toString() - << " to " << cfg->toString(); - status = Adjusted; - } - - return status; -} - -CameraConfiguration::Status RkISP1CameraConfiguration::validateMainPath(StreamConfiguration *cfg) -{ - return validatePath(cfg, RKISP1_RSZ_MP_FORMATS, RKISP1_RSZ_MP_SRC_MIN, - RKISP1_RSZ_MP_SRC_MAX, data_->mainPath_->video_); -} - -CameraConfiguration::Status RkISP1CameraConfiguration::validateSelfPath(StreamConfiguration *cfg) -{ - return validatePath(cfg, RKISP1_RSZ_SP_FORMATS, RKISP1_RSZ_SP_SRC_MIN, - RKISP1_RSZ_SP_SRC_MAX, data_->selfPath_->video_); -} - bool RkISP1CameraConfiguration::fitsAllPaths(const StreamConfiguration &cfg) { StreamConfiguration config; config = cfg; - if (validateMainPath(&config) != Valid) + if (data_->mainPath_->validate(&config) != Valid) return false; config = cfg; - if (validateSelfPath(&config) != Valid) + if (data_->selfPath_->validate(&config) != Valid) return false; return true; @@ -616,7 +531,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() /* Try to match stream without adjusting configuration. */ if (mainPathAvailable) { StreamConfiguration tryCfg = cfg; - if (validateMainPath(&tryCfg) == Valid) { + if (data_->mainPath_->validate(&tryCfg) == Valid) { mainPathAvailable = false; cfg = tryCfg; cfg.setStream(const_cast<Stream *>(&data_->mainPathStream_)); @@ -626,7 +541,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() if (selfPathAvailable) { StreamConfiguration tryCfg = cfg; - if (validateSelfPath(&tryCfg) == Valid) { + if (data_->selfPath_->validate(&tryCfg) == Valid) { selfPathAvailable = false; cfg = tryCfg; cfg.setStream(const_cast<Stream *>(&data_->selfPathStream_)); @@ -637,7 +552,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() /* Try to match stream allowing adjusting configuration. */ if (mainPathAvailable) { StreamConfiguration tryCfg = cfg; - if (validateMainPath(&tryCfg) == Adjusted) { + if (data_->mainPath_->validate(&tryCfg) == Adjusted) { mainPathAvailable = false; cfg = tryCfg; cfg.setStream(const_cast<Stream *>(&data_->mainPathStream_)); @@ -648,7 +563,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() if (selfPathAvailable) { StreamConfiguration tryCfg = cfg; - if (validateSelfPath(&tryCfg) == Adjusted) { + if (data_->selfPath_->validate(&tryCfg) == Adjusted) { selfPathAvailable = false; cfg = tryCfg; cfg.setStream(const_cast<Stream *>(&data_->selfPathStream_)); @@ -734,32 +649,17 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera return nullptr; } - std::map<PixelFormat, std::vector<SizeRange>> streamFormats; - Size maxResolution = data->sensor_->resolution(); + StreamConfiguration cfg; if (useMainPath) { + cfg = data->mainPath_->generateConfiguration( + data->sensor_->resolution()); mainPathAvailable = false; - maxResolution.boundTo(RKISP1_RSZ_MP_SRC_MAX); - for (const PixelFormat &format : RKISP1_RSZ_MP_FORMATS) - streamFormats[format] = { { - RKISP1_RSZ_MP_SRC_MIN, - maxResolution, - } }; } else { + cfg = data->selfPath_->generateConfiguration( + data->sensor_->resolution()); selfPathAvailable = false; - maxResolution.boundTo(RKISP1_RSZ_SP_SRC_MAX); - for (const PixelFormat &format : RKISP1_RSZ_SP_FORMATS) - streamFormats[format] = { { - RKISP1_RSZ_SP_SRC_MIN, - maxResolution, - } }; } - StreamFormats formats(streamFormats); - StreamConfiguration cfg(formats); - cfg.pixelFormat = formats::NV12; - cfg.size = maxResolution; - cfg.bufferCount = 4; - config->addConfiguration(cfg); } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index 66b5eebd..96c18b35 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -7,6 +7,7 @@ #include "rkisp1_path.h" +#include <libcamera/formats.h> #include <libcamera/stream.h> #include "libcamera/internal/media_device.h" @@ -17,8 +18,11 @@ namespace libcamera { LOG_DECLARE_CATEGORY(RkISP1) -RkISP1Path::RkISP1Path(const char *name) - : video_(nullptr), name_(name), resizer_(nullptr) +RkISP1Path::RkISP1Path(const char *name, const Span<const PixelFormat> &formats, + const Size &minResolution, const Size &maxResolution) + : video_(nullptr), name_(name), formats_(formats), + minResolution_(minResolution), maxResolution_(maxResolution), + resizer_(nullptr) { } @@ -44,6 +48,58 @@ bool RkISP1Path::init(MediaDevice *media) return true; } +StreamConfiguration RkISP1Path::generateConfiguration(const Size &resolution) +{ + Size maxResolution = resolution; + maxResolution.boundTo(maxResolution_); + + std::map<PixelFormat, std::vector<SizeRange>> streamFormats; + for (const PixelFormat &format : formats_) + streamFormats[format] = { { minResolution_, maxResolution } }; + + StreamFormats formats(streamFormats); + StreamConfiguration cfg(formats); + cfg.pixelFormat = formats::NV12; + cfg.size = maxResolution; + cfg.bufferCount = RKISP1_BUFFER_COUNT; + + return cfg; +} + +CameraConfiguration::Status RkISP1Path::validate(StreamConfiguration *cfg) +{ + const StreamConfiguration reqCfg = *cfg; + CameraConfiguration::Status status = CameraConfiguration::Valid; + + if (std::find(formats_.begin(), formats_.end(), cfg->pixelFormat) == + formats_.end()) + cfg->pixelFormat = formats::NV12; + + cfg->size.boundTo(maxResolution_); + cfg->size.expandTo(minResolution_); + cfg->bufferCount = RKISP1_BUFFER_COUNT; + + V4L2DeviceFormat format = {}; + format.fourcc = video_->toV4L2PixelFormat(cfg->pixelFormat); + format.size = cfg->size; + + int ret = video_->tryFormat(&format); + if (ret) + return CameraConfiguration::Invalid; + + cfg->stride = format.planes[0].bpl; + cfg->frameSize = format.planes[0].size; + + if (cfg->pixelFormat != reqCfg.pixelFormat || cfg->size != reqCfg.size) { + LOG(RkISP1, Debug) + << "Adjusting format from " << reqCfg.toString() + << " to " << cfg->toString(); + status = CameraConfiguration::Adjusted; + } + + return status; +} + int RkISP1Path::configure(const StreamConfiguration &config, const V4L2SubdeviceFormat &inputFormat) { @@ -93,13 +149,43 @@ int RkISP1Path::configure(const StreamConfiguration &config, return 0; } +namespace { +constexpr Size RKISP1_RSZ_MP_SRC_MIN{ 32, 16 }; +constexpr Size RKISP1_RSZ_MP_SRC_MAX{ 4416, 3312 }; +constexpr std::array<PixelFormat, 7> RKISP1_RSZ_MP_FORMATS{ + formats::YUYV, + formats::YVYU, + formats::VYUY, + formats::NV16, + formats::NV61, + formats::NV21, + formats::NV12, + /* \todo Add support for 8-bit greyscale to DRM formats */ +}; + +constexpr Size RKISP1_RSZ_SP_SRC_MIN{ 32, 16 }; +constexpr Size RKISP1_RSZ_SP_SRC_MAX{ 1920, 1920 }; +constexpr std::array<PixelFormat, 7> RKISP1_RSZ_SP_FORMATS{ + formats::YUYV, + formats::YVYU, + formats::VYUY, + formats::NV16, + formats::NV61, + formats::NV21, + formats::NV12, + /* \todo Add support for BGR888 and RGB565 */ +}; +} /* namespace */ + RkISP1MainPath::RkISP1MainPath() - : RkISP1Path("main") + : RkISP1Path("main", RKISP1_RSZ_MP_FORMATS, + RKISP1_RSZ_MP_SRC_MIN, RKISP1_RSZ_MP_SRC_MAX) { } RkISP1SelfPath::RkISP1SelfPath() - : RkISP1Path("self") + : RkISP1Path("self", RKISP1_RSZ_SP_FORMATS, + RKISP1_RSZ_SP_SRC_MIN, RKISP1_RSZ_SP_SRC_MAX) { } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h index 6eb01529..7433ad03 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h @@ -7,6 +7,13 @@ #ifndef __LIBCAMERA_PIPELINE_RKISP1_PATH_H__ #define __LIBCAMERA_PIPELINE_RKISP1_PATH_H__ +#include <vector> + +#include <libcamera/camera.h> +#include <libcamera/geometry.h> +#include <libcamera/pixel_format.h> +#include <libcamera/span.h> + namespace libcamera { class MediaDevice; @@ -18,11 +25,15 @@ struct V4L2SubdeviceFormat; class RkISP1Path { public: - RkISP1Path(const char *name); + RkISP1Path(const char *name, const Span<const PixelFormat> &formats, + const Size &minResolution, const Size &maxResolution); ~RkISP1Path(); bool init(MediaDevice *media); + StreamConfiguration generateConfiguration(const Size &resolution); + CameraConfiguration::Status validate(StreamConfiguration *cfg); + int configure(const StreamConfiguration &config, const V4L2SubdeviceFormat &inputFormat); @@ -30,8 +41,14 @@ public: V4L2VideoDevice *video_; private: + static constexpr unsigned int RKISP1_BUFFER_COUNT = 4; + const char *name_; + const Span<const PixelFormat> formats_; + const Size minResolution_; + const Size maxResolution_; + V4L2Subdevice *resizer_; }; |