gstreamer: Fix usage of default size for fixation
Pipeline managers sets a default value to StreamConfiguration::size. 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@collabora.com> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
d3be776654
commit
be05f8d1da
2 changed files with 47 additions and 8 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue