Changeset cd079331b9d03803f20d5e5e5cae23348731941c

Show
Ignore:
Timestamp:
04/07/08 16:51:51 (5 months ago)
Author:
Sam Hocevar <sam@zoy.org>
git-committer:
Sam Hocevar <sam@zoy.org> 1207579911 +0200
git-parent:

[19ac4fcc2941e629dab5ee83c00686f1fb583e43]

git-author:
Sam Hocevar <sam@zoy.org> 1207579669 +0200
Message:

Fix transform plugin 90-degree rotations on I422.

I422 is a planar chroma with non-square pixels. It requires some pixel
play when rotating the image at a 90-degree angle. For other transformations
we just fall back to the original function.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/video_filter/filter_picture.h

    r32c1dee rcd07933  
    2222 *****************************************************************************/ 
    2323 
    24 #define CASE_PLANAR_YUV                     \ 
     24/* FIXME: do all of these really have square pixels? */ 
     25#define CASE_PLANAR_YUV_SQUARE              \ 
    2526        case VLC_FOURCC('I','4','2','0'):   \ 
    2627        case VLC_FOURCC('I','Y','U','V'):   \ 
     
    3031        case VLC_FOURCC('I','4','1','0'):   \ 
    3132        case VLC_FOURCC('Y','V','U','9'):   \ 
    32         case VLC_FOURCC('I','4','2','2'):   \ 
    33         case VLC_FOURCC('J','4','2','2'):   \ 
    3433        case VLC_FOURCC('I','4','4','4'):   \ 
    3534        case VLC_FOURCC('J','4','4','4'):   \ 
    3635        case VLC_FOURCC('Y','U','V','A'): 
     36 
     37#define CASE_PLANAR_YUV_NONSQUARE           \ 
     38        case VLC_FOURCC('I','4','2','2'):   \ 
     39        case VLC_FOURCC('J','4','2','2'): 
     40 
     41#define CASE_PLANAR_YUV                     \ 
     42        CASE_PLANAR_YUV_SQUARE              \ 
     43        CASE_PLANAR_YUV_NONSQUARE           \ 
    3744 
    3845#define CASE_PACKED_YUV_422                 \ 
  • modules/video_filter/transform.c

    r733a686 rcd07933  
    5353 
    5454static void FilterPlanar( vout_thread_t *, const picture_t *, picture_t * ); 
     55static void FilterI422( vout_thread_t *, const picture_t *, picture_t * ); 
    5556static void FilterYUYV( vout_thread_t *, const picture_t *, picture_t * ); 
    5657 
     
    146147    switch( p_vout->fmt_in.i_chroma ) 
    147148    { 
    148         CASE_PLANAR_YUV 
     149        CASE_PLANAR_YUV_SQUARE 
    149150        case VLC_FOURCC('G','R','E','Y'): 
    150151            p_vout->p_sys->pf_filter = FilterPlanar; 
     152            break; 
     153 
     154        case VLC_FOURCC('I','4','2','2'): 
     155        case VLC_FOURCC('J','4','2','2'): 
     156            p_vout->p_sys->pf_filter = FilterI422; 
    151157            break; 
    152158 
     
    552558} 
    553559 
     560static void FilterI422( vout_thread_t *p_vout, 
     561                        const picture_t *p_pic, picture_t *p_outpic ) 
     562{ 
     563    int i_index; 
     564    switch( p_vout->p_sys->i_mode ) 
     565    { 
     566        case TRANSFORM_MODE_180: 
     567        case TRANSFORM_MODE_HFLIP: 
     568        case TRANSFORM_MODE_VFLIP: 
     569            /* Fall back on the default implementation */ 
     570            FilterPlanar( p_vout, p_pic, p_outpic ); 
     571            return; 
     572 
     573        case TRANSFORM_MODE_90: 
     574            for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) 
     575            { 
     576                int i_pitch = p_pic->p[i_index].i_pitch; 
     577 
     578                uint8_t *p_in = p_pic->p[i_index].p_pixels; 
     579 
     580                uint8_t *p_out = p_outpic->p[i_index].p_pixels; 
     581                uint8_t *p_out_end = p_out + 
     582                    p_outpic->p[i_index].i_visible_lines * 
     583                    p_outpic->p[i_index].i_pitch; 
     584 
     585                if( i_index == 0 ) 
     586                { 
     587                    for( ; p_out < p_out_end ; ) 
     588                    { 
     589                        uint8_t *p_line_end; 
     590 
     591                        p_out_end -= p_outpic->p[i_index].i_pitch 
     592                                      - p_outpic->p[i_index].i_visible_pitch; 
     593                        p_line_end = p_in + p_pic->p[i_index].i_visible_lines * 
     594                            i_pitch; 
     595 
     596                        for( ; p_in < p_line_end ; ) 
     597                        { 
     598                            p_line_end -= i_pitch; 
     599                            *(--p_out_end) = *p_line_end; 
     600                        } 
     601 
     602                        p_in++; 
     603                    } 
     604                } 
     605                else /* i_index == 1 or 2 */ 
     606                { 
     607                    for( ; p_out < p_out_end ; ) 
     608                    { 
     609                        uint8_t *p_line_end, *p_out_end2; 
     610 
     611                        p_out_end -= p_outpic->p[i_index].i_pitch 
     612                                      - p_outpic->p[i_index].i_visible_pitch; 
     613                        p_out_end2 = p_out_end - p_outpic->p[i_index].i_pitch; 
     614                        p_line_end = p_in + p_pic->p[i_index].i_visible_lines * 
     615                            i_pitch; 
     616 
     617                        for( ; p_in < p_line_end ; ) 
     618                        { 
     619                            uint8_t p1, p2; 
     620 
     621                            p_line_end -= i_pitch; 
     622                            p1 = *p_line_end; 
     623                            p_line_end -= i_pitch; 
     624                            p2 = *p_line_end; 
     625 
     626                            /* Trick for (x+y)/2 without overflow, based on 
     627                             *   x + y == (x ^ y) + 2 * (x & y) */ 
     628                            *(--p_out_end) = (p1 & p2) + ((p1 ^ p2) / 2); 
     629                            *(--p_out_end2) = (p1 & p2) + ((p1 ^ p2) / 2); 
     630                        } 
     631 
     632                        p_out_end = p_out_end2; 
     633                        p_in++; 
     634                    } 
     635                } 
     636            } 
     637            break; 
     638 
     639        case TRANSFORM_MODE_270: 
     640            for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) 
     641            { 
     642                int i_pitch = p_pic->p[i_index].i_pitch; 
     643 
     644                uint8_t *p_in = p_pic->p[i_index].p_pixels; 
     645 
     646                uint8_t *p_out = p_outpic->p[i_index].p_pixels; 
     647                uint8_t *p_out_end = p_out + 
     648                    p_outpic->p[i_index].i_visible_lines * 
     649                    p_outpic->p[i_index].i_pitch; 
     650 
     651                if( i_index == 0 ) 
     652                { 
     653                    for( ; p_out < p_out_end ; ) 
     654                    { 
     655                        uint8_t *p_in_end; 
     656 
     657                        p_in_end = p_in + p_pic->p[i_index].i_visible_lines * 
     658                            i_pitch; 
     659 
     660                        for( ; p_in < p_in_end ; ) 
     661                        { 
     662                            p_in_end -= i_pitch; 
     663                            *p_out++ = *p_in_end; 
     664                        } 
     665 
     666                        p_out += p_outpic->p[i_index].i_pitch 
     667                                  - p_outpic->p[i_index].i_visible_pitch; 
     668                        p_in++; 
     669                    } 
     670                } 
     671                else /* i_index == 1 or 2 */ 
     672                { 
     673                    for( ; p_out < p_out_end ; ) 
     674                    { 
     675                        uint8_t *p_in_end, *p_out2; 
     676 
     677                        p_in_end = p_in + p_pic->p[i_index].i_visible_lines * 
     678                            i_pitch; 
     679                        p_out2 = p_out + p_outpic->p[i_index].i_pitch; 
     680 
     681                        for( ; p_in < p_in_end ; ) 
     682                        { 
     683                            uint8_t p1, p2; 
     684 
     685                            p_in_end -= i_pitch; 
     686                            p1 = *p_in_end; 
     687                            p_in_end -= i_pitch; 
     688                            p2 = *p_in_end; 
     689 
     690                            /* Trick for (x+y)/2 without overflow, based on 
     691                             *   x + y == (x ^ y) + 2 * (x & y) */ 
     692                            *p_out++ = (p1 & p2) + ((p1 ^ p2) / 2); 
     693                            *p_out2++ = (p1 & p2) + ((p1 ^ p2) / 2); 
     694                        } 
     695 
     696                        p_out2 += p_outpic->p[i_index].i_pitch 
     697                                   - p_outpic->p[i_index].i_visible_pitch; 
     698                        p_out = p_out2; 
     699                        p_in++; 
     700                    } 
     701                } 
     702            } 
     703            break; 
     704 
     705        default: 
     706            break; 
     707    } 
     708} 
     709 
    554710static void FilterYUYV( vout_thread_t *p_vout, 
    555711                        const picture_t *p_pic, picture_t *p_outpic ) 
     
    563719    switch( p_vout->p_sys->i_mode ) 
    564720    { 
     721        case TRANSFORM_MODE_HFLIP: 
     722            /* Fall back on the default implementation */ 
     723            FilterPlanar( p_vout, p_pic, p_outpic ); 
     724            return; 
     725 
    565726        case TRANSFORM_MODE_90: 
    566727            for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) 
     
    685846            break; 
    686847 
    687         case TRANSFORM_MODE_HFLIP: 
    688             for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) 
    689             { 
    690                 uint8_t *p_in = p_pic->p[i_index].p_pixels; 
    691                 uint8_t *p_in_end = p_in + p_pic->p[i_index].i_visible_lines 
    692                                             * p_pic->p[i_index].i_pitch; 
    693  
    694                 uint8_t *p_out = p_outpic->p[i_index].p_pixels; 
    695  
    696                 for( ; p_in < p_in_end ; ) 
    697                 { 
    698                     p_in_end -= p_pic->p[i_index].i_pitch; 
    699                     p_vout->p_libvlc->pf_memcpy( p_out, p_in_end, 
    700                                            p_pic->p[i_index].i_visible_pitch ); 
    701                     p_out += p_pic->p[i_index].i_pitch; 
    702                 } 
    703             } 
    704             break; 
    705  
    706848        case TRANSFORM_MODE_VFLIP: 
    707849            for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ )