[FFmpeg-devel] libavfilter-soc: negate filter artifacts

Stefano Sabatini stefano.sabatini-lala
Sat Jul 25 18:11:34 CEST 2009


On date Friday 2009-07-24 09:07:45 +0200, Stefano Sabatini encoded:
> On date Friday 2009-07-24 01:58:07 +0200, Stefano Sabatini encoded:
> > On date Monday 2009-07-20 05:55:41 +0200, Vitor Sessak encoded:
> > > Stefano Sabatini wrote:
> > >> Hi,
> > >>
> > >> I wonder what's the point of the default offesets assigned in the config_props:
> > >> static int config_props(AVFilterLink *link)
> > >> {
> > >>     NegContext *neg = link->dst->priv;
> > >>
> > >>     avcodec_get_chroma_sub_sample(link->format, &neg->hsub, &neg->vsub);
> > >>
> > >>     switch(link->format) {
> > >>     case PIX_FMT_YUVJ444P:
> > >>     case PIX_FMT_YUVJ422P:
> > >>     case PIX_FMT_YUVJ420P:
> > >>     case PIX_FMT_YUVJ440P:
> > >>         neg->offY  =
> > >>         neg->offUV = 0;
> > >>         break;
> > >>     default:
> > >>         neg->offY  = -4;
> > >>         neg->offUV = 1;
> > >>     }
> > >>
> > >>     return 0;
> > >> }
> > >
> > > I think the problem here is that YUV (and not YUVJ) has Y data in the  
> > > 16...235 range. So ideally one would negate 235 <-> 16 (see  
> > > imgconvert.c:47). But as you show in your message, the code is buggy.
> > 
> > Check the patch attached if it looks reasonable.

The current code is correct.

The conversion to perform is as follows:
X' = 2 * mid_range - X

For YUV we have:
mid_range[Y] = (16 + 235) / 2
mid_range[Y] * 2 = 251 = 255 + offY;  
offY = 251 - 255 = -4;

Similarly:
mid_range[UV] = (16 + 240) / 2
mid_range[UV] * 2 = 256 = 255 + offUV;  
offUV = 256 - 255 = 1;

The problem I experienced was due to video4linux proving values
outside the YUV ranges, as apparently it's using values in the YUVJ
ranges and in v4l.c we have:

static const struct {
    int palette;
    int depth;
    enum PixelFormat pix_fmt;
} video_formats [] = {
    {.palette = VIDEO_PALETTE_YUV420P, .depth = 12, .pix_fmt = PIX_FMT_YUV420P },
    {.palette = VIDEO_PALETTE_YUV422,  .depth = 16, .pix_fmt = PIX_FMT_YUYV422 },
    {.palette = VIDEO_PALETTE_UYVY,    .depth = 16, .pix_fmt = PIX_FMT_UYVY422 },
    {.palette = VIDEO_PALETTE_YUYV,    .depth = 16, .pix_fmt = PIX_FMT_YUYV422 },
    /* NOTE: v4l uses BGR24, not RGB24 */
    {.palette = VIDEO_PALETTE_RGB24,   .depth = 24, .pix_fmt = PIX_FMT_BGR24   },
    {.palette = VIDEO_PALETTE_RGB565,  .depth = 16, .pix_fmt = PIX_FMT_BGR565  },
    {.palette = VIDEO_PALETTE_GREY,    .depth = 8,  .pix_fmt = PIX_FMT_GRAY8   },
};

My guess is that either the above mapping is wrong and we should
really use YUVJ420P, either the gspca v.1 driver I'm using is wrong.

Anyway I'll try to see to which format/ranges VIDEO_PALETTE_YUV420P
and friends correspond.

Regards.
-- 
FFmpeg = Fostering & Fundamentalist Mystic Peaceful Erotic Gadget



More information about the ffmpeg-devel mailing list