From e7544dc57ecef55ac2a39053307b5904644156ee Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 18 Oct 2013 18:08:25 +0200 Subject: [PATCH] vaapipostproc: add initial support for scaling. Add initial support for basic scaling with size specified through the "width" and "height" properties. If either user-provided dimension is zero and "force-aspect-ratio" is set to true (the default), then the other dimension is scaled to preserve the aspect ratio. --- gst/vaapi/gstvaapipostproc.c | 111 +++++++++++++++++++++++++++++++++++ gst/vaapi/gstvaapipostproc.h | 3 + 2 files changed, 114 insertions(+) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 95db300f2e..1abc228454 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -134,6 +134,9 @@ enum { PROP_0, PROP_FORMAT, + PROP_WIDTH, + PROP_HEIGHT, + PROP_FORCE_ASPECT_RATIO, PROP_DEINTERLACE_MODE, PROP_DEINTERLACE_METHOD, }; @@ -611,6 +614,11 @@ gst_vaapipostproc_update_src_caps(GstVaapiPostproc *postproc, GstCaps *caps, if (postproc->format != GST_VIDEO_INFO_FORMAT(&postproc->sinkpad_info)) postproc->flags |= GST_VAAPI_POSTPROC_FLAG_FORMAT; + + if ((postproc->width || postproc->height) && + postproc->width != GST_VIDEO_INFO_WIDTH(&postproc->sinkpad_info) && + postproc->height != GST_VIDEO_INFO_HEIGHT(&postproc->sinkpad_info)) + postproc->flags |= GST_VAAPI_POSTPROC_FLAG_SIZE; return TRUE; } @@ -743,6 +751,38 @@ ensure_allowed_srcpad_caps(GstVaapiPostproc *postproc) return postproc->allowed_srcpad_caps != NULL; } +static void +find_best_size(GstVaapiPostproc *postproc, GstVideoInfo *vip, + guint *width_ptr, guint *height_ptr) +{ + guint width, height; + + width = GST_VIDEO_INFO_WIDTH(vip); + height = GST_VIDEO_INFO_HEIGHT(vip); + if (postproc->width && postproc->height) { + width = postproc->width; + height = postproc->height; + } + else if (postproc->keep_aspect) { + const gdouble ratio = (gdouble)width / height; + if (postproc->width) { + width = postproc->width; + height = postproc->width / ratio; + } + else if (postproc->height) { + height = postproc->height; + width = postproc->height * ratio; + } + } + else if (postproc->width) + width = postproc->width; + else if (postproc->height) + height = postproc->height; + + *width_ptr = width; + *height_ptr = height; +} + static GstCaps * gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, GstPadDirection direction, GstCaps *caps) @@ -751,6 +791,7 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, GstVideoInfo vi; GstVideoFormat format; GstCaps *out_caps; + guint width, height; gint fps_n, fps_d, par_n, par_d; if (!gst_caps_is_fixed(caps)) { @@ -790,6 +831,9 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans, /* Signal the other pad that we generate only progressive frames */ GST_VIDEO_INFO_INTERLACE_MODE(&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; + + find_best_size(postproc, &vi, &width, &height); + gst_video_info_set_format(&vi, format, width, height); } else { if (is_deinterlace_enabled(postproc, &vi)) { @@ -1165,6 +1209,15 @@ gst_vaapipostproc_set_property( case PROP_FORMAT: postproc->format = g_value_get_enum(value); break; + case PROP_WIDTH: + postproc->width = g_value_get_uint(value); + break; + case PROP_HEIGHT: + postproc->height = g_value_get_uint(value); + break; + case PROP_FORCE_ASPECT_RATIO: + postproc->keep_aspect = g_value_get_boolean(value); + break; case PROP_DEINTERLACE_MODE: postproc->deinterlace_mode = g_value_get_enum(value); break; @@ -1191,6 +1244,15 @@ gst_vaapipostproc_get_property( case PROP_FORMAT: g_value_set_enum(value, postproc->format); break; + case PROP_WIDTH: + g_value_set_uint(value, postproc->width); + break; + case PROP_HEIGHT: + g_value_set_uint(value, postproc->height); + break; + case PROP_FORCE_ASPECT_RATIO: + g_value_set_boolean(value, postproc->keep_aspect); + break; case PROP_DEINTERLACE_MODE: g_value_set_enum(value, postproc->deinterlace_mode); break; @@ -1294,6 +1356,54 @@ gst_vaapipostproc_class_init(GstVaapiPostprocClass *klass) g_object_class_install_property(object_class, PROP_FORMAT, filter_op->pspec); + /** + * GstVaapiPostproc:width: + * + * The forced output width in pixels. If set to zero, the width is + * calculated from the height if aspect ration is preserved, or + * inherited from the sink caps width + */ + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_uint("width", + "Width", + "Forced output width", + 0, G_MAXINT, 0, + G_PARAM_READWRITE)); + + /** + * GstVaapiPostproc:height: + * + * The forced output height in pixels. If set to zero, the height + * is calculated from the width if aspect ration is preserved, or + * inherited from the sink caps height + */ + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_uint("height", + "Height", + "Forced output height", + 0, G_MAXINT, 0, + G_PARAM_READWRITE)); + + /** + * GstVaapiPostproc:force-aspect-ratio: + * + * When enabled, scaling respects video aspect ratio; when + * disabled, the video is distorted to fit the width and height + * properties. + */ + g_object_class_install_property + (object_class, + PROP_FORCE_ASPECT_RATIO, + g_param_spec_boolean("force-aspect-ratio", + "Force aspect ratio", + "When enabled, scaling will respect original aspect ratio", + TRUE, + G_PARAM_READWRITE)); + g_ptr_array_unref(filter_ops); } @@ -1304,6 +1414,7 @@ gst_vaapipostproc_init(GstVaapiPostproc *postproc) postproc->deinterlace_mode = DEFAULT_DEINTERLACE_MODE; postproc->deinterlace_method = DEFAULT_DEINTERLACE_METHOD; postproc->field_duration = GST_CLOCK_TIME_NONE; + postproc->keep_aspect = TRUE; gst_video_info_init(&postproc->sinkpad_info); gst_video_info_init(&postproc->srcpad_info); diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index b85b3cb7c8..b82f751748 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -111,6 +111,8 @@ struct _GstVaapiPostproc { GstVideoInfo filter_pool_info; GArray *filter_formats; GstVideoFormat format; /* output video format (encoded) */ + guint width; + guint height; guint flags; GstCaps *allowed_sinkpad_caps; @@ -131,6 +133,7 @@ struct _GstVaapiPostproc { guint is_raw_yuv : 1; guint use_vpp : 1; + guint keep_aspect : 1; }; struct _GstVaapiPostprocClass {