From ff0fae50af855e9e76390265914f5e34a3b25e28 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 16 Oct 2021 10:58:53 +0200 Subject: [PATCH] vapostproc: Add add-borders property to keep dar Just as videoscale, it enables add-borders property (FALSE by default) in vapostproc to add border, if necessary, to keep the display aspect ratio from the original image. Part-of: --- subprojects/gst-plugins-bad/sys/va/gstvafilter.c | 19 ++++++++ subprojects/gst-plugins-bad/sys/va/gstvafilter.h | 5 ++ subprojects/gst-plugins-bad/sys/va/gstvavpp.c | 60 +++++++++++++++++++++++- 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/subprojects/gst-plugins-bad/sys/va/gstvafilter.c b/subprojects/gst-plugins-bad/sys/va/gstvafilter.c index 9ca1ee0..9aa4a31 100644 --- a/subprojects/gst-plugins-bad/sys/va/gstvafilter.c +++ b/subprojects/gst-plugins-bad/sys/va/gstvafilter.c @@ -706,6 +706,21 @@ gst_va_filter_install_properties (GstVaFilter * self, GObjectClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)); + /** + * GstVaPostProc:add-borders: + * + * If set to %TRUE the filter will add black borders if necessary to + * keep the display aspect ratio. + * + * Since: 1.20 + */ + g_object_class_install_property (klass, GST_VA_FILTER_PROP_ADD_BORDERS, + g_param_spec_boolean ("add-borders", "Add Borders", + "Add black borders if necessary to keep the display aspect ratio", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS + | GST_PARAM_MUTABLE_PLAYING)); + + return TRUE; } @@ -1524,6 +1539,10 @@ _fill_va_sample (GstVaFilter * self, GstVaSample * sample, if (direction == GST_PAD_SRC) { GST_OBJECT_LOCK (self); sample->rect = self->output_region; + sample->rect.x = sample->borders_w / 2; + sample->rect.y = sample->borders_h / 2; + sample->rect.width -= sample->borders_w; + sample->rect.height -= sample->borders_h; GST_OBJECT_UNLOCK (self); return TRUE; diff --git a/subprojects/gst-plugins-bad/sys/va/gstvafilter.h b/subprojects/gst-plugins-bad/sys/va/gstvafilter.h index e7f720f..b60b26e 100644 --- a/subprojects/gst-plugins-bad/sys/va/gstvafilter.h +++ b/subprojects/gst-plugins-bad/sys/va/gstvafilter.h @@ -52,6 +52,7 @@ enum { GST_VA_FILTER_PROP_AUTO_CONTRAST, GST_VA_FILTER_PROP_DISABLE_PASSTHROUGH, GST_VA_FILTER_PROP_DEINTERLACE_METHOD, + GST_VA_FILTER_PROP_ADD_BORDERS, GST_VA_FILTER_PROP_LAST }; @@ -67,6 +68,10 @@ struct _GstVaSample VASurfaceID *backward_references; guint num_backward_references; + /* borders to preserve dar */ + gint borders_h; + gint borders_w; + /*< private >*/ VASurfaceID surface; VARectangle rect; diff --git a/subprojects/gst-plugins-bad/sys/va/gstvavpp.c b/subprojects/gst-plugins-bad/sys/va/gstvavpp.c index 19ef2b1..63c6438 100644 --- a/subprojects/gst-plugins-bad/sys/va/gstvavpp.c +++ b/subprojects/gst-plugins-bad/sys/va/gstvavpp.c @@ -118,6 +118,9 @@ struct _GstVaVpp GstVideoOrientationMethod direction; GstVideoOrientationMethod prev_direction; GstVideoOrientationMethod tag_direction; + gboolean add_borders; + gint borders_h; + gint borders_w; GList *channels; }; @@ -299,6 +302,9 @@ gst_va_vpp_set_property (GObject * object, guint prop_id, self->op_flags &= ~VPP_CONVERT_DUMMY; break; } + case GST_VA_FILTER_PROP_ADD_BORDERS: + self->add_borders = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -357,6 +363,9 @@ gst_va_vpp_get_property (GObject * object, guint prop_id, GValue * value, case GST_VA_FILTER_PROP_DISABLE_PASSTHROUGH: g_value_set_boolean (value, (self->op_flags & VPP_CONVERT_DUMMY)); break; + case GST_VA_FILTER_PROP_ADD_BORDERS: + g_value_set_boolean (value, self->add_borders); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -391,6 +400,7 @@ gst_va_vpp_set_info (GstVaBaseTransform * btrans, GstCaps * incaps, { GstVaVpp *self = GST_VA_VPP (btrans); GstCapsFeatures *infeat, *outfeat; + gint from_dar_n, from_dar_d, to_dar_n, to_dar_d; if (GST_VIDEO_INFO_INTERLACE_MODE (in_info) != GST_VIDEO_INFO_INTERLACE_MODE (out_info)) { @@ -398,6 +408,47 @@ gst_va_vpp_set_info (GstVaBaseTransform * btrans, GstCaps * incaps, return FALSE; } + /* calculate possible borders if display-aspect-ratio change */ + { + if (!gst_util_fraction_multiply (GST_VIDEO_INFO_WIDTH (in_info), + GST_VIDEO_INFO_HEIGHT (in_info), GST_VIDEO_INFO_PAR_N (in_info), + GST_VIDEO_INFO_PAR_D (in_info), &from_dar_n, &from_dar_d)) { + from_dar_n = from_dar_d = -1; + } + + if (!gst_util_fraction_multiply (GST_VIDEO_INFO_WIDTH (out_info), + GST_VIDEO_INFO_HEIGHT (out_info), GST_VIDEO_INFO_PAR_N (out_info), + GST_VIDEO_INFO_PAR_D (out_info), &to_dar_n, &to_dar_d)) { + to_dar_n = to_dar_d = -1; + } + + self->borders_h = self->borders_w = 0; + if (to_dar_n != from_dar_n || to_dar_d != from_dar_d) { + if (self->add_borders) { + gint n, d, to_h, to_w; + + if (from_dar_n != -1 && from_dar_d != -1 + && gst_util_fraction_multiply (from_dar_n, from_dar_d, + out_info->par_d, out_info->par_n, &n, &d)) { + to_h = gst_util_uint64_scale_int (out_info->width, d, n); + if (to_h <= out_info->height) { + self->borders_h = out_info->height - to_h; + self->borders_w = 0; + } else { + to_w = gst_util_uint64_scale_int (out_info->height, n, d); + g_assert (to_w <= out_info->width); + self->borders_h = 0; + self->borders_w = out_info->width - to_w; + } + } else { + GST_WARNING_OBJECT (self, "Can't calculate borders"); + } + } else { + GST_WARNING_OBJECT (self, "Can't keep DAR!"); + } + } + } + if (!gst_video_info_is_equal (in_info, out_info)) { if (GST_VIDEO_INFO_FORMAT (in_info) != GST_VIDEO_INFO_FORMAT (out_info)) self->op_flags |= VPP_CONVERT_FORMAT; @@ -405,7 +456,8 @@ gst_va_vpp_set_info (GstVaBaseTransform * btrans, GstCaps * incaps, self->op_flags &= ~VPP_CONVERT_FORMAT; if (GST_VIDEO_INFO_WIDTH (in_info) != GST_VIDEO_INFO_WIDTH (out_info) - || GST_VIDEO_INFO_HEIGHT (in_info) != GST_VIDEO_INFO_HEIGHT (out_info)) + || GST_VIDEO_INFO_HEIGHT (in_info) != GST_VIDEO_INFO_HEIGHT (out_info) + || self->borders_h > 0 || self->borders_w > 0) self->op_flags |= VPP_CONVERT_SIZE; else self->op_flags &= ~VPP_CONVERT_SIZE; @@ -420,6 +472,10 @@ gst_va_vpp_set_info (GstVaBaseTransform * btrans, GstCaps * incaps, else self->op_flags &= ~VPP_CONVERT_FEATURE; + if (self->op_flags & VPP_CONVERT_SIZE) { + + } + if (gst_va_filter_set_video_info (btrans->filter, in_info, out_info)) { gst_va_vpp_update_passthrough (self, FALSE); return TRUE; @@ -662,6 +718,8 @@ gst_va_vpp_transform (GstBaseTransform * trans, GstBuffer * inbuf, dst = (GstVaSample) { .buffer = outbuf, + .borders_h = self->borders_h, + .borders_w = self->borders_w, .flags = gst_va_buffer_get_surface_flags (outbuf, &btrans->out_info), }; /* *INDENT-ON* */ -- 2.7.4