From 959ccf65adcb17222f9f838861a3aea018dde58c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 9 Jan 2025 10:03:45 +0200 Subject: [PATCH] video-info: Validate chroma-site when parsing caps and set defaults if none is set Previously there was no validation at all and the defaults were set if the colorimetry was not set or invalid, but there's not really any connection between colorimetry and chroma-site. More validation could make sense in the future. Part-of: --- girs/GstVideo-1.0.gir | 2 +- .../gst-libs/gst/video/video-chroma.h | 2 +- .../gst-libs/gst/video/video-info.c | 61 +++++++++++++++++-- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/girs/GstVideo-1.0.gir b/girs/GstVideo-1.0.gir index 0d36971888..8fcb7dd314 100644 --- a/girs/GstVideo-1.0.gir +++ b/girs/GstVideo-1.0.gir @@ -5650,7 +5650,7 @@ performed. chroma is vertically cosited - choma samples are sited on alternate lines + chroma samples are sited on alternate lines chroma samples cosited with luma samples diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/video-chroma.h b/subprojects/gst-plugins-base/gst-libs/gst/video/video-chroma.h index 16720b4b52..878dc95a98 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/video-chroma.h +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/video-chroma.h @@ -31,7 +31,7 @@ G_BEGIN_DECLS * @GST_VIDEO_CHROMA_SITE_NONE: no cositing * @GST_VIDEO_CHROMA_SITE_H_COSITED: chroma is horizontally cosited * @GST_VIDEO_CHROMA_SITE_V_COSITED: chroma is vertically cosited - * @GST_VIDEO_CHROMA_SITE_ALT_LINE: choma samples are sited on alternate lines + * @GST_VIDEO_CHROMA_SITE_ALT_LINE: chroma samples are sited on alternate lines * @GST_VIDEO_CHROMA_SITE_COSITED: chroma samples cosited with luma samples * @GST_VIDEO_CHROMA_SITE_JPEG: jpeg style cositing, also for mpeg1 and mjpeg * @GST_VIDEO_CHROMA_SITE_MPEG2: mpeg2 style cositing diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/video-info.c b/subprojects/gst-plugins-base/gst-libs/gst/video/video-info.c index aec8e87cb5..04d52b03b2 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/video-info.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/video-info.c @@ -166,10 +166,8 @@ set_default_colorimetry (GstVideoInfo * info) if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo)) { if (info->height > 576) { - info->chroma_site = GST_VIDEO_CHROMA_SITE_H_COSITED; info->colorimetry = default_color[DEFAULT_YUV_HD]; } else { - info->chroma_site = GST_VIDEO_CHROMA_SITE_NONE; info->colorimetry = default_color[DEFAULT_YUV_SD]; } } else if (GST_VIDEO_FORMAT_INFO_IS_GRAY (finfo)) { @@ -182,7 +180,7 @@ set_default_colorimetry (GstVideoInfo * info) } static gboolean -validate_colorimetry (GstVideoInfo * info) +validate_colorimetry (const GstVideoInfo * info) { const GstVideoFormatInfo *finfo = info->finfo; @@ -205,6 +203,48 @@ validate_colorimetry (GstVideoInfo * info) return TRUE; } +static void +set_default_chroma_site (GstVideoInfo * info) +{ + const GstVideoFormatInfo *finfo = info->finfo; + + if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo)) { + if (info->height > 576) { + info->chroma_site = GST_VIDEO_CHROMA_SITE_H_COSITED; + } else { + info->chroma_site = GST_VIDEO_CHROMA_SITE_NONE; + } + } else { + info->chroma_site = GST_VIDEO_CHROMA_SITE_UNKNOWN; + } +} + +static gboolean +validate_chroma_site (const GstVideoInfo * info) +{ + const GstVideoFormatInfo *finfo = info->finfo; + + if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo)) { + // FIXME: Might also want to check here for subsampling? + // - chroma-site only makes sense with subsampled formats? + // - ALT_LINE only makes sense for formats with vertical subsampling, and if + // also V_COSITED? + if ((info->chroma_site & GST_VIDEO_CHROMA_SITE_NONE) && + (info->chroma_site & (GST_VIDEO_CHROMA_SITE_H_COSITED | + GST_VIDEO_CHROMA_SITE_V_COSITED))) { + GST_WARNING + ("No chroma siting together with horizontal or vertical cositing is invalid"); + return FALSE; + } + } else if (info->chroma_site != GST_VIDEO_CHROMA_SITE_UNKNOWN) { + GST_WARNING ("chroma-site only makes sense for YUV formats, %s is none", + finfo->name); + return FALSE; + } + + return TRUE; +} + static gboolean gst_video_info_set_format_common (GstVideoInfo * info, GstVideoFormat format, guint width, guint height) @@ -503,10 +543,19 @@ gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps) * PAR to be doubled/halved too many times */ } - if ((s = gst_structure_get_string (structure, "chroma-site"))) + if ((s = gst_structure_get_string (structure, "chroma-site"))) { info->chroma_site = gst_video_chroma_site_from_string (s); - else - info->chroma_site = GST_VIDEO_CHROMA_SITE_UNKNOWN; + if (!validate_chroma_site (info)) { + GST_WARNING ("invalid chroma-site, using default"); + set_default_chroma_site (info); + } else if (GST_VIDEO_FORMAT_INFO_IS_YUV (info->finfo) + && info->chroma_site == GST_VIDEO_CHROMA_SITE_UNKNOWN) { + /* force a default chroma-site for YUV formats */ + set_default_chroma_site (info); + } + } else { + set_default_chroma_site (info); + } if ((s = gst_structure_get_string (structure, "colorimetry"))) { if (!gst_video_colorimetry_from_string (&info->colorimetry, s)) {