2012-06-05 10:47:22 +00:00
|
|
|
/* GStreamer
|
|
|
|
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
|
|
|
* Library <2002> Ronald Bultje <rbultje@ronald.bitfreak.net>
|
|
|
|
* Copyright (C) 2007 David A. Schleef <ds@schleef.org>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the
|
2012-11-03 23:05:09 +00:00
|
|
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
2012-06-05 10:47:22 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2014-11-11 15:11:15 +00:00
|
|
|
#include <math.h>
|
2012-06-05 10:47:22 +00:00
|
|
|
|
|
|
|
#include "video-color.h"
|
|
|
|
|
2015-07-15 10:45:10 +00:00
|
|
|
#ifndef GST_DISABLE_GST_DEBUG
|
|
|
|
#define GST_CAT_DEFAULT ensure_debug_category()
|
|
|
|
static GstDebugCategory *
|
|
|
|
ensure_debug_category (void)
|
|
|
|
{
|
|
|
|
static gsize cat_gonce = 0;
|
|
|
|
|
|
|
|
if (g_once_init_enter (&cat_gonce)) {
|
|
|
|
gsize cat_done;
|
|
|
|
|
|
|
|
cat_done = (gsize) _gst_debug_category_new ("video-color", 0,
|
|
|
|
"video-color object");
|
|
|
|
|
|
|
|
g_once_init_leave (&cat_gonce, cat_done);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (GstDebugCategory *) cat_gonce;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define ensure_debug_category() /* NOOP */
|
|
|
|
#endif /* GST_DISABLE_GST_DEBUG */
|
|
|
|
|
2012-06-05 10:47:22 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
const gchar *name;
|
|
|
|
GstVideoColorimetry color;
|
|
|
|
} ColorimetryInfo;
|
|
|
|
|
|
|
|
#define MAKE_COLORIMETRY(n,r,m,t,p) { GST_VIDEO_COLORIMETRY_ ##n, \
|
|
|
|
{ GST_VIDEO_COLOR_RANGE ##r, GST_VIDEO_COLOR_MATRIX_ ##m, \
|
|
|
|
GST_VIDEO_TRANSFER_ ##t, GST_VIDEO_COLOR_PRIMARIES_ ##p } }
|
|
|
|
|
|
|
|
#define GST_VIDEO_COLORIMETRY_NONAME NULL
|
|
|
|
|
|
|
|
static const ColorimetryInfo colorimetry[] = {
|
2020-06-25 17:56:48 +00:00
|
|
|
MAKE_COLORIMETRY (BT601, _16_235, BT601, BT601, SMPTE170M),
|
2012-06-05 10:47:22 +00:00
|
|
|
MAKE_COLORIMETRY (BT709, _16_235, BT709, BT709, BT709),
|
|
|
|
MAKE_COLORIMETRY (SMPTE240M, _16_235, SMPTE240M, SMPTE240M, SMPTE240M),
|
2014-11-14 08:15:22 +00:00
|
|
|
MAKE_COLORIMETRY (SRGB, _0_255, RGB, SRGB, BT709),
|
2015-06-08 17:01:43 +00:00
|
|
|
MAKE_COLORIMETRY (BT2020, _16_235, BT2020, BT2020_12, BT2020),
|
2019-05-05 10:08:55 +00:00
|
|
|
MAKE_COLORIMETRY (BT2020_10, _16_235, BT2020, BT2020_10, BT2020),
|
2019-05-05 10:22:13 +00:00
|
|
|
MAKE_COLORIMETRY (BT2100_PQ, _16_235, BT2020, SMPTE2084, BT2020),
|
2019-05-05 12:02:55 +00:00
|
|
|
MAKE_COLORIMETRY (BT2100_HLG, _16_235, BT2020, ARIB_STD_B67, BT2020),
|
2012-06-05 10:47:22 +00:00
|
|
|
MAKE_COLORIMETRY (NONAME, _0_255, BT601, UNKNOWN, UNKNOWN),
|
2019-08-11 13:16:51 +00:00
|
|
|
MAKE_COLORIMETRY (NONAME, _UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN), /* Keep last! */
|
2012-06-05 10:47:22 +00:00
|
|
|
};
|
|
|
|
|
2019-08-11 13:16:51 +00:00
|
|
|
#define DEFAULT_UNKNOWN (G_N_ELEMENTS(colorimetry)-1)
|
2019-06-26 11:35:04 +00:00
|
|
|
|
2012-06-05 10:47:22 +00:00
|
|
|
static const ColorimetryInfo *
|
|
|
|
gst_video_get_colorimetry (const gchar * s)
|
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
for (i = 0; colorimetry[i].name; i++) {
|
|
|
|
if (g_str_equal (colorimetry[i].name, s))
|
|
|
|
return &colorimetry[i];
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-05-03 16:10:17 +00:00
|
|
|
#define CI_IS_EQUAL(ci,i) (((ci)->range == (i)->range) && \
|
|
|
|
((ci)->matrix == (i)->matrix) && \
|
|
|
|
((ci)->transfer == (i)->transfer) && \
|
|
|
|
((ci)->primaries == (i)->primaries))
|
|
|
|
|
|
|
|
#define IS_EQUAL(ci,i) CI_IS_EQUAL(&(ci)->color, (i))
|
2012-06-05 10:47:22 +00:00
|
|
|
|
|
|
|
#define IS_UNKNOWN(ci) (IS_EQUAL (&colorimetry[DEFAULT_UNKNOWN], ci))
|
|
|
|
|
|
|
|
/**
|
2012-07-13 10:11:06 +00:00
|
|
|
* gst_video_colorimetry_from_string:
|
2012-06-05 10:47:22 +00:00
|
|
|
* @cinfo: a #GstVideoColorimetry
|
|
|
|
* @color: a colorimetry string
|
|
|
|
*
|
|
|
|
* Parse the colorimetry string and update @cinfo with the parsed
|
|
|
|
* values.
|
|
|
|
*
|
2017-10-03 21:31:18 +00:00
|
|
|
* Returns: %TRUE if @color points to valid colorimetry info.
|
2012-06-05 10:47:22 +00:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_video_colorimetry_from_string (GstVideoColorimetry * cinfo,
|
|
|
|
const gchar * color)
|
|
|
|
{
|
|
|
|
const ColorimetryInfo *ci;
|
2014-11-19 11:04:02 +00:00
|
|
|
gboolean res = FALSE;
|
2012-06-05 10:47:22 +00:00
|
|
|
|
2019-05-24 13:22:58 +00:00
|
|
|
if (!color) {
|
|
|
|
*cinfo = colorimetry[DEFAULT_UNKNOWN].color;
|
|
|
|
res = TRUE;
|
|
|
|
} else if ((ci = gst_video_get_colorimetry (color))) {
|
2012-06-05 10:47:22 +00:00
|
|
|
*cinfo = ci->color;
|
2014-11-19 11:04:02 +00:00
|
|
|
res = TRUE;
|
2012-06-05 10:47:22 +00:00
|
|
|
} else {
|
|
|
|
gint r, m, t, p;
|
|
|
|
|
|
|
|
if (sscanf (color, "%d:%d:%d:%d", &r, &m, &t, &p) == 4) {
|
|
|
|
cinfo->range = r;
|
|
|
|
cinfo->matrix = m;
|
|
|
|
cinfo->transfer = t;
|
|
|
|
cinfo->primaries = p;
|
2014-11-19 11:04:02 +00:00
|
|
|
res = TRUE;
|
2012-06-05 10:47:22 +00:00
|
|
|
}
|
|
|
|
}
|
2014-11-19 11:04:02 +00:00
|
|
|
return res;
|
2012-06-05 10:47:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-07-13 10:11:06 +00:00
|
|
|
* gst_video_colorimetry_to_string:
|
2012-06-05 10:47:22 +00:00
|
|
|
* @cinfo: a #GstVideoColorimetry
|
|
|
|
*
|
|
|
|
* Make a string representation of @cinfo.
|
|
|
|
*
|
2019-07-16 17:44:12 +00:00
|
|
|
* Returns: (transfer full) (nullable): a string representation of @cinfo
|
|
|
|
* or %NULL if all the entries of @cinfo are unknown values.
|
2012-06-05 10:47:22 +00:00
|
|
|
*/
|
|
|
|
gchar *
|
2016-09-30 11:54:24 +00:00
|
|
|
gst_video_colorimetry_to_string (const GstVideoColorimetry * cinfo)
|
2012-06-05 10:47:22 +00:00
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
for (i = 0; colorimetry[i].name; i++) {
|
|
|
|
if (IS_EQUAL (&colorimetry[i], cinfo)) {
|
|
|
|
return g_strdup (colorimetry[i].name);
|
|
|
|
}
|
|
|
|
}
|
2016-11-01 21:51:47 +00:00
|
|
|
if (!IS_UNKNOWN (cinfo)) {
|
|
|
|
return g_strdup_printf ("%d:%d:%d:%d", cinfo->range, cinfo->matrix,
|
|
|
|
cinfo->transfer, cinfo->primaries);
|
|
|
|
}
|
|
|
|
return NULL;
|
2012-06-05 10:47:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_video_colorimetry_matches:
|
2014-03-02 04:06:07 +00:00
|
|
|
* @cinfo: a #GstVideoInfo
|
2012-06-05 10:47:22 +00:00
|
|
|
* @color: a colorimetry string
|
|
|
|
*
|
|
|
|
* Check if the colorimetry information in @info matches that of the
|
|
|
|
* string @color.
|
|
|
|
*
|
2017-10-03 21:31:18 +00:00
|
|
|
* Returns: %TRUE if @color conveys the same colorimetry info as the color
|
2012-06-05 10:47:22 +00:00
|
|
|
* information in @info.
|
|
|
|
*/
|
|
|
|
gboolean
|
2016-09-30 11:54:24 +00:00
|
|
|
gst_video_colorimetry_matches (const GstVideoColorimetry * cinfo,
|
|
|
|
const gchar * color)
|
2012-06-05 10:47:22 +00:00
|
|
|
{
|
|
|
|
const ColorimetryInfo *ci;
|
|
|
|
|
|
|
|
if ((ci = gst_video_get_colorimetry (color)))
|
|
|
|
return IS_EQUAL (ci, cinfo);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-07-13 15:13:10 +00:00
|
|
|
/**
|
|
|
|
* gst_video_color_range_offsets:
|
|
|
|
* @range: a #GstVideoColorRange
|
|
|
|
* @info: a #GstVideoFormatInfo
|
2018-05-21 07:18:24 +00:00
|
|
|
* @offset: (out caller-allocates) (array fixed-size=4): output offsets
|
|
|
|
* @scale: (out caller-allocates) (array fixed-size=4): output scale
|
2012-07-13 15:13:10 +00:00
|
|
|
*
|
|
|
|
* Compute the offset and scale values for each component of @info. For each
|
|
|
|
* component, (c[i] - offset[i]) / scale[i] will scale the component c[i] to the
|
|
|
|
* range [0.0 .. 1.0].
|
|
|
|
*
|
|
|
|
* The reverse operation (c[i] * scale[i]) + offset[i] can be used to convert
|
|
|
|
* the component values in range [0.0 .. 1.0] back to their representation in
|
|
|
|
* @info and @range.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
gst_video_color_range_offsets (GstVideoColorRange range,
|
|
|
|
const GstVideoFormatInfo * info, gint offset[GST_VIDEO_MAX_COMPONENTS],
|
|
|
|
gint scale[GST_VIDEO_MAX_COMPONENTS])
|
|
|
|
{
|
|
|
|
gboolean yuv;
|
|
|
|
|
|
|
|
yuv = GST_VIDEO_FORMAT_INFO_IS_YUV (info);
|
|
|
|
|
|
|
|
switch (range) {
|
|
|
|
default:
|
|
|
|
case GST_VIDEO_COLOR_RANGE_0_255:
|
|
|
|
offset[0] = 0;
|
|
|
|
if (yuv) {
|
|
|
|
offset[1] = 1 << (info->depth[1] - 1);
|
|
|
|
offset[2] = 1 << (info->depth[2] - 1);
|
|
|
|
} else {
|
|
|
|
offset[1] = 0;
|
|
|
|
offset[2] = 0;
|
|
|
|
}
|
|
|
|
scale[0] = (1 << info->depth[0]) - 1;
|
|
|
|
scale[1] = (1 << info->depth[1]) - 1;
|
|
|
|
scale[2] = (1 << info->depth[2]) - 1;
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_COLOR_RANGE_16_235:
|
|
|
|
offset[0] = 1 << (info->depth[0] - 4);
|
|
|
|
scale[0] = 219 << (info->depth[0] - 8);
|
|
|
|
if (yuv) {
|
|
|
|
offset[1] = 1 << (info->depth[1] - 1);
|
|
|
|
offset[2] = 1 << (info->depth[2] - 1);
|
|
|
|
scale[1] = 224 << (info->depth[1] - 8);
|
|
|
|
scale[2] = 224 << (info->depth[2] - 8);
|
|
|
|
} else {
|
|
|
|
offset[1] = 1 << (info->depth[1] - 4);
|
|
|
|
offset[2] = 1 << (info->depth[2] - 4);
|
|
|
|
scale[1] = 219 << (info->depth[1] - 8);
|
|
|
|
scale[2] = 219 << (info->depth[2] - 8);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* alpha channel is always full range */
|
|
|
|
offset[3] = 0;
|
|
|
|
scale[3] = (1 << info->depth[3]) - 1;
|
|
|
|
|
|
|
|
GST_DEBUG ("scale: %d %d %d %d", scale[0], scale[1], scale[2], scale[3]);
|
|
|
|
GST_DEBUG ("offset: %d %d %d %d", offset[0], offset[1], offset[2], offset[3]);
|
|
|
|
}
|
|
|
|
|
2015-05-03 16:10:17 +00:00
|
|
|
/**
|
|
|
|
* gst_video_colorimetry_is_equal:
|
|
|
|
* @cinfo: a #GstVideoColorimetry
|
|
|
|
* @other: another #GstVideoColorimetry
|
|
|
|
*
|
|
|
|
* Compare the 2 colorimetry sets for equality
|
|
|
|
*
|
2017-10-03 21:31:18 +00:00
|
|
|
* Returns: %TRUE if @cinfo and @other are equal.
|
2015-05-03 16:10:17 +00:00
|
|
|
*
|
|
|
|
* Since: 1.6
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_video_colorimetry_is_equal (const GstVideoColorimetry * cinfo,
|
|
|
|
const GstVideoColorimetry * other)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (cinfo != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (other != NULL, FALSE);
|
|
|
|
|
|
|
|
return CI_IS_EQUAL (cinfo, other);
|
|
|
|
}
|
2012-07-13 15:13:10 +00:00
|
|
|
|
2022-07-16 14:36:22 +00:00
|
|
|
/**
|
|
|
|
* gst_video_colorimetry_is_equivalent:
|
|
|
|
* @cinfo: a #GstVideoColorimetry
|
|
|
|
* @bitdepth: bitdepth of a format associated with @cinfo
|
|
|
|
* @other: another #GstVideoColorimetry
|
|
|
|
* @other_bitdepth: bitdepth of a format associated with @other
|
|
|
|
*
|
|
|
|
* Compare the 2 colorimetry sets for functionally equality
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if @cinfo and @other are equivalent.
|
|
|
|
*
|
|
|
|
* Since: 1.22
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_video_colorimetry_is_equivalent (const GstVideoColorimetry * cinfo,
|
|
|
|
guint bitdepth, const GstVideoColorimetry * other, guint other_bitdepth)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (cinfo != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (other != NULL, FALSE);
|
|
|
|
|
|
|
|
if (cinfo->range != other->range || cinfo->matrix != other->matrix)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (!gst_video_color_primaries_is_equivalent (cinfo->primaries,
|
|
|
|
other->primaries)) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gst_video_transfer_function_is_equivalent (cinfo->transfer, bitdepth,
|
|
|
|
other->transfer, other_bitdepth);
|
|
|
|
}
|
|
|
|
|
2012-06-05 10:47:22 +00:00
|
|
|
#define WP_C 0.31006, 0.31616
|
|
|
|
#define WP_D65 0.31271, 0.32902
|
2019-03-12 15:42:11 +00:00
|
|
|
#define WP_CENTRE (1/3), (1/3)
|
|
|
|
#define WP_WHITE 0.314, 0.351
|
2012-06-05 10:47:22 +00:00
|
|
|
|
2014-11-18 10:09:40 +00:00
|
|
|
static const GstVideoColorPrimariesInfo color_primaries[] = {
|
2012-06-05 10:47:22 +00:00
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_UNKNOWN, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_BT709, WP_D65, 0.64, 0.33, 0.30, 0.60, 0.15, 0.06},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_BT470M, WP_C, 0.67, 0.33, 0.21, 0.71, 0.14, 0.08},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_BT470BG, WP_D65, 0.64, 0.33, 0.29, 0.60, 0.15,
|
|
|
|
0.06},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_SMPTE170M, WP_D65, 0.63, 0.34, 0.31, 0.595, 0.155,
|
|
|
|
0.07},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_SMPTE240M, WP_D65, 0.63, 0.34, 0.31, 0.595, 0.155,
|
|
|
|
0.07},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_FILM, WP_C, 0.681, 0.319, 0.243, 0.692, 0.145,
|
2015-01-08 09:45:46 +00:00
|
|
|
0.049},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_BT2020, WP_D65, 0.708, 0.292, 0.170, 0.797, 0.131,
|
2016-01-21 09:45:40 +00:00
|
|
|
0.046},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_ADOBERGB, WP_D65, 0.64, 0.33, 0.21, 0.71, 0.15,
|
2019-03-12 15:42:11 +00:00
|
|
|
0.06},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_SMPTEST428, WP_CENTRE, 1.0, 0.0, 0.0, 1.0, 0.0,
|
|
|
|
0.0},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_SMPTERP431, WP_WHITE, 0.68, 0.32, 0.265, 0.69,
|
|
|
|
0.15, 0.06},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_SMPTEEG432, WP_D65, 0.68, 0.32, 0.265, 0.69, 0.15,
|
|
|
|
0.06},
|
|
|
|
{GST_VIDEO_COLOR_PRIMARIES_EBU3213, WP_D65, 0.63, 0.34, 0.295, 0.605, 0.155,
|
|
|
|
0.077},
|
2012-06-05 10:47:22 +00:00
|
|
|
};
|
2014-11-18 10:09:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_video_color_primaries_get_info:
|
|
|
|
* @primaries: a #GstVideoColorPrimaries
|
|
|
|
*
|
|
|
|
* Get information about the chromaticity coordinates of @primaries.
|
|
|
|
*
|
|
|
|
* Returns: a #GstVideoColorPrimariesInfo for @primaries.
|
|
|
|
*
|
|
|
|
* Since: 1.6
|
|
|
|
*/
|
|
|
|
const GstVideoColorPrimariesInfo *
|
|
|
|
gst_video_color_primaries_get_info (GstVideoColorPrimaries primaries)
|
|
|
|
{
|
2016-07-11 21:13:32 +00:00
|
|
|
g_return_val_if_fail ((gint) primaries <
|
|
|
|
G_N_ELEMENTS (color_primaries), NULL);
|
2014-11-18 10:09:40 +00:00
|
|
|
|
|
|
|
return &color_primaries[primaries];
|
|
|
|
}
|
2014-09-24 09:04:15 +00:00
|
|
|
|
2022-07-16 14:36:22 +00:00
|
|
|
/**
|
|
|
|
* gst_video_color_primaries_is_equivalent:
|
|
|
|
* @primaries: a #GstVideoColorPrimaries
|
|
|
|
* @other: another #GstVideoColorPrimaries
|
|
|
|
*
|
|
|
|
* Checks whether @primaries and @other are functionally equivalent
|
|
|
|
*
|
|
|
|
* Returns: TRUE if @primaries and @other can be considered equivalent.
|
|
|
|
*
|
|
|
|
* Since: 1.22
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_video_color_primaries_is_equivalent (GstVideoColorPrimaries primaries,
|
|
|
|
GstVideoColorPrimaries other)
|
|
|
|
{
|
|
|
|
if (primaries == other)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* smpte-170m and 240m use the same reference RGB primaries and white point */
|
|
|
|
if ((primaries == GST_VIDEO_COLOR_PRIMARIES_SMPTE170M ||
|
|
|
|
primaries == GST_VIDEO_COLOR_PRIMARIES_SMPTE240M) &&
|
|
|
|
(other == GST_VIDEO_COLOR_PRIMARIES_SMPTE170M ||
|
|
|
|
other == GST_VIDEO_COLOR_PRIMARIES_SMPTE240M)) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2014-09-24 09:04:15 +00:00
|
|
|
/**
|
|
|
|
* gst_video_color_matrix_get_Kr_Kb:
|
|
|
|
* @matrix: a #GstVideoColorMatrix
|
2018-04-20 19:53:16 +00:00
|
|
|
* @Kr: (out): result red channel coefficient
|
|
|
|
* @Kb: (out): result blue channel coefficient
|
2014-09-24 09:04:15 +00:00
|
|
|
*
|
|
|
|
* Get the coefficients used to convert between Y'PbPr and R'G'B' using @matrix.
|
|
|
|
*
|
|
|
|
* When:
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* 0.0 <= [Y',R',G',B'] <= 1.0)
|
|
|
|
* (-0.5 <= [Pb,Pr] <= 0.5)
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* the general conversion is given by:
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* Y' = Kr*R' + (1-Kr-Kb)*G' + Kb*B'
|
|
|
|
* Pb = (B'-Y')/(2*(1-Kb))
|
|
|
|
* Pr = (R'-Y')/(2*(1-Kr))
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* and the other way around:
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* R' = Y' + Cr*2*(1-Kr)
|
|
|
|
* G' = Y' - Cb*2*(1-Kb)*Kb/(1-Kr-Kb) - Cr*2*(1-Kr)*Kr/(1-Kr-Kb)
|
|
|
|
* B' = Y' + Cb*2*(1-Kb)
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* Returns: TRUE if @matrix was a YUV color format and @Kr and @Kb contain valid
|
|
|
|
* values.
|
|
|
|
*
|
|
|
|
* Since: 1.6
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_video_color_matrix_get_Kr_Kb (GstVideoColorMatrix matrix, gdouble * Kr,
|
|
|
|
gdouble * Kb)
|
|
|
|
{
|
|
|
|
gboolean res = TRUE;
|
|
|
|
|
|
|
|
switch (matrix) {
|
|
|
|
/* RGB */
|
|
|
|
default:
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_RGB:
|
|
|
|
res = FALSE;
|
|
|
|
break;
|
|
|
|
/* YUV */
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_FCC:
|
|
|
|
*Kr = 0.30;
|
|
|
|
*Kb = 0.11;
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_BT709:
|
|
|
|
*Kr = 0.2126;
|
|
|
|
*Kb = 0.0722;
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_BT601:
|
|
|
|
*Kr = 0.2990;
|
|
|
|
*Kb = 0.1140;
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_SMPTE240M:
|
|
|
|
*Kr = 0.212;
|
|
|
|
*Kb = 0.087;
|
|
|
|
break;
|
2015-01-08 09:45:46 +00:00
|
|
|
case GST_VIDEO_COLOR_MATRIX_BT2020:
|
|
|
|
*Kr = 0.2627;
|
|
|
|
*Kb = 0.0593;
|
|
|
|
break;
|
2014-09-24 09:04:15 +00:00
|
|
|
}
|
|
|
|
GST_DEBUG ("matrix: %d, Kr %f, Kb %f", matrix, *Kr, *Kb);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
2014-11-11 15:11:15 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_video_color_transfer_encode:
|
|
|
|
* @func: a #GstVideoTransferFunction
|
|
|
|
* @val: a value
|
|
|
|
*
|
2020-11-25 19:16:53 +00:00
|
|
|
* Deprecated: 1.20: Use gst_video_transfer_function_encode() instead.
|
2020-09-11 18:15:14 +00:00
|
|
|
*
|
|
|
|
* Since: 1.6
|
|
|
|
*/
|
|
|
|
gdouble
|
|
|
|
gst_video_color_transfer_encode (GstVideoTransferFunction func, gdouble val)
|
|
|
|
{
|
|
|
|
return gst_video_transfer_function_encode (func, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_video_transfer_function_encode:
|
|
|
|
* @func: a #GstVideoTransferFunction
|
|
|
|
* @val: a value
|
|
|
|
*
|
2014-11-11 15:11:15 +00:00
|
|
|
* Convert @val to its gamma encoded value.
|
|
|
|
*
|
|
|
|
* For a linear value L in the range [0..1], conversion to the non-linear
|
|
|
|
* (gamma encoded) L' is in general performed with a power function like:
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* L' = L ^ (1 / gamma)
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* Depending on @func, different formulas might be applied. Some formulas
|
|
|
|
* encode a linear segment in the lower range.
|
|
|
|
*
|
2020-09-03 19:19:29 +00:00
|
|
|
* Returns: the gamma encoded value of @val
|
2014-11-11 15:11:15 +00:00
|
|
|
*
|
2020-09-11 18:15:14 +00:00
|
|
|
* Since: 1.20
|
2014-11-11 15:11:15 +00:00
|
|
|
*/
|
|
|
|
gdouble
|
2020-09-11 18:15:14 +00:00
|
|
|
gst_video_transfer_function_encode (GstVideoTransferFunction func, gdouble val)
|
2014-11-11 15:11:15 +00:00
|
|
|
{
|
|
|
|
gdouble res;
|
|
|
|
|
|
|
|
switch (func) {
|
|
|
|
case GST_VIDEO_TRANSFER_UNKNOWN:
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA10:
|
|
|
|
default:
|
|
|
|
res = val;
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA18:
|
|
|
|
res = pow (val, 1.0 / 1.8);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA20:
|
|
|
|
res = pow (val, 1.0 / 2.0);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA22:
|
|
|
|
res = pow (val, 1.0 / 2.2);
|
|
|
|
break;
|
2020-06-25 17:56:48 +00:00
|
|
|
case GST_VIDEO_TRANSFER_BT601:
|
2014-11-11 15:11:15 +00:00
|
|
|
case GST_VIDEO_TRANSFER_BT709:
|
2019-05-05 10:08:55 +00:00
|
|
|
case GST_VIDEO_TRANSFER_BT2020_10:
|
2014-11-11 15:11:15 +00:00
|
|
|
if (val < 0.018)
|
|
|
|
res = 4.5 * val;
|
|
|
|
else
|
|
|
|
res = 1.099 * pow (val, 0.45) - 0.099;
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_SMPTE240M:
|
|
|
|
if (val < 0.0228)
|
|
|
|
res = val * 4.0;
|
|
|
|
else
|
|
|
|
res = 1.1115 * pow (val, 0.45) - 0.1115;
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_SRGB:
|
|
|
|
if (val <= 0.0031308)
|
|
|
|
res = 12.92 * val;
|
|
|
|
else
|
|
|
|
res = 1.055 * pow (val, 1.0 / 2.4) - 0.055;
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA28:
|
|
|
|
res = pow (val, 1 / 2.8);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_LOG100:
|
|
|
|
if (val < 0.01)
|
|
|
|
res = 0.0;
|
|
|
|
else
|
|
|
|
res = 1.0 + log10 (val) / 2.0;
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_LOG316:
|
|
|
|
if (val < 0.0031622777)
|
|
|
|
res = 0.0;
|
|
|
|
else
|
|
|
|
res = 1.0 + log10 (val) / 2.5;
|
|
|
|
break;
|
2015-01-08 09:45:46 +00:00
|
|
|
case GST_VIDEO_TRANSFER_BT2020_12:
|
|
|
|
if (val < 0.0181)
|
|
|
|
res = 4.5 * val;
|
|
|
|
else
|
|
|
|
res = 1.0993 * pow (val, 0.45) - 0.0993;
|
|
|
|
break;
|
2016-01-21 09:45:40 +00:00
|
|
|
case GST_VIDEO_TRANSFER_ADOBERGB:
|
|
|
|
res = pow (val, 1.0 / 2.19921875);
|
|
|
|
break;
|
2019-05-05 10:22:13 +00:00
|
|
|
case GST_VIDEO_TRANSFER_SMPTE2084:
|
|
|
|
{
|
2022-02-02 16:04:40 +00:00
|
|
|
gdouble c1 = 0.8359375;
|
|
|
|
gdouble c2 = 18.8515625;
|
|
|
|
gdouble c3 = 18.6875;
|
|
|
|
gdouble m1 = 0.1593017578125;
|
|
|
|
gdouble m2 = 78.84375;
|
|
|
|
gdouble Ln = pow (val, m1);
|
2019-05-05 10:22:13 +00:00
|
|
|
|
|
|
|
/* val equal to 1 for peak white is ordinarily intended to
|
|
|
|
* correspond to a reference output luminance level of 10000 cd/m^2 */
|
2022-02-02 16:04:40 +00:00
|
|
|
res = pow ((c1 + c2 * Ln) / (1.0 + c3 * Ln), m2);
|
2019-05-05 10:22:13 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-05-05 12:02:55 +00:00
|
|
|
case GST_VIDEO_TRANSFER_ARIB_STD_B67:
|
|
|
|
{
|
|
|
|
gdouble a = 0.17883277;
|
|
|
|
gdouble b = 0.28466892;
|
|
|
|
gdouble c = 0.55991073;
|
|
|
|
|
|
|
|
/* For [0, 1] normalized source as defined by HEVC specification */
|
|
|
|
if (val > (1.0 / 12.0))
|
|
|
|
res = a * log (12.0 * val - b) + c;
|
|
|
|
else
|
|
|
|
res = sqrt (3.0 * val);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2014-11-11 15:11:15 +00:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_video_color_transfer_decode:
|
|
|
|
* @func: a #GstVideoTransferFunction
|
|
|
|
* @val: a value
|
|
|
|
*
|
2020-11-25 19:16:53 +00:00
|
|
|
* Deprecated: 1.20: Use gst_video_transfer_function_decode() instead.
|
2020-09-11 18:15:14 +00:00
|
|
|
*
|
|
|
|
* Since: 1.6
|
|
|
|
*/
|
|
|
|
gdouble
|
|
|
|
gst_video_color_transfer_decode (GstVideoTransferFunction func, gdouble val)
|
|
|
|
{
|
|
|
|
return gst_video_transfer_function_decode (func, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_video_transfer_function_decode:
|
|
|
|
* @func: a #GstVideoTransferFunction
|
|
|
|
* @val: a value
|
|
|
|
*
|
2014-11-11 15:11:15 +00:00
|
|
|
* Convert @val to its gamma decoded value. This is the inverse operation of
|
2021-03-30 09:18:17 +00:00
|
|
|
* gst_video_color_transfer_encode().
|
2014-11-11 15:11:15 +00:00
|
|
|
*
|
|
|
|
* For a non-linear value L' in the range [0..1], conversion to the linear
|
|
|
|
* L is in general performed with a power function like:
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* L = L' ^ gamma
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* Depending on @func, different formulas might be applied. Some formulas
|
|
|
|
* encode a linear segment in the lower range.
|
|
|
|
*
|
2020-09-03 19:19:29 +00:00
|
|
|
* Returns: the gamma decoded value of @val
|
2014-11-11 15:11:15 +00:00
|
|
|
*
|
2020-09-11 18:15:14 +00:00
|
|
|
* Since: 1.20
|
2014-11-11 15:11:15 +00:00
|
|
|
*/
|
|
|
|
gdouble
|
2020-09-11 18:15:14 +00:00
|
|
|
gst_video_transfer_function_decode (GstVideoTransferFunction func, gdouble val)
|
2014-11-11 15:11:15 +00:00
|
|
|
{
|
|
|
|
gdouble res;
|
|
|
|
|
|
|
|
switch (func) {
|
|
|
|
case GST_VIDEO_TRANSFER_UNKNOWN:
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA10:
|
|
|
|
default:
|
|
|
|
res = val;
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA18:
|
|
|
|
res = pow (val, 1.8);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA20:
|
|
|
|
res = pow (val, 2.0);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA22:
|
|
|
|
res = pow (val, 2.2);
|
|
|
|
break;
|
2020-06-25 17:56:48 +00:00
|
|
|
case GST_VIDEO_TRANSFER_BT601:
|
2014-11-11 15:11:15 +00:00
|
|
|
case GST_VIDEO_TRANSFER_BT709:
|
2019-05-05 10:08:55 +00:00
|
|
|
case GST_VIDEO_TRANSFER_BT2020_10:
|
2014-11-11 15:11:15 +00:00
|
|
|
if (val < 0.081)
|
|
|
|
res = val / 4.5;
|
|
|
|
else
|
|
|
|
res = pow ((val + 0.099) / 1.099, 1.0 / 0.45);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_SMPTE240M:
|
|
|
|
if (val < 0.0913)
|
|
|
|
res = val / 4.0;
|
|
|
|
else
|
|
|
|
res = pow ((val + 0.1115) / 1.1115, 1.0 / 0.45);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_SRGB:
|
|
|
|
if (val <= 0.04045)
|
|
|
|
res = val / 12.92;
|
|
|
|
else
|
|
|
|
res = pow ((val + 0.055) / 1.055, 2.4);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA28:
|
|
|
|
res = pow (val, 2.8);
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_LOG100:
|
|
|
|
if (val == 0.0)
|
|
|
|
res = 0.0;
|
|
|
|
else
|
|
|
|
res = pow (10.0, 2.0 * (val - 1.0));
|
|
|
|
break;
|
|
|
|
case GST_VIDEO_TRANSFER_LOG316:
|
|
|
|
if (val == 0.0)
|
|
|
|
res = 0.0;
|
|
|
|
else
|
|
|
|
res = pow (10.0, 2.5 * (val - 1.0));
|
|
|
|
break;
|
2015-01-08 09:45:46 +00:00
|
|
|
case GST_VIDEO_TRANSFER_BT2020_12:
|
|
|
|
if (val < 0.08145)
|
|
|
|
res = val / 4.5;
|
|
|
|
else
|
|
|
|
res = pow ((val + 0.0993) / 1.0993, 1.0 / 0.45);
|
|
|
|
break;
|
2016-01-21 09:45:40 +00:00
|
|
|
case GST_VIDEO_TRANSFER_ADOBERGB:
|
|
|
|
res = pow (val, 2.19921875);
|
|
|
|
break;
|
2019-05-05 10:22:13 +00:00
|
|
|
case GST_VIDEO_TRANSFER_SMPTE2084:
|
|
|
|
{
|
2022-02-02 16:04:40 +00:00
|
|
|
gdouble c1 = 0.8359375;
|
|
|
|
gdouble c2 = 18.8515625;
|
|
|
|
gdouble c3 = 18.6875;
|
|
|
|
gdouble m1 = 0.1593017578125;
|
|
|
|
gdouble m2 = 78.84375;
|
|
|
|
gdouble tmp = pow (val, 1 / m2);
|
|
|
|
gdouble tmp2 = MAX (tmp - c1, 0.0f);
|
|
|
|
|
|
|
|
res = pow (tmp2 / (c2 - c3 * tmp), 1 / m1);
|
2019-05-05 10:22:13 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-05-05 12:02:55 +00:00
|
|
|
case GST_VIDEO_TRANSFER_ARIB_STD_B67:
|
|
|
|
{
|
|
|
|
gdouble a = 0.17883277;
|
|
|
|
gdouble b = 0.28466892;
|
|
|
|
gdouble c = 0.55991073;
|
|
|
|
|
|
|
|
if (val > 0.5)
|
|
|
|
res = (exp ((val - c) / a) + b) / 12.0;
|
|
|
|
else
|
|
|
|
res = val * val / 3.0;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2014-11-11 15:11:15 +00:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2019-07-09 15:16:58 +00:00
|
|
|
|
|
|
|
/* conversion between GStreamer color{matrix,transfer,primaries} enum
|
|
|
|
* and indices defined by ITU-T H.273 and ISO/IEC 230001-8 specification */
|
|
|
|
|
|
|
|
/* FIXME 2.0: Define color{matrix,transfer,primaries} with explicit numbering
|
|
|
|
* to be matched with specification
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_video_color_matrix_to_iso:
|
|
|
|
* @matrix: a #GstVideoColorMatrix
|
|
|
|
*
|
|
|
|
* Converts #GstVideoColorMatrix to the "matrix coefficients"
|
|
|
|
* (MatrixCoefficients) value defined by "ISO/IEC 23001-8 Section 7.3 Table 4"
|
|
|
|
* and "ITU-T H.273 Table 4".
|
|
|
|
* "H.264 Table E-5" and "H.265 Table E.5" share the identical values.
|
|
|
|
*
|
|
|
|
* Returns: The value of ISO/IEC 23001-8 matrix coefficients.
|
|
|
|
*
|
|
|
|
* Since: 1.18
|
|
|
|
*/
|
|
|
|
guint
|
|
|
|
gst_video_color_matrix_to_iso (GstVideoColorMatrix matrix)
|
|
|
|
{
|
|
|
|
switch (matrix) {
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_RGB:
|
|
|
|
return 0;
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_BT709:
|
|
|
|
return 1;
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_FCC:
|
|
|
|
return 4;
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_BT601:
|
|
|
|
return 6;
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_SMPTE240M:
|
|
|
|
return 7;
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_BT2020:
|
|
|
|
return 9;
|
|
|
|
case GST_VIDEO_COLOR_MATRIX_UNKNOWN:
|
|
|
|
default:
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-09-07 09:10:16 +00:00
|
|
|
* gst_video_transfer_function_to_iso:
|
2019-07-09 15:16:58 +00:00
|
|
|
* @func: a #GstVideoTransferFunction
|
|
|
|
*
|
|
|
|
* Converts #GstVideoTransferFunction to the "transfer characteristics"
|
|
|
|
* (TransferCharacteristics) value defined by "ISO/IEC 23001-8 Section 7.2 Table 3"
|
|
|
|
* and "ITU-T H.273 Table 3".
|
|
|
|
* "H.264 Table E-4" and "H.265 Table E.4" share the identical values.
|
|
|
|
*
|
|
|
|
* Returns: The value of ISO/IEC 23001-8 transfer characteristics.
|
|
|
|
*
|
|
|
|
* Since: 1.18
|
|
|
|
*/
|
|
|
|
guint
|
2020-09-07 09:10:16 +00:00
|
|
|
gst_video_transfer_function_to_iso (GstVideoTransferFunction func)
|
2019-07-09 15:16:58 +00:00
|
|
|
{
|
|
|
|
switch (func) {
|
|
|
|
case GST_VIDEO_TRANSFER_BT709:
|
|
|
|
return 1;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA22:
|
|
|
|
return 4;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA28:
|
|
|
|
return 5;
|
2020-06-25 17:56:48 +00:00
|
|
|
case GST_VIDEO_TRANSFER_BT601:
|
|
|
|
return 6;
|
2019-07-09 15:16:58 +00:00
|
|
|
case GST_VIDEO_TRANSFER_SMPTE240M:
|
|
|
|
return 7;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA10:
|
|
|
|
return 8;
|
|
|
|
case GST_VIDEO_TRANSFER_LOG100:
|
|
|
|
return 9;
|
|
|
|
case GST_VIDEO_TRANSFER_LOG316:
|
|
|
|
return 10;
|
|
|
|
case GST_VIDEO_TRANSFER_SRGB:
|
|
|
|
return 13;
|
|
|
|
case GST_VIDEO_TRANSFER_BT2020_10:
|
|
|
|
return 14;
|
|
|
|
case GST_VIDEO_TRANSFER_BT2020_12:
|
|
|
|
return 15;
|
|
|
|
case GST_VIDEO_TRANSFER_SMPTE2084:
|
|
|
|
return 16;
|
|
|
|
case GST_VIDEO_TRANSFER_ARIB_STD_B67:
|
|
|
|
return 18;
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA18:
|
|
|
|
case GST_VIDEO_TRANSFER_GAMMA20:
|
|
|
|
case GST_VIDEO_TRANSFER_ADOBERGB:
|
|
|
|
case GST_VIDEO_TRANSFER_UNKNOWN:
|
|
|
|
default:
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_video_color_primaries_to_iso:
|
|
|
|
* @primaries: a #GstVideoColorPrimaries
|
|
|
|
*
|
|
|
|
* Converts #GstVideoColorPrimaries to the "colour primaries" (ColourPrimaries)
|
|
|
|
* value defined by "ISO/IEC 23001-8 Section 7.1 Table 2"
|
|
|
|
* and "ITU-T H.273 Table 2".
|
|
|
|
* "H.264 Table E-3" and "H.265 Table E.3" share the identical values.
|
|
|
|
*
|
|
|
|
* Returns: The value of ISO/IEC 23001-8 colour primaries.
|
|
|
|
*
|
|
|
|
* Since: 1.18
|
|
|
|
*/
|
|
|
|
guint
|
|
|
|
gst_video_color_primaries_to_iso (GstVideoColorPrimaries primaries)
|
|
|
|
{
|
|
|
|
switch (primaries) {
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_BT709:
|
|
|
|
return 1;
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_BT470M:
|
|
|
|
return 4;
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_BT470BG:
|
|
|
|
return 5;
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_SMPTE170M:
|
|
|
|
return 6;
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_SMPTE240M:
|
|
|
|
return 7;
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_FILM:
|
|
|
|
return 8;
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_BT2020:
|
|
|
|
return 9;
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_SMPTEST428:
|
|
|
|
return 10;
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_SMPTERP431:
|
|
|
|
return 11;
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_SMPTEEG432:
|
|
|
|
return 12;
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_EBU3213:
|
|
|
|
return 22;
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_ADOBERGB:
|
|
|
|
case GST_VIDEO_COLOR_PRIMARIES_UNKNOWN:
|
|
|
|
default:
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_video_color_matrix_from_iso:
|
|
|
|
* @value: a ITU-T H.273 matrix coefficients value
|
|
|
|
*
|
|
|
|
* Converts the @value to the #GstVideoColorMatrix
|
|
|
|
* The matrix coefficients (MatrixCoefficients) value is
|
|
|
|
* defined by "ISO/IEC 23001-8 Section 7.3 Table 4"
|
|
|
|
* and "ITU-T H.273 Table 4".
|
|
|
|
* "H.264 Table E-5" and "H.265 Table E.5" share the identical values.
|
|
|
|
*
|
|
|
|
* Returns: the matched #GstVideoColorMatrix
|
|
|
|
*
|
|
|
|
* Since: 1.18
|
|
|
|
*/
|
|
|
|
GstVideoColorMatrix
|
|
|
|
gst_video_color_matrix_from_iso (guint value)
|
|
|
|
{
|
|
|
|
switch (value) {
|
|
|
|
case 0:
|
|
|
|
return GST_VIDEO_COLOR_MATRIX_RGB;
|
|
|
|
case 1:
|
|
|
|
return GST_VIDEO_COLOR_MATRIX_BT709;
|
|
|
|
case 4:
|
|
|
|
return GST_VIDEO_COLOR_MATRIX_FCC;
|
|
|
|
case 5:
|
|
|
|
case 6:
|
|
|
|
return GST_VIDEO_COLOR_MATRIX_BT601;
|
|
|
|
case 7:
|
|
|
|
return GST_VIDEO_COLOR_MATRIX_SMPTE240M;
|
|
|
|
case 9:
|
|
|
|
return GST_VIDEO_COLOR_MATRIX_BT2020;
|
|
|
|
case 2:
|
|
|
|
default:
|
|
|
|
return GST_VIDEO_COLOR_MATRIX_UNKNOWN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-09-07 09:10:16 +00:00
|
|
|
* gst_video_transfer_function_from_iso:
|
2019-07-09 15:16:58 +00:00
|
|
|
* @value: a ITU-T H.273 transfer characteristics value
|
|
|
|
*
|
|
|
|
* Converts the @value to the #GstVideoTransferFunction
|
|
|
|
* The transfer characteristics (TransferCharacteristics) value is
|
|
|
|
* defined by "ISO/IEC 23001-8 Section 7.2 Table 3"
|
|
|
|
* and "ITU-T H.273 Table 3".
|
|
|
|
* "H.264 Table E-4" and "H.265 Table E.4" share the identical values.
|
|
|
|
*
|
|
|
|
* Returns: the matched #GstVideoTransferFunction
|
|
|
|
*
|
|
|
|
* Since: 1.18
|
|
|
|
*/
|
|
|
|
GstVideoTransferFunction
|
2020-09-07 09:10:16 +00:00
|
|
|
gst_video_transfer_function_from_iso (guint value)
|
2019-07-09 15:16:58 +00:00
|
|
|
{
|
|
|
|
switch (value) {
|
|
|
|
case 1:
|
|
|
|
return GST_VIDEO_TRANSFER_BT709;
|
|
|
|
case 4:
|
|
|
|
return GST_VIDEO_TRANSFER_GAMMA22;
|
|
|
|
case 5:
|
|
|
|
return GST_VIDEO_TRANSFER_GAMMA28;
|
2020-06-25 17:56:48 +00:00
|
|
|
case 6:
|
|
|
|
return GST_VIDEO_TRANSFER_BT601;
|
2019-07-09 15:16:58 +00:00
|
|
|
case 7:
|
|
|
|
return GST_VIDEO_TRANSFER_SMPTE240M;
|
|
|
|
case 8:
|
|
|
|
return GST_VIDEO_TRANSFER_GAMMA10;
|
|
|
|
case 9:
|
|
|
|
return GST_VIDEO_TRANSFER_LOG100;
|
|
|
|
case 10:
|
|
|
|
return GST_VIDEO_TRANSFER_LOG316;
|
|
|
|
case 13:
|
|
|
|
return GST_VIDEO_TRANSFER_SRGB;
|
|
|
|
case 14:
|
|
|
|
return GST_VIDEO_TRANSFER_BT2020_10;
|
|
|
|
case 15:
|
|
|
|
return GST_VIDEO_TRANSFER_BT2020_12;
|
|
|
|
case 16:
|
|
|
|
return GST_VIDEO_TRANSFER_SMPTE2084;
|
|
|
|
case 18:
|
|
|
|
return GST_VIDEO_TRANSFER_ARIB_STD_B67;
|
|
|
|
case 2:
|
|
|
|
default:
|
|
|
|
return GST_VIDEO_TRANSFER_UNKNOWN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_video_color_primaries_from_iso:
|
|
|
|
* @value: a ITU-T H.273 colour primaries value
|
|
|
|
*
|
|
|
|
* Converts the @value to the #GstVideoColorPrimaries
|
|
|
|
* The colour primaries (ColourPrimaries) value is
|
|
|
|
* defined by "ISO/IEC 23001-8 Section 7.1 Table 2" and "ITU-T H.273 Table 2".
|
|
|
|
* "H.264 Table E-3" and "H.265 Table E.3" share the identical values.
|
|
|
|
*
|
|
|
|
* Returns: the matched #GstVideoColorPrimaries
|
|
|
|
*
|
|
|
|
* Since: 1.18
|
|
|
|
*/
|
|
|
|
GstVideoColorPrimaries
|
|
|
|
gst_video_color_primaries_from_iso (guint value)
|
|
|
|
{
|
|
|
|
switch (value) {
|
|
|
|
case 1:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_BT709;
|
|
|
|
case 4:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_BT470M;
|
|
|
|
case 5:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_BT470BG;
|
|
|
|
case 6:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
|
|
|
|
case 7:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_SMPTE240M;
|
|
|
|
case 8:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_FILM;
|
|
|
|
case 9:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_BT2020;
|
|
|
|
case 10:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_SMPTEST428;
|
|
|
|
case 11:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_SMPTERP431;
|
|
|
|
case 12:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_SMPTEEG432;
|
|
|
|
case 22:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_EBU3213;
|
|
|
|
case 2:
|
|
|
|
default:
|
|
|
|
return GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
|
|
|
|
}
|
|
|
|
}
|
video-converter: Make fast path work for equivalent transfer functions
For example, BT709, BT601, and BT2020_10 all have theoretically
different transfer functions, but the same function in practice. In
these cases, we should use the fast path for negotiating. Also,
BT2020_12 is essentially the same as the other three, just with one more
decimal point, so it gives the same result for fewer bits. This is now
also aliased to the former three.
Also make videoconvert do passthrough if the caps have equivalent
transfer functions but are otherwise matching.
As of the previous commit, we write the correct transfer function for
BT601, instead of the (functionally identical but different ISO code)
transfer function for BT709. Files created using GStreamer prior to that
commit write the wrong transfer function for BT601 and are, strictly
speaking, 2:4:5:4 instead. However, this commit takes care of
negotiation, so that conversions from/to the same transfer function are
done using the fast path.
Fixes #783
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/724>
2020-06-26 09:22:08 +00:00
|
|
|
|
|
|
|
static GstVideoTransferFunction
|
|
|
|
map_equivalent_transfer (GstVideoTransferFunction func, guint bpp)
|
|
|
|
{
|
|
|
|
switch (func) {
|
|
|
|
case GST_VIDEO_TRANSFER_BT2020_12:
|
|
|
|
if (bpp >= 12)
|
|
|
|
break;
|
|
|
|
/* fallthrough */
|
|
|
|
case GST_VIDEO_TRANSFER_BT709:
|
|
|
|
case GST_VIDEO_TRANSFER_BT601:
|
|
|
|
case GST_VIDEO_TRANSFER_BT2020_10:
|
|
|
|
return GST_VIDEO_TRANSFER_BT709;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return func;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-09-07 09:10:16 +00:00
|
|
|
* gst_video_transfer_function_is_equivalent:
|
video-converter: Make fast path work for equivalent transfer functions
For example, BT709, BT601, and BT2020_10 all have theoretically
different transfer functions, but the same function in practice. In
these cases, we should use the fast path for negotiating. Also,
BT2020_12 is essentially the same as the other three, just with one more
decimal point, so it gives the same result for fewer bits. This is now
also aliased to the former three.
Also make videoconvert do passthrough if the caps have equivalent
transfer functions but are otherwise matching.
As of the previous commit, we write the correct transfer function for
BT601, instead of the (functionally identical but different ISO code)
transfer function for BT709. Files created using GStreamer prior to that
commit write the wrong transfer function for BT601 and are, strictly
speaking, 2:4:5:4 instead. However, this commit takes care of
negotiation, so that conversions from/to the same transfer function are
done using the fast path.
Fixes #783
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/724>
2020-06-26 09:22:08 +00:00
|
|
|
* @from_func: #GstVideoTransferFunction to convert from
|
|
|
|
* @from_bpp: bits per pixel to convert from
|
|
|
|
* @to_func: #GstVideoTransferFunction to convert into
|
|
|
|
* @to_bpp: bits per pixel to convert into
|
|
|
|
*
|
|
|
|
* Returns whether @from_func and @to_func are equivalent. There are cases
|
|
|
|
* (e.g. BT601, BT709, and BT2020_10) where several functions are functionally
|
|
|
|
* identical. In these cases, when doing conversion, we should consider them
|
|
|
|
* as equivalent. Also, BT2020_12 is the same as the aforementioned three for
|
|
|
|
* less than 12 bits per pixel.
|
|
|
|
*
|
|
|
|
* Returns: TRUE if @from_func and @to_func can be considered equivalent.
|
|
|
|
*
|
|
|
|
* Since: 1.18
|
|
|
|
*/
|
|
|
|
gboolean
|
2020-09-07 09:10:16 +00:00
|
|
|
gst_video_transfer_function_is_equivalent (GstVideoTransferFunction from_func,
|
video-converter: Make fast path work for equivalent transfer functions
For example, BT709, BT601, and BT2020_10 all have theoretically
different transfer functions, but the same function in practice. In
these cases, we should use the fast path for negotiating. Also,
BT2020_12 is essentially the same as the other three, just with one more
decimal point, so it gives the same result for fewer bits. This is now
also aliased to the former three.
Also make videoconvert do passthrough if the caps have equivalent
transfer functions but are otherwise matching.
As of the previous commit, we write the correct transfer function for
BT601, instead of the (functionally identical but different ISO code)
transfer function for BT709. Files created using GStreamer prior to that
commit write the wrong transfer function for BT601 and are, strictly
speaking, 2:4:5:4 instead. However, this commit takes care of
negotiation, so that conversions from/to the same transfer function are
done using the fast path.
Fixes #783
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/724>
2020-06-26 09:22:08 +00:00
|
|
|
guint from_bpp, GstVideoTransferFunction to_func, guint to_bpp)
|
|
|
|
{
|
|
|
|
from_func = map_equivalent_transfer (from_func, from_bpp);
|
|
|
|
to_func = map_equivalent_transfer (to_func, to_bpp);
|
|
|
|
if (from_func == GST_VIDEO_TRANSFER_BT2020_12 && to_bpp < 12 &&
|
|
|
|
to_func == GST_VIDEO_TRANSFER_BT709)
|
|
|
|
return TRUE;
|
|
|
|
return from_func == to_func;
|
|
|
|
}
|