GDestroyNotify notify;
} ConverterAlloc;
+typedef void (*FastConvertFunc) (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest, gint plane);
+
struct _GstVideoConverter
{
gint flags;
GstVideoFrame *dest;
/* fastpath */
- GstVideoFormat fformat;
- GstVideoScaler *fh_scaler[4];
- GstVideoScaler *fv_scaler[4];
ConverterAlloc *flines;
gpointer *lineptr;
+
+ GstVideoFormat fformat[4];
+ gint fin_x[4];
+ gint fin_y[4];
+ gint fout_x[4];
+ gint fout_y[4];
+ gint fout_width[4];
+ gint fout_height[4];
+ gint fsplane[4];
+ GstVideoScaler *fh_scaler[4];
+ GstVideoScaler *fv_scaler[4];
+ FastConvertFunc fconvert[4];
};
typedef gpointer (*GstLineCacheAllocLineFunc) (GstLineCache * cache, gint idx,
}
}
-static void
-convert_I420_Y42B (GstVideoConverter * convert, const GstVideoFrame * src,
- GstVideoFrame * dest)
-{
- gint width = convert->in_width;
- gint height = convert->in_height;
-
- video_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
- FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
- FRAME_GET_Y_STRIDE (src), width, height);
-
- video_orc_planar_chroma_420_422 (FRAME_GET_U_LINE (dest, 0),
- 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (dest, 1),
- 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
- FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
-
- video_orc_planar_chroma_420_422 (FRAME_GET_V_LINE (dest, 0),
- 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (dest, 1),
- 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
- FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
-}
-
-static void
-convert_I420_Y444 (GstVideoConverter * convert, const GstVideoFrame * src,
- GstVideoFrame * dest)
-{
- gint width = convert->in_width;
- gint height = convert->in_height;
-
- video_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
- FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
- FRAME_GET_Y_STRIDE (src), width, height);
-
- video_orc_planar_chroma_420_444 (FRAME_GET_U_LINE (dest, 0),
- 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (dest, 1),
- 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
- FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
-
- video_orc_planar_chroma_420_444 (FRAME_GET_V_LINE (dest, 0),
- 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (dest, 1),
- 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
- FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
-
- /* now handle last line */
- if (height & 1) {
- UNPACK_FRAME (src, convert->tmpline, height - 1, convert->in_x, width);
- PACK_FRAME (dest, convert->tmpline, height - 1, width);
- }
-}
-
static void
convert_YUY2_I420 (GstVideoConverter * convert, const GstVideoFrame * src,
GstVideoFrame * dest)
convert_fill_border (convert, dest);
}
-static void
-convert_Y42B_I420 (GstVideoConverter * convert, const GstVideoFrame * src,
- GstVideoFrame * dest)
-{
- gint width = convert->in_width;
- gint height = convert->in_height;
-
- video_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
- FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
- FRAME_GET_Y_STRIDE (src), width, height);
-
- video_orc_planar_chroma_422_420 (FRAME_GET_U_LINE (dest, 0),
- FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
- 2 * FRAME_GET_U_STRIDE (src), FRAME_GET_U_LINE (src, 1),
- 2 * FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
-
- video_orc_planar_chroma_422_420 (FRAME_GET_V_LINE (dest, 0),
- FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
- 2 * FRAME_GET_V_STRIDE (src), FRAME_GET_V_LINE (src, 1),
- 2 * FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
-
- /* now handle last line */
- if (height & 1) {
- UNPACK_FRAME (src, convert->tmpline, height - 1, convert->in_x, width);
- PACK_FRAME (dest, convert->tmpline, height - 1, width);
- }
-}
-
-static void
-convert_Y42B_Y444 (GstVideoConverter * convert, const GstVideoFrame * src,
- GstVideoFrame * dest)
-{
- gint width = convert->in_width;
- gint height = convert->in_height;
- guint8 *dy, *sy, *du, *su, *dv, *sv;
-
- sy = FRAME_GET_Y_LINE (src, convert->in_y);
- sy += convert->in_x;
- su = FRAME_GET_U_LINE (src, convert->in_y);
- su += convert->in_x >> 1;
- sv = FRAME_GET_V_LINE (src, convert->in_y);
- sv += convert->in_x >> 1;
-
- dy = FRAME_GET_Y_LINE (dest, convert->out_y);
- dy += convert->out_x;
- du = FRAME_GET_U_LINE (dest, convert->out_y);
- du += convert->out_x;
- dv = FRAME_GET_V_LINE (dest, convert->out_y);
- dv += convert->out_x;
-
- video_orc_memcpy_2d (dy, FRAME_GET_Y_STRIDE (dest), sy,
- FRAME_GET_Y_STRIDE (src), width, height);
-
- video_orc_planar_chroma_422_444 (du,
- FRAME_GET_U_STRIDE (dest), su,
- FRAME_GET_U_STRIDE (src), (width + 1) / 2, height);
-
- video_orc_planar_chroma_422_444 (dv,
- FRAME_GET_V_STRIDE (dest), sv,
- FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
-
- convert_fill_border (convert, dest);
-}
-
static void
convert_Y42B_YUY2 (GstVideoConverter * convert, const GstVideoFrame * src,
GstVideoFrame * dest)
convert_fill_border (convert, dest);
}
-static void
-convert_Y444_I420 (GstVideoConverter * convert, const GstVideoFrame * src,
- GstVideoFrame * dest)
-{
- gint width = convert->in_width;
- gint height = convert->in_height;
-
- video_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
- FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
- FRAME_GET_Y_STRIDE (src), width, height);
-
- video_orc_planar_chroma_444_420 (FRAME_GET_U_LINE (dest, 0),
- FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
- 2 * FRAME_GET_U_STRIDE (src), FRAME_GET_U_LINE (src, 1),
- 2 * FRAME_GET_U_STRIDE (src), width / 2, height / 2);
-
- video_orc_planar_chroma_444_420 (FRAME_GET_V_LINE (dest, 0),
- FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
- 2 * FRAME_GET_V_STRIDE (src), FRAME_GET_V_LINE (src, 1),
- 2 * FRAME_GET_V_STRIDE (src), width / 2, height / 2);
-
- /* now handle last line */
- if (height & 1) {
- UNPACK_FRAME (src, convert->tmpline, height - 1, convert->in_x, width);
- PACK_FRAME (dest, convert->tmpline, height - 1, width);
- }
-}
-
-static void
-convert_Y444_Y42B (GstVideoConverter * convert, const GstVideoFrame * src,
- GstVideoFrame * dest)
-{
- gint width = convert->in_width;
- gint height = convert->in_height;
- guint8 *sy, *su, *sv, *dy, *du, *dv;
-
- sy = FRAME_GET_Y_LINE (src, convert->in_y);
- sy += convert->in_x;
- su = FRAME_GET_U_LINE (src, convert->in_y);
- su += convert->in_x;
- sv = FRAME_GET_V_LINE (src, convert->in_y);
- sv += convert->in_x;
-
- dy = FRAME_GET_Y_LINE (dest, convert->out_y);
- dy += convert->out_x;
- du = FRAME_GET_U_LINE (dest, convert->out_y);
- du += convert->out_x >> 1;
- dv = FRAME_GET_V_LINE (dest, convert->out_y);
- dv += convert->out_x >> 1;
-
- video_orc_memcpy_2d (dy,
- FRAME_GET_Y_STRIDE (dest), sy, FRAME_GET_Y_STRIDE (src), width, height);
-
- video_orc_planar_chroma_444_422 (du,
- FRAME_GET_U_STRIDE (dest), su,
- FRAME_GET_U_STRIDE (src), width / 2, height);
-
- video_orc_planar_chroma_444_422 (dv,
- FRAME_GET_V_STRIDE (dest), sv,
- FRAME_GET_V_STRIDE (src), width / 2, height);
-
- convert_fill_border (convert, dest);
-}
-
static void
convert_Y444_YUY2 (GstVideoConverter * convert, const GstVideoFrame * src,
GstVideoFrame * dest)
#define GET_TMP_LINE(fl,idx) &fl->data[fl->stride * ((idx) % fl->n_lines)]
static void
-convert_scale_planes (GstVideoConverter * convert,
- const GstVideoFrame * src, GstVideoFrame * dest)
+convert_plane_copy (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest, gint plane)
{
- int k, n_planes;
- GstVideoFormat format = convert->fformat;
- const GstVideoFormatInfo *in_finfo, *out_finfo;
- gpointer *lines = convert->lineptr;
+ guint8 *s, *d;
+ gint splane = convert->fsplane[plane];
- in_finfo = convert->in_info.finfo;
- out_finfo = convert->out_info.finfo;
+ s = FRAME_GET_PLANE_LINE (src, splane, convert->fin_y[splane]);
+ s += convert->fin_x[splane];
+ d = FRAME_GET_PLANE_LINE (dest, plane, convert->fout_y[plane]);
+ d += convert->fout_x[plane];
- n_planes = GST_VIDEO_FRAME_N_PLANES (src);
+ video_orc_memcpy_2d (d, FRAME_GET_PLANE_STRIDE (dest, plane),
+ s, FRAME_GET_PLANE_STRIDE (src, splane),
+ convert->fout_width[plane], convert->fout_height[plane]);
+}
- for (k = 0; k < n_planes; k++) {
- gint i, tmp_in, in_x, in_y, out_x, out_y, out_width, out_height, pstride;
- GstVideoScaler *v_scaler, *h_scaler;
- ConverterAlloc *alloc;
+static void
+convert_plane_h (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest, gint plane)
+{
+ gint i;
+ gint in_x, in_y, out_x, out_y, out_width, out_height;
+ GstFormat format;
+ GstVideoScaler *h_scaler;
+ guint8 *s, *d;
+ gint splane = convert->fsplane[plane];
- v_scaler = convert->fv_scaler[k];
- h_scaler = convert->fh_scaler[k];
+ in_x = convert->fin_x[splane];
+ in_y = convert->fin_y[splane];
+ out_x = convert->fout_x[plane];
+ out_y = convert->fout_y[plane];
+ out_width = convert->fout_width[plane];
+ out_height = convert->fout_height[plane];
+ format = convert->fformat[plane];
+ h_scaler = convert->fh_scaler[plane];
- alloc = convert->flines;
+ for (i = 0; i < out_height; i++) {
+ s = FRAME_GET_PLANE_LINE (src, splane, i + in_y);
+ d = FRAME_GET_PLANE_LINE (dest, plane, i + out_y);
- /* FIXME. assumes subsampling of component N is the same as plane N, which is
- * currently true for all formats we have but it might not be in the future. */
- in_x = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, k, convert->in_x);
- in_y = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (in_finfo, k, convert->in_y);
- out_x = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, k, convert->out_x);
- out_y = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, k, convert->out_y);
- out_width =
- GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, k, convert->out_width);
- out_height =
- GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, k, convert->out_height);
+ gst_video_scaler_horizontal (h_scaler, format,
+ s + in_x, d + out_x, 0, out_width);
+ }
+}
- pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (out_finfo, k);
- in_x *= pstride;
- out_x *= pstride;
-
- tmp_in = 0;
- for (i = 0; i < out_height; i++) {
- guint8 *d, *s;
- guint in, n_taps, j;
-
- gst_video_scaler_get_coeff (v_scaler, i, &in, &n_taps);
-
- while (tmp_in < in)
- tmp_in++;
- while (tmp_in < in + n_taps) {
- s = FRAME_GET_PLANE_LINE (src, k, tmp_in + in_y);
- gst_video_scaler_horizontal (h_scaler, format,
- s + in_x, GET_TMP_LINE (alloc, tmp_in), 0, out_width);
- tmp_in++;
- }
- for (j = 0; j < n_taps; j++)
- lines[j] = GET_TMP_LINE (alloc, in + j);
+static void
+convert_plane_h_double (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest, gint plane)
+{
+ guint8 *s, *d;
+ gint splane = convert->fsplane[plane];
+
+ s = FRAME_GET_PLANE_LINE (src, splane, convert->fin_y[splane]);
+ s += convert->fin_x[splane];
+ d = FRAME_GET_PLANE_LINE (dest, plane, convert->fout_y[plane]);
+ d += convert->fout_x[plane];
+
+ video_orc_planar_chroma_422_444 (d,
+ FRAME_GET_PLANE_STRIDE (dest, plane), s,
+ FRAME_GET_PLANE_STRIDE (src, splane), convert->fout_width[plane] / 2,
+ convert->fout_height[plane]);
+}
+
+static void
+convert_plane_h_halve (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest, gint plane)
+{
+ guint8 *s, *d;
+ gint splane = convert->fsplane[plane];
+
+ s = FRAME_GET_PLANE_LINE (src, splane, convert->fin_y[splane]);
+ s += convert->fin_x[splane];
+ d = FRAME_GET_PLANE_LINE (dest, plane, convert->fout_y[plane]);
+ d += convert->fout_x[plane];
- d = FRAME_GET_PLANE_LINE (dest, k, i + out_y);
- gst_video_scaler_vertical (v_scaler, format, lines, d + out_x, i,
- out_width);
+ video_orc_planar_chroma_444_422 (d,
+ FRAME_GET_PLANE_STRIDE (dest, plane), s,
+ FRAME_GET_PLANE_STRIDE (src, splane), convert->fout_width[plane],
+ convert->fout_height[plane]);
+}
+
+static void
+convert_plane_v (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest, gint plane)
+{
+ gint i;
+ gint in_x, in_y, out_x, out_y, out_width, out_height;
+ GstFormat format;
+ GstVideoScaler *v_scaler;
+ gpointer *lines;
+ gint splane = convert->fsplane[plane];
+
+ in_x = convert->fin_x[splane];
+ in_y = convert->fin_y[splane];
+ out_x = convert->fout_x[plane];
+ out_y = convert->fout_y[plane];
+ out_width = convert->fout_width[plane];
+ out_height = convert->fout_height[plane];
+ format = convert->fformat[plane];
+ v_scaler = convert->fv_scaler[plane];
+ lines = convert->lineptr;
+
+ for (i = 0; i < out_height; i++) {
+ guint in, n_taps, j;
+ guint8 *s, *d;
+
+ gst_video_scaler_get_coeff (v_scaler, i, &in, &n_taps);
+ for (j = 0; j < n_taps; j++) {
+ s = FRAME_GET_PLANE_LINE (src, splane, in + in_y + j);
+ s += in_x;
+ lines[j] = s;
}
+
+ d = FRAME_GET_PLANE_LINE (dest, plane, i + out_y);
+ gst_video_scaler_vertical (v_scaler, format, lines, d + out_x, i,
+ out_width);
+ }
+}
+
+static void
+convert_plane_v_double (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest, gint plane)
+{
+ guint8 *s, *d1, *d2;
+ gint ds, splane = convert->fsplane[plane];
+
+ s = FRAME_GET_PLANE_LINE (src, splane, convert->fin_y[splane]);
+ s += convert->fin_x[splane];
+ d1 = FRAME_GET_PLANE_LINE (dest, plane, convert->fout_y[plane]);
+ d1 += convert->fout_x[plane];
+ d2 = FRAME_GET_PLANE_LINE (dest, plane, convert->fout_y[plane] + 1);
+ d2 += convert->fout_x[plane];
+ ds = FRAME_GET_PLANE_STRIDE (dest, plane);
+
+ video_orc_planar_chroma_420_422 (d1, 2 * ds, d2, 2 * ds,
+ s, FRAME_GET_PLANE_STRIDE (src, splane), convert->fout_width[plane],
+ convert->fout_height[plane] / 2);
+}
+
+static void
+convert_plane_v_halve (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest, gint plane)
+{
+ guint8 *s1, *s2, *d;
+ gint ss, ds, splane = convert->fsplane[plane];
+
+ s1 = FRAME_GET_PLANE_LINE (src, splane, convert->fin_y[splane]);
+ s1 += convert->fin_x[splane];
+ s2 = FRAME_GET_PLANE_LINE (src, splane, convert->fin_y[splane] + 1);
+ s2 += convert->fin_x[splane];
+ d = FRAME_GET_PLANE_LINE (dest, plane, convert->fout_y[plane]);
+ d += convert->fout_x[plane];
+
+ ss = FRAME_GET_PLANE_STRIDE (src, splane);
+ ds = FRAME_GET_PLANE_STRIDE (dest, plane);
+
+ video_orc_planar_chroma_422_420 (d, ds, s1, 2 * ss, s2, 2 * ss,
+ convert->fout_width[plane], convert->fout_height[plane]);
+}
+
+static void
+convert_plane_hv (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest, gint plane)
+{
+ gint i, tmp_in;
+ gint in_x, in_y, out_x, out_y, out_width, out_height;
+ GstFormat format;
+ GstVideoScaler *h_scaler, *v_scaler;
+ ConverterAlloc *alloc;
+ gpointer *lines;
+ gint splane = convert->fsplane[plane];
+
+ in_x = convert->fin_x[splane];
+ in_y = convert->fin_y[splane];
+ out_x = convert->fout_x[plane];
+ out_y = convert->fout_y[plane];
+ out_width = convert->fout_width[plane];
+ out_height = convert->fout_height[plane];
+ format = convert->fformat[plane];
+ alloc = convert->flines;
+ lines = convert->lineptr;
+
+ h_scaler = convert->fh_scaler[plane];
+ v_scaler = convert->fv_scaler[plane];
+
+ tmp_in = 0;
+ for (i = 0; i < out_height; i++) {
+ guint in, n_taps, j;
+ guint8 *s, *d;
+
+ gst_video_scaler_get_coeff (v_scaler, i, &in, &n_taps);
+
+ while (tmp_in < in)
+ tmp_in++;
+ while (tmp_in < in + n_taps) {
+ s = FRAME_GET_PLANE_LINE (src, splane, tmp_in + in_y);
+ gst_video_scaler_horizontal (h_scaler, format,
+ s + in_x, GET_TMP_LINE (alloc, tmp_in), 0, out_width);
+ tmp_in++;
+ }
+ for (j = 0; j < n_taps; j++)
+ lines[j] = GET_TMP_LINE (alloc, in + j);
+
+ d = FRAME_GET_PLANE_LINE (dest, plane, i + out_y);
+ gst_video_scaler_vertical (v_scaler, format, lines, d + out_x, i,
+ out_width);
+ }
+}
+
+static void
+convert_plane_hv_double (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest, gint plane)
+{
+ guint8 *s, *d1, *d2;
+ gint ss, ds, splane = convert->fsplane[plane];
+
+ s = FRAME_GET_PLANE_LINE (src, splane, convert->fin_y[splane]);
+ s += convert->fin_x[splane];
+ d1 = FRAME_GET_PLANE_LINE (dest, plane, convert->fout_y[plane]);
+ d1 += convert->fout_x[plane];
+ d2 = FRAME_GET_PLANE_LINE (dest, plane, convert->fout_y[plane] + 1);
+ d2 += convert->fout_x[plane];
+ ss = FRAME_GET_PLANE_STRIDE (src, splane);
+ ds = FRAME_GET_PLANE_STRIDE (dest, plane);
+
+ video_orc_planar_chroma_420_444 (d1, 2 * ds, d2, 2 * ds, s, ss,
+ (convert->fout_width[plane] + 1) / 2, convert->fout_height[plane] / 2);
+}
+
+static void
+convert_plane_hv_halve (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest, gint plane)
+{
+ guint8 *s1, *s2, *d;
+ gint ss, ds, splane = convert->fsplane[plane];
+
+ s1 = FRAME_GET_PLANE_LINE (src, splane, convert->fin_y[splane]);
+ s1 += convert->fin_x[splane];
+ s2 = FRAME_GET_PLANE_LINE (src, splane, convert->fin_y[splane] + 1);
+ s2 += convert->fin_x[splane];
+ d = FRAME_GET_PLANE_LINE (dest, plane, convert->fout_y[plane]);
+ d += convert->fout_x[plane];
+ ss = FRAME_GET_PLANE_STRIDE (src, splane);
+ ds = FRAME_GET_PLANE_STRIDE (dest, plane);
+
+ video_orc_planar_chroma_444_420 (d, ds, s1, 2 * ss, s2, 2 * ss,
+ convert->fout_width[plane], convert->fout_height[plane]);
+}
+
+static void
+convert_scale_planes (GstVideoConverter * convert,
+ const GstVideoFrame * src, GstVideoFrame * dest)
+{
+ int i, n_planes;
+
+ n_planes = GST_VIDEO_FRAME_N_PLANES (dest);
+ for (i = 0; i < n_planes; i++) {
+ convert->fconvert[i] (convert, src, dest, i);
}
convert_fill_border (convert, dest);
}
setup_scale (GstVideoConverter * convert, GstVideoFormat fformat)
{
int i, n_planes;
- gint method, stride = 0, in_w, in_h, out_w, out_h;
+ gint method, stride = 0, in_width, in_height, out_width, out_height;
guint taps, max_taps = 0;
GstVideoInfo *in_info, *out_info;
const GstVideoFormatInfo *in_finfo, *out_finfo;
break;
}
- in_w = convert->in_width;
- in_h = convert->in_height;
- out_w = convert->out_width;
- out_h = convert->out_height;
+ in_width = convert->in_width;
+ in_height = convert->in_height;
+ out_width = convert->out_width;
+ out_height = convert->out_height;
if (n_planes == 1) {
if (GST_VIDEO_INFO_IS_YUV (in_info)) {
GstVideoScaler *y_scaler, *uv_scaler;
y_scaler = gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_NONE, taps,
- GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, GST_VIDEO_COMP_Y, in_w),
- GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, GST_VIDEO_COMP_Y,
- out_w), convert->config);
+ GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, GST_VIDEO_COMP_Y,
+ in_width), GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo,
+ GST_VIDEO_COMP_Y, out_width), convert->config);
uv_scaler =
gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_NONE, taps,
- GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, GST_VIDEO_COMP_U, in_w),
- GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, GST_VIDEO_COMP_U,
- out_w), convert->config);
+ GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, GST_VIDEO_COMP_U,
+ in_width), GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo,
+ GST_VIDEO_COMP_U, out_width), convert->config);
convert->fh_scaler[0] =
gst_video_scaler_combine_packed_YUV (y_scaler, uv_scaler,
} else {
convert->fh_scaler[0] =
gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_NONE, taps,
- in_w, out_w, convert->config);
+ in_width, out_width, convert->config);
}
stride = MAX (stride, GST_VIDEO_INFO_PLANE_STRIDE (in_info, 0));
stride = MAX (stride, GST_VIDEO_INFO_PLANE_STRIDE (out_info, 0));
convert->fv_scaler[0] =
gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_NONE, taps,
- in_h, out_h, convert->config);
+ in_height, out_height, convert->config);
gst_video_scaler_get_coeff (convert->fv_scaler[0], 0, NULL, &max_taps);
- convert->fformat = fformat;
+
+ convert->fconvert[0] = convert_plane_hv;
+ convert->fformat[0] = fformat;
+ convert->fsplane[0] = 0;
} else {
for (i = 0; i < n_planes; i++) {
- guint n_taps;
+ guint n_taps = 0;
+ gint j, iw, ih, ow, oh, pstride;
+ gboolean need_v_scaler, need_h_scaler;
+
+ /* find the component in this plane and map it to the plane of
+ * the source */
+ for (j = 0; i < GST_VIDEO_MAX_COMPONENTS; j++) {
+ if (GST_VIDEO_FORMAT_INFO_PLANE (out_finfo, j) == i) {
+ convert->fsplane[i] = GST_VIDEO_FORMAT_INFO_PLANE (in_finfo, j);
+ GST_DEBUG ("plane %d -> %d", i, convert->fsplane[i]);
+ break;
+ }
+ }
stride = MAX (stride, GST_VIDEO_INFO_COMP_STRIDE (in_info, i));
stride = MAX (stride, GST_VIDEO_INFO_COMP_STRIDE (out_info, i));
- convert->fh_scaler[i] =
- gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_NONE, taps,
- GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, i, in_w),
- GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, i, out_w),
- convert->config);
- convert->fv_scaler[i] =
- gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_NONE, taps,
- GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (in_finfo, i, in_h),
- GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, i, out_h),
- convert->config);
+ iw = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, i, in_width);
+ ih = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (in_finfo, i, in_height);
+ ow = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, i, out_width);
+ oh = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, i, out_height);
+
+ convert->fout_width[i] = ow;
+ convert->fout_height[i] = oh;
+
+ pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (out_finfo, i);
+ convert->fin_x[i] =
+ GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (in_finfo, i, convert->in_x);
+ convert->fin_x[i] *= pstride;
+ convert->fin_y[i] =
+ GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (in_finfo, i, convert->in_y);
+ convert->fout_x[i] =
+ GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (out_finfo, i, convert->out_x);
+ convert->fout_x[i] *= pstride;
+ convert->fout_y[i] =
+ GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (out_finfo, i, convert->out_y);
+
+ need_v_scaler = FALSE;
+ need_h_scaler = FALSE;
+ if (iw == ow) {
+ if (ih == oh) {
+ convert->fconvert[i] = convert_plane_copy;
+ GST_DEBUG ("plane %d: copy", i);
+ } else if (ih == 2 * oh) {
+ convert->fconvert[i] = convert_plane_v_halve;
+ GST_DEBUG ("plane %d: vertical halve", i);
+ } else if (2 * ih == oh) {
+ convert->fconvert[i] = convert_plane_v_double;
+ GST_DEBUG ("plane %d: vertical double", i);
+ } else {
+ convert->fconvert[i] = convert_plane_v;
+ GST_DEBUG ("plane %d: vertical scale", i);
+ need_v_scaler = TRUE;
+ }
+ } else if (ih == oh) {
+ if (iw == 2 * ow) {
+ convert->fconvert[i] = convert_plane_h_halve;
+ GST_DEBUG ("plane %d: horizontal halve", i);
+ } else if (2 * iw == ow) {
+ convert->fconvert[i] = convert_plane_h_double;
+ GST_DEBUG ("plane %d: horizontal double", i);
+ } else {
+ convert->fconvert[i] = convert_plane_h;
+ GST_DEBUG ("plane %d: horizontal scale", i);
+ need_h_scaler = TRUE;
+ }
+ } else {
+ if (iw == 2 * ow && ih == 2 * oh) {
+ convert->fconvert[i] = convert_plane_hv_halve;
+ GST_DEBUG ("plane %d: horizontal/vertical halve", i);
+ } else if (2 * iw == ow && 2 * ih == oh) {
+ convert->fconvert[i] = convert_plane_hv_double;
+ GST_DEBUG ("plane %d: horizontal/vertical double", i);
+ } else {
+ convert->fconvert[i] = convert_plane_hv;
+ GST_DEBUG ("plane %d: horizontal/vertical scale", i);
+ need_v_scaler = TRUE;
+ need_h_scaler = TRUE;
+ }
+ }
- gst_video_scaler_get_coeff (convert->fv_scaler[i], 0, NULL, &n_taps);
+ if (need_h_scaler) {
+ convert->fh_scaler[i] =
+ gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_NONE, taps,
+ iw, ow, convert->config);
+ }
+ if (need_v_scaler) {
+ convert->fv_scaler[i] =
+ gst_video_scaler_new (method, GST_VIDEO_SCALER_FLAG_NONE, taps,
+ ih, oh, convert->config);
+ gst_video_scaler_get_coeff (convert->fv_scaler[i], 0, NULL, &n_taps);
+ }
max_taps = MAX (max_taps, n_taps);
+ convert->fformat[i] = fformat;
}
- convert->fformat = fformat;
}
convert->flines =
converter_alloc_new (stride, max_taps + BACKLOG, NULL, NULL);
FALSE, 0, 0, convert_I420_UYVY},
{GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_AYUV, TRUE, FALSE, TRUE, FALSE,
FALSE, 0, 0, convert_I420_AYUV},
- {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_Y42B, FALSE, FALSE, TRUE, FALSE,
- FALSE, 0, 0, convert_I420_Y42B},
- {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_Y444, FALSE, FALSE, TRUE, FALSE,
- FALSE, 0, 0, convert_I420_Y444},
+
+ {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_Y42B, FALSE, FALSE, FALSE, TRUE,
+ TRUE, 0, 0, convert_scale_planes, GST_VIDEO_FORMAT_GRAY8},
+ {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_Y444, FALSE, FALSE, FALSE, TRUE,
+ TRUE, 0, 0, convert_scale_planes, GST_VIDEO_FORMAT_GRAY8},
{GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_YUY2, TRUE, FALSE, TRUE, FALSE,
FALSE, 0, 0, convert_I420_YUY2},
FALSE, 0, 0, convert_I420_UYVY},
{GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_AYUV, TRUE, FALSE, TRUE, FALSE,
FALSE, 0, 0, convert_I420_AYUV},
- {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_Y42B, FALSE, FALSE, TRUE, FALSE,
- FALSE, 0, 0, convert_I420_Y42B},
- {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_Y444, FALSE, FALSE, TRUE, FALSE,
- FALSE, 0, 0, convert_I420_Y444},
+ {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_Y42B, FALSE, FALSE, FALSE, TRUE,
+ TRUE, 0, 0, convert_scale_planes, GST_VIDEO_FORMAT_GRAY8},
+ {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_Y444, FALSE, FALSE, FALSE, TRUE,
+ TRUE, 0, 0, convert_scale_planes, GST_VIDEO_FORMAT_GRAY8},
{GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_I420, TRUE, FALSE, TRUE, FALSE,
FALSE, 0, 0, convert_YUY2_I420},
{GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_Y444, TRUE, FALSE, TRUE, TRUE,
TRUE, 0, 0, convert_AYUV_Y444},
- {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_I420, FALSE, FALSE, TRUE, FALSE,
- FALSE, 0, 0, convert_Y42B_I420},
- {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_YV12, FALSE, FALSE, TRUE, FALSE,
- FALSE, 0, 0, convert_Y42B_I420},
+ {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_I420, FALSE, FALSE, FALSE, TRUE,
+ TRUE, 0, 0, convert_scale_planes, GST_VIDEO_FORMAT_GRAY8},
+ {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_YV12, FALSE, FALSE, FALSE, TRUE,
+ TRUE, 0, 0, convert_scale_planes, GST_VIDEO_FORMAT_GRAY8},
{GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_YUY2, TRUE, FALSE, TRUE, TRUE,
TRUE, 0, 0, convert_Y42B_YUY2},
{GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_UYVY, TRUE, FALSE, TRUE, TRUE,
TRUE, 0, 0, convert_Y42B_UYVY},
{GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_AYUV, TRUE, FALSE, TRUE, TRUE,
TRUE, 1, 0, convert_Y42B_AYUV},
- {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_Y444, TRUE, FALSE, TRUE, TRUE,
- TRUE, 0, 0, convert_Y42B_Y444},
+ {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_Y444, TRUE, FALSE, FALSE, TRUE,
+ TRUE, 0, 0, convert_scale_planes, GST_VIDEO_FORMAT_GRAY8},
- {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_I420, FALSE, FALSE, TRUE, FALSE,
- FALSE, 1, 0, convert_Y444_I420},
- {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_YV12, FALSE, FALSE, TRUE, FALSE,
- FALSE, 1, 0, convert_Y444_I420},
+ {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_I420, FALSE, FALSE, FALSE, TRUE,
+ TRUE, 1, 0, convert_scale_planes, GST_VIDEO_FORMAT_GRAY8},
+ {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_YV12, FALSE, FALSE, FALSE, TRUE,
+ TRUE, 1, 0, convert_scale_planes, GST_VIDEO_FORMAT_GRAY8},
{GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_YUY2, TRUE, FALSE, TRUE, TRUE,
TRUE, 1, 0, convert_Y444_YUY2},
{GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_UYVY, TRUE, FALSE, TRUE, TRUE,
TRUE, 1, 0, convert_Y444_UYVY},
{GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_AYUV, TRUE, FALSE, TRUE, TRUE,
TRUE, 0, 0, convert_Y444_AYUV},
- {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_Y42B, TRUE, FALSE, TRUE, TRUE,
- TRUE, 1, 0, convert_Y444_Y42B},
+ {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_Y42B, TRUE, FALSE, FALSE, TRUE,
+ TRUE, 1, 0, convert_scale_planes, GST_VIDEO_FORMAT_GRAY8},
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
{GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_ARGB, TRUE, TRUE, TRUE, TRUE, TRUE,
transforms[i].out_format == out_format &&
(transforms[i].keeps_interlaced || !interlaced) &&
(transforms[i].needs_color_matrix || (same_matrix && same_primaries))
- && (transforms[i].keeps_size || !same_size)
+ && (!transforms[i].keeps_size || same_size)
&& (transforms[i].width_align & width) == 0
&& (transforms[i].height_align & height) == 0
&& (transforms[i].do_crop || !crop)