[FFmpeg-devel] [PATCH] Fixed CamStudio decoder picture corruptions

Laurent Aimar fenrir
Sat Oct 30 17:18:38 CEST 2010


Hi,

On Thu, Sep 09, 2010 at 10:22:20PM +0200, Reimar D?ffinger wrote:
> Sorry I completely missed this patch.
 And me too.

> Your changes should not at all depend on endianness, so I don't
> think it's necessary to test.
Ok.

> > @@ -30,31 +30,32 @@
> >  
> >  typedef struct {
> >      AVFrame pic;
> > -    int linelen, height, bpp;
> > +    int linelen, linepitch, height, bpp;
> 
> Using the term "stride" as we do in all other code would be better.
 If you ok my patch I will change "linepitch" to "stride" if you prefer.

> > @@ -229,8 +234,9 @@
> >      c->bpp = avctx->bits_per_coded_sample;
> >      c->pic.data[0] = NULL;
> >      c->linelen = avctx->width * avctx->bits_per_coded_sample / 8;
> > +    c->linepitch = (avctx->width * avctx->bits_per_coded_sample + 31) / 32 * 4;
> 
> I am almost certain that this codec just compresses a Windows bitmap 1:1
> and thus this code is wrong.
> For Windows bitmaps, alignment is only done for the RGB24 format,
> but not e.g. for the RGB555 format.
> If you have samples that prove one way or the other (i.e. if anyone has
> RGB555 samples with odd width) that would be helpful.
 I have checked with the code source of CamStudio, it always pads to 4
regardless of the chroma:

DWORD CodecInst::CompressRGB(ICCOMPRESS* icinfo)
{
    [...]
    int remainder = icinfo->lpbiInput->biWidth % 4;--
    if (remainder > 0)
    {
        int newbit = icinfo->lpbiInput->biBitCount;

        // In the original version, remainder was subtracted from newwidth.
        // This is wrong - it causes a black line to appear over the video
        // if the width's not divisible by 4, so it's been removed.
        int newwidth = icinfo->lpbiInput->biWidth;
        int newheight = icinfo->lpbiInput->biHeight;>-----
        int wLineLen = (newwidth * (newbit) + 31) / 32 * 4;
        int newsize = wLineLen * newheight;>-->---

        input = (unsigned char*)icinfo->lpInput;-->---

        // strange, adding this line will allow the image to be displayed!!
        in_len = newsize;
    }
    else // normal case
    {
        input = (unsigned char*)icinfo->lpInput;--
        in_len=icinfo->lpbiInput->biSizeImage;
    }
    [...]
}

but I don't have any 16 bits sample to confirm it is actually needed.

The sample I have is 24 bits:
http://trac.videolan.org/vlc/attachment/ticket/3778/example.zip

-- 
fenrir




More information about the ffmpeg-devel mailing list