mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
video-chroma: Add support for any combination of chroma-site flags
We've been allowing only a few known chroma-site values such as jpeg (not co-sited), mpeg2 (horizontally co-sited) and dv (co-sited on alternate lines). That's insufficient for representing all possible chroma-site values. By this commit, we can represent any combination of chroma-site flags. But, an exception here is that any combination with GST_VIDEO_CHROMA_SITE_NONE will be considered as invalid value. For any combination of chroma-site flags, gst_video_chroma_to_string() method is deprecated in order to return newly allocated string via a new gst_video_chroma_site_to_string() method. And for consistent API naming, gst_video_chroma_from_string() is also deprecated. Newly written code should use gst_video_chroma_site_from_string() instead. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/927>
This commit is contained in:
parent
6434db5298
commit
410efd196a
3 changed files with 193 additions and 5 deletions
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#include "video-orc.h"
|
#include "video-orc.h"
|
||||||
#include "video-format.h"
|
#include "video-format.h"
|
||||||
|
#include <gst/video/video-enumtypes.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gstvideochroma
|
* SECTION:gstvideochroma
|
||||||
|
@ -72,7 +72,9 @@ typedef struct
|
||||||
static const ChromaSiteInfo chromasite[] = {
|
static const ChromaSiteInfo chromasite[] = {
|
||||||
{"jpeg", GST_VIDEO_CHROMA_SITE_JPEG},
|
{"jpeg", GST_VIDEO_CHROMA_SITE_JPEG},
|
||||||
{"mpeg2", GST_VIDEO_CHROMA_SITE_MPEG2},
|
{"mpeg2", GST_VIDEO_CHROMA_SITE_MPEG2},
|
||||||
{"dv", GST_VIDEO_CHROMA_SITE_DV}
|
{"dv", GST_VIDEO_CHROMA_SITE_DV},
|
||||||
|
{"alt-line", GST_VIDEO_CHROMA_SITE_ALT_LINE},
|
||||||
|
{"cosited", GST_VIDEO_CHROMA_SITE_COSITED},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,18 +83,66 @@ static const ChromaSiteInfo chromasite[] = {
|
||||||
*
|
*
|
||||||
* Convert @s to a #GstVideoChromaSite
|
* Convert @s to a #GstVideoChromaSite
|
||||||
*
|
*
|
||||||
|
* Deprecated: 1.20: Use gst_video_chroma_site_from_string() instead.
|
||||||
|
*
|
||||||
* Returns: a #GstVideoChromaSite or %GST_VIDEO_CHROMA_SITE_UNKNOWN when @s does
|
* Returns: a #GstVideoChromaSite or %GST_VIDEO_CHROMA_SITE_UNKNOWN when @s does
|
||||||
* not contain a valid chroma description.
|
* not contain a valid chroma description.
|
||||||
*/
|
*/
|
||||||
GstVideoChromaSite
|
GstVideoChromaSite
|
||||||
gst_video_chroma_from_string (const gchar * s)
|
gst_video_chroma_from_string (const gchar * s)
|
||||||
|
{
|
||||||
|
return gst_video_chroma_site_from_string (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_video_chroma_site_from_string:
|
||||||
|
* @s: a chromasite string
|
||||||
|
*
|
||||||
|
* Convert @s to a #GstVideoChromaSite
|
||||||
|
*
|
||||||
|
* Returns: a #GstVideoChromaSite or %GST_VIDEO_CHROMA_SITE_UNKNOWN when @s does
|
||||||
|
* not contain a valid chroma-site description.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
GstVideoChromaSite
|
||||||
|
gst_video_chroma_site_from_string (const gchar * s)
|
||||||
{
|
{
|
||||||
gint i;
|
gint i;
|
||||||
|
gchar **split;
|
||||||
|
gchar **iter;
|
||||||
|
GstVideoChromaSite ret = GST_VIDEO_CHROMA_SITE_UNKNOWN;
|
||||||
|
GFlagsClass *klass;
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (chromasite); i++) {
|
for (i = 0; i < G_N_ELEMENTS (chromasite); i++) {
|
||||||
if (g_str_equal (chromasite[i].name, s))
|
if (g_str_equal (chromasite[i].name, s))
|
||||||
return chromasite[i].site;
|
return chromasite[i].site;
|
||||||
}
|
}
|
||||||
return GST_VIDEO_CHROMA_SITE_UNKNOWN;
|
|
||||||
|
klass = (GFlagsClass *) g_type_class_ref (GST_TYPE_VIDEO_CHROMA_SITE);
|
||||||
|
split = g_strsplit (s, "+", 0);
|
||||||
|
for (iter = split; *iter; iter++) {
|
||||||
|
GFlagsValue *value;
|
||||||
|
|
||||||
|
value = g_flags_get_value_by_nick (klass, *iter);
|
||||||
|
if (!value) {
|
||||||
|
ret = GST_VIDEO_CHROMA_SITE_UNKNOWN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret |= value->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_type_class_unref (klass);
|
||||||
|
g_strfreev (split);
|
||||||
|
|
||||||
|
/* Doesn't make sense */
|
||||||
|
if ((ret & GST_VIDEO_CHROMA_SITE_NONE) != 0 &&
|
||||||
|
ret != GST_VIDEO_CHROMA_SITE_NONE)
|
||||||
|
return GST_VIDEO_CHROMA_SITE_UNKNOWN;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,6 +151,8 @@ gst_video_chroma_from_string (const gchar * s)
|
||||||
*
|
*
|
||||||
* Converts @site to its string representation.
|
* Converts @site to its string representation.
|
||||||
*
|
*
|
||||||
|
* Deprecated: 1.20: Use gst_video_chroma_site_to_string() instead.
|
||||||
|
*
|
||||||
* Returns: a string describing @site.
|
* Returns: a string describing @site.
|
||||||
*/
|
*/
|
||||||
const gchar *
|
const gchar *
|
||||||
|
@ -114,6 +166,60 @@ gst_video_chroma_to_string (GstVideoChromaSite site)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_video_chroma_site_to_string:
|
||||||
|
* @site: a #GstVideoChromaSite
|
||||||
|
*
|
||||||
|
* Converts @site to its string representation.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full) (nullable): a string representation of @site
|
||||||
|
* or %NULL if @site contains undefined value or
|
||||||
|
* is equal to %GST_VIDEO_CHROMA_SITE_UNKNOWN
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
gchar *
|
||||||
|
gst_video_chroma_site_to_string (GstVideoChromaSite site)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
GString *str;
|
||||||
|
GFlagsValue *value;
|
||||||
|
GFlagsClass *klass;
|
||||||
|
|
||||||
|
/* return null string for GST_VIDEO_CHROMA_SITE_UNKNOWN */
|
||||||
|
if (site == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (chromasite); i++) {
|
||||||
|
if (chromasite[i].site == site)
|
||||||
|
return g_strdup (chromasite[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Doesn't make sense */
|
||||||
|
if ((site & GST_VIDEO_CHROMA_SITE_NONE) != 0 &&
|
||||||
|
site != GST_VIDEO_CHROMA_SITE_NONE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Construct new string */
|
||||||
|
klass = (GFlagsClass *) g_type_class_ref (GST_TYPE_VIDEO_CHROMA_SITE);
|
||||||
|
str = g_string_new (NULL);
|
||||||
|
while (site != GST_VIDEO_CHROMA_SITE_UNKNOWN &&
|
||||||
|
(value = g_flags_get_first_value (klass, site))) {
|
||||||
|
if (str->len > 0)
|
||||||
|
g_string_append (str, "+");
|
||||||
|
|
||||||
|
g_string_append (str, value->value_nick);
|
||||||
|
site &= ~value->value;
|
||||||
|
}
|
||||||
|
g_type_class_unref (klass);
|
||||||
|
|
||||||
|
/* This means given chroma-site has unknown value */
|
||||||
|
if (site != 0)
|
||||||
|
return g_string_free (str, TRUE);
|
||||||
|
|
||||||
|
return g_string_free (str, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
struct _GstVideoChromaResample
|
struct _GstVideoChromaResample
|
||||||
{
|
{
|
||||||
GstVideoChromaMethod method;
|
GstVideoChromaMethod method;
|
||||||
|
|
|
@ -52,12 +52,18 @@ typedef enum {
|
||||||
GST_VIDEO_CHROMA_SITE_DV = (GST_VIDEO_CHROMA_SITE_COSITED | GST_VIDEO_CHROMA_SITE_ALT_LINE),
|
GST_VIDEO_CHROMA_SITE_DV = (GST_VIDEO_CHROMA_SITE_COSITED | GST_VIDEO_CHROMA_SITE_ALT_LINE),
|
||||||
} GstVideoChromaSite;
|
} GstVideoChromaSite;
|
||||||
|
|
||||||
GST_VIDEO_API
|
GST_VIDEO_DEPRECATED_FOR(gst_video_chroma_site_from_string)
|
||||||
GstVideoChromaSite gst_video_chroma_from_string (const gchar * s);
|
GstVideoChromaSite gst_video_chroma_from_string (const gchar * s);
|
||||||
|
|
||||||
GST_VIDEO_API
|
GST_VIDEO_DEPRECATED_FOR(gst_video_chroma_site_to_string)
|
||||||
const gchar * gst_video_chroma_to_string (GstVideoChromaSite site);
|
const gchar * gst_video_chroma_to_string (GstVideoChromaSite site);
|
||||||
|
|
||||||
|
GST_VIDEO_API
|
||||||
|
GstVideoChromaSite gst_video_chroma_site_from_string (const gchar * s);
|
||||||
|
|
||||||
|
GST_VIDEO_API
|
||||||
|
gchar * gst_video_chroma_site_to_string (GstVideoChromaSite site);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVideoChromaMethod:
|
* GstVideoChromaMethod:
|
||||||
* @GST_VIDEO_CHROMA_METHOD_NEAREST: Duplicates the chroma samples when
|
* @GST_VIDEO_CHROMA_METHOD_NEAREST: Duplicates the chroma samples when
|
||||||
|
|
|
@ -2398,6 +2398,81 @@ GST_END_TEST;
|
||||||
#undef HEIGHT
|
#undef HEIGHT
|
||||||
#undef TIME
|
#undef TIME
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const gchar *name;
|
||||||
|
GstVideoChromaSite site;
|
||||||
|
} ChromaSiteElem;
|
||||||
|
|
||||||
|
GST_START_TEST (test_video_chroma_site)
|
||||||
|
{
|
||||||
|
ChromaSiteElem valid_sites[] = {
|
||||||
|
/* pre-defined flags */
|
||||||
|
{"jpeg", GST_VIDEO_CHROMA_SITE_JPEG},
|
||||||
|
{"mpeg2", GST_VIDEO_CHROMA_SITE_MPEG2},
|
||||||
|
{"dv", GST_VIDEO_CHROMA_SITE_DV},
|
||||||
|
{"alt-line", GST_VIDEO_CHROMA_SITE_ALT_LINE},
|
||||||
|
{"cosited", GST_VIDEO_CHROMA_SITE_COSITED},
|
||||||
|
/* new values */
|
||||||
|
{"v-cosited", GST_VIDEO_CHROMA_SITE_V_COSITED},
|
||||||
|
{"v-cosited+alt-line",
|
||||||
|
GST_VIDEO_CHROMA_SITE_V_COSITED | GST_VIDEO_CHROMA_SITE_ALT_LINE},
|
||||||
|
};
|
||||||
|
ChromaSiteElem unknown_sites[] = {
|
||||||
|
{NULL, GST_VIDEO_CHROMA_SITE_UNKNOWN},
|
||||||
|
/* Any combination with GST_VIDEO_CHROMA_SITE_NONE doesn' make sense */
|
||||||
|
{NULL, GST_VIDEO_CHROMA_SITE_NONE | GST_VIDEO_CHROMA_SITE_H_COSITED},
|
||||||
|
};
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (valid_sites); i++) {
|
||||||
|
gchar *site = gst_video_chroma_site_to_string (valid_sites[i].site);
|
||||||
|
|
||||||
|
fail_unless (site != NULL);
|
||||||
|
fail_unless (g_strcmp0 (site, valid_sites[i].name) == 0);
|
||||||
|
fail_unless (gst_video_chroma_site_from_string (site) ==
|
||||||
|
valid_sites[i].site);
|
||||||
|
g_free (site);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (unknown_sites); i++) {
|
||||||
|
gchar *site = gst_video_chroma_site_to_string (unknown_sites[i].site);
|
||||||
|
fail_unless (site == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* totally wrong string */
|
||||||
|
fail_unless (gst_video_chroma_site_from_string ("foo/bar") ==
|
||||||
|
GST_VIDEO_CHROMA_SITE_UNKNOWN);
|
||||||
|
|
||||||
|
/* valid ones */
|
||||||
|
fail_unless (gst_video_chroma_site_from_string ("jpeg") ==
|
||||||
|
GST_VIDEO_CHROMA_SITE_NONE);
|
||||||
|
fail_unless (gst_video_chroma_site_from_string ("none") ==
|
||||||
|
GST_VIDEO_CHROMA_SITE_NONE);
|
||||||
|
|
||||||
|
fail_unless (gst_video_chroma_site_from_string ("mpeg2") ==
|
||||||
|
GST_VIDEO_CHROMA_SITE_H_COSITED);
|
||||||
|
fail_unless (gst_video_chroma_site_from_string ("h-cosited") ==
|
||||||
|
GST_VIDEO_CHROMA_SITE_H_COSITED);
|
||||||
|
|
||||||
|
/* Equal to "cosited" */
|
||||||
|
fail_unless (gst_video_chroma_site_from_string ("v-cosited+h-cosited") ==
|
||||||
|
GST_VIDEO_CHROMA_SITE_COSITED);
|
||||||
|
|
||||||
|
fail_unless (gst_video_chroma_site_from_string ("v-cosited") ==
|
||||||
|
GST_VIDEO_CHROMA_SITE_V_COSITED);
|
||||||
|
|
||||||
|
/* none + something doesn't make sense */
|
||||||
|
fail_unless (gst_video_chroma_site_from_string ("none+v-cosited") ==
|
||||||
|
GST_VIDEO_CHROMA_SITE_UNKNOWN);
|
||||||
|
|
||||||
|
/* mix of valid and invalid strings */
|
||||||
|
fail_unless (gst_video_chroma_site_from_string ("mpeg2+foo/bar") ==
|
||||||
|
GST_VIDEO_CHROMA_SITE_UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
GST_START_TEST (test_video_scaler)
|
GST_START_TEST (test_video_scaler)
|
||||||
{
|
{
|
||||||
GstVideoScaler *scale;
|
GstVideoScaler *scale;
|
||||||
|
@ -3959,6 +4034,7 @@ video_suite (void)
|
||||||
tcase_add_test (tc_chain, test_overlay_composition_global_alpha);
|
tcase_add_test (tc_chain, test_overlay_composition_global_alpha);
|
||||||
tcase_add_test (tc_chain, test_video_pack_unpack2);
|
tcase_add_test (tc_chain, test_video_pack_unpack2);
|
||||||
tcase_add_test (tc_chain, test_video_chroma);
|
tcase_add_test (tc_chain, test_video_chroma);
|
||||||
|
tcase_add_test (tc_chain, test_video_chroma_site);
|
||||||
tcase_add_test (tc_chain, test_video_scaler);
|
tcase_add_test (tc_chain, test_video_scaler);
|
||||||
tcase_add_test (tc_chain, test_video_color_convert_rgb_rgb);
|
tcase_add_test (tc_chain, test_video_color_convert_rgb_rgb);
|
||||||
tcase_add_test (tc_chain, test_video_color_convert_rgb_yuv);
|
tcase_add_test (tc_chain, test_video_color_convert_rgb_yuv);
|
||||||
|
|
Loading…
Reference in a new issue