Changeset 1106a14087d306e0d1951fd57ab527332d086615

Show
Ignore:
Timestamp:
02/04/07 22:54:52 (2 years ago)
Author:
Antoine Cellerier <dionoea@videolan.org>
git-committer:
Antoine Cellerier <dionoea@videolan.org> 1175547292 +0000
git-parent:

[2b5629b6f4920f02b2bbb62683f7ad2d7d386c9e]

git-author:
Antoine Cellerier <dionoea@videolan.org> 1175547292 +0000
Message:

Fix I420/YV12 -> * blending. Looks like we did need separate functions.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/video_filter/blend.c

    rc0653a1 r1106a14  
    4848 
    4949/* TODO i_alpha support for BlendR16 */ 
    50 /* YUVA, I420, YV12 */ 
     50/* YUVA */ 
    5151static void BlendI420( filter_t *, picture_t *, picture_t *, picture_t *, 
    5252                       int, int, int, int, int ); 
    53 static void BlendI420I420( filter_t *, picture_t *, picture_t *, picture_t *, 
    54                            int, int, int, int ); 
    5553static void BlendR16( filter_t *, picture_t *, picture_t *, picture_t *, 
    5654                      int, int, int, int, int ); 
     
    5957static void BlendYUVPacked( filter_t *, picture_t *, picture_t *, picture_t *, 
    6058                            int, int, int, int, int ); 
     59 
     60/* I420, YV12 */ 
     61static void BlendI420I420( filter_t *, picture_t *, picture_t *, picture_t *, 
     62                           int, int, int, int, int ); 
     63static void BlendI420I420_no_alpha( 
     64                           filter_t *, picture_t *, picture_t *, picture_t *, 
     65                           int, int, int, int ); 
     66static void BlendI420R16( filter_t *, picture_t *, picture_t *, picture_t *, 
     67                           int, int, int, int, int ); 
     68static void BlendI420R24( filter_t *, picture_t *, picture_t *, picture_t *, 
     69                          int, int, int, int, int ); 
     70static void BlendI420YUVPacked( filter_t *, picture_t *, picture_t *, 
     71                                picture_t *, int, int, int, int, int ); 
    6172 
    6273/* YUVP */ 
     
    175186    switch( p_filter->fmt_in.video.i_chroma ) 
    176187    { 
    177         case VLC_FOURCC('Y','V','1','2'): 
    178         case VLC_FOURCC('I','4','2','0'): 
    179             if( i_alpha == 0xff && 
    180               ( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('I','4','2','0') 
    181              || p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','V','1','2') 
    182               ) ) 
    183             { 
    184                 BlendI420I420( p_filter, p_dst, p_dst_orig, p_src, 
    185                                i_x_offset, i_y_offset, 
    186                                i_width, i_height ); 
    187                 return; 
    188             } 
    189188        case VLC_FOURCC('Y','U','V','A'): 
    190189            switch( p_filter->fmt_out.video.i_chroma ) 
     
    239238                    return; 
    240239            } 
     240        case VLC_FOURCC('Y','V','1','2'): 
     241        case VLC_FOURCC('I','4','2','0'): 
     242            switch( p_filter->fmt_out.video.i_chroma ) 
     243            { 
     244                case VLC_FOURCC('I','4','2','0'): 
     245                case VLC_FOURCC('Y','V','1','2'): 
     246                    if( i_alpha == 0xff ) 
     247                        BlendI420I420_no_alpha( 
     248                                   p_filter, p_dst, p_dst_orig, p_src, 
     249                                   i_x_offset, i_y_offset, 
     250                                   i_width, i_height ); 
     251                    else 
     252                        BlendI420I420( p_filter, p_dst, p_dst_orig, p_src, 
     253                                       i_x_offset, i_y_offset, 
     254                                       i_width, i_height, i_alpha ); 
     255                    return; 
     256                case VLC_FOURCC('Y','U','Y','2'): 
     257                case VLC_FOURCC('U','Y','V','Y'): 
     258                case VLC_FOURCC('Y','V','Y','U'): 
     259                    BlendI420YUVPacked( p_filter, p_dst, p_dst_orig, p_src, 
     260                                        i_x_offset, i_y_offset, 
     261                                        i_width, i_height, i_alpha ); 
     262                    return; 
     263                case VLC_FOURCC('R','V','1','6'): 
     264                    BlendI420R16( p_filter, p_dst, p_dst_orig, p_src, 
     265                                  i_x_offset, i_y_offset, 
     266                                  i_width, i_height, i_alpha ); 
     267                    return; 
     268                case VLC_FOURCC('R','V','2','4'): 
     269                case VLC_FOURCC('R','V','3','2'): 
     270                    BlendI420R24( p_filter, p_dst, p_dst_orig, p_src, 
     271                                  i_x_offset, i_y_offset, 
     272                                  i_width, i_height, i_alpha ); 
     273                    return; 
     274            } 
    241275        case VLC_FOURCC('R','G','B','A'): 
    242276            switch( p_filter->fmt_out.video.i_chroma ) 
     
    364398               p_src->p[V_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
    365399 
    366     if( p_filter->fmt_in.video.i_chroma == VLC_FOURCC('Y','V','1','2') || 
    367         p_filter->fmt_in.video.i_chroma == VLC_FOURCC('I','4','2','0') ) 
    368     { 
    369         p_trans = NULL; 
    370         i_trans = i_alpha; 
    371     } 
    372     else 
    373     { 
    374         p_trans = p_src->p[A_PLANE].p_pixels + 
    375                   p_filter->fmt_in.video.i_x_offset + 
    376                   p_src->p[A_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
    377     } 
     400    p_trans = p_src->p[A_PLANE].p_pixels + 
     401              p_filter->fmt_in.video.i_x_offset + 
     402              p_src->p[A_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
    378403 
    379404#define MAX_TRANS 255 
     
    381406 
    382407    /* Draw until we reach the bottom of the subtitle */ 
    383     for( i_y = 0; i_y < i_height; i_y++, p_trans += p_trans?i_src2_pitch:0
     408    for( i_y = 0; i_y < i_height; i_y++, p_trans += i_src2_pitch
    384409         p_dst_y += i_dst_pitch, p_src1_y += i_src1_pitch, 
    385410         p_src2_y += i_src2_pitch, 
     
    438463    return; 
    439464} 
    440 static void BlendI420I420( filter_t *p_filter, picture_t *p_dst, 
    441                            picture_t *p_dst_orig, picture_t *p_src, 
    442                            int i_x_offset, int i_y_offset, 
    443                            int i_width, int i_height ) 
     465 
     466static void BlendR16( filter_t *p_filter, picture_t *p_dst_pic, 
     467                      picture_t *p_dst_orig, picture_t *p_src, 
     468                      int i_x_offset, int i_y_offset, 
     469                      int i_width, int i_height, int i_alpha ) 
    444470{ 
    445471    int i_src1_pitch, i_src2_pitch, i_dst_pitch; 
    446     uint8_t *p_src1_y, *p_src2_y, *p_dst_y; 
    447     uint8_t *p_src1_u, *p_src2_u, *p_dst_u; 
    448     uint8_t *p_src1_v, *p_src2_v, *p_dst_v; 
    449     int i_y; 
    450     vlc_bool_t b_even_scanline = i_y_offset % 2; 
    451  
    452     i_dst_pitch = p_dst->p[Y_PLANE].i_pitch; 
    453     p_dst_y = p_dst->p[Y_PLANE].p_pixels + i_x_offset + 
    454               p_filter->fmt_out.video.i_x_offset + 
    455               p_dst->p[Y_PLANE].i_pitch * 
    456               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
    457     p_dst_u = p_dst->p[U_PLANE].p_pixels + i_x_offset/2 + 
    458               p_filter->fmt_out.video.i_x_offset/2 + 
    459               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
    460               p_dst->p[U_PLANE].i_pitch; 
    461     p_dst_v = p_dst->p[V_PLANE].p_pixels + i_x_offset/2 + 
    462               p_filter->fmt_out.video.i_x_offset/2 + 
    463               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
    464               p_dst->p[V_PLANE].i_pitch; 
     472    uint8_t *p_dst, *p_src1, *p_src2_y; 
     473    uint8_t *p_src2_u, *p_src2_v; 
     474    uint8_t *p_trans; 
     475    int i_x, i_y, i_pix_pitch, i_trans = 0; 
     476    int r, g, b; 
     477 
     478    i_pix_pitch = p_dst_pic->p->i_pixel_pitch; 
     479    i_dst_pitch = p_dst_pic->p->i_pitch; 
     480    p_dst = p_dst_pic->p->p_pixels + i_x_offset * i_pix_pitch + 
     481            p_filter->fmt_out.video.i_x_offset * i_pix_pitch + 
     482            p_dst_pic->p->i_pitch * 
     483            ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
    465484 
    466485    i_src1_pitch = p_dst_orig->p[Y_PLANE].i_pitch; 
    467     p_src1_y = p_dst_orig->p[Y_PLANE].p_pixels + i_x_offset
    468                p_filter->fmt_out.video.i_x_offset
    469                p_dst_orig->p[Y_PLANE].i_pitch * 
     486    p_src1 = p_dst_orig->p->p_pixels + i_x_offset * i_pix_pitch
     487               p_filter->fmt_out.video.i_x_offset * i_pix_pitch
     488               p_dst_orig->p->i_pitch * 
    470489               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
    471     p_src1_u = p_dst_orig->p[U_PLANE].p_pixels + i_x_offset/2 + 
    472                p_filter->fmt_out.video.i_x_offset/2 + 
    473                ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
    474                p_dst_orig->p[U_PLANE].i_pitch; 
    475     p_src1_v = p_dst_orig->p[V_PLANE].p_pixels + i_x_offset/2 + 
    476                p_filter->fmt_out.video.i_x_offset/2 + 
    477                ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
    478                p_dst_orig->p[V_PLANE].i_pitch; 
    479490 
    480491    i_src2_pitch = p_src->p[Y_PLANE].i_pitch; 
     
    489500               p_src->p[V_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
    490501 
    491     i_width &= ~1; 
     502    p_trans = p_src->p[A_PLANE].p_pixels + 
     503              p_filter->fmt_in.video.i_x_offset + 
     504              p_src->p[A_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
     505 
     506#define MAX_TRANS 255 
     507#define TRANS_BITS  8 
    492508 
    493509    /* Draw until we reach the bottom of the subtitle */ 
    494     for( i_y = 0; i_y < i_height; i_y++, 
    495          p_dst_y += i_dst_pitch, p_src1_y += i_src1_pitch, 
    496          p_src2_y += i_src2_pitch, 
    497          p_dst_u += b_even_scanline ? i_dst_pitch/2 : 0, 
    498          p_src1_u += b_even_scanline ? i_src1_pitch/2 : 0, 
    499          p_src2_u += i_src2_pitch, 
    500          p_dst_v += b_even_scanline ? i_dst_pitch/2 : 0, 
    501          p_src1_v += b_even_scanline ? i_src1_pitch/2 : 0, 
     510    for( i_y = 0; i_y < i_height; i_y++, p_trans += i_src2_pitch, 
     511         p_dst += i_dst_pitch, p_src1 += i_src1_pitch, 
     512         p_src2_y += i_src2_pitch, p_src2_u += i_src2_pitch, 
    502513         p_src2_v += i_src2_pitch ) 
    503514    { 
    504         b_even_scanline = !b_even_scanline; 
    505  
    506         /* Completely opaque. Completely overwrite underlying pixel */ 
    507         p_filter->p_libvlc->pf_memcpy( p_dst_y, p_src2_y, i_width ); 
    508  
    509         if( b_even_scanline ) 
    510         { 
    511             p_filter->p_libvlc->pf_memcpy( p_dst_u, p_src2_u, i_width/2 ); 
    512             p_filter->p_libvlc->pf_memcpy( p_dst_y, p_src2_y, i_width/2 ); 
    513         } 
    514     } 
     515        /* Draw until we reach the end of the line */ 
     516        for( i_x = 0; i_x < i_width; i_x++ ) 
     517        { 
     518            if( p_trans ) 
     519                i_trans = ( p_trans[i_x] * i_alpha ) / 255; 
     520            if( !i_trans ) 
     521            { 
     522                /* Completely transparent. Don't change pixel */ 
     523                continue; 
     524            } 
     525            else if( i_trans == MAX_TRANS ) 
     526            { 
     527                /* Completely opaque. Completely overwrite underlying pixel */ 
     528                yuv_to_rgb( &r, &g, &b, 
     529                            p_src2_y[i_x], p_src2_u[i_x], p_src2_v[i_x] ); 
     530 
     531    ((uint16_t *)(&p_dst[i_x * i_pix_pitch]))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); 
     532                continue; 
     533            } 
     534 
     535            /* Blending */ 
     536            /* FIXME: do the blending */ 
     537            yuv_to_rgb( &r, &g, &b, 
     538                        p_src2_y[i_x], p_src2_u[i_x], p_src2_v[i_x] ); 
     539 
     540    ((uint16_t *)(&p_dst[i_x * i_pix_pitch]))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); 
     541        } 
     542    } 
     543 
     544#undef MAX_TRANS 
     545#undef TRANS_BITS 
    515546 
    516547    return; 
    517548} 
    518549 
    519 static void BlendR16( filter_t *p_filter, picture_t *p_dst_pic, 
     550static void BlendR24( filter_t *p_filter, picture_t *p_dst_pic, 
    520551                      picture_t *p_dst_orig, picture_t *p_src, 
    521552                      int i_x_offset, int i_y_offset, 
     
    553584               p_src->p[V_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
    554585 
    555     if( p_filter->fmt_in.video.i_chroma == VLC_FOURCC('Y','V','1','2') || 
    556         p_filter->fmt_in.video.i_chroma == VLC_FOURCC('I','4','2','0') ) 
    557     { 
    558         p_trans = NULL; 
    559         i_trans = i_alpha; 
    560     } 
    561     else 
    562     { 
    563         p_trans = p_src->p[A_PLANE].p_pixels + 
    564                   p_filter->fmt_in.video.i_x_offset + 
    565                   p_src->p[A_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
    566     } 
     586    p_trans = p_src->p[A_PLANE].p_pixels + 
     587              p_filter->fmt_in.video.i_x_offset + 
     588              p_src->p[A_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
    567589 
    568590#define MAX_TRANS 255 
     
    570592 
    571593    /* Draw until we reach the bottom of the subtitle */ 
    572     for( i_y = 0; i_y < i_height; i_y++, p_trans += p_trans?i_src2_pitch:0
     594    for( i_y = 0; i_y < i_height; i_y++, p_trans += i_src2_pitch
    573595         p_dst += i_dst_pitch, p_src1 += i_src1_pitch, 
    574596         p_src2_y += i_src2_pitch, p_src2_u += i_src2_pitch, 
     
    591613                            p_src2_y[i_x], p_src2_u[i_x], p_src2_v[i_x] ); 
    592614 
    593     ((uint16_t *)(&p_dst[i_x * i_pix_pitch]))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); 
     615                p_dst[i_x * i_pix_pitch]     = r; 
     616                p_dst[i_x * i_pix_pitch + 1] = g; 
     617                p_dst[i_x * i_pix_pitch + 2] = b; 
    594618                continue; 
    595619            } 
    596620 
    597621            /* Blending */ 
    598             /* FIXME: do the blending */ 
    599622            yuv_to_rgb( &r, &g, &b, 
    600623                        p_src2_y[i_x], p_src2_u[i_x], p_src2_v[i_x] ); 
    601624 
    602     ((uint16_t *)(&p_dst[i_x * i_pix_pitch]))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); 
     625            p_dst[i_x * i_pix_pitch]     = ( r * i_trans + 
     626                (uint16_t)p_src1[i_x * i_pix_pitch] * 
     627                (MAX_TRANS - i_trans) ) >> TRANS_BITS; 
     628            p_dst[i_x * i_pix_pitch + 1] = ( g * i_trans + 
     629                (uint16_t)p_src1[i_x * i_pix_pitch + 1] * 
     630                (MAX_TRANS - i_trans) ) >> TRANS_BITS; 
     631            p_dst[i_x * i_pix_pitch + 2] = ( b * i_trans + 
     632                (uint16_t)p_src1[i_x * i_pix_pitch + 2] * 
     633                (MAX_TRANS - i_trans) ) >> TRANS_BITS; 
    603634        } 
    604635    } 
     
    610641} 
    611642 
    612 static void BlendR24( filter_t *p_filter, picture_t *p_dst_pic, 
    613                       picture_t *p_dst_orig, picture_t *p_src, 
    614                       int i_x_offset, int i_y_offset, 
    615                       int i_width, int i_height, int i_alpha ) 
     643static void BlendYUVPacked( filter_t *p_filter, picture_t *p_dst_pic, 
     644                            picture_t *p_dst_orig, picture_t *p_src, 
     645                            int i_x_offset, int i_y_offset, 
     646                            int i_width, int i_height, int i_alpha ) 
    616647{ 
    617648    int i_src1_pitch, i_src2_pitch, i_dst_pitch; 
     
    620651    uint8_t *p_trans; 
    621652    int i_x, i_y, i_pix_pitch, i_trans = 0; 
    622     int r, g, b; 
    623  
    624     i_pix_pitch = p_dst_pic->p->i_pixel_pitch; 
     653    vlc_bool_t b_even = !((i_x_offset + p_filter->fmt_out.video.i_x_offset)%2); 
     654    int i_l_offset = 0, i_u_offset = 0, i_v_offset = 0; 
     655 
     656    if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','U','Y','2') ) 
     657    { 
     658        i_l_offset = 0; 
     659        i_u_offset = 1; 
     660        i_v_offset = 3; 
     661    } 
     662    else if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('U','Y','V','Y') ) 
     663    { 
     664        i_l_offset = 1; 
     665        i_u_offset = 0; 
     666        i_v_offset = 2; 
     667    } 
     668    else if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','V','Y','U') ) 
     669    { 
     670        i_l_offset = 0; 
     671        i_u_offset = 3; 
     672        i_v_offset = 1; 
     673    } 
     674 
     675    i_pix_pitch = 2; 
    625676    i_dst_pitch = p_dst_pic->p->i_pitch; 
    626677    p_dst = p_dst_pic->p->p_pixels + i_x_offset * i_pix_pitch + 
     
    646697               p_src->p[V_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
    647698 
    648     if( p_filter->fmt_in.video.i_chroma == VLC_FOURCC('Y','V','1','2') || 
    649         p_filter->fmt_in.video.i_chroma == VLC_FOURCC('I','4','2','0') ) 
    650     { 
    651         p_trans = NULL; 
    652         i_trans = i_alpha; 
    653     } 
    654     else 
    655     { 
    656         p_trans = p_src->p[A_PLANE].p_pixels + 
    657                   p_filter->fmt_in.video.i_x_offset + 
    658                   p_src->p[A_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
    659     } 
     699    p_trans = p_src->p[A_PLANE].p_pixels + 
     700              p_filter->fmt_in.video.i_x_offset + 
     701              p_src->p[A_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
     702 
     703    i_width = (i_width >> 1) << 1; /* Needs to be a multiple of 2 */ 
    660704 
    661705#define MAX_TRANS 255 
     
    663707 
    664708    /* Draw until we reach the bottom of the subtitle */ 
    665     for( i_y = 0; i_y < i_height; i_y++, p_trans += p_trans?i_src2_pitch:0
     709    for( i_y = 0; i_y < i_height; i_y++, p_trans += i_src2_pitch
    666710         p_dst += i_dst_pitch, p_src1 += i_src1_pitch, 
    667711         p_src2_y += i_src2_pitch, p_src2_u += i_src2_pitch, 
     
    669713    { 
    670714        /* Draw until we reach the end of the line */ 
    671         for( i_x = 0; i_x < i_width; i_x++ ) 
    672         { 
    673             if( p_trans ) 
    674                 i_trans = ( p_trans[i_x] * i_alpha ) / 255; 
    675             if( !i_trans ) 
    676             { 
    677                 /* Completely transparent. Don't change pixel */ 
    678                 continue; 
    679             } 
    680             else if( i_trans == MAX_TRANS ) 
    681             { 
    682                 /* Completely opaque. Completely overwrite underlying pixel */ 
    683                 yuv_to_rgb( &r, &g, &b, 
    684                             p_src2_y[i_x], p_src2_u[i_x], p_src2_v[i_x] ); 
    685  
    686                 p_dst[i_x * i_pix_pitch]     = r; 
    687                 p_dst[i_x * i_pix_pitch + 1] = g; 
    688                 p_dst[i_x * i_pix_pitch + 2] = b; 
    689                 continue; 
    690             } 
    691  
    692             /* Blending */ 
    693             yuv_to_rgb( &r, &g, &b, 
    694                         p_src2_y[i_x], p_src2_u[i_x], p_src2_v[i_x] ); 
    695  
    696             p_dst[i_x * i_pix_pitch]     = ( r * i_trans + 
    697                 (uint16_t)p_src1[i_x * i_pix_pitch] * 
    698                 (MAX_TRANS - i_trans) ) >> TRANS_BITS; 
    699             p_dst[i_x * i_pix_pitch + 1] = ( g * i_trans + 
    700                 (uint16_t)p_src1[i_x * i_pix_pitch + 1] * 
    701                 (MAX_TRANS - i_trans) ) >> TRANS_BITS; 
    702             p_dst[i_x * i_pix_pitch + 2] = ( b * i_trans + 
    703                 (uint16_t)p_src1[i_x * i_pix_pitch + 2] * 
    704                 (MAX_TRANS - i_trans) ) >> TRANS_BITS; 
    705         } 
    706     } 
    707  
    708 #undef MAX_TRANS 
    709 #undef TRANS_BITS 
    710  
    711     return; 
    712 } 
    713  
    714 static void BlendYUVPacked( filter_t *p_filter, picture_t *p_dst_pic, 
    715                             picture_t *p_dst_orig, picture_t *p_src, 
    716                             int i_x_offset, int i_y_offset, 
    717                             int i_width, int i_height, int i_alpha ) 
    718 { 
    719     int i_src1_pitch, i_src2_pitch, i_dst_pitch; 
    720     uint8_t *p_dst, *p_src1, *p_src2_y; 
    721     uint8_t *p_src2_u, *p_src2_v; 
    722     uint8_t *p_trans; 
    723     int i_x, i_y, i_pix_pitch, i_trans = 0; 
    724     vlc_bool_t b_even = !((i_x_offset + p_filter->fmt_out.video.i_x_offset)%2); 
    725     int i_l_offset = 0, i_u_offset = 0, i_v_offset = 0; 
    726  
    727     if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','U','Y','2') ) 
    728     { 
    729         i_l_offset = 0; 
    730         i_u_offset = 1; 
    731         i_v_offset = 3; 
    732     } 
    733     else if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('U','Y','V','Y') ) 
    734     { 
    735         i_l_offset = 1; 
    736         i_u_offset = 0; 
    737         i_v_offset = 2; 
    738     } 
    739     else if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','V','Y','U') ) 
    740     { 
    741         i_l_offset = 0; 
    742         i_u_offset = 3; 
    743         i_v_offset = 1; 
    744     } 
    745  
    746     i_pix_pitch = 2; 
    747     i_dst_pitch = p_dst_pic->p->i_pitch; 
    748     p_dst = p_dst_pic->p->p_pixels + i_x_offset * i_pix_pitch + 
    749             p_filter->fmt_out.video.i_x_offset * i_pix_pitch + 
    750             p_dst_pic->p->i_pitch * 
    751             ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
    752  
    753     i_src1_pitch = p_dst_orig->p[Y_PLANE].i_pitch; 
    754     p_src1 = p_dst_orig->p->p_pixels + i_x_offset * i_pix_pitch + 
    755                p_filter->fmt_out.video.i_x_offset * i_pix_pitch + 
    756                p_dst_orig->p->i_pitch * 
    757                ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
    758  
    759     i_src2_pitch = p_src->p[Y_PLANE].i_pitch; 
    760     p_src2_y = p_src->p[Y_PLANE].p_pixels + 
    761                p_filter->fmt_in.video.i_x_offset + 
    762                p_src->p[Y_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
    763     p_src2_u = p_src->p[U_PLANE].p_pixels + 
    764                p_filter->fmt_in.video.i_x_offset/2 + 
    765                p_src->p[U_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
    766     p_src2_v = p_src->p[V_PLANE].p_pixels + 
    767                p_filter->fmt_in.video.i_x_offset/2 + 
    768                p_src->p[V_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
    769  
    770     if( p_filter->fmt_in.video.i_chroma == VLC_FOURCC('Y','V','1','2') || 
    771         p_filter->fmt_in.video.i_chroma == VLC_FOURCC('I','4','2','0') ) 
    772     { 
    773         p_trans = NULL; 
    774         i_trans = i_alpha; 
    775     } 
    776     else 
    777     { 
    778         p_trans = p_src->p[A_PLANE].p_pixels + 
    779                   p_filter->fmt_in.video.i_x_offset + 
    780                   p_src->p[A_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
    781     } 
    782  
    783     i_width = (i_width >> 1) << 1; /* Needs to be a multiple of 2 */ 
    784  
    785 #define MAX_TRANS 255 
    786 #define TRANS_BITS  8 
    787  
    788     /* Draw until we reach the bottom of the subtitle */ 
    789     for( i_y = 0; i_y < i_height; i_y++, p_trans += p_trans?i_src2_pitch:0, 
    790          p_dst += i_dst_pitch, p_src1 += i_src1_pitch, 
    791          p_src2_y += i_src2_pitch, p_src2_u += i_src2_pitch, 
    792          p_src2_v += i_src2_pitch ) 
    793     { 
    794         /* Draw until we reach the end of the line */ 
    795715        for( i_x = 0; i_x < i_width; i_x++, b_even = !b_even ) 
    796716        { 
    797             if( p_trans ) 
    798                 i_trans = ( p_trans[i_x] * i_alpha ) / 255; 
     717            i_trans = ( p_trans[i_x] * i_alpha ) / 255; 
    799718            if( !i_trans ) 
    800719            { 
     
    857776    return; 
    858777} 
     778/*********************************************************************** 
     779 * I420, YV12 
     780 ***********************************************************************/ 
     781static void BlendI420I420( filter_t *p_filter, picture_t *p_dst, 
     782                           picture_t *p_dst_orig, picture_t *p_src, 
     783                           int i_x_offset, int i_y_offset, 
     784                           int i_width, int i_height, int i_alpha ) 
     785{ 
     786    int i_src1_pitch, i_src2_pitch, i_dst_pitch; 
     787    uint8_t *p_src1_y, *p_src2_y, *p_dst_y; 
     788    uint8_t *p_src1_u, *p_src2_u, *p_dst_u; 
     789    uint8_t *p_src1_v, *p_src2_v, *p_dst_v; 
     790    int i_x, i_y; 
     791    vlc_bool_t b_even_scanline = i_y_offset % 2; 
     792 
     793    i_dst_pitch = p_dst->p[Y_PLANE].i_pitch; 
     794    p_dst_y = p_dst->p[Y_PLANE].p_pixels + i_x_offset + 
     795              p_filter->fmt_out.video.i_x_offset + 
     796              p_dst->p[Y_PLANE].i_pitch * 
     797              ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
     798    p_dst_u = p_dst->p[U_PLANE].p_pixels + i_x_offset/2 + 
     799              p_filter->fmt_out.video.i_x_offset/2 + 
     800              ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
     801              p_dst->p[U_PLANE].i_pitch; 
     802    p_dst_v = p_dst->p[V_PLANE].p_pixels + i_x_offset/2 + 
     803              p_filter->fmt_out.video.i_x_offset/2 + 
     804              ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
     805              p_dst->p[V_PLANE].i_pitch; 
     806 
     807    i_src1_pitch = p_dst_orig->p[Y_PLANE].i_pitch; 
     808    p_src1_y = p_dst_orig->p[Y_PLANE].p_pixels + i_x_offset + 
     809               p_filter->fmt_out.video.i_x_offset + 
     810               p_dst_orig->p[Y_PLANE].i_pitch * 
     811               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
     812    p_src1_u = p_dst_orig->p[U_PLANE].p_pixels + i_x_offset/2 + 
     813               p_filter->fmt_out.video.i_x_offset/2 + 
     814               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
     815               p_dst_orig->p[U_PLANE].i_pitch; 
     816    p_src1_v = p_dst_orig->p[V_PLANE].p_pixels + i_x_offset/2 + 
     817               p_filter->fmt_out.video.i_x_offset/2 + 
     818               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
     819               p_dst_orig->p[V_PLANE].i_pitch; 
     820 
     821    i_src2_pitch = p_src->p[Y_PLANE].i_pitch; 
     822    p_src2_y = p_src->p[Y_PLANE].p_pixels + 
     823               p_filter->fmt_in.video.i_x_offset + 
     824               p_src->p[Y_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
     825    p_src2_u = p_src->p[U_PLANE].p_pixels + 
     826               p_filter->fmt_in.video.i_x_offset/2 + 
     827               p_src->p[U_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
     828    p_src2_v = p_src->p[V_PLANE].p_pixels + 
     829               p_filter->fmt_in.video.i_x_offset/2 + 
     830               p_src->p[V_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
     831 
     832#define MAX_TRANS 255 
     833#define TRANS_BITS  8 
     834 
     835    /* Draw until we reach the bottom of the subtitle */ 
     836    for( i_y = 0; i_y < i_height; i_y++, 
     837         p_dst_y += i_dst_pitch, p_src1_y += i_src1_pitch, 
     838         p_src2_y += i_src2_pitch ) 
     839    { 
     840        if( b_even_scanline ) 
     841        { 
     842            p_dst_u  += i_dst_pitch/2; 
     843            p_dst_v  += i_dst_pitch/2; 
     844            p_src1_u += i_src1_pitch/2; 
     845            p_src1_v += i_src1_pitch/2; 
     846        } 
     847        b_even_scanline = !b_even_scanline; 
     848 
     849        /* Draw until we reach the end of the line */ 
     850        for( i_x = 0; i_x < i_width; i_x++ ) 
     851        { 
     852            if( i_alpha == MAX_TRANS ) 
     853            { 
     854                /* Completely opaque. Completely overwrite underlying pixel */ 
     855                p_dst_y[i_x] = p_src2_y[i_x]; 
     856 
     857                if( b_even_scanline && i_x % 2 == 0 ) 
     858                { 
     859                    p_dst_u[i_x/2] = p_src2_u[i_x/2]; 
     860                    p_dst_v[i_x/2] = p_src2_v[i_x/2]; 
     861                } 
     862                continue; 
     863            } 
     864 
     865            /* Blending */ 
     866            p_dst_y[i_x] = ( (uint16_t)p_src2_y[i_x] * i_alpha + 
     867                (uint16_t)p_src1_y[i_x] * (MAX_TRANS - i_alpha) ) 
     868                >> TRANS_BITS; 
     869 
     870            if( b_even_scanline && i_x % 2 == 0 ) 
     871            { 
     872                p_dst_u[i_x/2] = ( (uint16_t)p_src2_u[i_x/2] * i_alpha + 
     873                (uint16_t)p_src1_u[i_x/2] * (MAX_TRANS - i_alpha) ) 
     874                >> TRANS_BITS; 
     875                p_dst_v[i_x/2] = ( (uint16_t)p_src2_v[i_x/2] * i_alpha + 
     876                (uint16_t)p_src1_v[i_x/2] * (MAX_TRANS - i_alpha) ) 
     877                >> TRANS_BITS; 
     878            } 
     879        } 
     880        if( i_y%2 == 1 ) 
     881        { 
     882            p_src2_u += i_src2_pitch/2; 
     883            p_src2_v += i_src2_pitch/2; 
     884        } 
     885    } 
     886 
     887#undef MAX_TRANS 
     888#undef TRANS_BITS 
     889 
     890    return; 
     891} 
     892static void BlendI420I420_no_alpha( filter_t *p_filter, picture_t *p_dst, 
     893                                    picture_t *p_dst_orig, picture_t *p_src, 
     894                                    int i_x_offset, int i_y_offset, 
     895                                    int i_width, int i_height ) 
     896{ 
     897    int i_src1_pitch, i_src2_pitch, i_dst_pitch; 
     898    uint8_t *p_src1_y, *p_src2_y, *p_dst_y; 
     899    uint8_t *p_src1_u, *p_src2_u, *p_dst_u; 
     900    uint8_t *p_src1_v, *p_src2_v, *p_dst_v; 
     901    int i_y; 
     902    vlc_bool_t b_even_scanline = i_y_offset % 2; 
     903 
     904    i_dst_pitch = p_dst->p[Y_PLANE].i_pitch; 
     905    p_dst_y = p_dst->p[Y_PLANE].p_pixels + i_x_offset + 
     906              p_filter->fmt_out.video.i_x_offset + 
     907              p_dst->p[Y_PLANE].i_pitch * 
     908              ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
     909    p_dst_u = p_dst->p[U_PLANE].p_pixels + i_x_offset/2 + 
     910              p_filter->fmt_out.video.i_x_offset/2 + 
     911              ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
     912              p_dst->p[U_PLANE].i_pitch; 
     913    p_dst_v = p_dst->p[V_PLANE].p_pixels + i_x_offset/2 + 
     914              p_filter->fmt_out.video.i_x_offset/2 + 
     915              ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
     916              p_dst->p[V_PLANE].i_pitch; 
     917 
     918    i_src1_pitch = p_dst_orig->p[Y_PLANE].i_pitch; 
     919    p_src1_y = p_dst_orig->p[Y_PLANE].p_pixels + i_x_offset + 
     920               p_filter->fmt_out.video.i_x_offset + 
     921               p_dst_orig->p[Y_PLANE].i_pitch * 
     922               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
     923    p_src1_u = p_dst_orig->p[U_PLANE].p_pixels + i_x_offset/2 + 
     924               p_filter->fmt_out.video.i_x_offset/2 + 
     925               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
     926               p_dst_orig->p[U_PLANE].i_pitch; 
     927    p_src1_v = p_dst_orig->p[V_PLANE].p_pixels + i_x_offset/2 + 
     928               p_filter->fmt_out.video.i_x_offset/2 + 
     929               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ) / 2 * 
     930               p_dst_orig->p[V_PLANE].i_pitch; 
     931 
     932    i_src2_pitch = p_src->p[Y_PLANE].i_pitch; 
     933    p_src2_y = p_src->p[Y_PLANE].p_pixels + 
     934               p_filter->fmt_in.video.i_x_offset + 
     935               p_src->p[Y_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
     936    p_src2_u = p_src->p[U_PLANE].p_pixels + 
     937               p_filter->fmt_in.video.i_x_offset/2 + 
     938               p_src->p[U_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
     939    p_src2_v = p_src->p[V_PLANE].p_pixels + 
     940               p_filter->fmt_in.video.i_x_offset/2 + 
     941               p_src->p[V_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
     942 
     943    i_width &= ~1; 
     944 
     945    /* Draw until we reach the bottom of the subtitle */ 
     946    for( i_y = 0; i_y < i_height; i_y++, 
     947         p_dst_y += i_dst_pitch, p_src1_y += i_src1_pitch, 
     948         p_src2_y += i_src2_pitch ) 
     949    { 
     950        /* Completely opaque. Completely overwrite underlying pixel */ 
     951        p_filter->p_libvlc->pf_memcpy( p_dst_y, p_src2_y, i_width ); 
     952        if( b_even_scanline ) 
     953        { 
     954            p_dst_u  += i_dst_pitch/2; 
     955            p_dst_v  += i_dst_pitch/2; 
     956            p_src1_u += i_src1_pitch/2; 
     957            p_src1_v += i_src1_pitch/2; 
     958        } 
     959        else 
     960        { 
     961            p_filter->p_libvlc->pf_memcpy( p_dst_u, p_src2_u, i_width/2 ); 
     962            p_filter->p_libvlc->pf_memcpy( p_dst_v, p_src2_v, i_width/2 ); 
     963        } 
     964        b_even_scanline = !b_even_scanline; 
     965        if( i_y%2 == 1 ) 
     966        { 
     967            p_src2_u += i_src2_pitch/2; 
     968            p_src2_v += i_src2_pitch/2; 
     969        } 
     970    } 
     971 
     972    return; 
     973} 
     974 
     975static void BlendI420R16( filter_t *p_filter, picture_t *p_dst_pic, 
     976                          picture_t *p_dst_orig, picture_t *p_src, 
     977                          int i_x_offset, int i_y_offset, 
     978                          int i_width, int i_height, int i_alpha ) 
     979{ 
     980    int i_src1_pitch, i_src2_pitch, i_dst_pitch; 
     981    uint8_t *p_dst, *p_src1, *p_src2_y; 
     982    uint8_t *p_src2_u, *p_src2_v; 
     983    int i_x, i_y, i_pix_pitch; 
     984    int r, g, b; 
     985 
     986    i_pix_pitch = p_dst_pic->p->i_pixel_pitch; 
     987    i_dst_pitch = p_dst_pic->p->i_pitch; 
     988    p_dst = p_dst_pic->p->p_pixels + i_x_offset * i_pix_pitch + 
     989            p_filter->fmt_out.video.i_x_offset * i_pix_pitch + 
     990            p_dst_pic->p->i_pitch * 
     991            ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
     992 
     993    i_src1_pitch = p_dst_orig->p[Y_PLANE].i_pitch; 
     994    p_src1 = p_dst_orig->p->p_pixels + i_x_offset * i_pix_pitch + 
     995               p_filter->fmt_out.video.i_x_offset * i_pix_pitch + 
     996               p_dst_orig->p->i_pitch * 
     997               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
     998 
     999    i_src2_pitch = p_src->p[Y_PLANE].i_pitch; 
     1000    p_src2_y = p_src->p[Y_PLANE].p_pixels + 
     1001               p_filter->fmt_in.video.i_x_offset + 
     1002               p_src->p[Y_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
     1003    p_src2_u = p_src->p[U_PLANE].p_pixels + 
     1004               p_filter->fmt_in.video.i_x_offset/2 + 
     1005               p_src->p[U_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
     1006    p_src2_v = p_src->p[V_PLANE].p_pixels + 
     1007               p_filter->fmt_in.video.i_x_offset/2 + 
     1008               p_src->p[V_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
     1009 
     1010#define MAX_TRANS 255 
     1011#define TRANS_BITS  8 
     1012 
     1013    /* Draw until we reach the bottom of the subtitle */ 
     1014    for( i_y = 0; i_y < i_height; i_y++, 
     1015         p_dst += i_dst_pitch, p_src1 += i_src1_pitch, 
     1016         p_src2_y += i_src2_pitch ) 
     1017    { 
     1018        /* Draw until we reach the end of the line */ 
     1019        for( i_x = 0; i_x < i_width; i_x++ ) 
     1020        { 
     1021            if( i_alpha == MAX_TRANS ) 
     1022            { 
     1023                /* Completely opaque. Completely overwrite underlying pixel */ 
     1024                yuv_to_rgb( &r, &g, &b, 
     1025                            p_src2_y[i_x], p_src2_u[i_x/2], p_src2_v[i_x/2] ); 
     1026 
     1027    ((uint16_t *)(&p_dst[i_x * i_pix_pitch]))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); 
     1028                continue; 
     1029            } 
     1030 
     1031            /* Blending */ 
     1032            /* FIXME: do the blending */ 
     1033            yuv_to_rgb( &r, &g, &b, 
     1034                        p_src2_y[i_x], p_src2_u[i_x/2], p_src2_v[i_x/2] ); 
     1035 
     1036    ((uint16_t *)(&p_dst[i_x * i_pix_pitch]))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); 
     1037        } 
     1038        if( i_y%2 == 1 ) 
     1039        { 
     1040            p_src2_u += i_src2_pitch/2; 
     1041            p_src2_v += i_src2_pitch/2; 
     1042        } 
     1043    } 
     1044 
     1045#undef MAX_TRANS 
     1046#undef TRANS_BITS 
     1047 
     1048    return; 
     1049} 
     1050 
     1051static void BlendI420R24( filter_t *p_filter, picture_t *p_dst_pic, 
     1052                          picture_t *p_dst_orig, picture_t *p_src, 
     1053                          int i_x_offset, int i_y_offset, 
     1054                          int i_width, int i_height, int i_alpha ) 
     1055{ 
     1056    int i_src1_pitch, i_src2_pitch, i_dst_pitch; 
     1057    uint8_t *p_dst, *p_src1, *p_src2_y; 
     1058    uint8_t *p_src2_u, *p_src2_v; 
     1059    int i_x, i_y, i_pix_pitch; 
     1060    int r, g, b; 
     1061 
     1062    i_pix_pitch = p_dst_pic->p->i_pixel_pitch; 
     1063    i_dst_pitch = p_dst_pic->p->i_pitch; 
     1064    p_dst = p_dst_pic->p->p_pixels + i_x_offset * i_pix_pitch + 
     1065            p_filter->fmt_out.video.i_x_offset * i_pix_pitch + 
     1066            p_dst_pic->p->i_pitch * 
     1067            ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
     1068 
     1069    i_src1_pitch = p_dst_orig->p[Y_PLANE].i_pitch; 
     1070    p_src1 = p_dst_orig->p->p_pixels + i_x_offset * i_pix_pitch + 
     1071               p_filter->fmt_out.video.i_x_offset * i_pix_pitch + 
     1072               p_dst_orig->p->i_pitch * 
     1073               ( i_y_offset + p_filter->fmt_out.video.i_y_offset ); 
     1074 
     1075    i_src2_pitch = p_src->p[Y_PLANE].i_pitch; 
     1076    p_src2_y = p_src->p[Y_PLANE].p_pixels + 
     1077               p_filter->fmt_in.video.i_x_offset + 
     1078               p_src->p[Y_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset; 
     1079    p_src2_u = p_src->p[U_PLANE].p_pixels + 
     1080               p_filter->fmt_in.video.i_x_offset/2 + 
     1081               p_src->p[U_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
     1082    p_src2_v = p_src->p[V_PLANE].p_pixels + 
     1083               p_filter->fmt_in.video.i_x_offset/2 + 
     1084               p_src->p[V_PLANE].i_pitch * p_filter->fmt_in.video.i_y_offset/2; 
     1085 
     1086#define MAX_TRANS 255 
     1087#define TRANS_BITS  8 
     1088 
     1089    /* Draw until we reach the bottom of the subtitle */ 
     1090    for( i_y = 0; i_y < i_height; i_y++, 
     1091         p_dst += i_dst_pitch, p_src1 += i_src1_pitch, 
     1092         p_src2_y += i_src2_pitch, p_src2_u += i_src2_pitch, 
     1093         p_src2_v += i_src2_pitch ) 
     1094    { 
     1095        /* Draw until we reach the end of the line */ 
     1096        for( i_x = 0; i_x < i_width; i_x++ ) 
     1097        { 
     1098            if( i_alpha == MAX_TRANS ) 
     1099            { 
     1100                /* Completely opaque. Completely overwrite underlying pixel */ 
     1101                yuv_to_rgb( &r, &g, &b, 
     1102                            p_src2_y[i_x], p_src2_u[i_x/2], p_src2_v[i_x/2] ); 
     1103 
     1104                p_dst[i_x * i_pix_pitch]     = r; 
     1105                p_dst[i_x * i_pix_pitch + 1] = g; 
     1106                p_dst[i_x * i_pix_pitch + 2] = b; 
     1107                continue; 
     1108            } 
     1109 
     1110            /* Blending */ 
     1111            yuv_to_rgb( &r, &g, &b, 
     1112                        p_src2_y[i_x], p_src2_u[i_x/2], p_src2_v[i_x/2] ); 
     1113 
     1114            p_dst[i_x * i_pix_pitch]     = ( r * i_alpha + 
     1115                (uint16_t)p_src1[i_x * i_pix_pitch] * 
     1116                (MAX_TRANS - i_alpha) ) >> TRANS_BITS; 
     1117            p_dst[i_x * i_pix_pitch + 1] = ( g * i_alpha + 
     1118                (uint16_t)p_src1[i_x * i_pix_pitch + 1] * 
     1119                (MAX_TRANS - i_alpha) ) >> TRANS_BITS; 
     1120            p_dst[i_x * i_pix_pitch + 2] = ( b * i_alpha + 
     1121                (uint16_t)p_src1[i_x * i_pix_pitch + 2] * 
     1122                (MAX_TRANS - i_alpha) ) >> TRANS_BITS; 
     1123        } 
     1124        if( i_y%2 == 1 ) 
     1125        { 
     1126            p_src2_u += i_src2_pitch/2; 
     1127            p_src2_v += i_src2_pitch/2; 
     1128        } 
     1129    } 
     1130 
     1131#undef MAX_TRANS 
     1132#undef TRANS_BITS 
     1133 
     1134    return; 
     1135} 
     1136 
     1137static void BlendI420YUVPacked( filter_t *p_filter, picture_t *p_dst_pic, 
     1138                                picture_t *p_dst_orig, picture_t *p_src, 
     1139                                int i_x_offset, int i_y_offset, 
     1140                                int i_width, int i_height, int i_alpha ) 
     1141{ 
     1142    int i_src1_pitch, i_src2_pitch, i_dst_pitch; 
     1143    uint8_t *p_dst, *p_src1, *p_src2_y; 
     1144    uint8_t *p_src2_u, *p_src2_v; 
     1145    int i_x, i_y, i_pix_pitch; 
     1146    vlc_bool_t b_even = !((i_x_offset + p_filter->fmt_out.video.i_x_offset)%2); 
     1147    int i_l_offset = 0, i_u_offset = 0, i_v_offset = 0; 
     1148 
     1149    if( p_filter->fmt_out.video.i_chroma == VLC_FOURCC('Y','U','Y','2') ) 
     1150    { 
     1151        i_l_offset = 0; 
     1152        i_u_offset = 1;