libcamera: v4l2_videodevice: Add V4L2PixelFormat class
The V4L2PixelFormat class describes the pixel format of a V4L2 buffer. It wraps the V4L2 numerical FourCC, and shall be used in all APIs that deal with V4L2 pixel formats. Its purpose is to prevent unintentional confusion of V4L2 and DRM FourCCs in code by catching implicit conversion attempts at compile time. The constructor taking a V4L2 FourCC integer value will be made explicit in a further commit to minimize the size of this change and keep it reviewable. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
parent
92c7b1cc1d
commit
a7f24a8d9a
3 changed files with 109 additions and 25 deletions
|
@ -149,10 +149,33 @@ private:
|
||||||
unsigned int missCounter_;
|
unsigned int missCounter_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class V4L2PixelFormat
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
V4L2PixelFormat()
|
||||||
|
: fourcc_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
V4L2PixelFormat(uint32_t fourcc)
|
||||||
|
: fourcc_(fourcc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValid() const { return fourcc_ != 0; }
|
||||||
|
uint32_t fourcc() const { return fourcc_; }
|
||||||
|
operator uint32_t() const { return fourcc_; }
|
||||||
|
|
||||||
|
std::string toString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t fourcc_;
|
||||||
|
};
|
||||||
|
|
||||||
class V4L2DeviceFormat
|
class V4L2DeviceFormat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint32_t fourcc;
|
V4L2PixelFormat fourcc;
|
||||||
Size size;
|
Size size;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -184,7 +207,7 @@ public:
|
||||||
|
|
||||||
int getFormat(V4L2DeviceFormat *format);
|
int getFormat(V4L2DeviceFormat *format);
|
||||||
int setFormat(V4L2DeviceFormat *format);
|
int setFormat(V4L2DeviceFormat *format);
|
||||||
ImageFormats formats();
|
std::map<V4L2PixelFormat, std::vector<SizeRange>> formats();
|
||||||
|
|
||||||
int setCrop(Rectangle *rect);
|
int setCrop(Rectangle *rect);
|
||||||
int setCompose(Rectangle *rect);
|
int setCompose(Rectangle *rect);
|
||||||
|
@ -205,10 +228,10 @@ public:
|
||||||
static V4L2VideoDevice *fromEntityName(const MediaDevice *media,
|
static V4L2VideoDevice *fromEntityName(const MediaDevice *media,
|
||||||
const std::string &entity);
|
const std::string &entity);
|
||||||
|
|
||||||
static PixelFormat toPixelFormat(uint32_t v4l2Fourcc);
|
static PixelFormat toPixelFormat(V4L2PixelFormat v4l2Fourcc);
|
||||||
uint32_t toV4L2Fourcc(const PixelFormat &pixelFormat);
|
V4L2PixelFormat toV4L2Fourcc(const PixelFormat &pixelFormat);
|
||||||
static uint32_t toV4L2Fourcc(const PixelFormat &pixelFormat,
|
static V4L2PixelFormat toV4L2Fourcc(const PixelFormat &pixelFormat,
|
||||||
bool multiplanar);
|
bool multiplanar);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string logPrefix() const;
|
std::string logPrefix() const;
|
||||||
|
@ -223,8 +246,8 @@ private:
|
||||||
int getFormatSingleplane(V4L2DeviceFormat *format);
|
int getFormatSingleplane(V4L2DeviceFormat *format);
|
||||||
int setFormatSingleplane(V4L2DeviceFormat *format);
|
int setFormatSingleplane(V4L2DeviceFormat *format);
|
||||||
|
|
||||||
std::vector<unsigned int> enumPixelformats();
|
std::vector<V4L2PixelFormat> enumPixelformats();
|
||||||
std::vector<SizeRange> enumSizes(unsigned int pixelFormat);
|
std::vector<SizeRange> enumSizes(V4L2PixelFormat pixelFormat);
|
||||||
|
|
||||||
int setSelection(unsigned int target, Rectangle *rect);
|
int setSelection(unsigned int target, Rectangle *rect);
|
||||||
|
|
||||||
|
|
|
@ -154,8 +154,8 @@ CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera,
|
||||||
if (roles.empty())
|
if (roles.empty())
|
||||||
return config;
|
return config;
|
||||||
|
|
||||||
std::map<unsigned int, std::vector<SizeRange>> v4l2Formats =
|
std::map<V4L2PixelFormat, std::vector<SizeRange>> v4l2Formats =
|
||||||
data->video_->formats().data();
|
data->video_->formats();
|
||||||
std::map<PixelFormat, std::vector<SizeRange>> deviceFormats;
|
std::map<PixelFormat, std::vector<SizeRange>> deviceFormats;
|
||||||
std::transform(v4l2Formats.begin(), v4l2Formats.end(),
|
std::transform(v4l2Formats.begin(), v4l2Formats.end(),
|
||||||
std::inserter(deviceFormats, deviceFormats.begin()),
|
std::inserter(deviceFormats, deviceFormats.begin()),
|
||||||
|
|
|
@ -278,6 +278,65 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class V4L2PixelFormat
|
||||||
|
* \brief V4L2 pixel format FourCC wrapper
|
||||||
|
*
|
||||||
|
* The V4L2PixelFormat class describes the pixel format of a V4L2 buffer. It
|
||||||
|
* wraps the V4L2 numerical FourCC, and shall be used in all APIs that deal with
|
||||||
|
* V4L2 pixel formats. Its purpose is to prevent unintentional confusion of
|
||||||
|
* V4L2 and DRM FourCCs in code by catching implicit conversion attempts at
|
||||||
|
* compile time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn V4L2PixelFormat::V4L2PixelFormat()
|
||||||
|
* \brief Construct a V4L2PixelFormat with an invalid format
|
||||||
|
*
|
||||||
|
* V4L2PixelFormat instances constructed with the default constructor are
|
||||||
|
* invalid, calling the isValid() function returns false.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn V4L2PixelFormat::V4L2PixelFormat(uint32_t fourcc)
|
||||||
|
* \brief Construct a V4L2PixelFormat from a FourCC value
|
||||||
|
* \param[in] fourcc The pixel format FourCC numerical value
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn bool V4L2PixelFormat::isValid() const
|
||||||
|
* \brief Check if the pixel format is valid
|
||||||
|
*
|
||||||
|
* V4L2PixelFormat instances constructed with the default constructor are
|
||||||
|
* invalid. Instances constructed with a FourCC defined in the V4L2 API are
|
||||||
|
* valid. The behaviour is undefined otherwise.
|
||||||
|
*
|
||||||
|
* \return True if the pixel format is valid, false otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn uint32_t V4L2PixelFormat::fourcc() const
|
||||||
|
* \brief Retrieve the pixel format FourCC numerical value
|
||||||
|
* \return The pixel format FourCC numerical value
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \fn V4L2PixelFormat::operator uint32_t() const
|
||||||
|
* \brief Convert to the pixel format FourCC numerical value
|
||||||
|
* \return The pixel format FourCC numerical value
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Assemble and return a string describing the pixel format
|
||||||
|
* \return A string describing the pixel format
|
||||||
|
*/
|
||||||
|
std::string V4L2PixelFormat::toString() const
|
||||||
|
{
|
||||||
|
char str[11];
|
||||||
|
snprintf(str, 11, "0x%08x", fourcc_);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class V4L2DeviceFormat
|
* \class V4L2DeviceFormat
|
||||||
* \brief The V4L2 video device image format and sizes
|
* \brief The V4L2 video device image format and sizes
|
||||||
|
@ -386,7 +445,7 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const
|
||||||
const std::string V4L2DeviceFormat::toString() const
|
const std::string V4L2DeviceFormat::toString() const
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << size.toString() << "-" << utils::hex(fourcc);
|
ss << size.toString() << "-" << fourcc.toString();
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,29 +960,31 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)
|
||||||
*
|
*
|
||||||
* \return A list of the supported video device formats
|
* \return A list of the supported video device formats
|
||||||
*/
|
*/
|
||||||
ImageFormats V4L2VideoDevice::formats()
|
std::map<V4L2PixelFormat, std::vector<SizeRange>> V4L2VideoDevice::formats()
|
||||||
{
|
{
|
||||||
ImageFormats formats;
|
std::map<V4L2PixelFormat, std::vector<SizeRange>> formats;
|
||||||
|
|
||||||
for (unsigned int pixelformat : enumPixelformats()) {
|
for (V4L2PixelFormat pixelFormat : enumPixelformats()) {
|
||||||
std::vector<SizeRange> sizes = enumSizes(pixelformat);
|
std::vector<SizeRange> sizes = enumSizes(pixelFormat);
|
||||||
if (sizes.empty())
|
if (sizes.empty())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
if (formats.addFormat(pixelformat, sizes)) {
|
if (formats.find(pixelFormat) != formats.end()) {
|
||||||
LOG(V4L2, Error)
|
LOG(V4L2, Error)
|
||||||
<< "Could not add sizes for pixel format "
|
<< "Could not add sizes for pixel format "
|
||||||
<< pixelformat;
|
<< pixelFormat;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
formats.emplace(pixelFormat, sizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return formats;
|
return formats;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned int> V4L2VideoDevice::enumPixelformats()
|
std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats()
|
||||||
{
|
{
|
||||||
std::vector<unsigned int> formats;
|
std::vector<V4L2PixelFormat> formats;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
for (unsigned int index = 0; ; index++) {
|
for (unsigned int index = 0; ; index++) {
|
||||||
|
@ -948,7 +1009,7 @@ std::vector<unsigned int> V4L2VideoDevice::enumPixelformats()
|
||||||
return formats;
|
return formats;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SizeRange> V4L2VideoDevice::enumSizes(unsigned int pixelFormat)
|
std::vector<SizeRange> V4L2VideoDevice::enumSizes(V4L2PixelFormat pixelFormat)
|
||||||
{
|
{
|
||||||
std::vector<SizeRange> sizes;
|
std::vector<SizeRange> sizes;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1563,7 +1624,7 @@ V4L2VideoDevice *V4L2VideoDevice::fromEntityName(const MediaDevice *media,
|
||||||
* \param[in] v4l2Fourcc The V4L2 pixel format (V4L2_PIX_FORMAT_*)
|
* \param[in] v4l2Fourcc The V4L2 pixel format (V4L2_PIX_FORMAT_*)
|
||||||
* \return The PixelFormat corresponding to \a v4l2Fourcc
|
* \return The PixelFormat corresponding to \a v4l2Fourcc
|
||||||
*/
|
*/
|
||||||
PixelFormat V4L2VideoDevice::toPixelFormat(uint32_t v4l2Fourcc)
|
PixelFormat V4L2VideoDevice::toPixelFormat(V4L2PixelFormat v4l2Fourcc)
|
||||||
{
|
{
|
||||||
switch (v4l2Fourcc) {
|
switch (v4l2Fourcc) {
|
||||||
/* RGB formats. */
|
/* RGB formats. */
|
||||||
|
@ -1612,7 +1673,7 @@ PixelFormat V4L2VideoDevice::toPixelFormat(uint32_t v4l2Fourcc)
|
||||||
libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(),
|
libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(),
|
||||||
LogError).stream()
|
LogError).stream()
|
||||||
<< "Unsupported V4L2 pixel format "
|
<< "Unsupported V4L2 pixel format "
|
||||||
<< utils::hex(v4l2Fourcc);
|
<< v4l2Fourcc.toString();
|
||||||
return PixelFormat();
|
return PixelFormat();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1628,7 +1689,7 @@ PixelFormat V4L2VideoDevice::toPixelFormat(uint32_t v4l2Fourcc)
|
||||||
*
|
*
|
||||||
* \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat
|
* \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat
|
||||||
*/
|
*/
|
||||||
uint32_t V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat)
|
V4L2PixelFormat V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat)
|
||||||
{
|
{
|
||||||
return V4L2VideoDevice::toV4L2Fourcc(pixelFormat, caps_.isMultiplanar());
|
return V4L2VideoDevice::toV4L2Fourcc(pixelFormat, caps_.isMultiplanar());
|
||||||
}
|
}
|
||||||
|
@ -1646,8 +1707,8 @@ uint32_t V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat)
|
||||||
*
|
*
|
||||||
* \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat
|
* \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat
|
||||||
*/
|
*/
|
||||||
uint32_t V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat,
|
V4L2PixelFormat V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat,
|
||||||
bool multiplanar)
|
bool multiplanar)
|
||||||
{
|
{
|
||||||
switch (pixelFormat) {
|
switch (pixelFormat) {
|
||||||
/* RGB formats. */
|
/* RGB formats. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue