[FFmpeg-soc] libavfilter - filter for .ass subtitle rendering using libass

Bobby Bingham uhmmmm at gmail.com
Tue Feb 24 19:20:26 CET 2009


Just a few quick comments I have in addition to Carl's.

On Tue, 24 Feb 2009 20:28:53 +0300
Alexey Lebedeff <binarin at binarin.ru> wrote:

> /*
>  * Usage: '-vfilters
> ass=filename:somefile.ass|margin:50|encoding:utf-8'
>  * Only 'filename' param is mandatory.
>  */

The pipe symbol is a pain because it must be escaped from the shell.
How about something like what mplayer does, so for the above example:
-vfilters ass=somefile.ass:50:utf-8
If the user want to omit a parameter, they can just leave it out, like:
-vfilters ass=somefile.ass::utf-8

> [...]
> 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;
> }

Do you handle the different ranges of YUV and JPEG YUV?

> [...]
> #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 )

Maybe you can use swscale instead.  It will certainly be faster as it
is hand-optimized, and should allow proper support for both types of
YUV.

> 
> 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;
>     }

Using swscale would also allow for better than nearest neighbor
downsampling here, I believe.

Also, indentation in ffmpeg is 4 spaces.
-- 
Bobby Bingham
Never trust atoms.  Or anything made of atoms.
このメールは再利用されたバイトでできている。



More information about the FFmpeg-soc mailing list