On date Saturday 2010-04-10 18:59:37 -0700, S.N. Hemanth Meenakshisundaram encoded: > On 04/09/2010 04:18 PM, Stefano Sabatini wrote: [...] > Please let me know if anything else needs to be fixed. > > Ronald, > > I will use just memcpy instead of fast_memcpy. Is that OK? > > 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); Alphabetical order. > > REGISTER_FILTER (BUFFER, buffer, vsrc); > REGISTER_FILTER (MOVIE, movie, vsrc); > Index: diffs/03_libavfilter_doc.diff > =================================================================== > --- diffs/03_libavfilter_doc.diff (revision 5734) > +++ diffs/03_libavfilter_doc.diff (working copy) > @@ -1,8 +1,8 @@ > -Index: doc/libavfilter.texi > +Index: libavfilter.texi > =================================================================== > ---- doc/libavfilter.texi (revision 22749) > -+++ doc/libavfilter.texi (working copy) > -@@ -139,6 +139,20 @@ > +--- libavfilter.texi (revision 22749) > ++++ libavfilter.texi (working copy) > +@@ -139,6 +139,30 @@ > > The default value of ``width'' and ``height'' is 0. > > @@ -14,6 +14,16 @@ > + > +Draw a box with x:y:width:height dimensions in a chosen color. > + > +...@section drawtext > ++ > +...@example > ++./ffmpeg -i in.avi -vfilters drawtext=font=FreeSerif.ttf:text=TestText > ++ :x=100:y=50:size=24:fgcolor=Yellow:bgcolor=Red:bg=1 out.avi > +...@end example > ++ > ++Draw 'TestText' with font FreeSerif of size 24 at (100,50), text color is > yellow, > ++background color is red, draw a box around text. Please add a table with the meaning of all the parameters. Check the pad filter documentation to see how. [...] > 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 Alphabetical order. > 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,494 @@ > +/* > + * vf_drawtext.c: print text over the screen No need for this, just put the copyright, description may stay in the @file doxy (also please mention libfreetype in this description). > + * Original vhook author: Gustavo Sverzut Barbieri <[email protected]> > + * Libavfilter version : S.N. Hemanth Meenakshisundaram <[email protected]> > + * > + * Example usage with all available options: > + * ./ffplay -vfilters > drawtext=font=FreeSerif.ttf:text=TestText:file=tfil.txt:\ > + * x=100:y=50:size=24:fgcolor=Yellow:bgcolor=Red:outline=1:bg=1 > in.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 "parseutils.h" > +#include "libavutil/pixdesc.h" > +#include "libavcodec/colorspace.h" > +#include <stdio.h> > +#include <stdlib.h> These should be unnecessary. > +#include <string.h> > +#undef time Why undef time? (I know they were in the vhook filter, but there is some reason for it?). > +#include <sys/time.h> > +#include <time.h> > + > +#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)) These and scalebits are already defined in colorspace.h. > +#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] ]; \ > +} These macros only work with YUV420P. Also please define them near to where they're used. > +typedef struct { > + const AVClass *class; /* To help parseutils to fill in > structure */ Nit: use ///< style for inline doxygen comments. Nit: I prefer to lowcase the first letter if the text describing the field is not a complete sentence (missing the verb like here), check how it is done in main SVN filters. > + unsigned char *font; /* Font to be used for drawing text */ > + unsigned char *text; /* Text to be drawn */ > + char *file; /* File with text to be drawn */ > + char *fgcolor; /* Text color */ > + char *bgcolor; /* Background/Box colour */ Nit: "color" fgcolor description should explicitely mention the term "ForeGround" or you'll have a confused reader, also maybe these fields are not necessary at all. > + unsigned int x; /* x position to start drawing text */ > + unsigned int y; /* y position to start drawing text */ > + unsigned int size; /* Font size to use */ > + unsigned char bcolor[3]; /* Text color in YUV */ > + unsigned char fcolor[3]; /* Background/Box color in YUV */ Having two variables names bcolor and bgcolor is horribly confusuing, I suggest: bgcolor_string bgcolor > + short int bg; /* Draw box around text - true or > false */ unexplicative name > + short int outline; /* Draw outline in bg color around > text */ > + int text_height; /* Height of a font symbol */ > + int baseline; /* Baseline to draw fonts from */ > + int use_kerning; /* Font kerning is used - true/false */ > + FT_Library library; /* Freetype font library handle */ > + FT_Face face; /* Freetype font face handle */ > + FT_Glyph glyphs[ 256 ]; /* Array holding glyphs of font */ > + FT_Bitmap bitmaps[ 256 ]; /* Array holding bitmaps of font */ > + /* Glyph bitmap dimensions */ > + int advance[ 256 ]; > + int bitmap_left[ 256 ]; > + int bitmap_top[ 256 ]; > + unsigned int glyphs_index[ 256 ]; vertical align > +} DrawTextContext; > + > +#define OFFSET(x) offsetof(DrawTextContext, x) > + > +static const AVOption drawtext_options[]= { > +{"font", "set font", OFFSET(font), FF_OPT_TYPE_STRING, 0, > CHAR_MIN, CHAR_MAX }, > +{"text", "set text", OFFSET(text), FF_OPT_TYPE_STRING, 0, > CHAR_MIN, CHAR_MAX }, > +{"file", "set file", OFFSET(file), FF_OPT_TYPE_STRING, 0, > CHAR_MIN, CHAR_MAX }, > +{"fgcolor", "set fgcolor", OFFSET(fgcolor), FF_OPT_TYPE_STRING, 0, > CHAR_MIN, CHAR_MAX }, > +{"bgcolor", "set bgcolor", OFFSET(bgcolor), FF_OPT_TYPE_STRING, 0, > CHAR_MIN, CHAR_MAX }, > +{"bg", "set bg", OFFSET(bg), FF_OPT_TYPE_INT, 0, > 0, 1 }, > +{"outline", "set outline", OFFSET(outline), FF_OPT_TYPE_INT, 0, > 0, 1 }, > +{"size", "set size", OFFSET(size), FF_OPT_TYPE_INT, 16, > 1, 72 }, > +{"x", "set x", OFFSET(x), FF_OPT_TYPE_INT, 0, > 0, INT_MAX }, > +{"y", "set y", OFFSET(y), FF_OPT_TYPE_INT, 0, > 0, INT_MAX }, nit: weird align > +{NULL}, > +}; > + > +static const char *drawtext_get_name(void *ctx) > +{ > + return "drawtext"; > +} > + > +static const AVClass drawtext_class = { > + "DrawTextContext", > + drawtext_get_name, > + drawtext_options > +}; > + > +static int query_formats(AVFilterContext *ctx) > +{ > + /* FIXME : Supports only YUV now. Add RGB support */ > + enum PixelFormat pix_fmts[] = { > + PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, > + PIX_FMT_YUV411P, PIX_FMT_YUV410P, > + PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ420P, > + PIX_FMT_YUV440P, PIX_FMT_YUVJ440P, > + PIX_FMT_NONE > + }; > + > + avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); > + return 0; > +} > + > +static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) > +{ > + unsigned short int c; > + uint8_t rgba[4]; > + uint8_t err, file_valid = 0; > + int yMax, yMin; y_max, y_min > + char *arg_cpy = NULL; > + FT_BBox bbox; > + DrawTextContext *dtext = ctx->priv; > + > + dtext->class = &drawtext_class; > + dtext->font = NULL; > + dtext->text = NULL; > + dtext->file = NULL; > + dtext->fgcolor = NULL; > + dtext->bgcolor = NULL; > + dtext->x = dtext->y = 0; > + dtext->size=DEF_DRAWTEXT_FONT_SZ; av_opt_set_defaults2() > + dtext->fcolor[0]=255; > + dtext->fcolor[1]=128; > + dtext->fcolor[2]=128; > + dtext->bcolor[0]=0; > + dtext->fcolor[1]=128; > + dtext->fcolor[2]=128; you can avoid to explicitely initialize these, use: dtext->fgcolor_string = strdup("white"); dtext->bgcolor_string = strdup("black"); > + dtext->bg = 0; > + dtext->outline = 0; > + dtext->text_height = 0; > + > + arg_cpy = av_strdup(args); why this? > + if (av_set_options_string(dtext, arg_cpy, "=", ":") < 0) { > + av_log(dtext, AV_LOG_ERROR, "Error parsing options string: '%s'\n", > args); > + return AVERROR(EINVAL); > + } > + > + if (!dtext->font || *(dtext->font) == 0) { > + av_log(dtext, AV_LOG_ERROR, "No font file provided! (-f > filename)\n"); "-f filename" is misleading as we don't support that syntax anymore, same below. > + return AVERROR(EINVAL); > + } > + > + if (!dtext->text || *(dtext->text) == 0) { > + av_log(dtext, AV_LOG_ERROR, "No text provided (-t text)\n"); > + return AVERROR(EINVAL); > + } > + > + if (dtext->file && *(dtext->file) != 0) { > + FILE *fp; > + if ((fp=fopen(dtext->file, "r")) == NULL) { please use "fp = fopen" for increased readability, also !FOO is preferred over FOO == NULL > + av_log(dtext, AV_LOG_INFO, "WARNING: The file could not be > opened.\ > + Using text provided with -t switch: %s", > dtext->text); > + } > + else { nit: "} else {" on the same line, here and below. > + fclose(fp); > + file_valid = 1; > + } > + } > + > + if ((dtext->fgcolor) && (av_parse_color(rgba, dtext->fgcolor, dtext) != > 0)) { > + av_log(dtext, AV_LOG_ERROR, "Invalid foreground color: '%s'.\n", > dtext->fgcolor); > + return AVERROR(EINVAL); > + } > + dtext->fcolor[0] = RGB_TO_Y(rgba[0], rgba[1], rgba[2]); > + dtext->fcolor[1] = RGB_TO_U(rgba[0], rgba[1], rgba[2], 0); > + dtext->fcolor[2] = RGB_TO_V(rgba[0], rgba[1], rgba[2], 0); > + > + if ((dtext->bgcolor) && (av_parse_color(rgba, dtext->bgcolor, dtext) != > 0)) { > + av_log(dtext, AV_LOG_ERROR, "Invalid background color: '%s'.\n", > dtext->bgcolor); > + return AVERROR(EINVAL); > + } > + > + dtext->bcolor[0] = RGB_TO_Y(rgba[0], rgba[1], rgba[2]); > + dtext->bcolor[1] = RGB_TO_U(rgba[0], rgba[1], rgba[2], 0); > + dtext->bcolor[2] = RGB_TO_V(rgba[0], rgba[1], rgba[2], 0); > + > + if ((err = FT_Init_FreeType(&(dtext->library))) != 0) { > + av_log(dtext, AV_LOG_ERROR, "Could not load FreeType (error# > %d).\n", err); > + return AVERROR(EINVAL); > + } Try to use libfreetype error messages, they have a weird system for setting errors, in my sandbox I have this snippet: /* build error strings table */ #define FT_ERROR_START_LIST { #define FT_ERRORDEF( e, v, s ) { e, s }, #define FT_ERROR_END_LIST { 0, 0 } }; #undef __FTERRORS_H__ const struct { int code; const char* msg; } ft_errors[] = #include FT_ERRORS_H #define FT_ERRMSG(e) ft_errors[e].msg maybe this can be simplified somehow. > + if ((err = FT_New_Face( dtext->library, dtext->font, 0, &(dtext->face) > )) != 0) { > + av_log(dtext, AV_LOG_ERROR, "Could not load face: %s (error# > %d).\n", dtext->font, err); > + return AVERROR(EINVAL); > + } > + if ((err = FT_Set_Pixel_Sizes( dtext->face, 0, dtext->size)) != 0) { > + av_log(dtext, AV_LOG_ERROR, "Could not set font size to %d pixels > (error# %d).\n", dtext->size, err); > + return AVERROR(EINVAL); > + } > + > + dtext->use_kerning = FT_HAS_KERNING(dtext->face); > + > + /* load and cache glyphs */ > + yMax = -32000; > + yMin = 32000; > + /* FIXME : Supports only ASCII text now. Add Unicode support */ > + for (c=0; c <= 255; c++) { > + > + if (!file_valid && !strrchr(dtext->text,(unsigned char)c)) > + continue; > + > + /* Load char */ > + err = FT_Load_Char( dtext->face, (unsigned char) c, FT_LOAD_RENDER | > FT_LOAD_MONOCHROME ); > + if (err) continue; /* ignore errors */ > + > + /* Save bitmap */ > + dtext->bitmaps[c] = dtext->face->glyph->bitmap; > + /* Save bitmap left */ > + dtext->bitmap_left[c] = dtext->face->glyph->bitmap_left; > + /* Save bitmap top */ > + dtext->bitmap_top[c] = dtext->face->glyph->bitmap_top; > + /* Save advance */ > + dtext->advance[c] = dtext->face->glyph->advance.x >> 6; vertical align, maybe you can remove the comments > + /* Save glyph */ > + err = FT_Get_Glyph( dtext->face->glyph, &(dtext->glyphs[c]) ); > + /* Save glyph index */ > + av_log(dtext, AV_LOG_ERROR, "c is %d\n", c); AV_LOG_DEBUG > + dtext->glyphs_index[c] = FT_Get_Char_Index( dtext->face, (unsigned > char) c ); > + > + /* Measure text height to calculate text_height (or the maximum text > height) */ > + FT_Glyph_Get_CBox( dtext->glyphs[ c ], ft_glyph_bbox_pixels, &bbox ); > + if (bbox.yMax > yMax) > + yMax = bbox.yMax; > + if (bbox.yMin < yMin) > + yMin = bbox.yMin; > + } > + > + dtext->text_height = yMax - yMin; > + dtext->baseline = yMax; > + > + return 0; > +} > + > +static av_cold void uninit(AVFilterContext *ctx) > +{ > + DrawTextContext *dtext = ctx->priv; > + av_freep(&dtext->font); > + av_freep(&dtext->text); > + av_freep(&dtext->file); > + av_freep(&dtext->fgcolor); > + av_freep(&dtext->bgcolor); > + FT_Done_Face(dtext->face); > + FT_Done_FreeType(dtext->library); > +} > + > +static int config_input(AVFilterLink *link) > +{ > + return 0; > +} > + > +static inline void draw_glyph(AVPicture *picture, FT_Bitmap *bitmap, > unsigned int x, > + unsigned int y, unsigned int width, unsigned int height, > + unsigned char yuv_fcolor[3], unsigned char yuv_bcolor[3], short > int outline) weird indent > +{ > + int r, c; > + uint8_t spixel, dpixel[3], in_glyph=0; > + > + if (bitmap->pixel_mode == ft_pixel_mode_mono) { > + in_glyph = 0; > + for (r=0; (r < bitmap->rows) && (r+y < height); r++) { > + for (c=0; (c < bitmap->width) && (c+x < width); c++) { > + /* pixel in the picture (destination) */ > + GET_PIXEL(picture, dpixel, (c+x), (y+r)); > + > + /* pixel in the glyph bitmap (source) */ > + spixel = bitmap->buffer[r*bitmap->pitch +c/8] & > (0x80>>(c%8)); > + > + if (spixel) > + memcpy(dpixel, yuv_fcolor, 3); > + > + if (outline) { > + /* border detection: */ > + if ( !in_glyph && spixel ) { > + /* left border detected */ > + in_glyph = 1; > + /* draw left pixel border */ > + if (c-1 >= 0) > + SET_PIXEL(picture, yuv_bcolor, (c+x-1), (y+r)); > + } > + else if ( in_glyph && !spixel ) { > + /* right border detected */ > + in_glyph = 0; > + /* 'draw' right pixel border */ > + memcpy(dpixel, yuv_bcolor, 3); > + } > + > + if (in_glyph) { > + /* see if we have a top/bottom border */ > + /* top */ > + if ((r-1 >= 0) && (! > bitmap->buffer[(r-1)*bitmap->pitch +c/8] & (0x80>>(c%8)))) > + /* we have a top border */ > + SET_PIXEL(picture, yuv_bcolor, (c+x), (y+r-1)); > + > + /* bottom border detection */ > + if ((r+1 < height) && (! > bitmap->buffer[(r+1)*bitmap->pitch +c/8] & (0x80>>(c%8)))) > + /* draw bottom border */ > + SET_PIXEL(picture, yuv_bcolor, (c+x), (y+r+1)); > + } > + } > + SET_PIXEL(picture, dpixel, (c+x), (y+r)); > + } > + } > + } > +} > + > +static inline void draw_box(AVPicture *picture, unsigned int x, unsigned int > y, > + unsigned int width, unsigned int height, unsigned char > yuv_color[3]) > +{ > + int i, j; > + > + for (j = 0; (j < height); j++) > + for (i = 0; (i < width); i++) { > + SET_PIXEL(picture, yuv_color, (i+x), (y+j)); > + } weird indent. Also this can be done much faster with a memcpy, see how it is done in vf_pad.c:draw_rectangle. > +} > + > +static void draw_text(DrawTextContext *dtext, AVPicture *picture, int width, > int height) > +{ > + FT_Face face = dtext->face; > + FT_GlyphSlot slot = face->glyph; > + FILE *fd = NULL; > + unsigned char *text = dtext->text; > + unsigned char c; > + int x = 0, y = 0, i=0, size=0; > + unsigned char buff[MAXSIZE_TEXT]; > + unsigned char tbuff[MAXSIZE_TEXT]; > + time_t now = time(0); > + int str_w, str_w_max; > + FT_Vector pos[MAXSIZE_TEXT]; > + FT_Vector delta; > + > + if (dtext->file) { > + if ((fd = fopen(dtext->file, "r")) == NULL) { > + text = dtext->text; > + av_log(dtext, AV_LOG_INFO, "WARNING: The file could not be > opened.\ > + Using text provided with -t switch: %s", strerror(errno)); > + } > + else { > + int l = fread(tbuff, sizeof(char), MAXSIZE_TEXT-1, fd); > + if (l >= 0) { > + tbuff[l] = 0; > + text = tbuff; > + } > + else { > + text = dtext->text; > + av_log(dtext, AV_LOG_INFO, "WARNING: The file could not be > read.\ > + Using text provided with -t switch: %s", > strerror(errno)); > + } > + fclose(fd); > + } > + } > + else { > + text = dtext->text; > + } > + strftime(buff, sizeof(buff), text, localtime(&now)); > + text = buff; > + size = strlen(text); > + > + /* measure string size and save glyphs position*/ > + str_w = str_w_max = 0; > + x = dtext->x; > + y = dtext->y; > + for (i=0; i < size; i++) { > + c = text[i]; > + /* kerning */ > + if ( (dtext->use_kerning) && (i > 0) && (dtext->glyphs_index[c]) ) { > + FT_Get_Kerning(dtext->face, dtext->glyphs_index[text[i-1]], > + dtext->glyphs_index[c], ft_kerning_default, > &delta); > + x += delta.x >> 6; > + } > + > + if (( (x + dtext->advance[ c ]) >= width ) || ( c == '\n' )) { > + if (c != '\n') > + str_w_max = width - dtext->x - 1; > + y += dtext->text_height; > + x = dtext->x; > + } > + > + /* save position */ > + pos[i].x = x + dtext->bitmap_left[c]; > + pos[i].y = y - dtext->bitmap_top[c] + dtext->baseline; > + x += dtext->advance[c]; > + str_w +=dtext->advance[c]; > + } > + if (y == 0) > + y += dtext->text_height; > + if (str_w_max == 0) > + str_w_max = str_w; > + if (dtext->bg) { > + /* Check if it doesn't pass the limits */ > + if ( str_w_max + dtext->x >= width ) > + str_w_max = width - dtext->x - 1; > + if ( y >= height ) > + y = height - 1 - 2*dtext->y; > + > + /* Draw Background */ > + draw_box( picture, dtext->x, dtext->y, str_w_max, y - dtext->y, > dtext->bcolor ); > + } > + > + /* Draw Glyphs */ > + for (i=0; i < size; i++) { > + c = text[i]; > + > + /* skip '_' (consider as space) if text was specified in cmd line and > + * skip new line char, just go to new line */ > + if (( (c == '_') && (text == dtext->text) ) || ( c == '\n' ) ) > + continue; > + > + /* now, draw to our target surface */ > + draw_glyph( picture, > + &(dtext->bitmaps[ c ]), > + pos[i].x, > + pos[i].y, > + width, > + height, > + dtext->fcolor, > + dtext->bcolor, > + dtext->outline ); > + > + /* increment pen position */ > + x += slot->advance.x >> 6; > + } > +} > + > +static void end_frame(AVFilterLink *link) > +{ > + DrawTextContext *context = link->dst->priv; > + AVFilterLink *output = link->dst->outputs[0]; > + AVFilterPicRef *pic_ref = link->cur_pic; > + AVPicture *pic = (AVPicture *)&pic_ref->data; This cast is not needed, you can just work on the AVFilterPicRef, and avoid a dependancy on libavcodec. > + > + draw_text(context, pic, pic_ref->w, pic_ref->h); > + > + avfilter_draw_slice(output, 0, pic_ref->h, 1); > + avfilter_end_frame(output); > +} > + > +AVFilter avfilter_vf_drawtext = { > + .name = "drawtext", > + .description = "Draw text on top of video frames.", please mention libfreetype in the description > + .priv_size = sizeof(DrawTextContext), > + .init = init, > + .uninit = uninit, > + > + .query_formats = query_formats, > + .inputs = (AVFilterPad[]) {{ .name = "default", > + .type = AVMEDIA_TYPE_VIDEO, > + .get_video_buffer= > avfilter_null_get_video_buffer, > + .start_frame = > avfilter_null_start_frame, > + .end_frame = end_frame, > + .config_props = config_input, > + .min_perms = AV_PERM_WRITE | > + AV_PERM_READ, > + .rej_perms = AV_PERM_PRESERVE }, > + { .name = NULL}}, > + .outputs = (AVFilterPad[]) {{ .name = "default", > + .type = AVMEDIA_TYPE_VIDEO, }, > + { .name = NULL}}, > +}; Regards _______________________________________________ FFmpeg-soc mailing list [email protected] https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc
