📄 filter_chain.c
字号:
free( psz_name ); int ret = filter_chain_AppendFromStringInternal( p_chain, psz_new_string ); free( psz_new_string ); if( ret < 0 ) { filter_chain_DeleteFilterInternal( p_chain, p_filter ); return ret; } return 1 + ret;}int filter_chain_AppendFromString( filter_chain_t *p_chain, const char *psz_string ){ int i_ret = filter_chain_AppendFromStringInternal( p_chain, psz_string ); if( i_ret < 0 ) return i_ret; int i_ret2 = UpdateBufferFunctions( p_chain ); if( i_ret2 < 0 ) return i_ret2; return i_ret;}static int filter_chain_DeleteFilterInternal( filter_chain_t *p_chain, filter_t *p_filter ){ int i; /* Find the filter in the chain */ for( i = 0; i < p_chain->filters.i_count; i++ ) if( (filter_t*)p_chain->filters.pp_elems[i] == p_filter ) break; /* Oops, filter wasn't found */ if( i == p_chain->filters.i_count ) { msg_Err( p_chain->p_this, "Couldn't find filter '%s' (%p) when trying " "to remove it from chain", p_filter->psz_object_name, p_filter ); return VLC_EGENERIC; } /* Remove it from the chain */ vlc_array_remove( &p_chain->filters, i ); msg_Dbg( p_chain->p_this, "Filter '%s' (%p) removed from chain", p_filter->psz_object_name, p_filter ); /* Destroy the filter object */ if( p_chain->pf_buffer_allocation_clear ) p_chain->pf_buffer_allocation_clear( p_filter ); vlc_object_detach( p_filter ); if( p_filter->p_module ) module_Unneed( p_filter, p_filter->p_module ); vlc_object_release( p_filter ); /* FIXME: check fmt_in/fmt_out consitency */ return VLC_SUCCESS;}int filter_chain_DeleteFilter( filter_chain_t *p_chain, filter_t *p_filter ){ int i_ret = filter_chain_DeleteFilterInternal( p_chain, p_filter ); if( i_ret < 0 ) return i_ret; return UpdateBufferFunctions( p_chain );}/** * Reading from the filter chain */filter_t *filter_chain_GetFilter( filter_chain_t *p_chain, int i_position, const char *psz_name ){ int i; filter_t **pp_filters = (filter_t **)p_chain->filters.pp_elems; if( i_position < 0 ) return NULL; if( !psz_name ) { if( i_position >= p_chain->filters.i_count ) return NULL; return pp_filters[i_position]; } for( i = 0; i < p_chain->filters.i_count; i++ ) { if( !strcmp( psz_name, pp_filters[i]->psz_object_name ) ) i_position--; if( i_position < 0 ) return pp_filters[i]; } return NULL;}int filter_chain_GetLength( filter_chain_t *p_chain ){ return p_chain->filters.i_count;}const es_format_t *filter_chain_GetFmtOut( filter_chain_t *p_chain ){ if( p_chain->b_allow_fmt_out_change ) return &p_chain->fmt_out; /* Unless filter_chain_Reset has been called we are doomed */ if( p_chain->filters.i_count <= 0 ) return &p_chain->fmt_out; /* */ filter_t *p_last = (filter_t*)p_chain->filters.pp_elems[p_chain->filters.i_count-1]; return &p_last->fmt_out;}/** * Apply the filter chain *//* FIXME This include is needed by the Ugly hack */#include <vlc_vout.h>picture_t *filter_chain_VideoFilter( filter_chain_t *p_chain, picture_t *p_pic ){ int i; filter_t **pp_filter = (filter_t **)p_chain->filters.pp_elems; for( i = 0; i < p_chain->filters.i_count; i++ ) { filter_t *p_filter = pp_filter[i]; picture_t *p_newpic = p_filter->pf_video_filter( p_filter, p_pic ); if( !p_newpic ) return NULL; p_pic = p_newpic; } return p_pic;}block_t *filter_chain_AudioFilter( filter_chain_t *p_chain, block_t *p_block ){ int i; filter_t **pp_filter = (filter_t **)p_chain->filters.pp_elems; for( i = 0; i < p_chain->filters.i_count; i++ ) { filter_t *p_filter = pp_filter[i]; p_block = p_filter->pf_audio_filter( p_filter, p_block ); if( !p_block ) return NULL; } return p_block;}#include <vlc_osd.h>void filter_chain_SubFilter( filter_chain_t *p_chain, mtime_t display_date ){ int i; filter_t **pp_filter = (filter_t **)p_chain->filters.pp_elems; for( i = 0; i < p_chain->filters.i_count; i++ ) { filter_t *p_filter = pp_filter[i]; subpicture_t *p_subpic = p_filter->pf_sub_filter( p_filter, display_date ); if( p_subpic ) spu_DisplaySubpicture( (spu_t*)p_chain->p_this, p_subpic ); }}/** * Internal chain buffer handling *//** * This function should be called after every filter chain change */static int UpdateBufferFunctions( filter_chain_t *p_chain ){ if( !strcmp( p_chain->psz_capability, "video filter2" ) ) { /** * Last filter uses the filter chain's parent buffer allocation * functions. All the other filters use internal functions. * This makes it possible to have format changes between each * filter without having to worry about the parent's picture * heap format. */ int i; filter_t **pp_filter = (filter_t **)p_chain->filters.pp_elems; filter_t *p_filter; for( i = 0; i < p_chain->filters.i_count - 1; i++ ) { p_filter = pp_filter[i]; if( p_filter->pf_vout_buffer_new != VideoBufferNew ) { if( p_chain->pf_buffer_allocation_clear ) p_chain->pf_buffer_allocation_clear( p_filter ); p_filter->pf_vout_buffer_new = VideoBufferNew; p_filter->pf_vout_buffer_del = VideoBufferDelete; } } if( p_chain->filters.i_count >= 1 ) { p_filter = pp_filter[i]; if( p_filter->pf_vout_buffer_new == VideoBufferNew ) { p_filter->pf_vout_buffer_new = NULL; p_filter->pf_vout_buffer_del = NULL; if( p_chain->pf_buffer_allocation_init( p_filter, p_chain->p_buffer_allocation_data ) != VLC_SUCCESS ) return VLC_EGENERIC; } } } return VLC_SUCCESS;}static picture_t *VideoBufferNew( filter_t *p_filter ){ const video_format_t *p_fmt = &p_filter->fmt_out.video; picture_t *p_picture = picture_New( p_fmt->i_chroma, p_fmt->i_width, p_fmt->i_height, p_fmt->i_aspect ); if( !p_picture ) msg_Err( p_filter, "Failed to allocate picture\n" ); return p_picture;}static void VideoBufferDelete( filter_t *p_filter, picture_t *p_picture ){ picture_Release( p_picture );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -