Changeset ce0e4fb0ab2f1d847f4b17ae9a895e01a1ae7224

Show
Ignore:
Timestamp:
04/15/07 23:00:09 (1 year ago)
Author:
Antoine Cellerier <dionoea@videolan.org>
git-committer:
Antoine Cellerier <dionoea@videolan.org> 1176670809 +0000
git-parent:

[4cdb486b976a23ca9f24242ab98ea4258e9558de]

git-author:
Antoine Cellerier <dionoea@videolan.org> 1176670809 +0000
Message:
  • mosaic_bridge.c: - Add "vfilters" option to apply video filters on the

image before sending it to the mosaic.

  • Add option ("chroma") to force the image chroma
  • Remove alpha mask code
  • mosaic.c: - Remove bluescreen code
    • Misc cosmetics changes
  • bluescreen.c: New bluescreen filter (mostly cut & paste from mosaic.c)
  • alphamask.c: New alpha mask filter (mostly cut & paste from mosaic_bridge.c)
  • invert.c: don't invert the alpha plane for YUVA images (We also need to

prevent that for RGBA images ... but that's not really used
currently)

  • configure.ac, video_filter/Modules.am: add alphamask and bluescreen
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • configure.ac

    r58663ff rce0e4fb  
    11881188  VLC_ADD_PLUGINS([access_fake access_filter_timeshift access_filter_record access_filter_dump]) 
    11891189  VLC_ADD_PLUGINS([gestures rc telnet hotkeys netsync showintf marq podcast shout sap fake folder]) 
    1190   VLC_ADD_PLUGINS([rss mosaic wall motiondetect clone crop erase]) 
     1190  VLC_ADD_PLUGINS([rss mosaic wall motiondetect clone crop erase bluescreen alphamask]) 
    11911191  VLC_ADD_PLUGINS([i420_yuy2 i422_yuy2 i420_ymga]) 
    11921192  VLC_ADD_PLUGINS([aout_file linear_resampler bandlimited_resampler]) 
  • modules/stream_out/mosaic_bridge.c

    r57c4462 rce0e4fb  
    22 * mosaic_bridge.c: 
    33 ***************************************************************************** 
    4  * Copyright (C) 2004-2005 the VideoLAN team 
     4 * Copyright (C) 2004-2007 the VideoLAN team 
    55 * $Id$ 
    66 * 
     
    3535#include <vlc_codec.h> 
    3636 
    37 #include "vlc_image.h" 
     37#include <vlc_image.h> 
     38#include <vlc_filter.h> 
    3839 
    3940#include "../video_filter/mosaic.h" 
     
    5455    vlc_bool_t b_inited; 
    5556 
    56     picture_t *p_mask; 
    57     vlc_mutex_t mask_lock; 
     57    int i_chroma; /* force image format chroma */ 
     58 
     59    filter_t **pp_vfilters; 
     60    int i_vfilters; 
    5861}; 
    5962 
     
    8689        } 
    8790    } 
    88 } 
    89  
    90 /* copied from video_filters/erase.c . Gruik ? */ 
    91 static void LoadMask( sout_stream_t *p_stream, const char *psz_filename ) 
    92 { 
    93     image_handler_t *p_image; 
    94     video_format_t fmt_in, fmt_out; 
    95     memset( &fmt_in, 0, sizeof( video_format_t ) ); 
    96     memset( &fmt_out, 0, sizeof( video_format_t ) ); 
    97     fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A'); 
    98     if( p_stream->p_sys->p_mask ) 
    99         p_stream->p_sys->p_mask->pf_release( p_stream->p_sys->p_mask ); 
    100     p_image = image_HandlerCreate( p_stream ); 
    101     p_stream->p_sys->p_mask = 
    102         image_ReadUrl( p_image, psz_filename, &fmt_in, &fmt_out ); 
    103     image_HandlerDelete( p_image ); 
    10491} 
    10592 
     
    113100static int               Send( sout_stream_t *, sout_stream_id_t *, block_t * ); 
    114101 
    115 static void video_del_buffer( decoder_t *, picture_t * ); 
    116 static picture_t *video_new_buffer( decoder_t * ); 
     102inline static void video_del_buffer_decoder( decoder_t *, picture_t * ); 
     103inline static void video_del_buffer_filter( filter_t *, picture_t * ); 
     104static void video_del_buffer( vlc_object_t *, picture_t * ); 
     105 
     106inline static picture_t *video_new_buffer_decoder( decoder_t * ); 
     107inline static picture_t *video_new_buffer_filter( filter_t * ); 
     108static picture_t *video_new_buffer( vlc_object_t *, decoder_owner_sys_t *, 
     109                                    es_format_t *, void (*)( picture_t * ) ); 
     110 
    117111static void video_link_picture_decoder( decoder_t *, picture_t * ); 
    118112static void video_unlink_picture_decoder( decoder_t *, picture_t * ); 
     
    136130#define RATIO_LONGTEXT N_( \ 
    137131    "Sample aspect ratio of the destination (1:1, 3:4, 2:3)." ) 
    138 #define MASK_TEXT N_("Transparency mask") 
    139 #define MASK_LONGTEXT N_( \ 
    140     "Alpha blending transparency mask. Use's a png alpha channel.") 
    141  
    142 #define SOUT_CFG_PREFIX "sout-mosaic-bridge-" 
     132 
     133#define VFILTER_TEXT N_("Video filter") 
     134#define VFILTER_LONGTEXT N_( \ 
     135    "Video filters will be applied to the video stream." ); 
     136 
     137#define CHROMA_TEXT N_("Image chroma") 
     138#define CHROMA_LONGTEXT N_( \ 
     139    "Force the use of a specific chroma. Use YUVA if you're planning " \ 
     140    "to use the Alphamask or Bluescreen video filter." ); 
     141 
     142#define CFG_PREFIX "sout-mosaic-bridge-" 
    143143 
    144144vlc_module_begin(); 
     
    148148    add_shortcut( "mosaic-bridge" ); 
    149149 
    150     add_string( SOUT_CFG_PREFIX "id", "Id", NULL, ID_TEXT, ID_LONGTEXT, 
     150    add_string( CFG_PREFIX "id", "Id", NULL, ID_TEXT, ID_LONGTEXT, 
    151151                VLC_FALSE ); 
    152     add_integer( SOUT_CFG_PREFIX "width", 0, NULL, WIDTH_TEXT, 
     152    add_integer( CFG_PREFIX "width", 0, NULL, WIDTH_TEXT, 
    153153                 WIDTH_LONGTEXT, VLC_TRUE ); 
    154     add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT, 
     154    add_integer( CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT, 
    155155                 HEIGHT_LONGTEXT, VLC_TRUE ); 
    156     add_string( SOUT_CFG_PREFIX "sar", "1:1", NULL, RATIO_TEXT, 
     156    add_string( CFG_PREFIX "sar", "1:1", NULL, RATIO_TEXT, 
    157157                RATIO_LONGTEXT, VLC_FALSE ); 
    158     add_string( SOUT_CFG_PREFIX "mask", NULL, NULL, MASK_TEXT, 
    159                 MASK_LONGTEXT, VLC_FALSE ); 
     158    add_string( CFG_PREFIX "chroma", 0, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, 
     159                VLC_FALSE ); 
     160 
     161    add_module_list( CFG_PREFIX "vfilter", "video filter2", 
     162                     NULL, NULL, VFILTER_TEXT, VFILTER_LONGTEXT, VLC_FALSE ); 
    160163 
    161164    set_callbacks( Open, Close ); 
     
    165168 
    166169static const char *ppsz_sout_options[] = { 
    167     "id", "width", "height", "sar", "mask", NULL 
     170    "id", "width", "height", "sar", "vfilter", "chroma", NULL 
    168171}; 
    169172 
     
    178181    vlc_value_t           val; 
    179182 
    180     config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, 
     183    config_ChainParse( p_stream, CFG_PREFIX, ppsz_sout_options, 
    181184                       p_stream->p_cfg ); 
    182185 
     
    193196    p_sys->p_lock = val.p_address; 
    194197 
    195     var_Get( p_stream, SOUT_CFG_PREFIX "id", &val ); 
     198    var_Get( p_stream, CFG_PREFIX "id", &val ); 
    196199    p_sys->psz_id = val.psz_string; 
    197200 
    198201    p_sys->i_height = 
    199         var_CreateGetIntegerCommand( p_stream, SOUT_CFG_PREFIX "height" ); 
    200     var_AddCallback( p_stream, SOUT_CFG_PREFIX "height", MosaicBridgeCallback, 
     202        var_CreateGetIntegerCommand( p_stream, CFG_PREFIX "height" ); 
     203    var_AddCallback( p_stream, CFG_PREFIX "height", MosaicBridgeCallback, 
    201204                     p_stream ); 
    202205 
    203206    p_sys->i_width = 
    204         var_CreateGetIntegerCommand( p_stream, SOUT_CFG_PREFIX "width" ); 
    205     var_AddCallback( p_stream, SOUT_CFG_PREFIX "width", MosaicBridgeCallback, 
     207        var_CreateGetIntegerCommand( p_stream, CFG_PREFIX "width" ); 
     208    var_AddCallback( p_stream, CFG_PREFIX "width", MosaicBridgeCallback, 
    206209                     p_stream ); 
    207210 
    208     vlc_mutex_init( p_stream, &p_sys->mask_lock ); 
    209     val.psz_string = 
    210         var_CreateGetStringCommand( p_stream, SOUT_CFG_PREFIX "mask" ); 
    211     var_AddCallback( p_stream, SOUT_CFG_PREFIX "mask", MosaicBridgeCallback, 
    212                      p_stream ); 
    213     if( val.psz_string && *val.psz_string ) 
    214     { 
    215         p_sys->p_mask = NULL; 
    216         LoadMask( p_stream, val.psz_string ); 
    217         if( !p_sys->p_mask ) 
    218             msg_Err( p_stream, "Error while loading mask (%s).", 
    219                      val.psz_string ); 
    220     } 
    221     else 
    222         p_sys->p_mask = NULL; 
    223     free( val.psz_string ); 
    224  
    225     var_Get( p_stream, SOUT_CFG_PREFIX "sar", &val ); 
     211    var_Get( p_stream, CFG_PREFIX "sar", &val ); 
    226212    if ( val.psz_string ) 
    227213    { 
     
    249235    } 
    250236 
     237    p_sys->i_chroma = 0; 
     238    val.psz_string = var_GetNonEmptyString( p_stream, CFG_PREFIX "chroma" ); 
     239    if( val.psz_string && strlen( val.psz_string ) >= 4 ) 
     240    { 
     241        memcpy( &p_sys->i_chroma, val.psz_string, 4 ); 
     242        msg_Dbg( p_stream, "Forcing image chroma to 0x%.8x (%4.4s)", p_sys->i_chroma, (char*)&p_sys->i_chroma ); 
     243    } 
     244 
    251245    p_stream->pf_add    = Add; 
    252246    p_stream->pf_del    = Del; 
     
    271265        free( p_sys->psz_id ); 
    272266 
    273     vlc_mutex_destroy( &p_sys->mask_lock ); 
    274     if( p_stream->p_sys->p_mask ) 
    275         p_stream->p_sys->p_mask->pf_release( p_stream->p_sys->p_mask ); 
    276  
    277267    free( p_sys ); 
    278268} 
     
    283273    bridge_t *p_bridge; 
    284274    bridged_es_t *p_es; 
     275    char *psz_chain, *psz_parser; 
    285276    int i; 
    286277 
     
    300291    p_sys->p_decoder->fmt_out.p_extra = 0; 
    301292    p_sys->p_decoder->pf_decode_video = 0; 
    302     p_sys->p_decoder->pf_vout_buffer_new = video_new_buffer
    303     p_sys->p_decoder->pf_vout_buffer_del = video_del_buffer
     293    p_sys->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder
     294    p_sys->p_decoder->pf_vout_buffer_del = video_del_buffer_decoder
    304295    p_sys->p_decoder->pf_picture_link    = video_link_picture_decoder; 
    305296    p_sys->p_decoder->pf_picture_unlink  = video_unlink_picture_decoder; 
     
    376367    msg_Dbg( p_stream, "mosaic bridge id=%s pos=%d", p_es->psz_id, i ); 
    377368 
     369    /* Create user specified video filters */ 
     370    psz_chain = var_GetNonEmptyString( p_stream, CFG_PREFIX "vfilter" ); 
     371    printf("psz_chain: %s\n", psz_chain ); 
     372    { 
     373        config_chain_t *p_cfg; 
     374        for( p_cfg = p_stream->p_cfg; p_cfg != NULL; p_cfg = p_cfg->p_next ) 
     375        { 
     376            printf(" - %s\n", p_cfg->psz_value ); 
     377        } 
     378    } 
     379    p_sys->i_vfilters = 0; 
     380    p_sys->pp_vfilters = NULL; 
     381    psz_parser = psz_chain; 
     382    while( psz_parser && *psz_parser ) 
     383    { 
     384        config_chain_t *p_cfg; 
     385        char *psz_name; 
     386        filter_t **pp_vfilter; 
     387        psz_parser = config_ChainCreate( &psz_name, &p_cfg, psz_parser ); 
     388        p_sys->i_vfilters++; 
     389        p_sys->pp_vfilters = 
     390            (filter_t **)realloc( p_sys->pp_vfilters, 
     391                                  p_sys->i_vfilters * sizeof(filter_t *) ); 
     392        pp_vfilter = p_sys->pp_vfilters+(p_sys->i_vfilters - 1); 
     393        *pp_vfilter = vlc_object_create( p_stream, VLC_OBJECT_FILTER ); 
     394        vlc_object_attach( *pp_vfilter, p_stream ); 
     395        (*pp_vfilter)->pf_vout_buffer_new = video_new_buffer_filter; 
     396        (*pp_vfilter)->pf_vout_buffer_del = video_del_buffer_filter; 
     397        (*pp_vfilter)->fmt_in = p_sys->p_decoder->fmt_out; 
     398        if( p_sys->i_chroma ) 
     399            (*pp_vfilter)->fmt_in.video.i_chroma = p_sys->i_chroma; 
     400        (*pp_vfilter)->fmt_out = (*pp_vfilter)->fmt_in; 
     401        (*pp_vfilter)->p_cfg = p_cfg; 
     402        (*pp_vfilter)->p_module = 
     403            module_Need( *pp_vfilter, "video filter2", psz_name, VLC_TRUE ); 
     404        if( (*pp_vfilter)->p_module ) 
     405        { 
     406            /* It worked! */ 
     407            (*pp_vfilter)->p_owner = (filter_owner_sys_t *) 
     408                p_sys->p_decoder->p_owner; 
     409            msg_Err( p_stream, "Added video filter %s to the chain", 
     410                     psz_name ); 
     411        } 
     412        else 
     413        { 
     414            /* Crap ... we didn't find a filter */ 
     415            msg_Warn( p_stream, 
     416                      "no video filter matching name \"%s\" found", 
     417                      psz_name ); 
     418            vlc_object_detach( *pp_vfilter ); 
     419            vlc_object_destroy( *pp_vfilter ); 
     420            p_sys->i_vfilters--; 
     421        } 
     422        //if( psz_parser && *psz_parser ) psz_parser++; 
     423        printf("\n\npsz_parser: %s\n\n", psz_parser ); 
     424    } 
     425    free( psz_chain ); 
     426 
    378427    return (sout_stream_id_t *)p_sys; 
    379428} 
     
    385434    bridged_es_t *p_es; 
    386435    vlc_bool_t b_last_es = VLC_TRUE; 
     436    filter_t **pp_vfilter, **pp_end; 
    387437    int i; 
    388438 
     
    413463    } 
    414464 
     465    /* Destroy user specified video filters */ 
     466    pp_vfilter = p_sys->pp_vfilters; 
     467    pp_end = pp_vfilter + p_sys->i_vfilters; 
     468    for( ; pp_vfilter < pp_end; pp_vfilter++ ) 
     469    { 
     470        vlc_object_detach( *pp_vfilter ); 
     471        if( (*pp_vfilter)->p_module ) 
     472            module_Unneed( *pp_vfilter, (*pp_vfilter)->p_module ); 
     473        vlc_object_destroy( *pp_vfilter ); 
     474    } 
     475    free( p_sys->pp_vfilters ); 
     476 
    415477    vlc_mutex_lock( p_sys->p_lock ); 
    416478 
     
    499561            fmt_in = p_sys->p_decoder->fmt_out.video; 
    500562 
    501             if( p_sys->p_mask ) 
    502             { 
    503                 vlc_mutex_lock( &p_sys->mask_lock ); 
    504                 fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A'); 
    505             } 
     563 
     564            if( p_sys->i_chroma ) 
     565                fmt_out.i_chroma = p_sys->i_chroma; 
    506566            else 
    507567                fmt_out.i_chroma = VLC_FOURCC('I','4','2','0'); 
     
    536596                continue; 
    537597            } 
    538  
    539             if( p_sys->p_mask ) 
    540             { 
    541                 plane_t *p_mask = p_sys->p_mask->p+A_PLANE; 
    542                 plane_t *p_apic = p_new_pic->p+A_PLANE; 
    543                 if(    p_mask->i_visible_pitch 
    544                     != p_apic->i_visible_pitch 
    545                     || p_mask->i_visible_lines 
    546                     != p_apic->i_visible_lines ) 
    547                 { 
    548                     msg_Warn( p_stream, 
    549                               "Mask size (%d x %d) and image size (%d x %d) " 
    550                               "don't match. The mask will not be applied.", 
    551                               p_mask->i_visible_pitch, 
    552                               p_mask->i_visible_lines, 
    553                               p_apic->i_visible_pitch, 
    554                               p_apic->i_visible_lines ); 
    555                 } 
    556                 else 
    557                 { 
    558                     if( p_mask->i_pitch != p_apic->i_pitch 
    559                     ||  p_mask->i_lines != p_apic->i_lines ) 
    560                     { 
    561                         /* visible plane sizes match ... but not the undelying 
    562                          * buffer. I'm not sure that this can happen, 
    563                          * but better safe than sorry. */ 
    564                         int i_line; 
    565                         int i_lines = p_mask->i_visible_lines; 
    566                         uint8_t *p_src = p_mask->p_pixels; 
    567                         uint8_t *p_dst = p_apic->p_pixels; 
    568                         int i_src_pitch = p_mask->i_pitch; 
    569                         int i_dst_pitch = p_apic->i_pitch; 
    570                         int i_visible_pitch = p_mask->i_visible_pitch; 
    571                         for( i_line = 0; i_line < i_lines; i_line++, 
    572                              p_src += i_src_pitch, p_dst += i_dst_pitch ) 
    573                         { 
    574                             p_stream->p_libvlc->pf_memcpy( 
    575                                 p_dst, p_src, i_visible_pitch ); 
    576                         } 
    577                     } 
    578                     else 
    579                     { 
    580                         /* plane sizes match */ 
    581                         p_stream->p_libvlc->pf_memcpy( 
    582                             p_apic->p_pixels, p_mask->p_pixels, 
    583                             p_mask->i_pitch * p_mask->i_lines ); 
    584                     } 
    585                 } 
    586                 vlc_mutex_unlock( &p_sys->mask_lock ); 
    587             } 
    588598        } 
    589599        else 
    590600        { 
    591601            p_new_pic = (picture_t*)malloc( sizeof(picture_t) ); 
     602            /* TODO: chroma conversion if needed */ 
    592603            vout_AllocatePicture( p_stream, p_new_pic, p_pic->format.i_chroma, 
    593604                                  p_pic->format.i_width, p_pic->format.i_height, 
     
    603614        p_new_pic->pf_release = ReleasePicture; 
    604615        p_new_pic->date = p_pic->date; 
    605  
    606616        p_pic->pf_release( p_pic ); 
     617 
     618        if( p_sys->pp_vfilters ) 
     619        { 
     620            /* Apply user specified video filters */ 
     621            filter_t **pp_vfilter = p_sys->pp_vfilters; 
     622            filter_t **pp_end = pp_vfilter + p_sys->i_vfilters; 
     623            for( ; pp_vfilter < pp_end; pp_vfilter++ ) 
     624            { 
     625                (*pp_vfilter)->fmt_in.i_codec = p_new_pic->format.i_chroma; 
     626                (*pp_vfilter)->fmt_out.i_codec = p_new_pic->format.i_chroma; 
     627                (*pp_vfilter)->fmt_in.video = p_new_pic->format; 
     628                (*pp_vfilter)->fmt_out.video = p_new_pic->format; 
     629                p_new_pic = (*pp_vfilter)->pf_video_filter( *pp_vfilter, 
     630                                                             p_new_pic ); 
     631                if( !p_new_pic ) 
     632                { 
     633                    msg_Err( p_stream, "video filter failed" ); 
     634                    break; 
     635                } 
     636            } 
     637            if( !p_new_pic ) continue; 
     638        } 
     639 
    607640        PushPicture( p_stream, p_new_pic ); 
    608641    } 
     
    617650}; 
    618651 
    619 static void video_release_buffer( picture_t *p_pic ) 
     652static void video_release_buffer_decoder( picture_t *p_pic ) 
    620653{ 
    621654    if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys ) 
    622655    { 
    623         video_del_buffer( (decoder_t *)p_pic->p_sys->p_owner, p_pic ); 
     656        video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic ); 
    624657    } 
    625658    else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--; 
    626659} 
    627660 
    628 static picture_t *video_new_buffer( decoder_t *p_dec ) 
    629 
    630     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner; 
    631     picture_t **pp_ring = p_dec->p_owner->pp_pics; 
     661static void video_release_buffer_filter( picture_t *p_pic ) 
     662
     663    if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys ) 
     664    { 
     665        video_del_buffer_filter( (filter_t *)p_pic->p_sys->p_owner, p_pic ); 
     666    } 
     667    else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--; 
     668
     669 
     670inline static picture_t *video_new_buffer_decoder( decoder_t *p_dec ) 
     671
     672    return video_new_buffer( VLC_OBJECT( p_dec ), 
     673                             (decoder_owner_sys_t *)p_dec->p_owner, 
     674                             &p_dec->fmt_out, 
     675                             video_release_buffer_decoder ); 
     676
     677 
     678inline static picture_t *video_new_buffer_filter( filter_t *p_filter ) 
     679
     680    return video_new_buffer( VLC_OBJECT( p_filter ), 
     681                             (decoder_owner_sys_t *)p_filter->p_owner, 
     682                             &p_filter->fmt_out, 
     683                             video_release_buffer_filter ); 
     684
     685 
     686static picture_t *video_new_buffer( vlc_object_t *p_this, 
     687                                    decoder_owner_sys_t *p_sys, 
     688                                    es_format_t *fmt_out, 
     689                                    void ( *pf_release )( picture_t * ) ) 
     690
     691    picture_t **pp_ring = p_sys->pp_pics; 
    632692    picture_t *p_pic; 
    633693    int i; 
    634694 
    635     if( p_dec->fmt_out.video.i_width != p_sys->video.i_width || 
    636         p_dec->fmt_out.video.i_height != p_sys->video.i_height || 
    637         p_dec->fmt_out.video.i_chroma != p_sys->video.i_chroma || 
    638         p_dec->fmt_out.video.i_aspect != p_sys->video.i_aspect ) 
    639     { 
    640         if( !p_dec->fmt_out.video.i_sar_num || 
    641             !p_dec->fmt_out.video.i_sar_den ) 
    642         { 
    643             p_dec->fmt_out.video.i_sar_num = 
    644               p_dec->fmt_out.video.i_aspect * p_dec->fmt_out.video.i_height; 
    645  
    646             p_dec->fmt_out.video.i_sar_den = VOUT_ASPECT_FACTOR * 
    647               p_dec->fmt_out.video.i_width; 
    648         } 
    649  
    650         vlc_ureduce( &p_dec->fmt_out.video.i_sar_num, 
    651                      &p_dec->fmt_out.video.i_sar_den, 
    652                      p_dec->fmt_out.video.i_sar_num, 
    653                      p_dec->fmt_out.video.i_sar_den, 0 ); 
    654  
    655         if( !p_dec->fmt_out.video.i_visible_width || 
    656             !p_dec->fmt_out.video.i_visible_height ) 
    657         { 
    658             p_dec->fmt_out.video.i_visible_width = 
    659                 p_dec->fmt_out.video.i_width; 
    660             p_dec->fmt_out.video.i_visible_height = 
    661                 p_dec->fmt_out.video.i_height; 
    662         } 
    663  
    664         p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec; 
    665         p_sys->video = p_dec->fmt_out.video; 
     695    if( fmt_out->video.i_width != p_sys->video.i_width || 
     696        fmt_out->video.i_height != p_sys->video.i_height || 
     697        fmt_out->video.i_chroma != p_sys->video.i_chroma || 
     698        fmt_out->video.i_aspect != p_sys->video.i_aspect ) 
     699    { 
     700        if( !fmt_out->video.i_sar_num || 
     701            !fmt_out->video.i_sar_den ) 
     702        { 
     703            fmt_out->video.i_sar_num = 
     704                fmt_out->video.i_aspect * fmt_out->video.i_height; 
     705 
     706            fmt_out->video.i_sar_den = 
     707                VOUT_ASPECT_FACTOR * fmt_out->video.i_width; 
     708        } 
     709 
     710        vlc_ureduce( &fmt_out->video.i_sar_num, 
     711                     &fmt_out->video.i_sar_den, 
     712                     fmt_out->video.i_sar_num, 
     713                     fmt_out->video.i_sar_den, 0 ); 
     714 
     715        if( !fmt_out->video.i_visible_width || 
     716            !fmt_out->video.i_visible_height ) 
     717        { 
     718            fmt_out->video.i_visible_width = fmt_out->video.i_width; 
     719            fmt_out->video.i_visible_height = fmt_out->video.i_height; 
     720        } 
     721 
     722        fmt_out->video.i_chroma = fmt_out->i_codec; 
     723        p_sys->video = fmt_out->video; 
    666724 
    667725        for( i = 0; i < PICTURE_RING_SIZE; i++ ) 
     
    701759    if( i == PICTURE_RING_SIZE ) 
    702760    { 
    703         msg_Err( p_dec, "decoder/filter is leaking pictures, " 
     761        msg_Err( p_this, "decoder/filter is leaking pictures, " 
    704762                 "resetting its ring buffer" ); 
    705763 
     
    713771 
    714772    p_pic = malloc( sizeof(picture_t) ); 
    715     p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec; 
    716     vout_AllocatePicture( VLC_OBJECT(p_dec), p_pic, 
    717                           p_dec->fmt_out.video.i_chroma, 
    718                           p_dec->fmt_out.video.i_width, 
    719                           p_dec->fmt_out.video.i_height, 
    720                           p_dec->fmt_out.video.i_aspect ); 
     773    fmt_out->video.i_chroma = fmt_out->i_codec; 
     774    vout_AllocatePicture( p_this, p_pic, 
     775                          fmt_out->video.i_chroma, 
     776                          fmt_out->video.i_width, 
     777                          fmt_out->video.i_height, 
     778                          fmt_out->video.i_aspect ); 
    721779 
    722780    if( !p_pic->i_planes ) 
     
    726784    } 
    727785 
    728     p_pic->pf_release = video_release_buffer
     786    p_pic->pf_release = pf_release
    729787    p_pic->p_sys = malloc( sizeof(picture_sys_t) ); 
    730     p_pic->p_sys->p_owner = VLC_OBJECT(p_dec)
     788    p_pic->p_sys->p_owner = p_this
    731789    p_pic->p_sys->b_dead = VLC_FALSE; 
    732790    p_pic->i_status = RESERVED_PICTURE; 
     
    737795} 
    738796 
    739 static void video_del_buffer( decoder_t *p_this, picture_t *p_pic ) 
     797inline static void video_del_buffer_decoder( decoder_t *p_this, 
     798                                             picture_t *p_pic ) 
     799
     800    video_del_buffer( VLC_OBJECT( p_this ), p_pic ); 
     801
     802 
     803inline static void video_del_buffer_filter( filter_t *p_this, 
     804                                            picture_t *p_pic ) 
     805
     806    video_del_buffer( VLC_OBJECT( p_this ), p_pic ); 
     807
     808 
     809static void video_del_buffer( vlc_object_t *p_this, picture_t *p_pic ) 
    740810{ 
    741811    p_pic->i_refcount = 0; 
     
    757827static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic ) 
    758828{ 
    759     video_release_buffer( p_pic ); 
     829    video_release_buffer_decoder( p_pic ); 
    760830} 
    761831 
     
    772842    int i_ret = VLC_SUCCESS; 
    773843 
    774 #define VAR_IS( a ) !strcmp( psz_var, SOUT_CFG_PREFIX a ) 
    775     if( VAR_IS( "mask" ) ) 
    776     { 
    777         vlc_mutex_lock( &p_sys->mask_lock ); 
    778         if( newval.psz_string && *newval.psz_string ) 
    779         { 
    780             LoadMask( p_stream, newval.psz_string ); 
    781             if( !p_sys->p_mask ) 
    782             { 
    783                 msg_Err( p_stream, "Error while loading mask (%s).", 
    784                          newval.psz_string ); 
    785                 i_ret = VLC_EGENERIC; 
    786             } 
    787         } 
    788         else if( p_sys->p_mask ) 
    789         { 
    790             p_sys->p_mask->pf_release( p_sys->p_mask ); 
    791             p_sys->p_mask = NULL; 
    792         } 
    793         vlc_mutex_unlock( &p_sys->mask_lock ); 
    794     } 
    795     else if( VAR_IS( "height" ) ) 
     844#define VAR_IS( a ) !strcmp( psz_var, CFG_PREFIX a ) 
     845    if( VAR_IS( "height" ) ) 
    796846    { 
    797847        /* We create the handler before updating the value in p_sys 
  • modules/video_filter/Modules.am

    ref8b4b0 rce0e4fb  
    3131SOURCES_sharpen = sharpen.c 
    3232SOURCES_erase = erase.c 
     33SOURCES_bluescreen = bluescreen.c 
     34SOURCES_alphamask = alphamask.c 
    3335noinst_HEADERS = filter_common.h 
  • modules/video_filter/invert.c

    rd3fe7f2 rce0e4fb  
    109109    picture_t *p_outpic; 
    110110    int i_index; 
     111    int i_planes; 
    111112 
    112113    if( !p_pic ) return NULL; 
     
    121122    } 
    122123 
    123     for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) 
     124    if( p_pic->format.i_chroma == VLC_FOURCC('Y','U','V','A') ) 
     125    { 
     126        /* We don't want to invert the alpha plane */ 
     127        i_planes = p_pic->i_planes - 1; 
     128        p_filter->p_libvlc->pf_memcpy( 
     129            p_outpic->p[A_PLANE].p_pixels, p_pic->p[A_PLANE].p_pixels, 
     130            p_pic->p[A_PLANE].i_pitch *  p_pic->p[A_PLANE].i_lines ); 
     131    } 
     132    else 
     133    { 
     134        i_planes = p_pic->i_planes; 
     135    } 
     136 
     137    for( i_index = 0 ; i_index < i_planes ; i_index++ ) 
    124138    { 
    125139        uint8_t *p_in, *p_in_end, *p_line_end, *p_out; 
  • modules/video_filter/mosaic.c

    r2ece18d rce0e4fb  
    22 * mosaic.c : Mosaic video plugin for vlc 
    33 ***************************************************************************** 
    4  * Copyright (C) 2004-2005 the VideoLAN team 
     4 * Copyright (C) 2004-2007 the VideoLAN team 
    55 * $Id$ 
    66 * 
     
    5050static int  CreateFilter    ( vlc_object_t * ); 
    5151static void DestroyFilter   ( vlc_object_t * ); 
    52  
    53 static subpicture_t *Filter( filter_t *, mtime_t ); 
    54  
    55 static int MosaicCallback( vlc_object_t *, char const *, vlc_value_t, 
    56                            vlc_value_t, void * ); 
     52static subpicture_t *Filter ( filter_t *, mtime_t ); 
     53 
     54static int MosaicCallback   ( vlc_object_t *, char const *, vlc_value_t, 
     55                              vlc_value_t, void * ); 
    5756 
    5857/***************************************************************************** 
     
    6160struct filter_sys_t 
    6261{ 
    63     vlc_mutex_t lock; 
    64     vlc_mutex_t *p_lock; 
     62    vlc_mutex_t lock;         /* Internal filter lock */ 
     63    vlc_mutex_t *p_lock;      /* Pointer to mosaic bridge lock */ 
    6564 
    6665    image_handler_t *p_image; 
    67     picture_t *p_pic; 
    68  
    69     int i_position; /* mosaic positioning method */ 
    70     vlc_bool_t b_ar; /* do we keep the aspect ratio ? */ 
    71     vlc_bool_t b_keep; /* do we keep the original picture format ? */ 
    72     int i_width, i_height; /* mosaic height and width */ 
    73     int i_cols, i_rows; /* mosaic rows and cols */ 
    74     int i_align; /* mosaic alignment in background video */ 
    75     int i_xoffset, i_yoffset; /* top left corner offset */ 
    76     int i_borderw, i_borderh; /* border width/height between miniatures */ 
    77     int i_alpha; /* subfilter alpha blending */ 
    78  
    79     vlc_bool_t b_bs; /* Bluescreen vars */ 
    80     int i_bsu, i_bsv, i_bsut, i_bsvt; 
    81  
    82     char **ppsz_order; /* list of picture-id */ 
     66 
     67    int i_position;           /* Mosaic positioning method */ 
     68    vlc_bool_t b_ar;          /* Do we keep the aspect ratio ? */ 
     69    vlc_bool_t b_keep;        /* Do we keep the original picture format ? */ 
     70    int i_width, i_height;    /* Mosaic height and width */ 
     71    int i_cols, i_rows;       /* Mosaic rows and cols */ 
     72    int i_align;              /* Mosaic alignment in background video */ 
     73    int i_xoffset, i_yoffset; /* Top left corner offset */ 
     74    int i_borderw, i_borderh; /* Border width/height between miniatures */ 
     75    int i_alpha;              /* Subfilter alpha blending */ 
     76 
     77    char **ppsz_order;        /* List of picture-ids */ 
    8378    int i_order_length; 
    8479 
    85     int *pi_x_offsets; /* list of substreams x offsets */ 
    86     int *pi_y_offsets; /* list of substreams y offsets */ 
     80    int *pi_x_offsets;        /* List of substreams x offsets */ 
     81    int *pi_y_offsets;        /* List of substreams y offsets */ 
    8782    int i_offsets_length; 
    8883 
     
    166161        "values you will need to raise caching at input.") 
    167162 
    168 #define BLUESCREEN_TEXT N_("Bluescreen" ) 
    169 #define BLUESCREEN_LONGTEXT N_( \ 
    170         "This effect, also known as \"greenscreen\" or \"chroma key\" blends " \ 
    171         "the \"blue parts\" of the foreground images of the mosaic on the " \ 
    172         "background (like weather forecast). You can choose the \"key\" " \ 
    173         "color for blending (blue by default)." ) 
    174  
    175 #define BLUESCREENU_TEXT N_("Bluescreen U value") 
    176 #define BLUESCREENU_LONGTEXT N_( \ 
    177         "\"U\" value for the bluescreen key color " \ 
    178         "(in YUV values). From 0 to 255. Defaults to 120 for blue." ) 
    179 #define BLUESCREENV_TEXT N_("Bluescreen V value") 
    180 #define BLUESCREENV_LONGTEXT N_( \ 
    181         "\"V\" value for the bluescreen key color " \ 
    182         "(in YUV values). From 0 to 255. Defaults to 90 for blue." ) 
    183 #define BLUESCREENUTOL_TEXT N_("Bluescreen U tolerance") 
    184 #define BLUESCREENUTOL_LONGTEXT N_( \ 
    185         "Tolerance of the bluescreen blender " \ 
    186         "on color variations for the U plane. A value between 10 and 20 " \ 
    187         "seems sensible." ) 
    188 #define BLUESCREENVTOL_TEXT N_("Bluescreen V tolerance") 
    189 #define BLUESCREENVTOL_LONGTEXT N_( \ 
    190         "Tolerance of the bluescreen blender " \ 
    191         "on color variations for the V plane. A value between 10 and 20 " \ 
    192         "seems sensible." ) 
    193  
     163enum 
     164
     165    position_auto = 0, position_fixed = 1, position_offsets = 2 
     166}; 
    194167static int pi_pos_values[] = { 0, 1, 2 }; 
    195 static const char * ppsz_pos_descriptions[] = 
    196 { N_("auto"), N_("fixed"), N_("offsets") }; 
     168static const char *ppsz_pos_descriptions[] = 
     169    { N_("auto"), N_("fixed"), N_("offsets") }; 
    197170 
    198171static int pi_align_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 }; 
     
    257230                 VLC_FALSE ); 
    258231 
    259     set_section( N_("Bluescreen effect"), NULL ); 
    260     add_bool( CFG_PREFIX "bs", 0, NULL, BLUESCREEN_TEXT, 
    261               BLUESCREEN_LONGTEXT, VLC_FALSE ); 
    262     add_integer_with_range( CFG_PREFIX "bsu", 120, 0, 255, NULL, 
    263                             BLUESCREENU_TEXT, BLUESCREENU_LONGTEXT, VLC_FALSE ); 
    264     add_integer_with_range( CFG_PREFIX "bsv", 90, 0, 255, NULL, 
    265                             BLUESCREENV_TEXT, BLUESCREENV_LONGTEXT, VLC_FALSE ); 
    266     add_integer_with_range( CFG_PREFIX "bsut", 17, 0, 255, NULL, 
    267                             BLUESCREENUTOL_TEXT, BLUESCREENUTOL_LONGTEXT, 
    268                             VLC_FALSE ); 
    269     add_integer_with_range( CFG_PREFIX "bsvt", 17, 0, 255, NULL, 
    270                             BLUESCREENVTOL_TEXT, BLUESCREENVTOL_LONGTEXT, 
    271                             VLC_FALSE ); 
    272  
    273232    var_Create( p_module->p_libvlc_global, "mosaic-lock", VLC_VAR_MUTEX ); 
    274233vlc_module_end(); 
     
    278237    "borderw", "borderh", "position", "rows", "cols", 
    279238    "keep-aspect-ratio", "keep-picture", "order", "offsets", 
    280     "delay", "bs", "bsu", "bsv", "bsut", "bsvt", NULL 
     239    "delay", NULL 
    281240}; 
    282241 
     
    286245 * and set the corresponding struct filter_sys_t entries. 
    287246 *****************************************************************************/ 
    288 static void mosaic_ParseSetOffsets( vlc_object_t *p_this, filter_sys_t *p_sys, char *psz_offsets ) 
     247#define mosaic_ParseSetOffsets( a, b, c ) \ 
     248      __mosaic_ParseSetOffsets( VLC_OBJECT( a ), b, c ) 
     249static void __mosaic_ParseSetOffsets( vlc_object_t *p_this, 
     250                                      filter_sys_t *p_sys, 
     251                                      char *psz_offsets ) 
    289252{ 
    290     if( psz_offsets[0] != 0
     253    if( *psz_offsets
    291254    { 
    292255        char *psz_end = NULL; 
     
    296259            i_index++; 
    297260 
    298             p_sys->pi_x_offsets = realloc( p_sys->pi_x_offsets, i_index * sizeof(int) ); 
     261            p_sys->pi_x_offsets = 
     262                realloc( p_sys->pi_x_offsets, i_index * sizeof(int) ); 
    299263            p_sys->pi_x_offsets[i_index - 1] = atoi( psz_offsets ); 
    300264            psz_end = strchr( psz_offsets, ',' ); 
    301265            psz_offsets = psz_end + 1; 
    302266 
    303             p_sys->pi_y_offsets = realloc( p_sys->pi_y_offsets, i_index * sizeof(int) ); 
     267            p_sys->pi_y_offsets = 
     268                realloc( p_sys->pi_y_offsets, i_index * sizeof(int) ); 
    304269            p_sys->pi_y_offsets[i_index - 1] = atoi( psz_offsets ); 
    305270            psz_end = strchr( psz_offsets, ',' ); 
    306271            psz_offsets = psz_end + 1; 
    307272 
    308             msg_Dbg( p_this, CFG_PREFIX "offset: id %d, x=%d, y=%d", i_index, p_sys->pi_x_offsets[i_index - 1], p_sys->pi_y_offsets[i_index - 1] ); 
    309  
    310         } while( NULL != psz_end ); 
     273            msg_Dbg( p_this, CFG_PREFIX "offset: id %d, x=%d, y=%d", 
     274                     i_index, p_sys->pi_x_offsets[i_index - 1], 
     275                              p_sys->pi_y_offsets[i_index - 1]  ); 
     276 
     277        } while( psz_end ); 
    311278        p_sys->i_offsets_length = i_index; 
    312279    } 
     
    338305 
    339306    p_filter->pf_sub_filter = Filter; 
    340     p_sys->p_pic = NULL; 
    341307 
    342308    vlc_mutex_init( p_filter, &p_sys->lock ); 
     
    377343                     p_sys ); 
    378344 
    379     p_sys->b_keep = var_CreateGetBool( p_filter, CFG_PREFIX "keep-picture" ); 
     345    p_sys->b_keep = var_CreateGetBoolCommand( p_filter, 
     346                                              CFG_PREFIX "keep-picture" ); 
    380347    if ( !p_sys->b_keep ) 
    381348    { 
     
    388355    var_AddCallback( p_filter, CFG_PREFIX "order", MosaicCallback, p_sys ); 
    389356 
    390     if( psz_order[0] != 0
     357    if( *psz_order
    391358    { 
    392359        char *psz_end = NULL; 
     
    401368                                           psz_end - psz_order ); 
    402369            psz_order = psz_end+1; 
    403         } while( NULL !=  psz_end ); 
     370        } while( psz_end ); 
    404371        p_sys->i_order_length = i_index; 
    405372    } 
     
    410377    p_sys->pi_x_offsets = NULL; 
    411378    p_sys->pi_y_offsets = NULL; 
    412     mosaic_ParseSetOffsets( (vlc_object_t *) p_filter, p_sys, psz_offsets ); 
     379    mosaic_ParseSetOffsets( p_filter, p_sys, psz_offsets ); 
    413380    var_AddCallback( p_filter, CFG_PREFIX "offsets", MosaicCallback, p_sys ); 
    414  
    415     /* Bluescreen specific stuff */ 
    416     GET_VAR( bsu, 0x00, 0xff ); 
    417     GET_VAR( bsv, 0x00, 0xff ); 
    418     GET_VAR( bsut, 0x00, 0xff ); 
    419     GET_VAR( bsvt, 0x00, 0xff ); 
    420     p_sys->b_bs = var_CreateGetBoolCommand( p_filter, CFG_PREFIX "bs" ); 
    421     var_AddCallback( p_filter, CFG_PREFIX "bs", MosaicCallback, p_sys ); 
    422     if( p_sys->b_bs && p_sys->b_keep ) 
    423     { 
    424         msg_Warn( p_filter, CFG_PREFIX "keep-picture needs to be disabled for" 
    425                             " bluescreen to work" ); 
    426     } 
    427381 
    428382    vlc_mutex_unlock( &p_sys->lock ); 
     
    462416        p_sys->i_offsets_length = 0; 
    463417    } 
    464     var_Destroy( p_libvlc_global, CFG_PREFIX "offsets" ); 
    465     var_Destroy( p_libvlc_global, CFG_PREFIX "alpha" ); 
    466     var_Destroy( p_libvlc_global, CFG_PREFIX "height" ); 
    467     var_Destroy( p_libvlc_global, CFG_PREFIX "align" ); 
    468     var_Destroy( p_libvlc_global, CFG_PREFIX "width" ); 
    469     var_Destroy( p_libvlc_global, CFG_PREFIX "xoffset" ); 
    470     var_Destroy( p_libvlc_global, CFG_PREFIX "yoffset" ); 
    471     var_Destroy( p_libvlc_global, CFG_PREFIX "vborder" ); 
    472     var_Destroy( p_libvlc_global, CFG_PREFIX "hborder" ); 
    473     var_Destroy( p_libvlc_global, CFG_PREFIX "position" ); 
    474     var_Destroy( p_libvlc_global, CFG_PREFIX "rows" ); 
    475     var_Destroy( p_libvlc_global, CFG_PREFIX "cols" ); 
    476     var_Destroy( p_libvlc_global, CFG_PREFIX "keep-aspect-ratio" ); 
    477  
    478     var_Destroy( p_libvlc_global, CFG_PREFIX "bsu" ); 
    479     var_Destroy( p_libvlc_global, CFG_PREFIX "bsv" ); 
    480     var_Destroy( p_libvlc_global, CFG_PREFIX "bsut" ); 
    481     var_Destroy( p_libvlc_global, CFG_PREFIX "bsvt" ); 
    482     var_Destroy( p_libvlc_global, CFG_PREFIX "bs" ); 
    483  
    484     if( p_sys->p_pic ) p_sys->p_pic->pf_release( p_sys->p_pic ); 
     418 
    485419    vlc_mutex_unlock( &p_sys->lock ); 
    486420    vlc_mutex_destroy( &p_sys->lock ); 
     
    543477    } 
    544