Message ID | 20190616133402.21934-17-niklas.soderlund@ragnatech.se |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
Hi Niklas, Thank you for the patch. On Sun, Jun 16, 2019 at 03:34:02PM +0200, Niklas Söderlund wrote: > Extend the uvcvideo pipeline with format information and validation. The > format information is gathered by enumerating the v4l2 device. This > enumeration approach is valid for UVC as it has a static and simple > media graph. > > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> > Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > --- > src/libcamera/pipeline/uvcvideo.cpp | 41 ++++++++++++++++++++++------- > 1 file changed, 31 insertions(+), 10 deletions(-) > > diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp > index 45260f34c8f5daba..7ca9d0eefe8223e8 100644 > --- a/src/libcamera/pipeline/uvcvideo.cpp > +++ b/src/libcamera/pipeline/uvcvideo.cpp > @@ -5,6 +5,8 @@ > * uvcvideo.cpp - Pipeline handler for uvcvideo devices > */ > > +#include <algorithm> > + > #include <libcamera/camera.h> > #include <libcamera/request.h> > #include <libcamera/stream.h> > @@ -95,18 +97,33 @@ CameraConfiguration::Status UVCCameraConfiguration::validate() > } > > StreamConfiguration &cfg = config_[0]; > - > - /* \todo: Validate the configuration against the device capabilities. */ > + const StreamFormats &formats = cfg.formats(); > const unsigned int pixelFormat = cfg.pixelFormat; > const Size size = cfg.size; > > - cfg.pixelFormat = V4L2_PIX_FMT_YUYV; > - cfg.size = { 640, 480 }; > + const std::vector<unsigned int> pixelFormats = formats.pixelformats(); > + auto iter = std::find(pixelFormats.begin(), pixelFormats.end(), pixelFormat); > + if (iter == pixelFormats.end()) { > + cfg.pixelFormat = pixelFormats.front(); > + LOG(UVC, Debug) > + << "Adjusting pixel format from " << pixelFormat > + << " to " << cfg.pixelFormat; > + status = Adjusted; > + } > + > + const std::vector<Size> &formatSizes = formats.sizes(cfg.pixelFormat); > + cfg.size = formatSizes.front(); > + for (const Size &formatsSize : formatSizes) { > + if (formatsSize > size) > + break; > + > + cfg.size = formatsSize; > + } > > - if (cfg.pixelFormat != pixelFormat || cfg.size != size) { > + if (cfg.size != size) { > LOG(UVC, Debug) > - << "Adjusting configuration from " << cfg.toString() > - << " to " << cfg.size.toString() << "-YUYV"; > + << "Adjusting size from " << size.toString() > + << " to " << cfg.size.toString(); > status = Adjusted; > } > > @@ -123,14 +140,18 @@ PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager) > CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera, > const StreamRoles &roles) > { > + UVCCameraData *data = cameraData(camera); > CameraConfiguration *config = new UVCCameraConfiguration(); > > if (roles.empty()) > return config; > > - StreamConfiguration cfg{}; > - cfg.pixelFormat = V4L2_PIX_FMT_YUYV; > - cfg.size = { 640, 480 }; > + ImageFormats v4l2formats = data->video_->formats(); > + StreamFormats formats(v4l2formats.data()); > + StreamConfiguration cfg(formats); > + > + cfg.pixelFormat = formats.pixelformats().front(); > + cfg.size = formats.sizes(cfg.pixelFormat).back(); > cfg.bufferCount = 4; > > config->addConfiguration(cfg);
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 45260f34c8f5daba..7ca9d0eefe8223e8 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -5,6 +5,8 @@ * uvcvideo.cpp - Pipeline handler for uvcvideo devices */ +#include <algorithm> + #include <libcamera/camera.h> #include <libcamera/request.h> #include <libcamera/stream.h> @@ -95,18 +97,33 @@ CameraConfiguration::Status UVCCameraConfiguration::validate() } StreamConfiguration &cfg = config_[0]; - - /* \todo: Validate the configuration against the device capabilities. */ + const StreamFormats &formats = cfg.formats(); const unsigned int pixelFormat = cfg.pixelFormat; const Size size = cfg.size; - cfg.pixelFormat = V4L2_PIX_FMT_YUYV; - cfg.size = { 640, 480 }; + const std::vector<unsigned int> pixelFormats = formats.pixelformats(); + auto iter = std::find(pixelFormats.begin(), pixelFormats.end(), pixelFormat); + if (iter == pixelFormats.end()) { + cfg.pixelFormat = pixelFormats.front(); + LOG(UVC, Debug) + << "Adjusting pixel format from " << pixelFormat + << " to " << cfg.pixelFormat; + status = Adjusted; + } + + const std::vector<Size> &formatSizes = formats.sizes(cfg.pixelFormat); + cfg.size = formatSizes.front(); + for (const Size &formatsSize : formatSizes) { + if (formatsSize > size) + break; + + cfg.size = formatsSize; + } - if (cfg.pixelFormat != pixelFormat || cfg.size != size) { + if (cfg.size != size) { LOG(UVC, Debug) - << "Adjusting configuration from " << cfg.toString() - << " to " << cfg.size.toString() << "-YUYV"; + << "Adjusting size from " << size.toString() + << " to " << cfg.size.toString(); status = Adjusted; } @@ -123,14 +140,18 @@ PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager) CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera, const StreamRoles &roles) { + UVCCameraData *data = cameraData(camera); CameraConfiguration *config = new UVCCameraConfiguration(); if (roles.empty()) return config; - StreamConfiguration cfg{}; - cfg.pixelFormat = V4L2_PIX_FMT_YUYV; - cfg.size = { 640, 480 }; + ImageFormats v4l2formats = data->video_->formats(); + StreamFormats formats(v4l2formats.data()); + StreamConfiguration cfg(formats); + + cfg.pixelFormat = formats.pixelformats().front(); + cfg.size = formats.sizes(cfg.pixelFormat).back(); cfg.bufferCount = 4; config->addConfiguration(cfg);