[FFmpeg-soc] libavfilter audio work - qualification task
Stefano Sabatini
stefano.sabatini-lala at poste.it
Sat Apr 10 01:18:24 CEST 2010
On date Friday 2010-04-09 08:02:50 -0700, S.N. Hemanth Meenakshisundaram encoded:
> On 04/08/2010 09:54 PM, S.N. Hemanth Meenakshisundaram wrote:
> >I removed the Makefile changes and added what you suggested above
> >into the configure script (as in configure.diff).
> >config.err still showed some errors initially and after tweaking
> >it a little, the errors stopped. (My headers are in
> >/usr/include/freetype).
[...]
> >Can you give me some pointers on what could be wrong. For the 1st
> >problem, I tried looking for any other places a new filter needs
> >to be registered/included and couldn't find any. For the 2nd,
> >
> >I am a newbie to configure scripts, so can you please explain what
> >the configure script lines actually mean.
For the moment use this:
--- a/configure
+++ b/configure
@@ -2699,6 +2699,8 @@ enabled_any alsa_indev alsa_outdev && check_lib2 alsa/asou
enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack
+enabled drawtext_filter && add_cflags $(pkg-config --cflags freetype2) && requi
+
enabled x11grab &&
check_header X11/Xlib.h &&
check_header X11/extensions/XShm.h &&
I have still to think about this /ask to Mans if this is fine (the
problem with this is that the user has to explicitely disable the
drawtext filter if libfreetype is not present),
> >
> >Thanks,
> >
> Had missed out uninit earlier. Attaching fixed version. From the
> config.err log, it looks like -lfreetype is included and yet the
> linking fails. I tried building a standalone program using freetype
> in the same way and it works. So the freetype libs and include paths
> are ok and something must be going wrong with configure. Could
> someone help me out with a quick way to link in the library directly
> so I can test drawtext for now.
>
> Thanks
>
> Index: allfilters.c
> ===================================================================
> --- allfilters.c (revision 5734)
> +++ allfilters.c (working copy)
> @@ -54,6 +54,7 @@
> REGISTER_FILTER (SPLIT, split, vf);
> REGISTER_FILTER (TRANSPOSE, transpose, vf);
> REGISTER_FILTER (VFLIP, vflip, vf);
> + REGISTER_FILTER (DRAWTEXT, drawtext, vf);
>
> REGISTER_FILTER (BUFFER, buffer, vsrc);
> REGISTER_FILTER (MOVIE, movie, vsrc);
> Index: Makefile
> ===================================================================
> --- Makefile (revision 5734)
> +++ Makefile (working copy)
> @@ -35,6 +35,7 @@
> OBJS-$(CONFIG_SPLIT_FILTER) += vf_split.o
> OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o
> OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o
> +OBJS-$(CONFIG_DRAWTEXT_FILTER) += vf_drawtext.o
>
> OBJS-$(CONFIG_BUFFER_FILTER) += vsrc_buffer.o
> OBJS-$(CONFIG_MOVIE_FILTER) += vsrc_movie.o
> Index: vf_drawtext.c
> ===================================================================
> --- vf_drawtext.c (revision 0)
> +++ vf_drawtext.c (revision 0)
> @@ -0,0 +1,589 @@
> +/*
> + * vf_drawtext.c: print text over the screen
> + ******************************************************************************
> + * Options:
> + * -f <filename> font filename (MANDATORY!!!)
> + * -s <pixel_size> font size in pixels [default 16]
> + * -b print background
> + * -o outline glyphs (use the bg color)
> + * -x <pos> x position ( >= 0) [default 0]
> + * -y <pos> y position ( >= 0) [default 0]
> + * -t <text> text to print (will be passed to strftime())
> + * MANDATORY: will be used even when -T is used.
> + * in this case, -t will be used if some error
> + * occurs
> + * -T <filename> file with the text (re-read every frame)
> + * -c <#RRGGBB> foreground color ('internet' way) [default #ffffff]
> + * -C <#RRGGBB> background color ('internet' way) [default #000000]
> + *
> + ******************************************************************************
> + * Features:
> + * - True Type, Type1 and others via FreeType2 library
> + * - Font kerning (better output)
> + * - Line Wrap (if the text doesn't fit, the next char go to the next line)
> + * - Background box
> + * - Outline
> + ******************************************************************************
User-documentation for filters should be put in doc/libavfilter.texi,
also I don't like this syntax, possibly we should try hard at giving a
consistent interface to the user, so we should either use
PARAM-1:PARAM-2:...:PARAM-N either use libavutil/parseutils.c (which
still depends on opt.c so I don't believe Michail won't accept this to
be included in the main repo, but that's not a problem for now).
> + * Original vhook author: Gustavo Sverzut Barbieri <gsbarbieri at yahoo.com.br>
> + * Libavfilter version : S.N. Hemanth Meenakshisundaram <smeenaks at ucsd.edu>
> + *
> + * Example usage :
> + * ffmpeg -i input.avi -vfilters \
> + * 'drawtext=f:Vera.ttf:t:Test Text:x:5:y:5:s:20' output.avi
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +/**
> + * @file libavfilter/vf_drawtext.c
> + * video filter to draw text over screen
> + */
> +
> +#define MAXSIZE_TEXT 1024
> +
> +#include "avfilter.h"
> +#include "libavutil/pixdesc.h"
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <fcntl.h>
> +#include <stdarg.h>
> +#include <string.h>
> +#include <unistd.h>
> +#undef time
> +#include <sys/time.h>
> +#include <time.h>
please avoid unnecessary headers inclusion
> +#include <ft2build.h>
> +#include <freetype/config/ftheader.h>
> +#include FT_FREETYPE_H
> +#include FT_GLYPH_H
> +
> +#define SCALEBITS 10
> +#define DEF_DRAWTEXT_FONT_SZ 16
> +#define MAX_DRAWTEXT_OPT 10
> +#define ONE_HALF (1 << (SCALEBITS - 1))
> +#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
> +
> +#define RGB_TO_YUV(rgb_color, yuv_color) do { \
> + yuv_color[0] = (FIX(0.29900) * rgb_color[0] + FIX(0.58700) * rgb_color[1] + FIX(0.11400) * rgb_color[2] + ONE_HALF) >> SCALEBITS; \
> + yuv_color[2] = ((FIX(0.50000) * rgb_color[0] - FIX(0.41869) * rgb_color[1] - FIX(0.08131) * rgb_color[2] + ONE_HALF - 1) >> SCALEBITS) + 128; \
> + yuv_color[1] = ((- FIX(0.16874) * rgb_color[0] - FIX(0.33126) * rgb_color[1] + FIX(0.50000) * rgb_color[2] + ONE_HALF - 1) >> SCALEBITS) + 128; \
> +} while (0)
use the macro defined in "libavcodec/colorspace.h"
> +#define COPY_3(dst,src) { \
> + dst[0]=src[0]; \
> + dst[1]=src[1]; \
> + dst[2]=src[2]; \
> +}
I don't think this is necessary, a simple memcpy should be enough.
> +#define SET_PIXEL(picture, yuv_color, x, y) { \
> + picture->data[0][ (x) + (y)*picture->linesize[0] ] = yuv_color[0]; \
> + picture->data[1][ ((x/2) + (y/2)*picture->linesize[1]) ] = yuv_color[1]; \
> + picture->data[2][ ((x/2) + (y/2)*picture->linesize[2]) ] = yuv_color[2]; \
> +}
> +
> +#define GET_PIXEL(picture, yuv_color, x, y) { \
> + yuv_color[0] = picture->data[0][ (x) + (y)*picture->linesize[0] ]; \
> + yuv_color[1] = picture->data[1][ (x/2) + (y/2)*picture->linesize[1] ]; \
> + yuv_color[2] = picture->data[2][ (x/2) + (y/2)*picture->linesize[2] ]; \
> +}
> +
> +
> +typedef struct {
> + unsigned char *text;
> + char *file;
> + unsigned int x;
> + unsigned int y;
> + int bg;
> + int outline;
> + unsigned char bgcolor[3]; /* YUV */
> + unsigned char fgcolor[3]; /* YUV */
> + FT_Library library;
> + FT_Face face;
> + FT_Glyph glyphs[ 255 ];
> + FT_Bitmap bitmaps[ 255 ];
> + int advance[ 255 ];
> + int bitmap_left[ 255 ];
> + int bitmap_top[ 255 ];
> + unsigned int glyphs_index[ 255 ];
> + int text_height;
> + int baseline;
> + int use_kerning;
> +} DtextContext;
please use DrawTextContext, no need to use obfuscated names, chars are
cheapers these days.
Also all the variables should be documented when their meaning is not
obvious.
> +static int query_formats(AVFilterContext *ctx)
> +{
> + static const enum PixelFormat pix_fmts[] = {
> + PIX_FMT_RGB48BE, PIX_FMT_RGB48LE,
> + PIX_FMT_ARGB, PIX_FMT_RGBA,
> + PIX_FMT_ABGR, PIX_FMT_BGRA,
> + PIX_FMT_RGB24, PIX_FMT_BGR24,
> + PIX_FMT_RGB565BE, PIX_FMT_RGB565LE,
> + PIX_FMT_RGB555BE, PIX_FMT_RGB555LE,
> + PIX_FMT_BGR565BE, PIX_FMT_BGR565LE,
> + PIX_FMT_BGR555BE, PIX_FMT_BGR555LE,
> + PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE,
> + PIX_FMT_YUV420P16LE, PIX_FMT_YUV420P16BE,
> + PIX_FMT_YUV422P16LE, PIX_FMT_YUV422P16BE,
> + PIX_FMT_YUV444P16LE, PIX_FMT_YUV444P16BE,
> + PIX_FMT_YUV444P, PIX_FMT_YUV422P,
> + PIX_FMT_YUV420P, PIX_FMT_YUV411P,
> + PIX_FMT_YUV410P, PIX_FMT_YUV440P,
> + PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P,
> + PIX_FMT_YUVJ420P, PIX_FMT_YUVJ440P,
> + PIX_FMT_YUVA420P,
> + PIX_FMT_RGB8, PIX_FMT_BGR8,
> + PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE,
> + PIX_FMT_PAL8, PIX_FMT_GRAY8,
> + PIX_FMT_NONE
> + };
Are you sure all these formats are supported?
> + avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
> +
> + return 0;
> +}
> +
> +static int parse_color(char *text, unsigned char yuv_color[3])
> +{
> + char tmp[3];
> + unsigned char rgb_color[3];
> + int i;
> +
> + tmp[2] = '\0';
> +
> + if ((!text) || (strlen(text) != 7) || (text[0] != '#') )
> + return -1;
> +
> + for (i=0; i < 3; i++)
> + {
> + tmp[0] = text[i*2+1];
> + tmp[1] = text[i*2+2];
> +
> + rgb_color[i] = strtol(tmp, NULL, 16);
> + }
> +
> + RGB_TO_YUV(rgb_color, yuv_color);
> +
> + return 0;
> +}
av_parse_color()
> +static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
> +{
> + int err, chars_read, num_opt = 0;
> + char str[256], cmd[2];
> + const char *args_cur;
> + char *font = NULL;
> + int c;
> + unsigned int size=DEF_DRAWTEXT_FONT_SZ;
> + FT_BBox bbox;
> + int yMax, yMin;
General stylistic note: use K&R style,
if (cond) {
...
}
style is preferred, plain_variable is preferred over camelVariable
style, try also the patcheck tool for checking the most common trivial
errors.
> + DtextContext *dtext = ctx->priv;
> +
> + dtext->fgcolor[0]=255;
> + dtext->fgcolor[1]=128;
> + dtext->fgcolor[2]=128;
> + dtext->bgcolor[0]=0;
> + dtext->fgcolor[1]=128;
> + dtext->fgcolor[2]=128;
> + dtext->bg = 0;
> + dtext->outline = 0;
> + dtext->text_height = 0;
> +
> + optind = 1;
> +
> + if ((err = FT_Init_FreeType(&(dtext->library))) != 0)
> + {
> + av_log(NULL, AV_LOG_ERROR, "Could not load FreeType (error# %d).\n", err);
Use the filter context for logging.
> + return -1;
I'd like to start to use meaningful error codes in libavfilter, use
AVERROR(EINVAL) in this case.
> + }
>
> + args_cur = args;
> + if(args_cur) {
> + while (2 == sscanf(args_cur, "%1[FtfxyiRGBA]:%255[^:]%n", cmd, str, &chars_read))
> + {
> + if (num_opt>=MAX_DRAWTEXT_OPT) {
> + av_log(NULL, AV_LOG_ERROR,
> + "drawtext init() cannot handle more than %d arguments\n",
> + MAX_DRAWTEXT_OPT);
> + return -1;
> + }
> + switch(cmd[0]) {
> + case 'f':
> + font = av_strdup(str);
> + break;
> + case 't':
> + dtext->text = av_strdup(str);
> + break;
> + case 'T':
> + dtext->file = av_strdup(str);
> + break;
> + case 'x':
> + dtext->x = (unsigned int)atoi(str);
> + break;
> + case 'y':
> + dtext->y = (unsigned int)atoi(str);
> + break;
> + case 's':
> + size = (unsigned int)atoi(str);
> + break;
> + case 'c':
> + if (parse_color(optarg, dtext->fgcolor) == -1)
> + {
> + av_log(NULL, AV_LOG_ERROR, "Invalid foreground color: '%s'.\n", optarg);
> + return -1;
> + }
> + break;
> + case 'C':
> + if (parse_color(optarg, dtext->bgcolor) == -1)
> + {
> + av_log(NULL, AV_LOG_ERROR, "Invalid background color: '%s'.\n", optarg);
> + return -1;
> + }
> + break;
> + case 'b':
> + dtext->bg = 1;
> + break;
> + case 'o':
> + dtext->bg = 1;
> + break;
> + case '?':
> + av_log(NULL, AV_LOG_ERROR, "Unrecognized argument '%c:%s'\n", cmd[0], str);
> + return -1;
> + }
> + num_opt++;
> + args_cur += chars_read;
> + if (*args_cur==':')
> + args_cur++;
> + }
> + }
All this can be greatly simplified and made more robust using
parseutils.c.
[...]
> +AVFilter avfilter_vf_drawtext = {
> + .name = "drawtext",
missing long name.
Regards.
More information about the FFmpeg-soc
mailing list