mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +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-format.h"
|
||||
|
||||
#include <gst/video/video-enumtypes.h>
|
||||
|
||||
/**
|
||||
* SECTION:gstvideochroma
|
||||
|
@ -72,7 +72,9 @@ typedef struct
|
|||
static const ChromaSiteInfo chromasite[] = {
|
||||
{"jpeg", GST_VIDEO_CHROMA_SITE_JPEG},
|
||||
{"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
|
||||
*
|
||||
* Deprecated: 1.20: Use gst_video_chroma_site_from_string() instead.
|
||||
*
|
||||
* Returns: a #GstVideoChromaSite or %GST_VIDEO_CHROMA_SITE_UNKNOWN when @s does
|
||||
* not contain a valid chroma description.
|
||||
*/
|
||||
GstVideoChromaSite
|
||||
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;
|
||||
gchar **split;
|
||||
gchar **iter;
|
||||
GstVideoChromaSite ret = GST_VIDEO_CHROMA_SITE_UNKNOWN;
|
||||
GFlagsClass *klass;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (chromasite); i++) {
|
||||
if (g_str_equal (chromasite[i].name, s))
|
||||
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.
|
||||
*
|
||||
* Deprecated: 1.20: Use gst_video_chroma_site_to_string() instead.
|
||||
*
|
||||
* Returns: a string describing @site.
|
||||
*/
|
||||
const gchar *
|
||||
|
@ -114,6 +166,60 @@ gst_video_chroma_to_string (GstVideoChromaSite site)
|
|||
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
|
||||
{
|
||||
GstVideoChromaMethod method;
|
||||
|
|
|
@ -52,12 +52,18 @@ typedef enum {
|
|||
GST_VIDEO_CHROMA_SITE_DV = (GST_VIDEO_CHROMA_SITE_COSITED | GST_VIDEO_CHROMA_SITE_ALT_LINE),
|
||||
} GstVideoChromaSite;
|
||||
|
||||
GST_VIDEO_API
|
||||
GST_VIDEO_DEPRECATED_FOR(gst_video_chroma_site_from_string)
|
||||
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);
|
||||
|
||||
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:
|
||||
* @GST_VIDEO_CHROMA_METHOD_NEAREST: Duplicates the chroma samples when
|
||||
|
|
|
@ -2398,6 +2398,81 @@ GST_END_TEST;
|
|||
#undef HEIGHT
|
||||
#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)
|
||||
{
|
||||
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_video_pack_unpack2);
|
||||
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_color_convert_rgb_rgb);
|
||||
tcase_add_test (tc_chain, test_video_color_convert_rgb_yuv);
|
||||
|
|
Loading…
Reference in a new issue