From 9e8799924bbcadb155f9e0371e71468188df580f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 25 Feb 2015 15:33:26 +0100 Subject: [PATCH] video-scaler: add scaler optimization If we are vertically downscaling, it is better to first downscale and then do the horizontal scaling in most cases. --- gst-libs/gst/video/video-scaler.c | 57 ++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/gst-libs/gst/video/video-scaler.c b/gst-libs/gst/video/video-scaler.c index 08c2ce9..647d051 100644 --- a/gst-libs/gst/video/video-scaler.c +++ b/gst-libs/gst/video/video-scaler.c @@ -1423,27 +1423,54 @@ gst_video_scaler_2d (GstVideoScaler * hscale, GstVideoScaler * vscale, } } else { gint tmp_in = y; + gint s1, s2; if (hscale->tmpwidth < width) realloc_tmplines (hscale, n_elems, width); - /* horizontal and vertical scaling FIXME, we could probably do better - * by swapping horizontal or vertical scaling in some cases */ - for (i = y; i < height; i++) { - guint in, j; - - in = vscale->resampler.offset[i]; - while (tmp_in < in) - tmp_in++; - while (tmp_in < in + v_taps) { - hfunc (hscale, LINE (src, src_stride, tmp_in), TMP_LINE (vscale, - tmp_in, v_taps), x, width, n_elems); - tmp_in++; + s1 = width * vscale->resampler.offset[height - 1]; + s2 = width * height; + + if (s1 <= s2) { + for (i = y; i < height; i++) { + guint in, j; + + in = vscale->resampler.offset[i]; + while (tmp_in < in) + tmp_in++; + while (tmp_in < in + v_taps) { + hfunc (hscale, LINE (src, src_stride, tmp_in), TMP_LINE (vscale, + tmp_in, v_taps), x, width, n_elems); + tmp_in++; + } + for (j = 0; j < v_taps; j++) + lines[j] = TMP_LINE (vscale, in + j, v_taps); + + vfunc (vscale, lines, LINE (dest, dest_stride, i), i, width, n_elems); } - for (j = 0; j < v_taps; j++) - lines[j] = TMP_LINE (vscale, in + j, v_taps); + } else { + guint vx, vw; - vfunc (vscale, lines, LINE (dest, dest_stride, i), i, width, n_elems); + vx = hscale->resampler.offset[x]; + vw = hscale->resampler.offset[x + width - 1] + + hscale->resampler.max_taps; + + if (vscale->tmpwidth < vw) + realloc_tmplines (vscale, n_elems, vw); + + for (i = y; i < height; i++) { + guint in, j; + + in = vscale->resampler.offset[i]; + for (j = 0; j < v_taps; j++) + lines[j] = LINE (src, src_stride, in + j) + vx * n_elems; + + vfunc (vscale, lines, TMP_LINE (vscale, 0, v_taps) + vx * n_elems, i, + vw - vx, n_elems); + + hfunc (hscale, TMP_LINE (vscale, 0, v_taps), LINE (dest, dest_stride, + i), x, width, n_elems); + } } } } -- 2.7.4