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

📄 vout_subpictures.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * vout_subpictures.c : subpicture management functions ***************************************************************************** * Copyright (C) 2000-2005 VideoLAN * $Id: vout_subpictures.c 11305 2005-06-05 17:05:20Z gbazin $ * * 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., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h>                                                /* free() */#include <stdio.h>                                              /* sprintf() */#include <string.h>                                            /* strerror() */#include <vlc/vlc.h>#include "vlc_block.h"#include "vlc_video.h"#include "video_output.h"#include "vlc_spu.h"#include "vlc_filter.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 * );struct filter_owner_sys_t{    spu_t *p_spu;    int i_channel;};/** * 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_object_create( p_this, VLC_OBJECT_SPU );    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->i_filter = 0;    p_spu->pf_control = spu_vaControlDefault;    /* Register the default subpicture channel */    p_spu->i_channel = 2;    vlc_mutex_init( p_this, &p_spu->subpicture_lock );    vlc_object_attach( p_spu, p_this );    return p_spu;}/** * Initialise the subpicture unit * * \param p_spu the subpicture unit object */int spu_Init( spu_t *p_spu ){    char *psz_filter, *psz_filter_orig;    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_Get( p_spu, "sub-filter", &val );    psz_filter = psz_filter_orig = val.psz_string;    while( psz_filter && *psz_filter )    {        char *psz_parser = strchr( psz_filter, ':' );        if( psz_parser ) *psz_parser++ = 0;        p_spu->pp_filter[p_spu->i_filter] =            vlc_object_create( p_spu, VLC_OBJECT_FILTER );        vlc_object_attach( p_spu->pp_filter[p_spu->i_filter], p_spu );        p_spu->pp_filter[p_spu->i_filter]->pf_sub_buffer_new = sub_new_buffer;        p_spu->pp_filter[p_spu->i_filter]->pf_sub_buffer_del = sub_del_buffer;        p_spu->pp_filter[p_spu->i_filter]->p_module =            module_Need( p_spu->pp_filter[p_spu->i_filter],                         "sub filter", psz_filter, 0 );        if( p_spu->pp_filter[p_spu->i_filter]->p_module )        {            filter_owner_sys_t *p_sys = malloc( sizeof(filter_owner_sys_t) );            p_spu->pp_filter[p_spu->i_filter]->p_owner = p_sys;            spu_Control( p_spu, SPU_CHANNEL_REGISTER, &p_sys->i_channel );            p_sys->p_spu = p_spu;            p_spu->i_filter++;        }        else        {            msg_Dbg( p_spu, "no sub filter found" );            vlc_object_detach( p_spu->pp_filter[p_spu->i_filter] );            vlc_object_destroy( p_spu->pp_filter[p_spu->i_filter] );        }        if( p_spu->i_filter >= 10 )        {            msg_Dbg( p_spu, "can't add anymore filters" );        }        psz_filter = psz_parser;    }    if( psz_filter_orig ) free( psz_filter_orig );    return VLC_EGENERIC;}/** * 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;    vlc_object_detach( p_spu );    /* 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 )    {        if( p_spu->p_blend->p_module )            module_Unneed( p_spu->p_blend, p_spu->p_blend->p_module );        vlc_object_detach( p_spu->p_blend );        vlc_object_destroy( p_spu->p_blend );    }    if( p_spu->p_text )    {        if( p_spu->p_text->p_module )            module_Unneed( p_spu->p_text, p_spu->p_text->p_module );        vlc_object_detach( p_spu->p_text );        vlc_object_destroy( p_spu->p_text );    }    if( p_spu->p_scale )    {        if( p_spu->p_scale->p_module )            module_Unneed( p_spu->p_scale, p_spu->p_scale->p_module );        vlc_object_detach( p_spu->p_scale );        vlc_object_destroy( p_spu->p_scale );    }    while( p_spu->i_filter-- )    {        module_Unneed( p_spu->pp_filter[p_spu->i_filter],                       p_spu->pp_filter[p_spu->i_filter]->p_module );        free( p_spu->pp_filter[p_spu->i_filter]->p_owner );        vlc_object_detach( p_spu->pp_filter[p_spu->i_filter] );        vlc_object_destroy( p_spu->pp_filter[p_spu->i_filter] );    }    vlc_mutex_destroy( &p_spu->subpicture_lock );    vlc_object_destroy( 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, vlc_bool_t 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 ){    if( p_pic->p_data_orig ) free( p_pic->p_data_orig );}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) );    memset( p_region, 0, sizeof(subpicture_region_t) );    p_region->p_next = 0;    p_region->p_cache = 0;    p_region->fmt = *p_fmt;    p_region->psz_text = 0;    p_region->i_text_color = 0xFFFFFF;    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 = 0;    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) );    memset( p_region, 0, sizeof(subpicture_region_t) );    p_region->p_next = 0;    p_region->p_cache = 0;    p_region->fmt = *p_fmt;    p_region->psz_text = 0;    p_region->i_text_color = 0xFFFFFF;    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 );    if( p_region->fmt.p_palette ) free( p_region->fmt.p_palette );    if( p_region->psz_text ) free( p_region->psz_text );    if( p_region->p_cache ) __spu_DestroyRegion( p_this, p_region->p_cache );    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;    }

⌨️ 快捷键说明

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