Changeset aa1b2f6ffffa6ce35440e5fe7b3e81e19b0c771e

Show
Ignore:
Timestamp:
04/06/08 22:05:07 (6 months ago)
Author:
Antoine Cellerier <dionoea@videolan.org>
git-committer:
Antoine Cellerier <dionoea@videolan.org> 1212609907 +0200
git-parent:

[2e65b47b71e8458270d3988271200232536acbe5]

git-author:
Antoine Cellerier <dionoea@videolan.org> 1212602296 +0200
Message:

Add support for Packed YUV 422 to rotate video filter. Output quality is
less than that of the planar version (uses nearest neighboor instead of
interpolated colors)

Files:

Legend:

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

    r3561b9b raa1b2f6  
    22 * rotate.c : video rotation filter 
    33 ***************************************************************************** 
    4  * Copyright (C) 2000-2006 the VideoLAN team 
     4 * Copyright (C) 2000-2008 the VideoLAN team 
    55 * $Id$ 
    66 * 
     
    4646 
    4747static picture_t *Filter( filter_t *, picture_t * ); 
     48static picture_t *FilterPacked( filter_t *, picture_t * ); 
    4849 
    4950static int RotateCallback( vlc_object_t *p_this, char const *psz_var, 
     
    106107    filter_sys_t *p_sys; 
    107108 
     109    if( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma ) 
     110    { 
     111        msg_Err( p_filter, "Input and output chromas don't match" ); 
     112        return VLC_EGENERIC; 
     113    } 
     114 
    108115    switch( p_filter->fmt_in.video.i_chroma ) 
    109116    { 
    110117        CASE_PLANAR_YUV 
     118            p_filter->pf_video_filter = Filter; 
     119            break; 
     120 
     121        CASE_PACKED_YUV_422 
     122            p_filter->pf_video_filter = FilterPacked; 
    111123            break; 
    112124 
     
    115127                     (char*)&(p_filter->fmt_in.video.i_chroma) ); 
    116128            return VLC_EGENERIC; 
    117     } 
    118  
    119     if( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma ) 
    120     { 
    121         msg_Err( p_filter, "Input and output chromas don't match" ); 
    122         return VLC_EGENERIC; 
    123129    } 
    124130 
     
    144150 
    145151    cache_trigo( p_sys->i_angle, &p_sys->i_sin, &p_sys->i_cos ); 
    146  
    147     p_filter->pf_video_filter = Filter; 
    148152 
    149153    return VLC_SUCCESS; 
     
    280284    } 
    281285 
    282     p_outpic->date = p_pic->date; 
    283     p_outpic->b_force = p_pic->b_force; 
    284     p_outpic->i_nb_fields = p_pic->i_nb_fields; 
    285     p_outpic->b_progressive = p_pic->b_progressive; 
    286     p_outpic->b_top_field_first = p_pic->b_top_field_first; 
    287  
    288     if( p_pic->pf_release ) 
    289         p_pic->pf_release( p_pic ); 
    290  
    291     return p_outpic; 
     286    return CopyMetaAndRelease( p_outpic, p_pic ); 
     287
     288 
     289/***************************************************************************** 
     290 * 
     291 *****************************************************************************/ 
     292static picture_t *FilterPacked( filter_t *p_filter, picture_t *p_pic ) 
     293
     294    picture_t *p_outpic; 
     295    filter_sys_t *p_sys = p_filter->p_sys; 
     296    const int i_sin = p_sys->i_sin, i_cos = p_sys->i_cos; 
     297 
     298    if( !p_pic ) return NULL; 
     299 
     300    int i_u_offset, i_v_offset, i_y_offset; 
     301 
     302    if( GetPackedYuvOffsets( p_pic->format.i_chroma, &i_y_offset, 
     303                             &i_u_offset, &i_v_offset ) != VLC_SUCCESS ) 
     304    { 
     305        msg_Warn( p_filter, "Unsupported input chroma (%4s)", 
     306                  (char*)&(p_pic->format.i_chroma) ); 
     307        if( p_pic->pf_release ) 
     308            p_pic->pf_release( p_pic ); 
     309        return NULL; 
     310    } 
     311 
     312    p_outpic = p_filter->pf_vout_buffer_new( p_filter ); 
     313    if( !p_outpic ) 
     314    { 
     315        msg_Warn( p_filter, "can't get output picture" ); 
     316        if( p_pic->pf_release ) 
     317            p_pic->pf_release( p_pic ); 
     318        return NULL; 
     319    } 
     320 
     321    const uint8_t *p_in   = p_pic->p->p_pixels+i_y_offset; 
     322    const uint8_t *p_in_u = p_pic->p->p_pixels+i_u_offset; 
     323    const uint8_t *p_in_v = p_pic->p->p_pixels+i_v_offset; 
     324 
     325    const int i_pitch         = p_pic->p->i_pitch; 
     326    const int i_visible_pitch = p_pic->p->i_visible_pitch>>1; /* In fact it's i_visible_pixels */ 
     327    const int i_visible_lines = p_pic->p->i_visible_lines; 
     328 
     329    uint8_t *p_out   = p_outpic->p->p_pixels+i_y_offset; 
     330    uint8_t *p_out_u = p_outpic->p->p_pixels+i_u_offset; 
     331    uint8_t *p_out_v = p_outpic->p->p_pixels+i_v_offset; 
     332 
     333    const int i_line_center = i_visible_lines>>1; 
     334    const int i_col_center  = i_visible_pitch>>1; 
     335 
     336    int i_col, i_line; 
     337    for( i_line = 0; i_line < i_visible_lines; i_line++ ) 
     338    { 
     339        for( i_col = 0; i_col < i_visible_pitch; i_col++ ) 
     340        { 
     341            int i_line_orig; 
     342            int i_col_orig; 
     343            /* Handle "1st Y", U and V */ 
     344            i_line_orig = i_line_center + 
     345                ( ( i_sin * ( i_col - i_col_center ) 
     346                  + i_cos * ( i_line - i_line_center ) )>>12 ); 
     347            i_col_orig = i_col_center + 
     348                ( ( i_cos * ( i_col - i_col_center ) 
     349                  - i_sin * ( i_line - i_line_center ) )>>12 ); 
     350            if( 0 <= i_col_orig && i_col_orig < i_visible_pitch 
     351             && 0 <= i_line_orig && i_line_orig < i_visible_lines ) 
     352            { 
     353                p_out[i_line*i_pitch+2*i_col] = p_in[i_line_orig*i_pitch+2*i_col_orig]; 
     354                i_col_orig /= 2; 
     355                p_out_u[i_line*i_pitch+2*i_col] = p_in_u[i_line_orig*i_pitch+4*i_col_orig]; 
     356                p_out_v[i_line*i_pitch+2*i_col] = p_in_v[i_line_orig*i_pitch+4*i_col_orig]; 
     357            } 
     358            else 
     359            { 
     360                p_out[i_line*i_pitch+2*i_col] = 0x00; 
     361                i_col_orig /= 2; 
     362                p_out_u[i_line*i_pitch+2*i_col] = 0x80; 
     363                p_out_v[i_line*i_pitch+2*i_col] = 0x80; 
     364            } 
     365 
     366            /* Handle "2nd Y" */ 
     367            i_col++; 
     368            if( i_col >= i_visible_pitch ) 
     369                break; 
     370 
     371            i_line_orig = i_line_center + 
     372                ( ( i_sin * ( i_col - i_col_center ) 
     373                  + i_cos * ( i_line - i_line_center ) )>>12 ); 
     374            i_col_orig = i_col_center + 
     375                ( ( i_cos * ( i_col - i_col_center ) 
     376                  - i_sin * ( i_line - i_line_center ) )>>12 ); 
     377            if( 0 <= i_col_orig && i_col_orig < i_visible_pitch 
     378             && 0 <= i_line_orig && i_line_orig < i_visible_lines ) 
     379            { 
     380                p_out[i_line*i_pitch+2*i_col] = p_in[i_line_orig*i_pitch+2*i_col_orig]; 
     381            } 
     382            else 
     383            { 
     384                p_out[i_line*i_pitch+2*i_col] = 0x00; 
     385            } 
     386        } 
     387    } 
     388 
     389    return CopyMetaAndRelease( p_outpic, p_pic ); 
    292390} 
    293391