mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-01 05:39:51 +00:00
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.
This commit is contained in:
parent
cf69e7269c
commit
e7544dc57e
2 changed files with 114 additions and 0 deletions
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue