Changeset 8b09b55dd76c038d1363ff4827f49f131bd42429

Show
Ignore:
Timestamp:
11/06/02 19:07:57 (6 years ago)
Author:
Sam Hocevar <sam@videolan.org>
git-committer:
Sam Hocevar <sam@videolan.org> 1036606077 +0000
git-parent:

[2401b66298e2d714223c9d5f32aa23376a0afc4c]

git-author:
Sam Hocevar <sam@videolan.org> 1036606077 +0000
Message:
  • ./modules/access/dvdplay/access.c: activated button highlighting.
  • ./modules/codec/spudec/parse.c: implemented subtitle cropping and
    temporarily disabled subtitle cropping.
  • ./modules/codec/spudec/render.c: split RenderSPU into chroma-specific
    functions.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/video.h

    r64d33dc r8b09b55  
    55 ***************************************************************************** 
    66 * Copyright (C) 1999, 2000 VideoLAN 
    7  * $Id: video.h,v 1.56 2002/07/23 00:39:16 sam Exp $ 
     7 * $Id: video.h,v 1.57 2002/11/06 18:07:57 sam Exp $ 
    88 * 
    99 * Authors: Vincent Seguin <seguin@via.ecp.fr> 
     
    167167    int             i_type;                                          /* type */ 
    168168    int             i_status;                                       /* flags */ 
    169     int             i_size;                                     /* data size */ 
    170169    subpicture_t *  p_next;                 /* next subtitle to be displayed */ 
    171170 
     
    200199#endif 
    201200 
    202     /* The subpicture rendering routine */ 
    203     void ( *pf_render ) ( vout_thread_t *, picture_t *, const subpicture_t * ); 
     201    /* The subpicture rendering and destruction routines */ 
     202    void ( *pf_render )  ( vout_thread_t *, picture_t *, const subpicture_t * ); 
     203    void ( *pf_destroy ) ( subpicture_t * ); 
    204204 
    205205    /* Private data - the subtitle plugin might want to put stuff here to 
    206206     * keep track of the subpicture */ 
    207207    subpicture_sys_t *p_sys;                              /* subpicture data */ 
    208     void             *p_sys_orig;                 /* pointer before memalign */ 
    209208}; 
    210209 
     
    217216#define RESERVED_SUBPICTURE    1                   /* allocated and reserved */ 
    218217#define READY_SUBPICTURE       2                        /* ready for display */ 
    219 #define DESTROYED_SUBPICTURE   3           /* allocated but not used anymore */ 
    220  
     218 
  • include/video_output.h

    r0a47ec0 r8b09b55  
    66 ***************************************************************************** 
    77 * Copyright (C) 1999, 2000 VideoLAN 
    8  * $Id: video_output.h,v 1.84 2002/10/17 16:03:18 sam Exp $ 
     8 * $Id: video_output.h,v 1.85 2002/11/06 18:07:57 sam Exp $ 
    99 * 
    1010 * Authors: Vincent Seguin <seguin@via.ecp.fr> 
     
    159159                                                       subpicture_t * ); 
    160160 
    161 VLC_EXPORT( subpicture_t *,  vout_CreateSubPicture,   ( vout_thread_t *, int, int ) ); 
     161VLC_EXPORT( subpicture_t *,  vout_CreateSubPicture,   ( vout_thread_t *, int ) ); 
    162162VLC_EXPORT( void,            vout_DestroySubPicture,  ( vout_thread_t *, subpicture_t * ) ); 
    163163VLC_EXPORT( void,            vout_DisplaySubPicture,  ( vout_thread_t *, subpicture_t * ) ); 
  • modules/access/dvdplay/access.c

    r09cbae7 r8b09b55  
    33 ***************************************************************************** 
    44 * Copyright (C) 2001 VideoLAN 
    5  * $Id: access.c,v 1.4 2002/10/26 15:24:19 gbazin Exp $ 
     5 * $Id: access.c,v 1.5 2002/11/06 18:07:57 sam Exp $ 
    66 * 
    77 * Author: St�ane Borel <stef@via.ecp.fr> 
     
    8888    if( p_dvd == NULL ) 
    8989    { 
    90         msg_Err( p_input, "dvdplay error: out of memory" ); 
     90        msg_Err( p_input, "out of memory" ); 
    9191        return -1; 
    9292    } 
     
    115115    if( p_dvd->vmg == NULL ) 
    116116    { 
    117         msg_Err( p_input, "dvdplay error: can't open source" ); 
     117        msg_Err( p_input, "cannot open %s", psz_source ); 
    118118        free( p_dvd ); 
    119119        return -1; 
     
    185185    p_input->psz_demux = "dvdplay"; 
    186186 
     187    /* FIXME: we might lose variables here */ 
     188    var_Create( p_input, "x-start", VLC_VAR_INTEGER ); 
     189    var_Create( p_input, "y-start", VLC_VAR_INTEGER ); 
     190    var_Create( p_input, "x-end", VLC_VAR_INTEGER ); 
     191    var_Create( p_input, "y-end", VLC_VAR_INTEGER ); 
     192 
     193    var_Create( p_input, "color", VLC_VAR_ADDRESS ); 
     194    var_Create( p_input, "contrast", VLC_VAR_ADDRESS ); 
     195 
     196    var_Create( p_input, "highlight", VLC_VAR_BOOL ); 
     197    var_Create( p_input, "highlight-mutex", VLC_VAR_MUTEX ); 
     198 
    187199    return 0; 
    188200} 
     
    195207    input_thread_t * p_input = (input_thread_t *)p_this; 
    196208    dvd_data_t *     p_dvd = (dvd_data_t *)p_input->p_access_data; 
     209 
     210    var_Destroy( p_input, "highlight-mutex" ); 
     211    var_Destroy( p_input, "highlight" ); 
     212 
     213    var_Destroy( p_input, "x-start" ); 
     214    var_Destroy( p_input, "x-end" ); 
     215    var_Destroy( p_input, "y-start" ); 
     216    var_Destroy( p_input, "y-end" ); 
     217 
     218    var_Destroy( p_input, "color" ); 
     219    var_Destroy( p_input, "contrast" ); 
    197220 
    198221    /* close libdvdplay */ 
     
    351374    input_thread_t *    p_input; 
    352375    dvd_data_t *        p_dvd; 
     376    vlc_value_t         val; 
    353377    int                 i; 
    354378 
     
    408432        break; 
    409433    case NEW_HIGHLIGHT: 
    410          
     434        if( var_Get( p_input, "highlight-mutex", &val ) == VLC_SUCCESS ) 
     435        { 
     436            vlc_mutex_t *p_mutex = val.p_address; 
     437            vlc_mutex_lock( p_mutex ); 
     438 
     439            /* Retrieve the highlight from dvdplay */ 
     440            dvdplay_highlight( p_dvd->vmg, &p_dvd->hli ); 
     441 
     442            /* Fill our internal variables with this data */ 
     443            val.i_int = p_dvd->hli.i_x_start; 
     444            var_Set( p_input, "x-start", val ); 
     445            val.i_int = p_dvd->hli.i_y_start; 
     446            var_Set( p_input, "y-start", val ); 
     447            val.i_int = p_dvd->hli.i_x_end; 
     448            var_Set( p_input, "x-end", val ); 
     449            val.i_int = p_dvd->hli.i_y_end; 
     450            var_Set( p_input, "y-end", val ); 
     451 
     452            val.p_address = (void *)p_dvd->hli.pi_color; 
     453            var_Set( p_input, "color", val ); 
     454            val.p_address = (void *)p_dvd->hli.pi_contrast; 
     455            var_Set( p_input, "contrast", val ); 
     456 
     457            /* Tell the SPU decoder that there's a new highlight */ 
     458            val.b_bool = VLC_TRUE; 
     459            var_Set( p_input, "highlight", val ); 
     460 
     461            vlc_mutex_unlock( p_mutex ); 
     462        } 
    411463        break; 
    412464    default: 
    413         msg_Err( p_input, "unknown event from libdvdplay (%d)", 
    414                       event ); 
     465        msg_Err( p_input, "unknown event from libdvdplay (%d)", event ); 
    415466    } 
    416467 
     
    495546    return 0; 
    496547} 
     548 
  • modules/access/dvdplay/dvd.h

    r19ea8fe r8b09b55  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999-2001 VideoLAN 
    5  * $Id: dvd.h,v 1.1 2002/08/04 17:23:42 sam Exp $ 
     5 * $Id: dvd.h,v 1.2 2002/11/06 18:07:57 sam Exp $ 
    66 * 
    77 * Author: St�ane Borel <stef@via.ecp.fr> 
     
    5757    dvdplay_event_t         event; 
    5858    dvdplay_ctrl_t          control;    
     59    dvdplay_highlight_t     hli; 
    5960 
    6061} dvd_data_t; 
  • modules/access/dvdplay/intf.c

    r0a47ec0 r8b09b55  
    33 ***************************************************************************** 
    44 * Copyright (C) 2002 VideoLAN 
    5  * $Id: intf.c,v 1.2 2002/10/17 16:03:18 sam Exp $ 
     5 * $Id: intf.c,v 1.3 2002/11/06 18:07:57 sam Exp $ 
    66 * 
    77 * Authors: St�ane Borel <stef@via.ecp.fr> 
     
    3434#include "stream_control.h" 
    3535#include "input_ext-intf.h" 
     36#include "input_ext-dec.h" 
    3637 
    3738#include "dvd.h" 
     
    191192            } 
    192193 
    193             msg_Dbg( p_intf, "send button coordinates: %dx%d", 
    194                              p_intf->p_sys->control.mouse.i_x, 
    195                              p_intf->p_sys->control.mouse.i_y ); 
    196  
    197194            /* we can safely interact with libdvdplay 
    198195             * with the stream lock */ 
     
    344341    vlc_mutex_unlock( &p_intf->change_lock ); 
    345342 
    346     return 0; 
    347 
    348  
    349  
     343    return VLC_SUCCESS; 
     344
     345 
  • modules/codec/spudec/parse.c

    rcae5489 r8b09b55  
    33 ***************************************************************************** 
    44 * Copyright (C) 2000-2001 VideoLAN 
    5  * $Id: parse.c,v 1.3 2002/10/31 09:40:26 gbazin Exp $ 
     5 * $Id: parse.c,v 1.4 2002/11/06 18:07:57 sam Exp $ 
    66 * 
    77 * Authors: Samuel Hocevar <sam@zoy.org> 
     
    4545 * Local prototypes. 
    4646 *****************************************************************************/ 
    47 static int  ParseControlSequences( spudec_thread_t *, subpicture_t * ); 
    48 static int  ParseRLE             ( spudec_thread_t *, subpicture_t *, u8 * ); 
     47static int  ParseControlSeq  ( spudec_thread_t *, subpicture_t * ); 
     48static int  ParseRLE         ( spudec_thread_t *, subpicture_t *, uint8_t * ); 
     49 
     50static void DestroySPU       ( subpicture_t * ); 
     51 
     52static void UpdateSPU        ( subpicture_t *, vlc_object_t * ); 
     53static int  CropCallback     ( vlc_object_t *, char const *, 
     54                               vlc_value_t, vlc_value_t, void * ); 
    4955 
    5056/***************************************************************************** 
     
    5258 *****************************************************************************/ 
    5359static inline unsigned int AddNibble( unsigned int i_code, 
    54                                       u8 *p_src, int *pi_index ) 
     60                                      uint8_t *p_src, int *pi_index ) 
    5561{ 
    5662    if( *pi_index & 0x1 ) 
     
    102108{ 
    103109    subpicture_t * p_spu; 
    104     u8           * p_src; 
     110    uint8_t      * p_src; 
    105111    unsigned int   i_offset; 
    106112    mtime_t        i_pts; 
     
    118124 
    119125    /* Allocate the subpicture internal data. */ 
    120     p_spu = vout_CreateSubPicture( p_spudec->p_vout, MEMORY_SUBPICTURE, 
    121                                    sizeof( subpicture_sys_t ) 
    122                                     + p_spudec->i_rle_size * 4 ); 
     126    p_spu = vout_CreateSubPicture( p_spudec->p_vout, MEMORY_SUBPICTURE ); 
     127 
     128    if( p_spu == NULL ) 
     129    { 
     130        return; 
     131    } 
     132 
    123133    /* Rationale for the "p_spudec->i_rle_size * 4": we are going to 
    124134     * expand the RLE stuff so that we won't need to read nibbles later 
    125135     * on. This will speed things up a lot. Plus, we'll only need to do 
    126136     * this stupid interlacing stuff once. */ 
    127  
    128     if( p_spu == NULL ) 
    129     { 
     137    p_spu->p_sys = malloc( sizeof( subpicture_sys_t ) 
     138                            + p_spudec->i_rle_size * 4 ); 
     139 
     140    if( p_spu->p_sys == NULL ) 
     141    { 
     142        vout_DestroySubPicture( p_spudec->p_vout, p_spu ); 
    130143        return; 
    131144    } 
    132145 
    133146    /* Fill the p_spu structure */ 
     147    vlc_mutex_init( p_spudec->p_fifo, &p_spu->p_sys->lock ); 
     148 
    134149    p_spu->pf_render = E_(RenderSPU); 
    135     p_spu->p_sys->p_data = (u8*)p_spu->p_sys + sizeof( subpicture_sys_t ); 
     150    p_spu->pf_destroy = DestroySPU; 
     151    p_spu->p_sys->p_data = (uint8_t*)p_spu->p_sys + sizeof( subpicture_sys_t ); 
    136152    p_spu->p_sys->b_palette = VLC_FALSE; 
    137153 
     
    141157    p_spu->p_sys->pi_alpha[3] = 0x0f; 
    142158 
     159    p_spu->p_sys->b_crop = VLC_FALSE; 
     160 
    143161    /* Get display time now. If we do it later, we may miss the PTS. */ 
    144162    p_spu->p_sys->i_pts = i_pts; 
     163 
     164    /* Attach to our input thread */ 
     165    p_spu->p_sys->p_input = vlc_object_find( p_spudec->p_fifo, 
     166                                             VLC_OBJECT_INPUT, FIND_PARENT ); 
     167    if( p_spu->p_sys->p_input ) 
     168    { 
     169        vlc_value_t val; 
     170 
     171        if( !var_Get( p_spu->p_sys->p_input, "highlight-mutex", &val ) ) 
     172        { 
     173            vlc_mutex_t *p_mutex = val.p_address; 
     174 
     175            vlc_mutex_lock( p_mutex ); 
     176            UpdateSPU( p_spu, VLC_OBJECT(p_spu->p_sys->p_input) ); 
     177            var_AddCallback( p_spu->p_sys->p_input, 
     178                             "highlight", CropCallback, p_spu ); 
     179            vlc_mutex_unlock( p_mutex ); 
     180        } 
     181    } 
    145182 
    146183    /* Allocate the temporary buffer we will parse */ 
     
    177214 
    178215    /* Getting the control part */ 
    179     if( ParseControlSequences( p_spudec, p_spu ) ) 
     216    if( ParseControlSeq( p_spudec, p_spu ) ) 
    180217    { 
    181218        /* There was a parse error, delete the subpicture */ 
     
    204241    vout_DisplaySubPicture( p_spudec->p_vout, p_spu ); 
    205242 
     243    /* TODO: do stuff! */ 
     244 
    206245    /* Clean up */ 
    207246    free( p_src ); 
     
    209248 
    210249/***************************************************************************** 
    211  * ParseControlSequences: parse all SPU control sequences 
     250 * ParseControlSeq: parse all SPU control sequences 
    212251 ***************************************************************************** 
    213252 * This is the most important part in SPU decoding. We get dates, palette 
     
    215254 * subtitles format, see http://sam.zoy.org/doc/dvd/subtitles/index.html 
    216255 *****************************************************************************/ 
    217 static int ParseControlSequences( spudec_thread_t *p_spudec, 
     256static int ParseControlSeq( spudec_thread_t *p_spudec, 
    218257                                  subpicture_t * p_spu ) 
    219258{ 
     
    225264 
    226265    /* Command and date */ 
    227     u8 i_command = SPU_CMD_END; 
     266    uint8_t i_command = SPU_CMD_END; 
    228267    mtime_t date = 0; 
    229268 
     
    276315                 && *(int*)p_spudec->p_fifo->p_demux_data == 0xBeeF ) 
    277316            { 
    278                 u32 i_color; 
     317                uint32_t i_color; 
    279318 
    280319                p_spu->p_sys->b_palette = VLC_TRUE; 
    281320                for( i = 0; i < 4 ; i++ ) 
    282321                { 
    283                     i_color = ((u32*)((char*)p_spudec->p_fifo-> 
     322                    i_color = ((uint32_t*)((char*)p_spudec->p_fifo-> 
    284323                                p_demux_data + sizeof(int)))[ 
    285324                                  GetBits(&p_spudec->bit_stream, 4) ]; 
     
    432471 *****************************************************************************/ 
    433472static int ParseRLE( spudec_thread_t *p_spudec, 
    434                      subpicture_t * p_spu, u8 * p_src ) 
     473                     subpicture_t * p_spu, uint8_t * p_src ) 
    435474{ 
    436475    unsigned int i_code; 
     
    440479    unsigned int i_x, i_y; 
    441480 
    442     u16 *p_dest = (u16 *)p_spu->p_sys->p_data; 
     481    uint16_t *p_dest = (uint16_t *)p_spu->p_sys->p_data; 
    443482 
    444483    /* The subtitles are interlaced, we need two offsets */ 
     
    447486    unsigned int *pi_offset; 
    448487 
     488#if 0 /* cropping */ 
    449489    vlc_bool_t b_empty_top = VLC_TRUE, 
    450490               b_empty_bottom = VLC_FALSE; 
    451491    unsigned int i_skipped_top = 0, 
    452492                 i_skipped_bottom = 0; 
     493#endif 
    453494 
    454495    /* Colormap statistics */ 
     
    514555            } 
    515556 
     557#if 0 /* cropping */ 
    516558            if( (i_code >> 2) == i_width 
    517559                 && p_spu->p_sys->pi_alpha[ i_code & 0x3 ] == 0x00 ) 
     
    542584                i_skipped_bottom = 0; 
    543585            } 
     586#else 
     587            *p_dest++ = i_code; 
     588#endif 
    544589        } 
    545590 
     
    582627             p_spu->i_width, p_spu->i_height, p_spu->i_x, p_spu->i_y ); 
    583628 
     629#if 0 /* cropping */ 
    584630    /* Crop if necessary */ 
    585631    if( i_skipped_top || i_skipped_bottom ) 
     
    591637                 p_spu->i_width, p_spu->i_height, p_spu->i_x, p_spu->i_y ); 
    592638    } 
     639#endif 
    593640 
    594641    /* Handle color if no palette was found */ 
     
    652699} 
    653700 
     701/***************************************************************************** 
     702 * DestroySPU: subpicture destructor 
     703 *****************************************************************************/ 
     704static void DestroySPU( subpicture_t *p_spu ) 
     705{ 
     706    if( p_spu->p_sys->p_input ) 
     707    { 
     708        /* Detach from our input thread */ 
     709        var_DelCallback( p_spu->p_sys->p_input, "highlight", 
     710                         CropCallback, p_spu ); 
     711        vlc_object_release( p_spu->p_sys->p_input ); 
     712    } 
     713 
     714    vlc_mutex_destroy( &p_spu->p_sys->lock ); 
     715    free( p_spu->p_sys ); 
     716} 
     717 
     718/***************************************************************************** 
     719 * UpdateSPU: update subpicture settings 
     720 ***************************************************************************** 
     721 * This function is called from CropCallback and at initialization time, to 
     722 * retrieve crop information from the input. 
     723 *****************************************************************************/ 
     724static void UpdateSPU( subpicture_t *p_spu, vlc_object_t *p_object ) 
     725{ 
     726    vlc_value_t val; 
     727 
     728    if( var_Get( p_object, "highlight", &val ) ) 
     729    { 
     730        return; 
     731    } 
     732 
     733    p_spu->p_sys->b_crop = val.b_bool; 
     734    if( !p_spu->p_sys->b_crop ) 
     735    { 
     736        return; 
     737    } 
     738 
     739    var_Get( p_object, "x-start", &val ); 
     740    p_spu->p_sys->i_x_start = val.i_int; 
     741    var_Get( p_object, "y-start", &val ); 
     742    p_spu->p_sys->i_y_start = val.i_int; 
     743    var_Get( p_object, "x-end", &val ); 
     744    p_spu->p_sys->i_x_end = val.i_int; 
     745    var_Get( p_object, "y-end", &val ); 
     746    p_spu->p_sys->i_y_end = val.i_int; 
     747 
     748#if 0 
     749    if( var_Get( p_object, "color", &val ) == VLC_SUCCESS ) 
     750    { 
     751        p_spu->p_sys->pi_color[0] = ((uint8_t *)val.p_address)[0]; 
     752        p_spu->p_sys->pi_color[1] = ((uint8_t *)val.p_address)[1]; 
     753        p_spu->p_sys->pi_color[2] = ((uint8_t *)val.p_address)[2]; 
     754        p_spu->p_sys->pi_color[3] = ((uint8_t *)val.p_address)[3]; 
     755    } 
     756#endif 
     757 
     758    if( var_Get( p_object, "contrast", &val ) == VLC_SUCCESS ) 
     759    { 
     760        p_spu->p_sys->pi_alpha[0] = ((uint8_t *)val.p_address)[0]; 
     761        p_spu->p_sys->pi_alpha[1] = ((uint8_t *)val.p_address)[1]; 
     762        p_spu->p_sys->pi_alpha[2] = ((uint8_t *)val.p_address)[2]; 
     763        p_spu->p_sys->pi_alpha[3] = ((uint8_t *)val.p_address)[3]; 
     764    } 
     765} 
     766 
     767/***************************************************************************** 
     768 * CropCallback: called when the highlight properties are changed 
     769 ***************************************************************************** 
     770 * This callback is called from the input thread when we need cropping 
     771 *****************************************************************************/ 
     772static int CropCallback( vlc_object_t *p_object, char const *psz_var, 
     773                         vlc_value_t oldval, vlc_value_t newval, void *p_data ) 
     774{ 
     775    UpdateSPU( (subpicture_t *)p_data, p_object ); 
     776 
     777    return VLC_SUCCESS; 
     778} 
     779 
  • modules/codec/spudec/render.c

    rbf2f5b0 r8b09b55  
    33 ***************************************************************************** 
    44 * Copyright (C) 2000-2001 VideoLAN 
    5  * $Id: render.c,v 1.2 2002/09/30 18:30:26 titer Exp $ 
     5 * $Id: render.c,v 1.3 2002/11/06 18:07:57 sam Exp $ 
    66 * 
    77 * Authors: Samuel Hocevar <sam@zoy.org> 
     
    4545 
    4646/***************************************************************************** 
     47 * Local prototypes 
     48 *****************************************************************************/ 
     49static void RenderI420( vout_thread_t *, picture_t *, const subpicture_t *, 
     50                        vlc_bool_t ); 
     51static void RenderRV16( vout_thread_t *, picture_t *, const subpicture_t *, 
     52                        vlc_bool_t ); 
     53static void RenderRV32( vout_thread_t *, picture_t *, const subpicture_t *, 
     54                        vlc_bool_t ); 
     55static void RenderYUY2( vout_thread_t *, picture_t *, const subpicture_t *, 
     56                        vlc_bool_t ); 
     57 
     58/***************************************************************************** 
    4759 * RenderSPU: draw an SPU on a picture 
    4860 ***************************************************************************** 
     
    5567                    const subpicture_t *p_spu ) 
    5668{ 
     69    switch( p_vout->output.i_chroma ) 
     70    { 
     71        /* I420 target, no scaling */ 
     72        case VLC_FOURCC('I','4','2','0'): 
     73        case VLC_FOURCC('I','Y','U','V'): 
     74        case VLC_FOURCC('Y','V','1','2'): 
     75            RenderI420( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop ); 
     76            break; 
     77 
     78        /* RV16 target, scaling */ 
     79        case VLC_FOURCC('R','V','1','6'): 
     80            RenderRV16( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop ); 
     81            break; 
     82 
     83        /* RV32 target, scaling */ 
     84        case VLC_FOURCC('R','V','2','4'): 
     85        case VLC_FOURCC('R','V','3','2'): 
     86            RenderRV32( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop ); 
     87            break; 
     88 
     89        /* NVidia overlay, no scaling */ 
     90        case VLC_FOURCC('Y','U','Y','2'): 
     91            RenderYUY2( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop ); 
     92            break; 
     93 
     94        default: 
     95            msg_Err( p_vout, "unknown chroma, can't render SPU" ); 
     96            break; 
     97    } 
     98} 
     99 
     100/* Following functions are local */ 
     101 
     102static void RenderI420( vout_thread_t *p_vout, picture_t *p_pic, 
     103                        const subpicture_t *p_spu, vlc_bool_t b_crop ) 
     104{ 
    57105    /* Common variables */ 
    58     u16  p_clut16[4]; 
    59     u32  p_clut32[4]; 
    60106    u8  *p_dest; 
    61107    u8  *p_destptr; 
     
    65111    int i_len, i_color; 
    66112    u16 i_colprecomp, i_destalpha; 
    67     u8  i_cnt; 
    68  
    69     /* RGB-specific */ 
    70     int i_xscale, i_yscale, i_width, i_height, i_ytmp, i_yreal, i_ynext; 
    71  
    72     switch( p_vout->output.i_chroma ) 
    73     { 
    74     /* I420 target, no scaling */ 
    75     case VLC_FOURCC('I','4','2','0'): 
    76     case VLC_FOURCC('I','Y','U','V'): 
    77     case VLC_FOURCC('Y','V','1','2'): 
     113 
     114    /* Crop-specific */ 
     115    int i_x_start, i_y_start, i_x_end, i_y_end; 
    78116 
    79117    p_dest = p_pic->Y_PIXELS + p_spu->i_x + p_spu->i_width 
    80118              + p_pic->Y_PITCH * ( p_spu->i_y + p_spu->i_height ); 
     119 
     120    i_x_start = p_spu->i_width - p_spu->p_sys->i_x_end; 
     121    i_y_start = p_pic->Y_PITCH * (p_spu->i_height - p_spu->p_sys->i_y_end ); 
     122    i_x_end = p_spu->i_width - p_spu->p_sys->i_x_start; 
     123    i_y_end = p_pic->Y_PITCH * (p_spu->i_height - p_spu->p_sys->i_y_start ); 
    81124 
    82125    /* Draw until we reach the bottom of the subtitle */ 
     
    86129    { 
    87130        /* Draw until we reach the end of the line */ 
    88         for( i_x = p_spu->i_width ; i_x ;
     131        for( i_x = p_spu->i_width ; i_x ; i_x -= i_len
    89132        { 
    90133            /* Get the RLE part, then draw the line */ 
    91134            i_color = *p_source & 0x3; 
    92135            i_len = *p_source++ >> 2; 
     136 
     137            if( b_crop 
     138                 && ( i_x < i_x_start || i_x > i_x_end 
     139                       || i_y < i_y_start || i_y > i_y_end ) ) 
     140            { 
     141                continue; 
     142            } 
    93143 
    94144            switch( p_spu->p_sys->pi_alpha[i_color] ) 
     
    118168                    } 
    119169                    break; 
    120  
    121             } 
    122             i_x -= i_len; 
     170            } 
    123171        } 
    124172    } 
    125  
    126     break; 
    127  
    128     /* RV16 target, scaling */ 
    129     case VLC_FOURCC('R','V','1','6'): 
     173
     174 
     175static void RenderRV16( vout_thread_t *p_vout, picture_t *p_pic, 
     176                        const subpicture_t *p_spu, vlc_bool_t b_crop ) 
     177
     178    /* Common variables */ 
     179    u16  p_clut16[4]; 
     180    u8  *p_dest; 
     181    u16 *p_source = (u16 *)p_spu->p_sys->p_data; 
     182 
     183    int i_x, i_y; 
     184    int i_len, i_color; 
     185 
     186    /* RGB-specific */ 
     187    int i_xscale, i_yscale, i_width, i_height, i_ytmp, i_yreal, i_ynext; 
     188 
     189    /* Crop-specific */ 
     190    int i_x_start, i_y_start, i_x_end, i_y_end; 
    130191 
    131192    /* XXX: this is a COMPLETE HACK, memcpy is unable to do u16s anyway */ 
     
    147208              + ( (p_spu->i_x * i_xscale) >> 6 ) * 2 
    148209              + ( (p_spu->i_y * i_yscale) >> 6 ) * p_pic->p->i_pitch; 
     210 
     211    i_x_start = i_width - i_xscale * p_spu->p_sys->i_x_end; 
     212    i_y_start = i_yscale * p_spu->p_sys->i_y_start; 
     213    i_x_end = i_width - i_xscale * p_spu->p_sys->i_x_start; 
     214    i_y_end = i_yscale * p_spu->p_sys->i_y_end; 
    149215 
    150216    /* Draw until we reach the bottom of the subtitle */ 
     
    161227 
    162228            /* Draw until we reach the end of the line */ 
    163             for( i_x = i_width ; i_x ;
     229            for( i_x = i_width ; i_x ; i_x -= i_len
    164230            { 
    165231                /* Get the RLE part, then draw the line */ 
    166232                i_color = *p_source & 0x3; 
     233                i_len = i_xscale * ( *p_source++ >> 2 ); 
     234 
     235                if( b_crop 
     236                     && ( i_x < i_x_start || i_x > i_x_end 
     237                           || i_y < i_y_start || i_y > i_y_end ) ) 
     238                { 
     239                    continue; 
     240                } 
    167241 
    168242                switch( p_spu->p_sys->pi_alpha[ i_color ] ) 
    169243                { 
    170244                case 0x00: 
    171                     i_x -= i_xscale * ( *p_source++ >> 2 ); 
    172245                    break; 
    173246 
    174247                case 0x0f: 
    175                     i_len = i_xscale * ( *p_source++ >> 2 ); 
    176248                    memset( p_dest - 2 * ( i_x >> 6 ) + i_yreal, 
    177249                            p_clut16[ i_color ], 
    178250                            2 * ( ( i_len >> 6 ) + 1 ) ); 
    179                     i_x -= i_len; 
    180251                    break; 
    181252 
    182253                default: 
    183254                    /* FIXME: we should do transparency */ 
    184                     i_len = i_xscale * ( *p_source++ >> 2 ); 
    185255                    memset( p_dest - 2 * ( i_x >> 6 ) + i_yreal, 
    186256                            p_clut16[ i_color ], 
    187257                            2 * ( ( i_len >> 6 ) + 1 ) ); 
    188                     i_x -= i_len; 
    189                     break; 
    190                 } 
    191  
     258                    break; 
     259                } 
    192260            } 
    193261        } 
     
    198266 
    199267            /* Draw until we reach the end of the line */ 
    200             for( i_x = i_width ; i_x ;
     268            for( i_x = i_width ; i_x ; i_x -= i_len
    201269            { 
    202270                /* Get the RLE part, then draw as many lines as needed */ 
    203271                i_color = *p_source & 0x3; 
     272                i_len = i_xscale * ( *p_source++ >> 2 ); 
     273 
     274                if( b_crop 
     275                     && ( i_x < i_x_start || i_x > i_x_end 
     276                           || i_y < i_y_start || i_y > i_y_end ) ) 
     277                { 
     278                    continue; 
     279                } 
    204280 
    205281                switch( p_spu->p_sys->pi_alpha[ i_color ] ) 
    206282                { 
    207283                case 0x00: 
    208                     i_x -= i_xscale * ( *p_source++ >> 2 ); 
    209284                    break; 
    210285 
    211286                case 0x0f: 
    212                     i_len = i_xscale * ( *p_source++ >> 2 ); 
    213287                    for( i_ytmp = i_yreal ; i_ytmp < i_ynext ; 
    214288                         i_ytmp += p_pic->p->i_pitch ) 
     
    218292                                2 * ( ( i_len >> 6 ) + 1 ) ); 
    219293                    } 
    220                     i_x -= i_len; 
    221294                    break; 
    222295 
    223296                default: 
    224297                    /* FIXME: we should do transparency */ 
    225                     i_len = i_xscale * ( *p_source++ >> 2 ); 
    226298                    for( i_ytmp = i_yreal ; i_ytmp < i_ynext ; 
    227299                         i_ytmp += p_pic->p->i_pitch ) 
     
    231303                                2 * ( ( i_len >> 6 ) + 1 ) ); 
    232304                    } 
    233                     i_x -= i_len; 
    234305                    break; 
    235306                } 
     
    237308        } 
    238309    } 
    239  
    240     break; 
    241  
    242     /* RV32 target, scaling */ 
    243     case VLC_FOURCC('R','V','2','4'): 
    244     case VLC_FOURCC('R','V','3','2'): 
     310
     311 
     312static void RenderRV32( vout_thread_t *p_vout, picture_t *p_pic, 
     313                        const subpicture_t *p_spu, vlc_bool_t b_crop ) 
     314
     315    /* Common variables */ 
     316    u32  p_clut32[4]; 
     317    u8  *p_dest; 
     318    u16 *p_source = (u16 *)p_spu->p_sys->p_data; 
     319 
     320    int i_x, i_y; 
     321    int i_len, i_color; 
     322 
     323    /* RGB-specific */ 
     324    int i_xscale, i_yscale, i_width, i_height, i_ytmp, i_yreal, i_ynext; 
     325 
     326    /* Crop-specific */ 
     327    int i_x_start, i_y_start, i_x_end, i_y_end; 
    245328 
    246329    /* XXX: this is a COMPLETE HACK, memcpy is unable to do u32s anyway */ 
     
    257340    i_width  = p_spu->i_width  * i_xscale; 
    258341    i_height = p_spu->i_height * i_yscale; 
     342 
     343    i_x_start = i_width - i_xscale * p_spu->p_sys->i_x_end; 
     344    i_y_start = i_yscale * p_spu->p_sys->i_y_start; 
     345    i_x_end = i_width - i_xscale * p_spu->p_sys->i_x_start; 
     346    i_y_end = i_yscale * p_spu->p_sys->i_y_end; 
    259347 
    260348    p_dest = p_pic->p->p_pixels + ( i_width >> 6 ) * 4 
     
    276364 
    277365            /* Draw until we reach the end of the line */ 
    278             for( i_x = i_width ; i_x ;
     366            for( i_x = i_width ; i_x ; i_x -= i_len
    279367            { 
    280368                /* Get the RLE part, then draw the line */ 
    281369                i_color = *p_source & 0x3; 
     370                i_len = i_xscale * ( *p_source++ >> 2 ); 
     371 
     372                if( b_crop 
     373                     && ( i_x < i_x_start || i_x > i_x_end 
     374                           || i_y < i_y_start || i_y > i_y_end ) ) 
     375                { 
     376                    continue; 
     377                } 
    282378 
    283379                switch( p_spu->p_sys->pi_alpha[ i_color ] ) 
    284380                { 
    285381                case 0x00: 
    286                     i_x -= i_xscale * ( *p_source++ >> 2 ); 
    287382                    break; 
    288383 
    289384                case 0x0f: 
    290                     i_len = i_xscale * ( *p_source++ >> 2 ); 
    291385                    memset( p_dest - 4 * ( i_x >> 6 ) + i_yreal, 
    292386                            p_clut32[ i_color ], 4 * ( ( i_len >> 6 ) + 1 ) ); 
    293                     i_x -= i_len; 
    294387                    break; 
    295388 
    296389                default: 
    297390                    /* FIXME: we should do transparency */ 
    298                     i_len = i_xscale * ( *p_source++ >> 2 ); 
    299391                    memset( p_dest - 4 * ( i_x >> 6 ) + i_yreal, 
    300392                            p_clut32[ i_color ], 4 * ( ( i_len >> 6 ) + 1 ) ); 
    301                     i_x -= i_len; 
    302                     break; 
    303                 } 
    304  
     393                    break; 
     394                } 
    305395            } 
    306396        } 
     
    311401 
    312402            /* Draw until we reach the end of the line */ 
    313             for( i_x = i_width ; i_x ;
     403            for( i_x = i_width ; i_x ; i_x -= i_len
    314404            { 
    315405                /* Get the RLE part, then draw as many lines as needed */ 
    316406                i_color = *p_source & 0x3; 
     407                i_len = i_xscale * ( *p_source++ >> 2 ); 
     408 
     409                if( b_crop 
     410                     && ( i_x < i_x_start || i_x > i_x_end 
     411                           || i_y < i_y_start || i_y > i_y_end ) ) 
     412                { 
     413                    continue; 
     414                } 
    317415 
    318416                switch( p_spu->p_sys->pi_alpha[ i_color ] ) 
    319417                { 
    320418                case 0x00: 
    321                     i_x -= i_xscale * ( *p_source++ >> 2 ); 
    322419                    break; 
    323420 
    324421                case 0x0f: 
    325                     i_len = i_xscale * ( *p_source++ >> 2 ); 
    326422                    for( i_ytmp = i_yreal ; i_ytmp < i_ynext ; 
    327423                         i_ytmp += p_pic->p->i_pitch ) 
     
    331427                                4 * ( ( i_len >> 6 ) + 1 ) ); 
    332428                    } 
    333                     i_x -= i_len; 
    334429                    break; 
    335430 
    336431                default: 
    337432                    /* FIXME: we should do transparency */ 
    338                     i_len = i_xscale * ( *p_source++ >> 2 ); 
    339433                    for( i_ytmp = i_yreal ; i_ytmp < i_ynext ; 
    340434                         i_ytmp += p_pic->p->i_pitch ) 
     
    344438                                4 * ( ( i_len >> 6 ) + 1 ) ); 
    345439                    } 
    346                     i_x -= i_len; 
    347440                    break; 
    348441                } 
     
    350443        } 
    351444    } 
    352  
    353     break; 
    354  
    355     /* NVidia overlay, no scaling */ 
    356     case VLC_FOURCC(