video-converter: keep separate lines with border

Make separate with a border around them so that we can avoid a memcpy.
This commit is contained in:
Wim Taymans 2014-11-05 11:54:31 +01:00
parent cf970376df
commit 7888b4f9fa

View file

@ -96,6 +96,10 @@ struct _GstVideoConverter
guint16 *errline; guint16 *errline;
guint tmplines_idx; guint tmplines_idx;
guint n_btmplines;
gpointer *btmplines;
guint btmplines_idx;
gboolean fill_border; gboolean fill_border;
gpointer borderline; gpointer borderline;
guint32 border_argb; guint32 border_argb;
@ -289,18 +293,25 @@ static gboolean do_hscale_lines (GstLineCache * cache, gint out_line,
gint in_line, gpointer user_data); gint in_line, gpointer user_data);
static void static void
alloc_tmplines (GstVideoConverter * convert, guint lines, gint width) alloc_tmplines (GstVideoConverter * convert, guint lines, guint blines,
gint width)
{ {
gint i; gint i;
convert->n_tmplines = lines; convert->n_tmplines = lines;
convert->tmplines = g_malloc (lines * sizeof (gpointer)); convert->tmplines = g_malloc (lines * sizeof (gpointer));
for (i = 0; i < lines; i++) { for (i = 0; i < lines; i++)
convert->tmplines[i] = g_malloc (sizeof (guint16) * (width + 8) * 4); convert->tmplines[i] = g_malloc (sizeof (guint16) * (width + 8) * 4);
if (convert->borderline)
memcpy (convert->tmplines[i], convert->borderline, width * 8);
}
convert->tmplines_idx = 0; convert->tmplines_idx = 0;
convert->n_btmplines = blines;
convert->btmplines = g_malloc (blines * sizeof (gpointer));
for (i = 0; i < blines; i++) {
convert->btmplines[i] = g_malloc (sizeof (guint16) * (width + 8) * 4);
if (convert->borderline)
memcpy (convert->btmplines[i], convert->borderline, width * 8);
}
convert->btmplines_idx = 0;
} }
static gpointer static gpointer
@ -317,6 +328,20 @@ get_temp_line (GstLineCache * cache, gint idx, gpointer user_data)
return tmpline; return tmpline;
} }
static gpointer
get_border_temp_line (GstLineCache * cache, gint idx, gpointer user_data)
{
GstVideoConverter *convert = user_data;
gpointer tmpline;
GST_DEBUG ("get border temp line %d", idx);
tmpline = (guint8 *) convert->btmplines[convert->btmplines_idx] +
(convert->out_x * convert->pack_pstride);
convert->btmplines_idx = (convert->btmplines_idx + 1) % convert->n_btmplines;
return tmpline;
}
static GstLineCache * static GstLineCache *
chain_unpack_line (GstVideoConverter * convert) chain_unpack_line (GstVideoConverter * convert)
{ {
@ -495,7 +520,7 @@ setup_allocators (GstVideoConverter * convert)
if (convert->identity_pack) if (convert->identity_pack)
alloc_line = get_dest_line; alloc_line = get_dest_line;
else else
alloc_line = get_temp_line; alloc_line = get_border_temp_line;
/* now walk backwards, we try to write into the dest lines directly /* now walk backwards, we try to write into the dest lines directly
* and keep track if the source needs to be writable */ * and keep track if the source needs to be writable */
@ -699,7 +724,7 @@ gst_video_converter_new (GstVideoInfo * in_info, GstVideoInfo * out_info,
} }
/* FIXME */ /* FIXME */
alloc_tmplines (convert, 64, width); alloc_tmplines (convert, 64, 4, width);
done: done:
return convert; return convert;
@ -761,6 +786,9 @@ gst_video_converter_free (GstVideoConverter * convert)
for (i = 0; i < convert->n_tmplines; i++) for (i = 0; i < convert->n_tmplines; i++)
g_free (convert->tmplines[i]); g_free (convert->tmplines[i]);
g_free (convert->tmplines); g_free (convert->tmplines);
for (i = 0; i < convert->n_btmplines; i++)
g_free (convert->btmplines[i]);
g_free (convert->btmplines);
g_free (convert->errline); g_free (convert->errline);
g_free (convert->borderline); g_free (convert->borderline);
@ -1347,10 +1375,22 @@ get_dest_line (GstLineCache * cache, gint idx, gpointer user_data)
{ {
GstVideoConverter *convert = user_data; GstVideoConverter *convert = user_data;
guint8 *line; guint8 *line;
gint pstride = convert->pack_pstride;
gint out_x = convert->out_x;
GST_DEBUG ("get dest line %d", idx); GST_DEBUG ("get dest line %d", idx);
line = FRAME_GET_LINE (convert->dest, idx); line = FRAME_GET_LINE (convert->dest, idx);
line += convert->out_x * convert->pack_pstride;
if (convert->borderline) {
gint r_border = (out_x + convert->out_width) * pstride;
gint rb_width = convert->out_maxwidth * pstride - r_border;
gint lb_width = out_x * pstride;
memcpy (line, convert->borderline, lb_width);
memcpy (line + r_border, convert->borderline, rb_width);
}
line += out_x * pstride;
return line; return line;
} }
@ -1520,9 +1560,8 @@ video_converter_generic (GstVideoConverter * convert, const GstVideoFrame * src,
gint out_maxwidth, out_maxheight; gint out_maxwidth, out_maxheight;
gint out_x, out_y, out_height; gint out_x, out_y, out_height;
gint pack_lines, pstride; gint pack_lines, pstride;
gint r_border, out_width, lb_width, rb_width; gint lb_width;
out_width = convert->out_width;
out_height = convert->out_height; out_height = convert->out_height;
out_maxwidth = convert->out_maxwidth; out_maxwidth = convert->out_maxwidth;
out_maxheight = convert->out_maxheight; out_maxheight = convert->out_maxheight;
@ -1536,8 +1575,6 @@ video_converter_generic (GstVideoConverter * convert, const GstVideoFrame * src,
pack_lines = convert->lines; /* only 1 for now */ pack_lines = convert->lines; /* only 1 for now */
pstride = convert->pack_pstride; pstride = convert->pack_pstride;
r_border = (out_x + out_width) * pstride;
rb_width = out_maxwidth * pstride - r_border;
lb_width = out_x * pstride; lb_width = out_x * pstride;
if (convert->borderline) { if (convert->borderline) {
@ -1548,23 +1585,14 @@ video_converter_generic (GstVideoConverter * convert, const GstVideoFrame * src,
for (i = 0; i < out_height; i += pack_lines) { for (i = 0; i < out_height; i += pack_lines) {
gpointer *lines; gpointer *lines;
guint8 *l;
/* load the lines needed to pack */ /* load the lines needed to pack */
lines = lines = gst_line_cache_get_lines (convert->pack_lines, i + out_y,
gst_line_cache_get_lines (convert->pack_lines, i + out_y, i, i, pack_lines);
pack_lines);
/* take away the border */
l = ((guint8 *) lines[0]) - lb_width;
if (convert->borderline) {
/* FIXME this can be optimized if we make separate temp lines with
* border for the output lines */
memcpy (l, convert->borderline, lb_width);
memcpy (l + r_border, convert->borderline, rb_width);
}
if (!convert->identity_pack) { if (!convert->identity_pack) {
/* take away the border */
guint8 *l = ((guint8 *) lines[0]) - lb_width;
/* and pack into destination */ /* and pack into destination */
GST_DEBUG ("pack line %d", i + out_y); GST_DEBUG ("pack line %d", i + out_y);
PACK_FRAME (dest, l, i + out_y, out_maxwidth); PACK_FRAME (dest, l, i + out_y, out_maxwidth);
@ -2417,7 +2445,7 @@ video_converter_lookup_fastpath (GstVideoConverter * convert)
if (transforms[i].needs_color_matrix) if (transforms[i].needs_color_matrix)
video_converter_compute_matrix (convert); video_converter_compute_matrix (convert);
convert->convert = transforms[i].convert; convert->convert = transforms[i].convert;
alloc_tmplines (convert, 1, GST_VIDEO_INFO_WIDTH (&convert->in_info)); alloc_tmplines (convert, 1, 0, GST_VIDEO_INFO_WIDTH (&convert->in_info));
return TRUE; return TRUE;
} }
} }