⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vout_subpictures.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * vout_subpictures.c : subpicture management functions ***************************************************************************** * Copyright (C) 2000-2007 the VideoLAN team * $Id: f171693c1c3b20eb5e38e9b8716ad4a37c066059 $ * * Authors: Vincent Seguin <seguin@via.ecp.fr> *          Samuel Hocevar <sam@zoy.org> *          Gildas Bazin <gbazin@videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_vout.h>#include <vlc_block.h>#include <vlc_filter.h>#include <vlc_osd.h>#include "../libvlc.h"#include <assert.h>/***************************************************************************** * Local prototypes *****************************************************************************/static void UpdateSPU   ( spu_t *, vlc_object_t * );static int  CropCallback( vlc_object_t *, char const *,                          vlc_value_t, vlc_value_t, void * );static int spu_vaControlDefault( spu_t *, int, va_list );static subpicture_t *sub_new_buffer( filter_t * );static void sub_del_buffer( filter_t *, subpicture_t * );static subpicture_t *spu_new_buffer( filter_t * );static void spu_del_buffer( filter_t *, subpicture_t * );static picture_t *spu_new_video_buffer( filter_t * );static void spu_del_video_buffer( filter_t *, picture_t * );static int spu_ParseChain( spu_t * );static int SubFilterCallback( vlc_object_t *, char const *,                              vlc_value_t, vlc_value_t, void * );static int sub_filter_allocation_init( filter_t *, void * );static void sub_filter_allocation_clear( filter_t * );struct filter_owner_sys_t{    spu_t *p_spu;    int i_channel;};enum {    SCALE_DEFAULT,    SCALE_TEXT,    SCALE_SIZE};static void FilterRelease( filter_t *p_filter ){    if( p_filter->p_module )        module_Unneed( p_filter, p_filter->p_module );    vlc_object_detach( p_filter );    vlc_object_release( p_filter );}/** * Creates the subpicture unit * * \param p_this the parent object which creates the subpicture unit */spu_t *__spu_Create( vlc_object_t *p_this ){    int i_index;    spu_t *p_spu = vlc_custom_create( p_this, sizeof( spu_t ),                                      VLC_OBJECT_GENERIC, "subpicture" );    for( i_index = 0; i_index < VOUT_MAX_SUBPICTURES; i_index++)    {        p_spu->p_subpicture[i_index].i_status = FREE_SUBPICTURE;    }    p_spu->p_blend = NULL;    p_spu->p_text = NULL;    p_spu->p_scale = NULL;    p_spu->p_scale_yuvp = NULL;    p_spu->pf_control = spu_vaControlDefault;    /* Register the default subpicture channel */    p_spu->i_channel = 2;    vlc_mutex_init( &p_spu->subpicture_lock );    vlc_object_attach( p_spu, p_this );    p_spu->p_chain = filter_chain_New( p_spu, "sub filter", false,                                       sub_filter_allocation_init,                                       sub_filter_allocation_clear,                                       p_spu );    return p_spu;}/** * Initialise the subpicture unit * * \param p_spu the subpicture unit object */int spu_Init( spu_t *p_spu ){    vlc_value_t val;    /* If the user requested a sub margin, we force the position. */    var_Create( p_spu, "sub-margin", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    var_Get( p_spu, "sub-margin", &val );    p_spu->i_margin = val.i_int;    var_Create( p_spu, "sub-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );    var_AddCallback( p_spu, "sub-filter", SubFilterCallback, p_spu );    spu_ParseChain( p_spu );    return VLC_SUCCESS;}int spu_ParseChain( spu_t *p_spu ){    char *psz_parser = var_GetString( p_spu, "sub-filter" );    if( filter_chain_AppendFromString( p_spu->p_chain, psz_parser ) < 0 )    {        free( psz_parser );        return VLC_EGENERIC;    }    free( psz_parser );    return VLC_SUCCESS;}/** * Destroy the subpicture unit * * \param p_this the parent object which destroys the subpicture unit */void spu_Destroy( spu_t *p_spu ){    int i_index;    /* Destroy all remaining subpictures */    for( i_index = 0; i_index < VOUT_MAX_SUBPICTURES; i_index++ )    {        if( p_spu->p_subpicture[i_index].i_status != FREE_SUBPICTURE )        {            spu_DestroySubpicture( p_spu, &p_spu->p_subpicture[i_index] );        }    }    if( p_spu->p_blend )        FilterRelease( p_spu->p_blend );    if( p_spu->p_text )        FilterRelease( p_spu->p_text );    if( p_spu->p_scale_yuvp )        FilterRelease( p_spu->p_scale_yuvp );    if( p_spu->p_scale )        FilterRelease( p_spu->p_scale );    filter_chain_Delete( p_spu->p_chain );    vlc_mutex_destroy( &p_spu->subpicture_lock );    vlc_object_release( p_spu );}/** * Attach/Detach the SPU from any input * * \param p_this the object in which to destroy the subpicture unit * \param b_attach to select attach or detach */void spu_Attach( spu_t *p_spu, vlc_object_t *p_this, bool b_attach ){    vlc_object_t *p_input;    p_input = vlc_object_find( p_this, VLC_OBJECT_INPUT, FIND_PARENT );    if( !p_input ) return;    if( b_attach )    {        UpdateSPU( p_spu, VLC_OBJECT(p_input) );        var_AddCallback( p_input, "highlight", CropCallback, p_spu );        vlc_object_release( p_input );    }    else    {        /* Delete callback */        var_DelCallback( p_input, "highlight", CropCallback, p_spu );        vlc_object_release( p_input );    }}/** * Create a subpicture region * * \param p_this vlc_object_t * \param p_fmt the format that this subpicture region should have */static void RegionPictureRelease( picture_t *p_pic ){    free( p_pic->p_data_orig );    /* We use pf_release nullity to know if the picture has already been released. */    p_pic->pf_release = NULL;}subpicture_region_t *__spu_CreateRegion( vlc_object_t *p_this,                                         video_format_t *p_fmt ){    subpicture_region_t *p_region = malloc( sizeof(subpicture_region_t) );    if( !p_region ) return NULL;    memset( p_region, 0, sizeof(subpicture_region_t) );    p_region->i_alpha = 0xff;    p_region->p_next = NULL;    p_region->p_cache = NULL;    p_region->fmt = *p_fmt;    p_region->psz_text = NULL;    p_region->p_style = NULL;    if( p_fmt->i_chroma == VLC_FOURCC('Y','U','V','P') )        p_fmt->p_palette = p_region->fmt.p_palette =            malloc( sizeof(video_palette_t) );    else p_fmt->p_palette = p_region->fmt.p_palette = NULL;    p_region->picture.p_data_orig = NULL;    if( p_fmt->i_chroma == VLC_FOURCC('T','E','X','T') ) return p_region;    vout_AllocatePicture( p_this, &p_region->picture, p_fmt->i_chroma,                          p_fmt->i_width, p_fmt->i_height, p_fmt->i_aspect );    if( !p_region->picture.i_planes )    {        free( p_region );        free( p_fmt->p_palette );        return NULL;    }    p_region->picture.pf_release = RegionPictureRelease;    return p_region;}/** * Make a subpicture region from an existing picture_t * * \param p_this vlc_object_t * \param p_fmt the format that this subpicture region should have * \param p_pic a pointer to the picture creating the region (not freed) */subpicture_region_t *__spu_MakeRegion( vlc_object_t *p_this,                                       video_format_t *p_fmt,                                       picture_t *p_pic ){    subpicture_region_t *p_region = malloc( sizeof(subpicture_region_t) );    (void)p_this;    if( !p_region ) return NULL;    memset( p_region, 0, sizeof(subpicture_region_t) );    p_region->i_alpha = 0xff;    p_region->p_next = 0;    p_region->p_cache = 0;    p_region->fmt = *p_fmt;    p_region->psz_text = 0;    p_region->p_style = NULL;    if( p_fmt->i_chroma == VLC_FOURCC('Y','U','V','P') )        p_fmt->p_palette = p_region->fmt.p_palette =            malloc( sizeof(video_palette_t) );    else p_fmt->p_palette = p_region->fmt.p_palette = NULL;    memcpy( &p_region->picture, p_pic, sizeof(picture_t) );    p_region->picture.pf_release = RegionPictureRelease;    return p_region;}/** * Destroy a subpicture region * * \param p_this vlc_object_t * \param p_region the subpicture region to destroy */void __spu_DestroyRegion( vlc_object_t *p_this, subpicture_region_t *p_region ){    if( !p_region ) return;    if( p_region->picture.pf_release )        p_region->picture.pf_release( &p_region->picture );    free( p_region->fmt.p_palette );    if( p_region->p_cache ) __spu_DestroyRegion( p_this, p_region->p_cache );    free( p_region->psz_text );    free( p_region->psz_html );    //free( p_region->p_style ); FIXME --fenrir plugin does not allocate the memory for it. I think it might lead to segfault, video renderer can live longer than the decoder    free( p_region );}/** * Display a subpicture * * Remove the reservation flag of a subpicture, which will cause it to be * ready for display. * \param p_spu the subpicture unit object * \param p_subpic the subpicture to display */void spu_DisplaySubpicture( spu_t *p_spu, subpicture_t *p_subpic ){    /* Check if status is valid */    if( p_subpic->i_status != RESERVED_SUBPICTURE )    {        msg_Err( p_spu, "subpicture %p has invalid status #%d",                 p_subpic, p_subpic->i_status );    }    /* Remove reservation flag */    p_subpic->i_status = READY_SUBPICTURE;    if( p_subpic->i_channel == DEFAULT_CHAN )    {        p_subpic->i_channel = 0xFFFF;        spu_Control( p_spu, SPU_CHANNEL_CLEAR, DEFAULT_CHAN );        p_subpic->i_channel = DEFAULT_CHAN;    }}/** * Allocate a subpicture in the spu heap. * * This function create a reserved subpicture in the spu heap. * A null pointer is returned if the function fails. This method provides an * already allocated zone of memory in the spu data fields. It needs locking * since several pictures can be created by several producers threads. * \param p_spu the subpicture unit in which to create the subpicture * \return NULL on error, a reserved subpicture otherwise */subpicture_t *spu_CreateSubpicture( spu_t *p_spu ){    int                 i_subpic;                        /* subpicture index */    subpicture_t *      p_subpic = NULL;            /* first free subpicture */    /* Get lock */    vlc_mutex_lock( &p_spu->subpicture_lock );    /*     * Look for an empty place     */    p_subpic = NULL;    for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )    {        if( p_spu->p_subpicture[i_subpic].i_status == FREE_SUBPICTURE )        {            /* Subpicture is empty and ready for allocation */            p_subpic = &p_spu->p_subpicture[i_subpic];            p_spu->p_subpicture[i_subpic].i_status = RESERVED_SUBPICTURE;            break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -