[MPlayer-dev-eng] patch for bmovl
Nicolas George
nicolas.george at normalesup.org
Wed Mar 7 14:38:09 CET 2012
Le quartidi 24 nivôse, an CCXX, Emmanuel Anne a écrit :
> Ok, here is finally a patch for the problem I posted 1 week ago.
Thanks for the patch, and sorry for the delay.
> Finally it's not related to fps, but rather to the size of the video : if
> the video buffer is aligned its size changes while the bmovl buffer
> doesn't, which produces a nice crash. Fixed by passing the right flag to
> vf_get_image
>
> Then if you play a video with a broken size (like 540x396), the application
> communicating via bmovl will send a buffer for a 540 pixels wide buffer and
> it will be totally distorted because the actual width here is 544 for
> alignement reasons. So this patch now makes the difference between the
> width of the source bitmap and the one of the destination bitmap instead of
> assuming they are always identical.
>
> So far all the videos I could test pass without problem (tested on 2
> computers !).
> Index: libmpcodecs/vf_bmovl.c
> ===================================================================
> --- libmpcodecs/vf_bmovl.c (r?vision 34553)
> +++ libmpcodecs/vf_bmovl.c (copie de travail)
> @@ -221,11 +221,13 @@
> unsigned char red=0, green=0, blue=0;
> int alpha;
> mp_image_t* dmpi;
> + static int halfw;
Static local variables are rarely a good idea (except const ones). This
would break if two instances of the filter are inserted.
>
> + /* get dmpi aligned as mpi */
> dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_TEMP,
> - MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
> - mpi->w, mpi->h);
> -
> + MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE ,
> + mpi->w, mpi->height);
Changing w into width too seems more consistent.
> +
> memcpy_pic( dmpi->planes[0], mpi->planes[0], mpi->width, mpi->height, dmpi->stride[0], mpi->stride[0] );
> memcpy_pic( dmpi->planes[1], mpi->planes[1], mpi->chroma_width, mpi->chroma_height, dmpi->stride[1], mpi->stride[1] );
> memcpy_pic( dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, dmpi->stride[2], mpi->stride[2] );
> @@ -346,6 +348,7 @@
> }
> return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
> }
> + halfw = vf->priv->w/2;
>
> for( buf_y=0 ; (buf_y < imgh) && (buf_y < (vf->priv->h-imgy)) ; buf_y++ ) {
> for( buf_x=0 ; (buf_x < (imgw*pxsz)) && (buf_x < ((vf->priv->w+imgx)*pxsz)) ; buf_x += pxsz ) {
> @@ -389,7 +392,7 @@
> vf->priv->bitmap.oa[pos] = alpha;
> vf->priv->bitmap.a[pos] = INRANGE((alpha+imgalpha),0,255);
> if((buf_y%2) && ((buf_x/pxsz)%2)) {
> - pos = ( ((buf_y+imgy)/2) * dmpi->stride[1] ) + (((buf_x/pxsz)+imgx)/2);
> + pos = ( ((buf_y+imgy)/2) * halfw ) + (((buf_x/pxsz)+imgx)/2);
> vf->priv->bitmap.u[pos] = rgb2u(red,green,blue);
> vf->priv->bitmap.v[pos] = rgb2v(red,green,blue);
> }
> @@ -421,34 +424,37 @@
> } else { // Blit the bitmap to the videoscreen, pixel for pixel
> for( ypos=vf->priv->y1 ; ypos < vf->priv->y2 ; ypos++ ) {
> for ( xpos=vf->priv->x1 ; xpos < vf->priv->x2 ; xpos++ ) {
> + int pos0 = (ypos * vf->priv->w) + xpos;
> pos = (ypos * dmpi->stride[0]) + xpos;
>
> - alpha = vf->priv->bitmap.a[pos];
> + alpha = vf->priv->bitmap.a[pos0];
>
> if (alpha == 0) continue; // Completly transparent pixel
>
> if (alpha == 255) { // Opaque pixel
> - dmpi->planes[0][pos] = vf->priv->bitmap.y[pos];
> + dmpi->planes[0][pos] = vf->priv->bitmap.y[pos0];
> if ((ypos%2) && (xpos%2)) {
> pos = ( (ypos/2) * dmpi->stride[1] ) + (xpos/2);
> - dmpi->planes[1][pos] = vf->priv->bitmap.u[pos];
> - dmpi->planes[2][pos] = vf->priv->bitmap.v[pos];
> + pos0 = ( (ypos/2) * halfw ) + (xpos/2);
> + dmpi->planes[1][pos] = vf->priv->bitmap.u[pos0];
> + dmpi->planes[2][pos] = vf->priv->bitmap.v[pos0];
> }
> } else { // Alphablended pixel
> dmpi->planes[0][pos] =
> ((255 - alpha) * (int)dmpi->planes[0][pos] +
> - alpha * (int)vf->priv->bitmap.y[pos]) >> 8;
> + alpha * (int)vf->priv->bitmap.y[pos0]) >> 8;
>
> if ((ypos%2) && (xpos%2)) {
> pos = ( (ypos/2) * dmpi->stride[1] ) + (xpos/2);
> + pos0 = ( (ypos/2) * halfw ) + (xpos/2);
>
> dmpi->planes[1][pos] =
> ((255 - alpha) * (int)dmpi->planes[1][pos] +
> - alpha * (int)vf->priv->bitmap.u[pos]) >> 8;
> + alpha * (int)vf->priv->bitmap.u[pos0]) >> 8;
>
> dmpi->planes[2][pos] =
> ((255 - alpha) * (int)dmpi->planes[2][pos] +
> - alpha * (int)vf->priv->bitmap.v[pos]) >> 8;
> + alpha * (int)vf->priv->bitmap.v[pos0]) >> 8;
> }
> }
> } // for xpos
> Index: sub/sub.c
> ===================================================================
> --- sub/sub.c (r?vision 34553)
> +++ sub/sub.c (copie de travail)
> @@ -157,8 +157,8 @@
> obj->allocated = len;
> free(obj->bitmap_buffer);
> free(obj->alpha_buffer);
> - obj->bitmap_buffer = memalign(16, len);
> - obj->alpha_buffer = memalign(16, len);
> + obj->bitmap_buffer = (len ? memalign(16, len) : NULL);
> + obj->alpha_buffer = (len ? memalign(16, len) : NULL);
> }
> memset(obj->bitmap_buffer, sub_bg_color, len);
> memset(obj->alpha_buffer, sub_bg_alpha, len);
This part seems unrelated.
I have the attached commit in my work tree that I have tested, I will commit
it soon unless someone has remarks.
Regards,
--
Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20120307/e9d7f4aa/attachment.asc>
More information about the MPlayer-dev-eng
mailing list