[libcamera-devel] [PATCH v2] gstreamer: Fix usage of default size for fixation

Nicolas Dufresne nicolas.dufresne at collabora.com
Thu Aug 26 16:35:29 CEST 2021


Le jeudi 26 août 2021 à 15:33 +0100, Kieran Bingham a écrit :
> On 26/08/2021 15:16, Nicolas Dufresne wrote:
> > From: Nicolas Dufresne <nicolas.dufresne at collabora.com>
> > 
> > Pipeline managers sets a default value to StreamConfiguration::size. 
> 
> If you're happy, I'd change this to
> 
> "Pipeline handlers provide a default StreamConfiguration when given a
> StreamRole."

That is fine with me. 

> 
> Eitherway, we can merge this now I think.
> --
> Kieran
> 
> > The
> > original fixation code was attempting to use it, but as it was truncating
> > the caps to its first structure it would never actually find a best match.
> > 
> > In this patch, instead of truncating, we weight various matches using the
> > product of the width and height delta. We also split delta from ranges
> > apart and prefer fixed size over them as ranges are not reliable.
> > 
> > This patch also removes the related todo, as it seems that libcamera core
> > won't go further then providing this default value and won't be sorting the
> > format and size lists.
> > 
> > Signed-off-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
> > Tested-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> > Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> > ---
> >  src/gstreamer/gstlibcamera-utils.cpp | 51 +++++++++++++++++++++++++---
> >  src/gstreamer/gstlibcamerasrc.cpp    |  4 ---
> >  2 files changed, 47 insertions(+), 8 deletions(-)
> > 
> > diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
> > index 61370d5f..723c4fa3 100644
> > --- a/src/gstreamer/gstlibcamera-utils.cpp
> > +++ b/src/gstreamer/gstlibcamera-utils.cpp
> > @@ -136,14 +136,57 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,
> >  					 GstCaps *caps)
> >  {
> >  	GstVideoFormat gst_format = pixel_format_to_gst_format(stream_cfg.pixelFormat);
> > +	guint i;
> > +	gint best_fixed = -1, best_in_range = -1;
> > +	GstStructure *s;
> > +
> > +	/*
> > +	 * These are delta weight computed from:
> > +	 *   ABS(width - stream_cfg.size.width) * ABS(height - stream_cfg.size.height)
> > +	 */
> > +	guint best_fixed_delta = G_MAXUINT;
> > +	guint best_in_range_delta = G_MAXUINT;
> >  
> >  	/* First fixate the caps using default configuration value. */
> >  	g_assert(gst_caps_is_writable(caps));
> > -	caps = gst_caps_truncate(caps);
> > -	GstStructure *s = gst_caps_get_structure(caps, 0);
> >  
> > -	gst_structure_fixate_field_nearest_int(s, "width", stream_cfg.size.width);
> > -	gst_structure_fixate_field_nearest_int(s, "height", stream_cfg.size.height);
> > +	/* Lookup the structure for a close match to the stream_cfg.size */
> > +	for (i = 0; i < gst_caps_get_size(caps); i++) {
> > +		s = gst_caps_get_structure(caps, i);
> > +		gint width, height;
> > +		guint delta;
> > +
> > +		if (gst_structure_has_field_typed(s, "width", G_TYPE_INT) &&
> > +		    gst_structure_has_field_typed(s, "height", G_TYPE_INT)) {
> > +			gst_structure_get_int(s, "width", &width);
> > +			gst_structure_get_int(s, "height", &height);
> > +
> > +			delta = ABS(width - (gint)stream_cfg.size.width) * ABS(height - (gint)stream_cfg.size.height);
> > +
> > +			if (delta < best_fixed_delta) {
> > +				best_fixed_delta = delta;
> > +				best_fixed = i;
> > +			}
> > +		} else {
> > +			gst_structure_fixate_field_nearest_int(s, "width", stream_cfg.size.width);
> > +			gst_structure_fixate_field_nearest_int(s, "height", stream_cfg.size.height);
> > +			gst_structure_get_int(s, "width", &width);
> > +			gst_structure_get_int(s, "height", &height);
> > +
> > +			delta = ABS(width - (gint)stream_cfg.size.width) * ABS(height - (gint)stream_cfg.size.height);
> > +
> > +			if (delta < best_in_range_delta) {
> > +				best_in_range_delta = delta;
> > +				best_in_range = i;
> > +			}
> > +		}
> > +	}
> > +
> > +	/* Prefer reliable fixed value over ranges */
> > +	if (best_fixed >= 0)
> > +		s = gst_caps_get_structure(caps, best_fixed);
> > +	else
> > +		s = gst_caps_get_structure(caps, best_in_range);
> >  
> >  	if (gst_structure_has_name(s, "video/x-raw")) {
> >  		const gchar *format = gst_video_format_to_string(gst_format);
> > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
> > index b243aeb3..4c7b36ae 100644
> > --- a/src/gstreamer/gstlibcamerasrc.cpp
> > +++ b/src/gstreamer/gstlibcamerasrc.cpp
> > @@ -25,10 +25,6 @@
> >   *  - Add timestamp support
> >   *  - Use unique names to select the camera devices
> >   *  - Add GstVideoMeta support (strides and offsets)
> > - *
> > - * \todo libcamera UVC drivers picks the lowest possible resolution first, this
> > - * should be fixed so that we get a decent resolution and framerate for the
> > - * role by default.
> >   */
> >  
> >  #include "gstlibcamerasrc.h"
> > 




More information about the libcamera-devel mailing list