On Tue, 24 Feb 2009 13:54:08 +0300, Alexey Lebedeff wrote: AL> If there is any interest in it, I'll do some cleanup to code, AL> properly integrate it into build process, and share the results.
Here is the very primitive patch to libavfilter Makefile, and source of filter itself. No proper build process integration yet.
--- Makefile.orig 2009-02-23 10:41:03.000000000 +0000 +++ Makefile 2009-02-24 16:57:36.000000000 +0000 @@ -13,6 +13,7 @@ graphparser.o \ +OBJS-$(CONFIG_ASS_FILTER) += vf_ass.o OBJS-$(CONFIG_CROP_FILTER) += vf_crop.o OBJS-$(CONFIG_DRAWBOX_FILTER) += vf_drawbox.o OBJS-$(CONFIG_FPS_FILTER) += vf_fps.o @@ -34,4 +35,8 @@ HEADERS = avfilter.h +CFLAGS += -I/usr/include/ass +EXTRALIBS += -lass + include $(SUBDIR)../subdir.mak + --- allfilters.c.orig 2009-02-23 10:41:03.000000000 +0000 +++ allfilters.c 2009-02-23 11:26:18.000000000 +0000 @@ -34,6 +34,7 @@ return; initialized = 1; + REGISTER_FILTER(ASS,ass,vf); REGISTER_FILTER(CROP,crop,vf); REGISTER_FILTER(DRAWBOX,drawbox,vf); REGISTER_FILTER(FIFO,fifo,vf);
/* * SSA/ASS subtitles rendering filter, using libssa. * Based on vf_drawbox.c from libavfilter and vf_ass.c from mplayer. * * Copyright (c) 2006 Evgeniy Stepanov <eugeni.stepa...@gmail.com> * Copyright (c) 2008 Affine Systems, Inc (Michael Sullivan, Bobby Impollonia) * Copyright (c) 2009 Alexey Lebedeff <bina...@binarin.ru> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program 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 General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ /* * Usage: '-vfilters ass=filename:somefile.ass|margin:50|encoding:utf-8' * Only 'filename' param is mandatory. */ #include <string.h> #include <stdio.h> #include <ctype.h> #include <ass.h> #include "avfilter.h" typedef struct { ass_library_t *ass_library; ass_renderer_t *ass_renderer; ass_track_t *ass_track; int margin; char *filename; char *encoding; int frame_width, frame_height; int vsub,hsub; //< chroma subsampling } AssContext; static int parse_args(AVFilterContext *ctx, AssContext *context, const char* args); static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) { AssContext *context= ctx->priv; /* defaults */ context->margin = 10; context->encoding = "utf-8"; if ( parse_args(ctx, context, args) ) return 1; return 0; } static int query_formats(AVFilterContext *ctx) { avfilter_set_common_formats (ctx, avfilter_make_format_list(10, 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)); return 0; } static int config_input(AVFilterLink *link) { AssContext *context = link->dst->priv; context->frame_width = link->w; context->frame_height = link->h; context->ass_library = ass_library_init(); if ( !context->ass_library ) { av_log(0, AV_LOG_ERROR, "ass_library_init() failed!\n"); return 1; } ass_set_fonts_dir(context->ass_library, ""); ass_set_extract_fonts(context->ass_library, 1); ass_set_style_overrides(context->ass_library, NULL); context->ass_renderer = ass_renderer_init(context->ass_library); if ( ! context->ass_renderer ) { av_log(0, AV_LOG_ERROR, "ass_renderer_init() failed!\n"); return 1; } ass_set_frame_size(context->ass_renderer, link->w, link->h); ass_set_margins(context->ass_renderer, context->margin, context->margin, context->margin, context->margin); ass_set_use_margins(context->ass_renderer, 1); ass_set_font_scale(context->ass_renderer, 1.); ass_set_fonts(context->ass_renderer, NULL, "Sans"); context->ass_track = ass_read_file(context->ass_library, context->filename, context->encoding); if ( !context->ass_track ) { av_log(0, AV_LOG_ERROR, "Failed to read subtitle file with ass_read_file()!\n"); return 1; } avcodec_get_chroma_sub_sample(link->format, &context->hsub, &context->vsub); return 0; } static void start_frame(AVFilterLink *link, AVFilterPicRef *picref) { avfilter_start_frame(link->dst->outputs[0], picref); } #define _r(c) ((c)>>24) #define _g(c) (((c)>>16)&0xFF) #define _b(c) (((c)>>8)&0xFF) #define _a(c) ((c)&0xFF) #define rgba2y(c) ( (( 263*_r(c) + 516*_g(c) + 100*_b(c)) >> 10) + 16 ) #define rgba2u(c) ( ((-152*_r(c) - 298*_g(c) + 450*_b(c)) >> 10) + 128 ) #define rgba2v(c) ( (( 450*_r(c) - 376*_g(c) - 73*_b(c)) >> 10) + 128 ) static void draw_ass_image(AVFilterPicRef *pic, ass_image_t *img, AssContext *context) { unsigned char *row[4]; unsigned char c_y = rgba2y(img->color); unsigned char c_u = rgba2u(img->color); unsigned char c_v = rgba2v(img->color); unsigned char opacity = 255 - _a(img->color); unsigned char *src; int i, j; unsigned char *bitmap = img->bitmap; int bitmap_w = img->w; int bitmap_h = img->h; int dst_x = img->dst_x; int dst_y = img->dst_y; int channel; int x,y; src = bitmap; for (i = 0; i < bitmap_h; ++i) { y = dst_y + i; if ( y >= pic->h ) break; row[0] = pic->data[0] + y * pic->linesize[0]; for (channel = 1; channel < 3; channel++) row[channel] = pic->data[channel] + pic->linesize[channel] * (y>> context->vsub); for (j = 0; j < bitmap_w; ++j) { unsigned k = ((unsigned)src[j]) * opacity / 255; x = dst_x + j; if ( y >= pic->w ) break; row[0][x] = (k*c_y + (255-k)*row[0][x]) / 255; row[1][x >> context->hsub] = (k*c_u + (255-k)*row[1][x >> context->hsub]) / 255; row[2][x >> context->hsub] = (k*c_v + (255-k)*row[2][x >> context->hsub]) / 255; } src += img->stride; } } static void end_frame(AVFilterLink *link) { AssContext *context = link->dst->priv; AVFilterLink* output = link->dst->outputs[0]; AVFilterPicRef *pic = link->cur_pic; ass_image_t* img = ass_render_frame(context->ass_renderer, context->ass_track, pic->pts * 1000 / AV_TIME_BASE, NULL); while ( img ) { draw_ass_image(pic, img, context); img = img->next; } avfilter_draw_slice(output, 0, pic->h); avfilter_end_frame(output); } static int parse_args(AVFilterContext *ctx, AssContext *context, const char* args) { char *arg_copy = av_strdup(args); char *strtok_arg = arg_copy; char *param; while ( param = strtok(strtok_arg, "|") ) { char *tmp = param; char *param_name; char *param_value; strtok_arg = NULL; while ( *tmp && *tmp != ':' ) { tmp++; } if ( param == tmp || ! *tmp ) { av_log(ctx, AV_LOG_ERROR, "Error while parsing arguments - must be like 'param1:value1|param2:value2'\n"); return 1; } param_name = av_malloc(tmp - param + 1); memset(param_name, 0, tmp - param + 1); strncpy(param_name, param, tmp-param); tmp++; if ( ! *tmp ) { av_log(ctx, AV_LOG_ERROR, "Error while parsing arguments - parameter value cannot be empty\n"); return 1; } param_value = av_strdup(tmp); if ( !strcmp("margin", param_name ) ) { context->margin = atoi(param_value); } else if ( !strcmp("filename", param_name ) ) { context->filename = av_strdup(param_value); } else if ( !strcmp("encoding", param_name ) ) { context->encoding = av_strdup(param_value); } else { av_log(ctx, AV_LOG_ERROR, "Error while parsing arguments - unsupported parameter '%s'\n", param_name); return 1; } av_free(param_name); av_free(param_value); } if ( ! context->filename ) { av_log(ctx, AV_LOG_ERROR, "Error while parsing arguments - mandatory parameter 'filename' missing\n"); return 1; } return 0; } AVFilter avfilter_vf_ass= { .name = "ass", .priv_size = sizeof(AssContext), .init = init, .query_formats = query_formats, .inputs = (AVFilterPad[]) {{ .name = "default", .type = CODEC_TYPE_VIDEO, .start_frame = start_frame, .end_frame = end_frame, .config_props = config_input, .min_perms = AV_PERM_WRITE | AV_PERM_READ, .rej_perms = AV_PERM_REUSE | AV_PERM_REUSE2}, { .name = NULL}}, .outputs = (AVFilterPad[]) {{ .name = "default", .type = CODEC_TYPE_VIDEO, }, { .name = NULL}}, };
pgp4ObvTomaD3.pgp
Description: PGP signature
_______________________________________________ FFmpeg-soc mailing list FFmpeg-soc@mplayerhq.hu https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc