| Message ID | 20261015194326.287935-1-halfline@gmail.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
On Thu, Oct 15, 2026 at 03:43:26PM -0400, Ray Strode wrote: > From: Ray Strode <rstrode@redhat.com> > > V4L2 subdevice format negotiation uses the format setter to obtain an > accepted pad format. > > Fixed-format subdevices may omit that ioctl, so their existing format > cannot be returned through the setter path. That's not the can any more in the kernel. > This commit reads the existing format when the setter reports ENOTTY, > using the same active or try format selection. Other failures retain the > usual error handling. > > Signed-off-by: Ray Strode <rstrode@redhat.com> > --- > src/libcamera/v4l2_subdevice.cpp | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp > index a69de154..12a320d6 100644 > --- a/src/libcamera/v4l2_subdevice.cpp > +++ b/src/libcamera/v4l2_subdevice.cpp > @@ -1393,60 +1393,64 @@ int V4L2Subdevice::getFormat(const Stream &stream, V4L2SubdeviceFormat *format, > * \param[in] stream The stream the format is to be applied to > * \param[inout] format The image bus format to apply to the stream > * \param[in] whence The format to set, \ref V4L2Subdevice::ActiveFormat > * "ActiveFormat" or \ref V4L2Subdevice::TryFormat "TryFormat" > * > * Apply the requested image format to the desired stream and return the > * actually applied format parameters, as getFormat() would do. > * > * \return 0 on success or a negative error code otherwise > */ > int V4L2Subdevice::setFormat(const Stream &stream, V4L2SubdeviceFormat *format, > Whence whence) > { > struct v4l2_subdev_format subdevFmt = {}; > subdevFmt.which = whence; > subdevFmt.pad = stream.pad; > subdevFmt.stream = stream.stream; > subdevFmt.format.width = format->size.width; > subdevFmt.format.height = format->size.height; > subdevFmt.format.code = format->code; > subdevFmt.format.field = V4L2_FIELD_NONE; > if (format->colorSpace) { > fromColorSpace(format->colorSpace, subdevFmt.format); > > /* The CSC flag is only applicable to source pads. */ > if (entity_->pads()[stream.pad]->flags() & MEDIA_PAD_FL_SOURCE) > subdevFmt.format.flags |= V4L2_MBUS_FRAMEFMT_SET_CSC; > } > > int ret = ioctl(VIDIOC_SUBDEV_S_FMT, &subdevFmt); 30 lines of context ?? > + /* Fixed-format subdevices may not implement a format setter. */ > + if (ret == -ENOTTY) > + return getFormat(stream, format, whence); > + > if (ret) { > LOG(V4L2, Error) > << "Unable to set format on pad " << stream << ": " > << strerror(-ret); > return ret; > } > > format->size.width = subdevFmt.format.width; > format->size.height = subdevFmt.format.height; > format->code = subdevFmt.format.code; > format->colorSpace = toColorSpace(subdevFmt.format); > > return 0; > } > > /** > * \fn V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format, > * Whence whence) > * \brief Set an image format on one of the V4L2 subdevice pads > * \param[in] pad The 0-indexed pad number the format is to be applied to > * \param[inout] format The image bus format to apply to the subdevice's pad > * \param[in] whence The format to set, \ref V4L2Subdevice::ActiveFormat > * "ActiveFormat" or \ref V4L2Subdevice::TryFormat "TryFormat" > * > * Apply the requested image format to the desired media pad and return the > * actually applied format parameters, as getFormat() would do. > * > * \return 0 on success or a negative error code otherwise > */
Hi,
On Thu, Oct 15, 2026 at 4:24 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> That's not the case any more in the kernel.
ah ok.. just found this:
https://git.linuxtv.org/media.git/commit/drivers/media/v4l2-core/v4l2-subdev.c?id=48d8b2418f55efb7e4c437ab19e8c39ba271656d
which i guess is what you're referring to. Good enough, though it's
not in linus tree yet.
Thanks,
--Ray
diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index a69de154..12a320d6 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -1393,60 +1393,64 @@ int V4L2Subdevice::getFormat(const Stream &stream, V4L2SubdeviceFormat *format, * \param[in] stream The stream the format is to be applied to * \param[inout] format The image bus format to apply to the stream * \param[in] whence The format to set, \ref V4L2Subdevice::ActiveFormat * "ActiveFormat" or \ref V4L2Subdevice::TryFormat "TryFormat" * * Apply the requested image format to the desired stream and return the * actually applied format parameters, as getFormat() would do. * * \return 0 on success or a negative error code otherwise */ int V4L2Subdevice::setFormat(const Stream &stream, V4L2SubdeviceFormat *format, Whence whence) { struct v4l2_subdev_format subdevFmt = {}; subdevFmt.which = whence; subdevFmt.pad = stream.pad; subdevFmt.stream = stream.stream; subdevFmt.format.width = format->size.width; subdevFmt.format.height = format->size.height; subdevFmt.format.code = format->code; subdevFmt.format.field = V4L2_FIELD_NONE; if (format->colorSpace) { fromColorSpace(format->colorSpace, subdevFmt.format); /* The CSC flag is only applicable to source pads. */ if (entity_->pads()[stream.pad]->flags() & MEDIA_PAD_FL_SOURCE) subdevFmt.format.flags |= V4L2_MBUS_FRAMEFMT_SET_CSC; } int ret = ioctl(VIDIOC_SUBDEV_S_FMT, &subdevFmt); + /* Fixed-format subdevices may not implement a format setter. */ + if (ret == -ENOTTY) + return getFormat(stream, format, whence); + if (ret) { LOG(V4L2, Error) << "Unable to set format on pad " << stream << ": " << strerror(-ret); return ret; } format->size.width = subdevFmt.format.width; format->size.height = subdevFmt.format.height; format->code = subdevFmt.format.code; format->colorSpace = toColorSpace(subdevFmt.format); return 0; } /** * \fn V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format, * Whence whence) * \brief Set an image format on one of the V4L2 subdevice pads * \param[in] pad The 0-indexed pad number the format is to be applied to * \param[inout] format The image bus format to apply to the subdevice's pad * \param[in] whence The format to set, \ref V4L2Subdevice::ActiveFormat * "ActiveFormat" or \ref V4L2Subdevice::TryFormat "TryFormat" * * Apply the requested image format to the desired media pad and return the * actually applied format parameters, as getFormat() would do. * * \return 0 on success or a negative error code otherwise */