Commit 5e752f4e authored by Wim Taymans's avatar Wim Taymans
Browse files

video-converter: fix interlaced scaling some more

Fix problem with the line cache where it would forget the first line in
the cache in some cases.
Keep as much backlog as we have taps. This generally works better and we
could do even better by calculating the overlap in all taps.
Allocated enough lines for the line cache.
Use only half the number of taps for the interlaced lines because we
only have half the number of lines.
The pixel shift should be relative to the new output pixel size so scale
it.
Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=767921
parent 950c73af
......@@ -395,8 +395,6 @@ gst_line_cache_get_lines (GstLineCache * cache, gint out_line, gint in_line,
g_ptr_array_remove_range (cache->lines, 0, to_remove);
}
cache->first += to_remove;
if (cache->first < in_line)
cache->first = in_line;
} else if (in_line < cache->first) {
gst_line_cache_clear (cache);
cache->first = in_line;
......@@ -1457,7 +1455,7 @@ chain_vscale (GstVideoConverter * convert, GstLineCache * prev)
taps, convert->in_height, convert->out_height, convert->config);
gst_video_scaler_get_coeff (convert->v_scaler_i, 0, NULL, &taps_i);
backlog = BACKLOG;
backlog = taps_i;
}
convert->v_scaler_p =
gst_video_scaler_new (method, 0, taps, convert->in_height,
......@@ -1909,8 +1907,8 @@ setup_allocators (GstVideoConverter * convert)
if (!cache->pass_alloc) {
/* can't pass allocator, make new temp line allocator */
user_data =
converter_alloc_new (sizeof (guint16) * width * 4, n_lines + BACKLOG,
convert, NULL);
converter_alloc_new (sizeof (guint16) * width * 4,
n_lines + cache->backlog, convert, NULL);
notify = (GDestroyNotify) converter_alloc_free;
alloc_line = get_temp_line;
alloc_writable = FALSE;
......
......@@ -410,6 +410,8 @@ gst_video_resampler_init (GstVideoResampler * resampler,
params.dx = ceil (2.0 * params.envelope / params.fx);
n_taps = CLAMP (params.dx, 0, max_taps);
}
if (flags & GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS && n_taps > 3)
n_taps /= 2;
params.fx = 2.0 * params.envelope / n_taps;
params.ex = 2.0 / n_taps;
......
......@@ -116,6 +116,9 @@ typedef enum {
/**
* GstVideoResamplerFlags:
* @GST_VIDEO_RESAMPLER_FLAG_NONE: no flags
* @GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS: when no taps are given, half the
* number of calculated taps. This can be used when making scalers
* for the different fields of an interlaced picture. Since 1.10
*
* Different resampler flags.
*
......@@ -123,6 +126,7 @@ typedef enum {
*/
typedef enum {
GST_VIDEO_RESAMPLER_FLAG_NONE = (0),
GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS = (1 << 0),
} GstVideoResamplerFlags;
/**
......
......@@ -185,6 +185,8 @@ scaler_dump (GstVideoScaler * scale)
#endif
}
#define INTERLACE_SHIFT 0.5
/**
* gst_video_scaler_new: (skip)
* @method: a #GstVideoResamplerMethod
......@@ -221,14 +223,18 @@ gst_video_scaler_new (GstVideoResamplerMethod method, GstVideoScalerFlags flags,
if (flags & GST_VIDEO_SCALER_FLAG_INTERLACED) {
GstVideoResampler tresamp, bresamp;
gdouble shift;
shift = (INTERLACE_SHIFT * out_size) / in_size;
gst_video_resampler_init (&tresamp, method, 0, (out_size + 1) / 2, n_taps,
-0.5, (in_size + 1) / 2, (out_size + 1) / 2, options);
gst_video_resampler_init (&tresamp, method,
GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS, (out_size + 1) / 2, n_taps, shift,
(in_size + 1) / 2, (out_size + 1) / 2, options);
n_taps = tresamp.max_taps;
gst_video_resampler_init (&bresamp, method, 0, out_size - tresamp.out_size,
n_taps, 0.5, in_size - tresamp.in_size,
n_taps, -shift, in_size - tresamp.in_size,
out_size - tresamp.out_size, options);
resampler_zip (&scale->resampler, &tresamp, &bresamp);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment