[FFmpeg-devel] [PATCH] av_picture_copy misses pixels on packed planar AVPictures with odd width or height

Michael Niedermayer michaelni
Wed Oct 29 17:38:57 CET 2008


On Tue, Oct 28, 2008 at 11:52:46AM -0700, Art Clarke wrote:
> To reproduce:
> 1) Create a AVPicture with an odd width and height (e.g. 503w x 251h)
> in a packed pixel format (e.g. YUV_420P).

P stands for planar


> 2) Use the av_picture_copy method
> 3) Check if all bytes are the same in the copied AVPicture: you'll be
> missing one U and V values at the end of each line, and all the U and
> V values for last line.
> 
> Cause:
> A rounding error computing the width and height to copy.  A picture
> 503w x 251h pixels should have U and V plane widths of 252, and 126
> total rows of u and v data but due to the rounding error the
> av_picture_copy only copes over 251 bytes for each row's width, and
> calculates 125 total rows of data.  ff_fill_* methods do the correct
> math.
> 
> Fix:
> 1) Make sure we compute plane width and height by rounding up with
> adjusting for chroma_shifts (as in the ff_fill_linesinze methods)
> 2) remove an unused "width" calculation that was never used.
> 
> - Art

> Index: libavcodec/imgconvert.c
> ===================================================================
> --- libavcodec/imgconvert.c	(revision 15735)
> +++ libavcodec/imgconvert.c	(working copy)
> @@ -870,7 +870,7 @@
>          break;
>      case FF_PIXEL_PLANAR:
>              if (plane == 1 || plane == 2)
> -                width >>= pf->x_chroma_shift;
> +                width = (width + (1 << pf->x_chroma_shift) - 1) >> pf->x_chroma_shift;

width= -((-width)>>pf->x_chroma_shift);


>  
>              return (width * pf->depth + 7) >> 3;
>          break;

> @@ -894,13 +894,11 @@
>      case FF_PIXEL_PACKED:
>      case FF_PIXEL_PLANAR:
>          for(i = 0; i < pf->nb_channels; i++) {
> -            int w, h;
> +            int h;
>              int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
> -            w = width;
>              h = height;
>              if (i == 1 || i == 2) {
> -                w >>= pf->x_chroma_shift;
> -                h >>= pf->y_chroma_shift;
> +                h = (height + (1 << pf->y_chroma_shift) - 1) >> pf->y_chroma_shift;
>              }
>              ff_img_copy_plane(dst->data[i], dst->linesize[i],
>                             src->data[i], src->linesize[i],

this seems to contain an unrelated change

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I am the wisest man alive, for I know one thing, and that is that I know
nothing. -- Socrates
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20081029/6600a175/attachment.pgp>



More information about the ffmpeg-devel mailing list