[FFmpeg-soc] [PATCH] new avfilter vf_logo.c to overlay a (alpha-pathed) logo onto a video stream
Vitor Sessak
vitor1001 at gmail.com
Sun Apr 26 15:46:16 CEST 2009
Jürgen Meissner wrote:
> vf_logo.c implements avfilters "logo" and "logo_without_alpha"
Great! This is one of the feature most requested by users!
> logo=10:20:logo.jpg overlays the video at x=10 y=20 with the logo (is
> respecting the alpha-path of the logo)
> logo=-1:1:logo.png overlays the video at 1 pixel from the right and 1
> pixel from the top border
> logo_without_alpha=10:20:logo.gif overlays the video at 10,20 for all
> pixels of the logo, doesn't look for an alpha-path in the logo
> logo=0:0:0:10:20:logo.gif overlays video at 10,20 and assumes black
> RGB=(0,0,0) is the transparent color in the logo
>
> vf_logo.c is relying on the new pixdesc.c rather than the old pix-fmt.c
> and therefor needs pixdesc.o to be included into the libavcodec.a archive.
I'll add a few comments to those Setefano gave.
> 03_libavcodec_Makefile.diff adds the pixdesc.o to the OBS list in the
> libavcodec/Makefile
I leave this to Stefano/Michael...
> +/**
> + * RGBA pixel.
> + */
> +typedef struct {
> + uint8_t R; ///< Red.
> + uint8_t G; ///< Green.
> + uint8_t B; ///< Blue.
> + uint8_t A; ///< Alpha.
> +} RGBA;
> +
We usually do not use those type of structs, but just uint8_t[4].
> +static const char *pixdesc_name(int pix_fmt)
> +{
> + return av_pix_fmt_descriptors[pix_fmt].name;
> +}
> +
I think you can just inline this function where it is needed.
> + if (logo->pCodecCtx->pix_fmt != PIX_FMT_RGBA) {
> + // transform it with swscaler to PIX_FMT_RGBA
It seems that you always convert the logo to RGBA. This is a bad idea
because if both the logo and the movie is in YUV format, the logo will
be converted YUV->RGB->YUV, that would degrade the logo quality.
> + // Allocate an AVFrame structure
> + logo->plogo_frame_rgba32 = avcodec_alloc_frame();
What this comment says is already obvious from the line it describes,
making it useless and distracting (that probably happens elsewhere in
the code too).
> +static void uninit(AVFilterContext * ctx)
> +{
> +
> + LogoContext *logo;
> +
> + logo = ctx->priv;
> +
> + if (logo->sws != NULL)
> + sws_freeContext(logo->sws);
I think that if you do colorspace conversion just once, there is no need
to having logo->sws in the context (and that would simplify
allocation/freeing).
> +static AVFilterFormats *make_format_list(LogoContext * logo)
> +{
> + AVFilterFormats *ret;
> + int i;
> +
> + ret = av_mallocz(sizeof(AVFilterFormats));
> + ret->formats = av_malloc(sizeof(int) * PIX_FMT_NB);
> +
> + for (i = 0; i < PIX_FMT_NB; i++) {
> + switch (i) {
> + /* don't support these */
> + case PIX_FMT_YUYV422:
> + case PIX_FMT_MONOBLACK:
> + case PIX_FMT_UYVY422:
> + break;
> + /* support everything else (if named) */
> + default:
> + if (av_pix_fmt_descriptors[i].name)
> + ret->formats[ret->format_count++] = i;
> + }
> + }
> + return ret;
While I agree with Stefano that it would be hard to do less ugly, what
bothers me about this code is that it is fragile. It is very likely it
will break when new formats are added....
Thanks for your contribution!
-Vitor
More information about the FFmpeg-soc
mailing list