mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-23 08:35:07 +03:00
v4l2: v4l2_camera_proxy: Use stream config in tryFormat
For handling try_fmt, the values should be filled in by validating the stream configuration, and not by recalculating them or manually checking against the cached list of formats and sizes. Add a new V4L2Camera::validateConfiguration() function to validate a configuration and use it to obtain size, format, stride, and frameSize values. If the format negotiation fails, return error from try_fmt and s_fmt. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
a3b5ee998e
commit
323a53c232
4 changed files with 48 additions and 18 deletions
|
@ -138,6 +138,26 @@ int V4L2Camera::configure(StreamConfiguration *streamConfigOut,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int V4L2Camera::validateConfiguration(const PixelFormat &pixelFormat,
|
||||
const Size &size,
|
||||
StreamConfiguration *streamConfigOut)
|
||||
{
|
||||
std::unique_ptr<CameraConfiguration> config =
|
||||
camera_->generateConfiguration({ StreamRole::Viewfinder });
|
||||
StreamConfiguration &cfg = config->at(0);
|
||||
cfg.size = size;
|
||||
cfg.pixelFormat = pixelFormat;
|
||||
cfg.bufferCount = 1;
|
||||
|
||||
CameraConfiguration::Status validation = config->validate();
|
||||
if (validation == CameraConfiguration::Invalid)
|
||||
return -EINVAL;
|
||||
|
||||
*streamConfigOut = cfg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int V4L2Camera::allocBuffers(unsigned int count)
|
||||
{
|
||||
Stream *stream = config_->at(0).stream();
|
||||
|
|
|
@ -47,6 +47,9 @@ public:
|
|||
int configure(StreamConfiguration *streamConfigOut,
|
||||
const Size &size, const PixelFormat &pixelformat,
|
||||
unsigned int bufferCount);
|
||||
int validateConfiguration(const PixelFormat &pixelformat,
|
||||
const Size &size,
|
||||
StreamConfiguration *streamConfigOut);
|
||||
|
||||
int allocBuffers(unsigned int count);
|
||||
void freeBuffers();
|
||||
|
|
|
@ -296,33 +296,36 @@ int V4L2CameraProxy::vidioc_g_fmt(V4L2CameraFile *file, struct v4l2_format *arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void V4L2CameraProxy::tryFormat(struct v4l2_format *arg)
|
||||
int V4L2CameraProxy::tryFormat(struct v4l2_format *arg)
|
||||
{
|
||||
V4L2PixelFormat v4l2Format = V4L2PixelFormat(arg->fmt.pix.pixelformat);
|
||||
PixelFormat format = PixelFormatInfo::info(v4l2Format).format;
|
||||
const std::vector<PixelFormat> &formats =
|
||||
streamConfig_.formats().pixelformats();
|
||||
if (std::find(formats.begin(), formats.end(), format) == formats.end())
|
||||
format = streamConfig_.formats().pixelformats()[0];
|
||||
|
||||
Size size(arg->fmt.pix.width, arg->fmt.pix.height);
|
||||
const std::vector<Size> &sizes = streamConfig_.formats().sizes(format);
|
||||
if (std::find(sizes.begin(), sizes.end(), size) == sizes.end())
|
||||
size = streamConfig_.formats().sizes(format)[0];
|
||||
|
||||
const PixelFormatInfo &formatInfo = PixelFormatInfo::info(format);
|
||||
StreamConfiguration config;
|
||||
int ret = vcam_->validateConfiguration(format, size, &config);
|
||||
if (ret < 0) {
|
||||
LOG(V4L2Compat, Error)
|
||||
<< "Failed to negotiate a valid format: "
|
||||
<< format.toString();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
arg->fmt.pix.width = size.width;
|
||||
arg->fmt.pix.height = size.height;
|
||||
arg->fmt.pix.pixelformat = formatInfo.v4l2Format;
|
||||
const PixelFormatInfo &info = PixelFormatInfo::info(config.pixelFormat);
|
||||
|
||||
arg->fmt.pix.width = config.size.width;
|
||||
arg->fmt.pix.height = config.size.height;
|
||||
arg->fmt.pix.pixelformat = info.v4l2Format;
|
||||
arg->fmt.pix.field = V4L2_FIELD_NONE;
|
||||
arg->fmt.pix.bytesperline = formatInfo.stride(size.width, 0);
|
||||
arg->fmt.pix.sizeimage = formatInfo.frameSize(size);
|
||||
arg->fmt.pix.bytesperline = config.stride;
|
||||
arg->fmt.pix.sizeimage = config.frameSize;
|
||||
arg->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
|
||||
arg->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
|
||||
arg->fmt.pix.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
|
||||
arg->fmt.pix.quantization = V4L2_QUANTIZATION_DEFAULT;
|
||||
arg->fmt.pix.xfer_func = V4L2_XFER_FUNC_DEFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int V4L2CameraProxy::vidioc_s_fmt(V4L2CameraFile *file, struct v4l2_format *arg)
|
||||
|
@ -339,7 +342,9 @@ int V4L2CameraProxy::vidioc_s_fmt(V4L2CameraFile *file, struct v4l2_format *arg)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
tryFormat(arg);
|
||||
ret = tryFormat(arg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
Size size(arg->fmt.pix.width, arg->fmt.pix.height);
|
||||
V4L2PixelFormat v4l2Format = V4L2PixelFormat(arg->fmt.pix.pixelformat);
|
||||
|
@ -361,7 +366,9 @@ int V4L2CameraProxy::vidioc_try_fmt(V4L2CameraFile *file, struct v4l2_format *ar
|
|||
if (!validateBufferType(arg->type))
|
||||
return -EINVAL;
|
||||
|
||||
tryFormat(arg);
|
||||
int ret = tryFormat(arg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ private:
|
|||
bool validateMemoryType(uint32_t memory);
|
||||
void setFmtFromConfig(StreamConfiguration &streamConfig);
|
||||
void querycap(std::shared_ptr<Camera> camera);
|
||||
void tryFormat(struct v4l2_format *arg);
|
||||
int tryFormat(struct v4l2_format *arg);
|
||||
enum v4l2_priority maxPriority();
|
||||
void updateBuffers();
|
||||
void freeBuffers();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue