mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-22 22:16:22 +00:00
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>
This commit is contained in:
parent
1d0ccf8baa
commit
ad55d3ce9d
4 changed files with 79 additions and 1 deletions
|
@ -897,3 +897,51 @@ gst_video_color_primaries_from_iso (guint value)
|
|||
return GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_color_transfer_is_equivalent:
|
||||
* @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
|
||||
gst_video_color_transfer_is_equivalent (GstVideoTransferFunction from_func,
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -287,6 +287,12 @@ GstVideoTransferFunction gst_video_color_transfer_from_iso (guint value);
|
|||
GST_VIDEO_API
|
||||
GstVideoColorPrimaries gst_video_color_primaries_from_iso (guint value);
|
||||
|
||||
GST_VIDEO_API
|
||||
gboolean gst_video_color_transfer_is_equivalent (GstVideoTransferFunction from_func,
|
||||
guint from_bpp,
|
||||
GstVideoTransferFunction to_func,
|
||||
guint to_bpp);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_VIDEO_COLOR_H__ */
|
||||
|
|
|
@ -6741,6 +6741,7 @@ video_converter_lookup_fastpath (GstVideoConverter * convert)
|
|||
gboolean interlaced, same_matrix, same_primaries, same_size, crop, border;
|
||||
gboolean need_copy, need_set, need_mult;
|
||||
gint width, height;
|
||||
guint in_bpp, out_bpp;
|
||||
|
||||
width = GST_VIDEO_INFO_WIDTH (&convert->in_info);
|
||||
height = GST_VIDEO_INFO_HEIGHT (&convert->in_info);
|
||||
|
@ -6748,6 +6749,9 @@ video_converter_lookup_fastpath (GstVideoConverter * convert)
|
|||
if (GET_OPT_DITHER_QUANTIZATION (convert) != 1)
|
||||
return FALSE;
|
||||
|
||||
in_bpp = convert->in_info.finfo->bits;
|
||||
out_bpp = convert->out_info.finfo->bits;
|
||||
|
||||
/* we don't do gamma conversion in fastpath */
|
||||
in_transf = convert->in_info.colorimetry.transfer;
|
||||
out_transf = convert->out_info.colorimetry.transfer;
|
||||
|
@ -6755,7 +6759,9 @@ video_converter_lookup_fastpath (GstVideoConverter * convert)
|
|||
same_size = (width == convert->out_width && height == convert->out_height);
|
||||
|
||||
/* fastpaths don't do gamma */
|
||||
if (CHECK_GAMMA_REMAP (convert) && (!same_size || in_transf != out_transf))
|
||||
if (CHECK_GAMMA_REMAP (convert) && (!same_size
|
||||
|| !gst_video_color_transfer_is_equivalent (in_transf, in_bpp,
|
||||
out_transf, out_bpp)))
|
||||
return FALSE;
|
||||
|
||||
need_copy = (convert->alpha_mode & ALPHA_MODE_COPY) == ALPHA_MODE_COPY;
|
||||
|
|
|
@ -430,6 +430,9 @@ gst_video_convert_set_info (GstVideoFilter * filter,
|
|||
GstVideoInfo * out_info)
|
||||
{
|
||||
GstVideoConvert *space;
|
||||
GstBaseTransformClass *gstbasetransform_class =
|
||||
GST_BASE_TRANSFORM_GET_CLASS (filter);
|
||||
GstVideoInfo tmp_info;
|
||||
|
||||
space = GST_VIDEO_CONVERT_CAST (filter);
|
||||
|
||||
|
@ -451,6 +454,21 @@ gst_video_convert_set_info (GstVideoFilter * filter,
|
|||
if (in_info->interlace_mode != out_info->interlace_mode)
|
||||
goto format_mismatch;
|
||||
|
||||
/* if the only thing different in the caps is the transfer function, and
|
||||
* we're converting between equivalent transfer functions, do passthrough */
|
||||
tmp_info = *in_info;
|
||||
tmp_info.colorimetry.transfer = out_info->colorimetry.transfer;
|
||||
if (gst_video_info_is_equal (&tmp_info, out_info)) {
|
||||
if (gst_video_color_transfer_is_equivalent (in_info->colorimetry.transfer,
|
||||
in_info->finfo->bits, out_info->colorimetry.transfer,
|
||||
out_info->finfo->bits)) {
|
||||
gstbasetransform_class->passthrough_on_same_caps = FALSE;
|
||||
gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
gstbasetransform_class->passthrough_on_same_caps = TRUE;
|
||||
gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), FALSE);
|
||||
|
||||
space->convert = gst_video_converter_new (in_info, out_info,
|
||||
gst_structure_new ("GstVideoConvertConfig",
|
||||
|
|
Loading…
Reference in a new issue