[FFmpeg-devel] ff_fill_line_with_color(), ff_draw_rectangle() and ff_copy_rectangle()
yann.lepetitcorps at free.fr
yann.lepetitcorps at free.fr
Sun Sep 9 03:50:47 CEST 2012
I think that ff_fill_line_with_color(), ff_draw_rectangle() and
ff_copy_rectangle() funcs can to be unrolled to a similar fashion into
libavfilter/drawutils.c with something like this for a little performance win :
#define YLP_OPTI 1
int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w, uint8_t
dst_color[4],
enum PixelFormat pix_fmt, uint8_t rgba_color[4],
int *is_packed_rgba, uint8_t rgba_map_ptr[4])
{
uint8_t rgba_map[4] = {0};
int i, step;
const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
int hsub = pix_desc->log2_chroma_w;
*is_packed_rgba = ff_fill_rgba_map(rgba_map, pix_fmt) >= 0;
if (*is_packed_rgba) {
step = (av_get_bits_per_pixel(pix_desc))>>3;
w *= step;
line[0] = av_malloc(w);
pixel_step[0] = step;
for (i = 0; i < 4; i++)
dst_color[rgba_map[i]] = rgba_color[i];
for (i = 0; i < w ; i += step)
memcpy(line[0] + i, dst_color, step);
if (rgba_map_ptr)
memcpy(rgba_map_ptr, rgba_map, sizeof(uint8_t) * 4);
} else {
#ifndef YLP_OPTI
int plane;
dst_color[0] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1],
rgba_color[2]);
dst_color[1] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1],
rgba_color[2], 0);
dst_color[2] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1],
rgba_color[2], 0);
dst_color[3] = rgba_color[3];
for (plane = 0; plane < 4; plane++) {
int line_size;
int hsub1 = (plane == 1 || plane == 2) ? hsub : 0;
pixel_step[plane] = 1;
line_size = (w >> hsub1) * pixel_step[plane];
line[plane] = av_malloc(line_size);
memset(line[plane], dst_color[plane], line_size);
}
#else
pixel_step[0] = 1;
line[0] = av_malloc(w);
memset(line[0], RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]), w);
step = w >> hsub;
pixel_step[1] = 1;
line[1] = av_malloc(step);
memset(line[1], RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]),
step);
pixel_step[2] = 1;
line[2] = av_malloc(step);
memset(line[2], RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]),
step);
pixel_step[3] = 1;
line[3] = av_malloc(w);
memset(line[3], rgba_color[3], w);
#endif
}
return 0;
}
void ff_draw_rectangle(uint8_t *dst[4], int dst_linesize[4],
uint8_t *src[4], int pixelstep[4],
int hsub, int vsub, int x, int y, int w, int h)
{
int i, plane;
uint8_t *p;
#ifndef YLP_OPTI
for (plane = 0; plane < 4 && dst[plane]; plane++) {
int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
p = dst[plane] + (y >> vsub1) * dst_linesize[plane];
for (i = 0; i < (h >> vsub1); i++) {
memcpy(p + (x >> hsub1) * pixelstep[plane],
src[plane], (w >> hsub1) * pixelstep[plane]);
p += dst_linesize[plane];
}
}
#else
int lsize, wstep;
lsize = dst_linesize[0];
wstep = w * pixelstep[0];
p = dst[0] + y * lsize + x * pixelstep[0];
for( i = 0 ; i < h ; i++, p += lsize )
memcpy(p, src[0], wstep); // or memset(p, *src[0], wstep) ???
if ( dst[1] == NULL) return;
lsize = dst_linesize[1];
wstep = (w >> hsub) * pixelstep[1];
p = dst[1] + (y >> vsub) * lsize + (x >> hsub) * pixelstep[1];
for( i = 0 ; i < h ; i += 2, p += lsize )
memcpy(p, src[1], wstep); // or memset(p, *src[1], wstep) ???
if ( dst[2] == NULL) return;
lsize = dst_linesize[2];
wstep = (w >> hsub) * pixelstep[2];
p = dst[2] + (y >> vsub) * lsize + (x >> hsub) * pixelstep[2];
for( i = 0 ; i < h ; i += 2, p += lsize )
memcpy(p, src[2], wstep); // or memset(p, *src[2], wstep) ???
if ( dst[3] == NULL) return;
lsize = dst_linesize[3];
wstep = w * pixelstep[3];
p = dst[3] + y * lsize + x * pixelstep[3];
for( i = 0 ; i < h ; i++, p += lsize )
memcpy(p, src[3], wstep);// or memset(p, *src[3], wstep) ???
#endif
}
void ff_copy_rectangle(uint8_t *dst[4], int dst_linesize[4],
uint8_t *src[4], int src_linesize[4], int pixelstep[4],
int hsub, int vsub, int x, int y, int y2, int w, int h)
{
#ifndef YLP_OPTI
int i, plane;
uint8_t *p;
for (plane = 0; plane < 4 && dst[plane]; plane++) {
int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
p = dst[plane] + (y >> vsub1) * dst_linesize[plane];
for (i = 0; i < (h >> vsub1); i++) {
memcpy(p + (x >> hsub1) * pixelstep[plane],
src[plane] + src_linesize[plane]*(i+(y2>>vsub1)), (w >>
hsub1) * pixelstep[plane]);
p += dst_linesize[plane];
}
}
#else
int i, ssize, dsize, wstep;
uint8_t *psrc, *pdst;
ssize = src_linesise[0];
dsize = dst_linesize[0];
wstep = w * pixelstep[0];
psrc = src[0] + y2 * ssize;
pdst = dst[0] + y * dsize + x * pixelstep[0];
for( i = 0 ; i < h ; i++, psrc += ssize, pdst += dsize )
memcpy(pdst, psrc, wstep);
if ( dst[1] == NULL) return;
ssize = src_linesize[1];
dsize = dst_linesize[1];
wstep = (w >> hsub) * pixelstep[1];
psrc = src[1] + (y2 >> vsub) * ssize;
pdst = dst[1] + (y >> vsub) * dsize + (x >> hsub) * pixelstep[1];
for( i = 0 ; i < h ; i += 2, psrc += ssize, pdst += dsize )
memcpy(pdst, psrc, wstep);
if ( dst[2] == NULL) return;
ssize = src_linesize[2];
dsize = dst_linesize[2];
wstep = (w >> hsub) * pixelstep[2];
psrc = src[2] + (y2 >> vsub) * ssize;
pdst = dst[2] + (y >> vsub) * dsize + (x >> hsub) * pixelstep[2];
for( i = 0 ; i < h ; i += 2, psrc += ssize, pdst += dsize )
memcpy(pdst, psrc, wstep);
if ( dst[3] == NULL) return;
ssize = src_linesize[3];
dsize = dst_linesize[3];
wstep = w * pixelstep[3];
psrc = src[3] + y2 * ssize;
pdst = dst[3] + y * dsize + x * pixelstep[3];
for( i = 0 ; i < h ; i++, psrc += ssize, pdst += dsize )
memcpy(pdst, psrc, wstep);
#endif
}
@+
Yannoo
More information about the ffmpeg-devel
mailing list