Changeset deef7f86ffe121398d3c86ab828e29a621dbad9d

Show
Ignore:
Timestamp:
06/22/08 16:58:22 (3 months ago)
Author:
Antoine Cellerier <dionoea@videolan.org>
git-committer:
Antoine Cellerier <dionoea@videolan.org> 1214146702 +0200
git-parent:

[e2499dc3873f07fc916f292187c07d0eff74061c]

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

Add support for format changes inside a video filter2 chain. (Not sure
if something similar is needed for audio filter2 ... I don't think it
is)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/misc/filter_chain.c

    rc0b61e8 rdeef7f8  
    4242 
    4343/** 
     44 * Local prototypes 
     45 */ 
     46static filter_t *filter_chain_AppendFilterInternal( filter_chain_t *, const char *, config_chain_t *, const es_format_t *, const es_format_t * ); 
     47static int filter_chain_AppendFromStringInternal( filter_chain_t *, const char * ); 
     48static int filter_chain_DeleteFilterInternal( filter_chain_t *, filter_t * ); 
     49 
     50static int UpdateBufferFunctions( filter_chain_t * ); 
     51static picture_t *VideoBufferNew( filter_t * ); 
     52static void VideoBufferRelease( picture_t * ); 
     53 
     54/** 
    4455 * Filter chain initialisation 
    4556 */ 
     
    7990{ 
    8091    while( p_chain->filters.i_count ) 
    81         filter_chain_DeleteFilter( p_chain, 
     92        filter_chain_DeleteFilterInternal( p_chain, 
    8293                                   (filter_t*)p_chain->filters.pp_elems[0] ); 
    8394    vlc_array_clear( &p_chain->filters ); 
     
    94105{ 
    95106    while( p_chain->filters.i_count ) 
    96         filter_chain_DeleteFilter( p_chain, 
     107        filter_chain_DeleteFilterInternal( p_chain, 
    97108                                   (filter_t*)p_chain->filters.pp_elems[0] ); 
    98109    if( p_fmt_in ) 
     
    112123 * Modifying the filter chain 
    113124 */ 
    114 filter_t *filter_chain_AppendFilter( filter_chain_t *p_chain, 
    115                                      const char *psz_name, 
    116                                      config_chain_t *p_cfg, 
    117                                      const es_format_t *p_fmt_in, 
    118                                      const es_format_t *p_fmt_out ) 
     125static filter_t *filter_chain_AppendFilterInternal( filter_chain_t *p_chain, 
     126                                                    const char *psz_name, 
     127                                                    config_chain_t *p_cfg, 
     128                                                    const es_format_t *p_fmt_in, 
     129                                                    const es_format_t *p_fmt_out ) 
    119130{ 
    120131    filter_t *p_filter = 
     
    176187} 
    177188 
    178 int filter_chain_AppendFromString( filter_chain_t *p_chain, 
    179                                    const char *psz_string ) 
     189filter_t *filter_chain_AppendFilter( filter_chain_t *p_chain, 
     190                                     const char *psz_name, 
     191                                     config_chain_t *p_cfg, 
     192                                     const es_format_t *p_fmt_in, 
     193                                     const es_format_t *p_fmt_out ) 
     194
     195    filter_t *p_filter = filter_chain_AppendFilterInternal( p_chain, psz_name, 
     196                                                            p_cfg, p_fmt_in, 
     197                                                            p_fmt_out ); 
     198    if( UpdateBufferFunctions( p_chain ) < 0 ) 
     199        msg_Err( p_filter, "Woah! This doesn't look good." ); 
     200    return p_filter; 
     201
     202 
     203static int filter_chain_AppendFromStringInternal( filter_chain_t *p_chain, 
     204                                                  const char *psz_string ) 
    180205{ 
    181206    config_chain_t *p_cfg = NULL; 
     
    186211    psz_string = config_ChainCreate( &psz_name, &p_cfg, psz_string ); 
    187212 
    188     filter_t *p_filter = filter_chain_AppendFilter( p_chain, psz_name, p_cfg
    189                                                     NULL, NULL ); 
     213    filter_t *p_filter = filter_chain_AppendFilterInternal( p_chain, psz_name
     214                                                            p_cfg, NULL, NULL ); 
    190215    if( !p_filter ) 
    191216    { 
     
    198223    free( psz_name ); 
    199224 
    200     int ret = filter_chain_AppendFromString( p_chain, psz_string ); 
     225    int ret = filter_chain_AppendFromStringInternal( p_chain, psz_string ); 
    201226    if( ret < 0 ) 
    202227    { 
    203         filter_chain_DeleteFilter( p_chain, p_filter ); 
     228        filter_chain_DeleteFilterInternal( p_chain, p_filter ); 
    204229        return ret; 
    205230    } 
     
    207232} 
    208233 
    209 int filter_chain_DeleteFilter( filter_chain_t *p_chain, filter_t *p_filter ) 
     234int filter_chain_AppendFromString( filter_chain_t *p_chain, 
     235                                   const char *psz_string ) 
     236
     237    int i_ret = filter_chain_AppendFromStringInternal( p_chain, psz_string ); 
     238    if( i_ret < 0 ) return i_ret; 
     239    int i_ret2 = UpdateBufferFunctions( p_chain ); 
     240    if( i_ret2 < 0 ) return i_ret2; 
     241    return i_ret; 
     242
     243 
     244static int filter_chain_DeleteFilterInternal( filter_chain_t *p_chain, 
     245                                              filter_t *p_filter ) 
    210246{ 
    211247    int i; 
     
    238274 
    239275    /* FIXME: check fmt_in/fmt_out consitency */ 
    240  
    241276    return VLC_SUCCESS; 
     277} 
     278 
     279int filter_chain_DeleteFilter( filter_chain_t *p_chain, filter_t *p_filter ) 
     280{ 
     281    int i_ret = filter_chain_DeleteFilterInternal( p_chain, p_filter ); 
     282    if( i_ret < 0 ) return i_ret; 
     283    return UpdateBufferFunctions( p_chain ); 
    242284} 
    243285 
     
    338380    { 
    339381        filter_t *p_filter = pp_filter[i]; 
    340         subpicture_t *p_subpic = p_filter->pf_sub_filter( p_filter, display_date ); 
     382        subpicture_t *p_subpic = p_filter->pf_sub_filter( p_filter, 
     383                                                          display_date ); 
    341384        if( p_subpic ) 
    342385            spu_DisplaySubpicture( (spu_t*)p_chain->p_this, p_subpic ); 
    343386    } 
    344387} 
     388 
     389/** 
     390 * Internal chain buffer handling 
     391 */ 
     392 
     393/** 
     394 * This function should be called after every filter chain change 
     395 */ 
     396static int UpdateBufferFunctions( filter_chain_t *p_chain ) 
     397{ 
     398    if( !strcmp( p_chain->psz_capability, "video filter2" ) ) 
     399    { 
     400        /** 
     401         * Last filter uses the filter chain's parent buffer allocation 
     402         * functions. All the other filters use internal functions. 
     403         * This makes it possible to have format changes between each 
     404         * filter without having to worry about the parent's picture 
     405         * heap format. 
     406         */ 
     407        int i; 
     408        filter_t **pp_filter = (filter_t **)p_chain->filters.pp_elems; 
     409        filter_t *p_filter; 
     410        for( i = 0; i < p_chain->filters.i_count - 1; i++ ) 
     411        { 
     412            p_filter = pp_filter[i]; 
     413            if( p_filter->pf_vout_buffer_new != VideoBufferNew ) 
     414            { 
     415                if( p_chain->pf_buffer_allocation_clear ) 
     416                    p_chain->pf_buffer_allocation_clear( p_filter ); 
     417                p_filter->pf_vout_buffer_new = VideoBufferNew; 
     418                p_filter->pf_vout_buffer_del = NULL; 
     419            } 
     420        } 
     421        if( p_chain->filters.i_count >= 1 ) 
     422        { 
     423            p_filter = pp_filter[i]; 
     424            if( p_filter->pf_vout_buffer_new == VideoBufferNew ) 
     425            { 
     426                p_filter->pf_vout_buffer_new = NULL; 
     427                if( p_chain->pf_buffer_allocation_init( p_filter, 
     428                        p_chain->p_buffer_allocation_data ) != VLC_SUCCESS ) 
     429                    return VLC_EGENERIC; 
     430            } 
     431        } 
     432    } 
     433    return VLC_SUCCESS; 
     434} 
     435 
     436static picture_t *VideoBufferNew( filter_t *p_filter ) 
     437{ 
     438    picture_t *p_pic = malloc( sizeof( picture_t ) ); 
     439    if( !p_pic ) return NULL; 
     440    memset( p_pic, 0, sizeof( picture_t * ) ); 
     441    int i_ret = vout_AllocatePicture( VLC_OBJECT( p_filter ), p_pic, 
     442                                      p_filter->fmt_out.video.i_chroma, 
     443                                      p_filter->fmt_out.video.i_width, 
     444                                      p_filter->fmt_out.video.i_height, 
     445                                      p_filter->fmt_out.video.i_aspect ); 
     446    if( i_ret != VLC_SUCCESS ) 
     447    { 
     448        msg_Err( p_filter, "Failed to allocate picture: %s", 
     449                 vlc_error( i_ret ) ); 
     450        free( p_pic ); 
     451        return NULL; 
     452    } 
     453    p_pic->pf_release = VideoBufferRelease; 
     454    p_pic->i_type = MEMORY_PICTURE; 
     455    p_pic->i_status = RESERVED_PICTURE; 
     456    return p_pic; 
     457} 
     458 
     459static void VideoBufferRelease( picture_t *p_pic ) 
     460{ 
     461    free( p_pic->p_data_orig ); 
     462    free( p_pic ); 
     463}