From 1e6920c33b9a4ae67a349711fa48c6a4daae538e Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Tue, 10 Jan 2023 21:53:55 +0100 Subject: [PATCH] video: Add extra field indicating if modifier value is valid The drm format modifier value `0` is actually `DRM_FORMAT_MOD_LINEAR`, a commonly used modifier. Unfortunately there appears to be no value that can savely used as placeholder for "no value", as e.g. `DRM_FORMAT_MOD_INVALID` is often used to indicate an implicit modifier. Thus add an extra field that clearly indicates whether the modifier value is set or not, add it to the util fuctions and use it for the current only user, the libcamera backend. Fixes 5a6da7d5e1d03272e Closes https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2943 --- spa/include/spa/param/video/format-utils.h | 20 ++++++++++++++++---- spa/include/spa/param/video/raw.h | 7 +++++-- spa/plugins/libcamera/libcamera-source.cpp | 5 ++++- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/spa/include/spa/param/video/format-utils.h b/spa/include/spa/param/video/format-utils.h index 339e7e523..6f7b11a84 100644 --- a/spa/include/spa/param/video/format-utils.h +++ b/spa/include/spa/param/video/format-utils.h @@ -42,7 +42,9 @@ static inline int spa_format_video_raw_parse(const struct spa_pod *format, struct spa_video_info_raw *info) { - return spa_pod_parse_object(format, + int res; + + res = spa_pod_parse_object(format, SPA_TYPE_OBJECT_Format, NULL, SPA_FORMAT_VIDEO_format, SPA_POD_OPT_Id(&info->format), SPA_FORMAT_VIDEO_modifier, SPA_POD_OPT_Long(&info->modifier), @@ -59,16 +61,26 @@ spa_format_video_raw_parse(const struct spa_pod *format, SPA_FORMAT_VIDEO_colorMatrix, SPA_POD_OPT_Id(&info->color_matrix), SPA_FORMAT_VIDEO_transferFunction, SPA_POD_OPT_Id(&info->transfer_function), SPA_FORMAT_VIDEO_colorPrimaries, SPA_POD_OPT_Id(&info->color_primaries)); + + info->use_modifier = spa_pod_find_prop (format, NULL, SPA_FORMAT_VIDEO_modifier) ? true : false; + + return res; } static inline int spa_format_video_dsp_parse(const struct spa_pod *format, struct spa_video_info_dsp *info) { - return spa_pod_parse_object(format, + int res; + + res = spa_pod_parse_object(format, SPA_TYPE_OBJECT_Format, NULL, SPA_FORMAT_VIDEO_format, SPA_POD_OPT_Id(&info->format), SPA_FORMAT_VIDEO_modifier, SPA_POD_OPT_Long(&info->modifier)); + + info->use_modifier = spa_pod_find_prop (format, NULL, SPA_FORMAT_VIDEO_modifier) ? true : false; + + return res; } static inline struct spa_pod * @@ -90,7 +102,7 @@ spa_format_video_raw_build(struct spa_pod_builder *builder, uint32_t id, if (info->framerate.denom != 0) spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&info->framerate), 0); - if (info->modifier != 0) + if (info->use_modifier) spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_modifier, SPA_POD_Long(info->modifier), 0); if (info->max_framerate.denom != 0) @@ -142,7 +154,7 @@ spa_format_video_dsp_build(struct spa_pod_builder *builder, uint32_t id, if (info->format != SPA_VIDEO_FORMAT_UNKNOWN) spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_format, SPA_POD_Id(info->format), 0); - if (info->modifier) + if (info->use_modifier) spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_modifier, SPA_POD_Long(info->modifier), 0); return (struct spa_pod*)spa_pod_builder_pop(builder, &f); diff --git a/spa/include/spa/param/video/raw.h b/spa/include/spa/param/video/raw.h index 47fbd19b3..2beed4456 100644 --- a/spa/include/spa/param/video/raw.h +++ b/spa/include/spa/param/video/raw.h @@ -186,7 +186,9 @@ enum spa_video_interlace_mode { */ struct spa_video_info_raw { enum spa_video_format format; /**< the format */ - int64_t modifier; /**< format modifier + + bool use_modifier; /**< whether the modifier field has a valid value */ + uint64_t modifier; /**< format modifier * only used with DMA-BUF */ struct spa_rectangle size; /**< the frame size of the video */ struct spa_fraction framerate; /**< the framerate of the video, 0/1 means variable rate */ @@ -210,7 +212,8 @@ struct spa_video_info_raw { struct spa_video_info_dsp { enum spa_video_format format; - int64_t modifier; + bool use_modifier; + uint64_t modifier; }; #define SPA_VIDEO_INFO_DSP_INIT(...) ((struct spa_video_info_dsp) { __VA_ARGS__ }) diff --git a/spa/plugins/libcamera/libcamera-source.cpp b/spa/plugins/libcamera/libcamera-source.cpp index 26ef14874..62a73281d 100644 --- a/spa/plugins/libcamera/libcamera-source.cpp +++ b/spa/plugins/libcamera/libcamera-source.cpp @@ -676,7 +676,10 @@ static int port_set_format(struct impl *impl, struct port *port, info.media_subtype == port->current_format->media_subtype && info.info.raw.format == port->current_format->info.raw.format && info.info.raw.size.width == port->current_format->info.raw.size.width && - info.info.raw.size.height == port->current_format->info.raw.size.height) + info.info.raw.size.height == port->current_format->info.raw.size.height && + info.info.raw.use_modifier == port->current_format->info.raw.use_modifier && + (!info.info.raw.use_modifier || + info.info.raw.modifier == port->current_format->info.raw.modifier)) return 0; break; case SPA_MEDIA_SUBTYPE_mjpg: