mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 20:05:38 +00:00
videoscale: scale each field in interlace mode
When we are dealing with interlaced content, scale each field intependently so that we don't destroy the interlacing. See https://bugzilla.gnome.org/show_bug.cgi?id=588535
This commit is contained in:
parent
be866d4b78
commit
0085a77919
1 changed files with 48 additions and 11 deletions
|
@ -203,6 +203,9 @@ static void gst_video_scale_set_property (GObject * object, guint prop_id,
|
|||
static void gst_video_scale_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstFlowReturn do_scale (GstVideoFilter * filter, VSImage dest[4],
|
||||
VSImage src[4]);
|
||||
|
||||
#define gst_video_scale_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstVideoScale, gst_video_scale, GST_TYPE_VIDEO_FILTER);
|
||||
|
||||
|
@ -1002,7 +1005,7 @@ done:
|
|||
|
||||
static void
|
||||
gst_video_scale_setup_vs_image (VSImage * image, GstVideoFrame * frame,
|
||||
gint component, gint b_w, gint b_h)
|
||||
gint component, gint b_w, gint b_h, gboolean interlaced, gint field)
|
||||
{
|
||||
GstVideoFormat format;
|
||||
gint width, height;
|
||||
|
@ -1018,6 +1021,11 @@ gst_video_scale_setup_vs_image (VSImage * image, GstVideoFrame * frame,
|
|||
image->height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (frame->info.finfo,
|
||||
component, MAX (1, height - b_h));
|
||||
|
||||
if (interlaced) {
|
||||
image->real_height /= 2;
|
||||
image->height /= 2;
|
||||
}
|
||||
|
||||
image->border_top = (image->real_height - image->height) / 2;
|
||||
image->border_bottom = image->real_height - image->height - image->border_top;
|
||||
|
||||
|
@ -1035,12 +1043,19 @@ gst_video_scale_setup_vs_image (VSImage * image, GstVideoFrame * frame,
|
|||
image->border_right = image->real_width - image->width - image->border_left;
|
||||
}
|
||||
|
||||
image->real_pixels = frame->data[component];
|
||||
image->stride = frame->info.stride[component];
|
||||
image->real_pixels = GST_VIDEO_FRAME_PLANE_DATA (frame, component);
|
||||
image->stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, component);
|
||||
|
||||
if (interlaced) {
|
||||
if (field == 1)
|
||||
image->real_pixels += image->stride;
|
||||
image->stride *= 2;
|
||||
}
|
||||
|
||||
image->pixels =
|
||||
image->real_pixels + image->border_top * image->stride +
|
||||
image->border_left * GST_VIDEO_FRAME_COMP_PSTRIDE (frame, component);
|
||||
|
||||
}
|
||||
|
||||
static const guint8 *
|
||||
|
@ -1111,11 +1126,39 @@ gst_video_scale_transform_frame (GstVideoFilter * filter,
|
|||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
VSImage dest[4] = { {NULL,}, };
|
||||
VSImage src[4] = { {NULL,}, };
|
||||
gint i;
|
||||
gboolean interlaced;
|
||||
|
||||
interlaced = GST_VIDEO_FRAME_IS_INTERLACED (in_frame);
|
||||
|
||||
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (in_frame); i++) {
|
||||
gst_video_scale_setup_vs_image (&src[i], in_frame, i, 0, 0, interlaced, 0);
|
||||
gst_video_scale_setup_vs_image (&dest[i], out_frame, i,
|
||||
videoscale->borders_w, videoscale->borders_h, interlaced, 0);
|
||||
}
|
||||
ret = do_scale (filter, dest, src);
|
||||
|
||||
if (interlaced) {
|
||||
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (in_frame); i++) {
|
||||
gst_video_scale_setup_vs_image (&src[i], in_frame, i, 0, 0, interlaced,
|
||||
1);
|
||||
gst_video_scale_setup_vs_image (&dest[i], out_frame, i,
|
||||
videoscale->borders_w, videoscale->borders_h, interlaced, 1);
|
||||
}
|
||||
ret = do_scale (filter, dest, src);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
do_scale (GstVideoFilter * filter, VSImage dest[4], VSImage src[4])
|
||||
{
|
||||
GstVideoScale *videoscale = GST_VIDEO_SCALE (filter);
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
gint method;
|
||||
const guint8 *black;
|
||||
gboolean add_borders;
|
||||
GstVideoFormat format;
|
||||
gint i;
|
||||
gboolean add_borders;
|
||||
|
||||
GST_OBJECT_LOCK (videoscale);
|
||||
method = videoscale->method;
|
||||
|
@ -1133,12 +1176,6 @@ gst_video_scale_transform_frame (GstVideoFilter * filter,
|
|||
method = GST_VIDEO_SCALE_BILINEAR;
|
||||
}
|
||||
|
||||
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (in_frame); i++) {
|
||||
gst_video_scale_setup_vs_image (&src[i], in_frame, i, 0, 0);
|
||||
gst_video_scale_setup_vs_image (&dest[i], out_frame, i,
|
||||
videoscale->borders_w, videoscale->borders_h);
|
||||
}
|
||||
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, filter,
|
||||
"doing videoscale format %s", GST_VIDEO_INFO_NAME (&filter->in_info));
|
||||
|
||||
|
|
Loading…
Reference in a new issue