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

📄 subsusf.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * subsusf.c : USF subtitles decoder ***************************************************************************** * Copyright (C) 2000-2006 the VideoLAN team * $Id: ff8e3d77113758e888ebe8eabf2728f59f33a439 $ * * Authors: Bernie Purcell <bitmap@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. *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include "subsdec.h"#include <vlc_plugin.h>/***************************************************************************** * Local prototypes *****************************************************************************/static int  OpenDecoder   ( vlc_object_t * );static void CloseDecoder  ( vlc_object_t * );static subpicture_t *DecodeBlock   ( decoder_t *, block_t ** );static char         *CreatePlainText( char * );static int           ParseImageAttachments( decoder_t *p_dec );static subpicture_t        *ParseText     ( decoder_t *, block_t * );static void                 ParseUSFHeader( decoder_t * );static subpicture_region_t *ParseUSFString( decoder_t *, char *, subpicture_t * );static subpicture_region_t *LoadEmbeddedImage( decoder_t *p_dec, subpicture_t *p_spu, const char *psz_filename, int i_transparent_color );/***************************************************************************** * Module descriptor. *****************************************************************************/vlc_module_begin();    set_capability( "decoder", 40 );    set_shortname( N_("USFSubs"));    set_description( N_("USF subtitles decoder") );    set_callbacks( OpenDecoder, CloseDecoder );    set_category( CAT_INPUT );    set_subcategory( SUBCAT_INPUT_SCODEC );    /* We inherit subsdec-align and subsdec-formatted from subsdec.c */vlc_module_end();/***************************************************************************** * OpenDecoder: probe the decoder and return score ***************************************************************************** * Tries to launch a decoder and return score so that the interface is able * to chose. *****************************************************************************/static int OpenDecoder( vlc_object_t *p_this ){    decoder_t     *p_dec = (decoder_t*)p_this;    decoder_sys_t *p_sys;    vlc_value_t    val;    if( p_dec->fmt_in.i_codec != VLC_FOURCC('u','s','f',' ') )    {        return VLC_EGENERIC;    }    p_dec->pf_decode_sub = DecodeBlock;    /* Allocate the memory needed to store the decoder's structure */    if( ( p_dec->p_sys = p_sys =          (decoder_sys_t *)calloc(1, sizeof(decoder_sys_t)) ) == NULL )    {        return VLC_ENOMEM;    }    /* Unused fields of p_sys - not needed for USF decoding */    p_sys->b_ass = false;    p_sys->iconv_handle = (vlc_iconv_t)-1;    p_sys->b_autodetect_utf8 = false;    /* init of p_sys */    p_sys->i_align = 0;    p_sys->i_original_height = -1;    p_sys->i_original_width = -1;    TAB_INIT( p_sys->i_ssa_styles, p_sys->pp_ssa_styles );    TAB_INIT( p_sys->i_images, p_sys->pp_images );    /* USF subtitles are mandated to be UTF-8, so don't need vlc_iconv */    var_Create( p_dec, "subsdec-align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    var_Get( p_dec, "subsdec-align", &val );    p_sys->i_align = val.i_int;    ParseImageAttachments( p_dec );    if( var_CreateGetBool( p_dec, "subsdec-formatted" ) )    {        if( p_dec->fmt_in.i_extra > 0 )            ParseUSFHeader( p_dec );    }    return VLC_SUCCESS;}/**************************************************************************** * DecodeBlock: the whole thing **************************************************************************** * This function must be fed with complete subtitles units. ****************************************************************************/static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ){    subpicture_t *p_spu;    block_t *p_block;    if( !pp_block || *pp_block == NULL )        return NULL;    p_block = *pp_block;    if( p_block->i_rate != 0 )        p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT;    p_spu = ParseText( p_dec, p_block );    block_Release( p_block );    *pp_block = NULL;    return p_spu;}/***************************************************************************** * CloseDecoder: clean up the decoder *****************************************************************************/static void CloseDecoder( vlc_object_t *p_this ){    decoder_t *p_dec = (decoder_t *)p_this;    decoder_sys_t *p_sys = p_dec->p_sys;    if( p_sys->pp_ssa_styles )    {        int i;        for( i = 0; i < p_sys->i_ssa_styles; i++ )        {            if( !p_sys->pp_ssa_styles[i] )                continue;            free( p_sys->pp_ssa_styles[i]->psz_stylename );            free( p_sys->pp_ssa_styles[i]->font_style.psz_fontname );            free( p_sys->pp_ssa_styles[i] );        }        TAB_CLEAN( p_sys->i_ssa_styles, p_sys->pp_ssa_styles );    }    if( p_sys->pp_images )    {        int i;        for( i = 0; i < p_sys->i_images; i++ )        {            if( !p_sys->pp_images[i] )                continue;            if( p_sys->pp_images[i]->p_pic )                picture_Release( p_sys->pp_images[i]->p_pic );            free( p_sys->pp_images[i]->psz_filename );            free( p_sys->pp_images[i] );        }        TAB_CLEAN( p_sys->i_images, p_sys->pp_images );    }    free( p_sys );}/***************************************************************************** * ParseText: parse an text subtitle packet and send it to the video output *****************************************************************************/static subpicture_t *ParseText( decoder_t *p_dec, block_t *p_block ){    decoder_sys_t *p_sys = p_dec->p_sys;    subpicture_t *p_spu = NULL;    char *psz_subtitle = NULL;    /* We cannot display a subpicture with no date */    if( p_block->i_pts == 0 )    {        msg_Warn( p_dec, "subtitle without a date" );        return NULL;    }    /* Check validity of packet data */    /* An "empty" line containing only \0 can be used to force       and ephemer picture from the screen */    if( p_block->i_buffer < 1 )    {        msg_Warn( p_dec, "no subtitle data" );        return NULL;    }    /* Should be resiliant against bad subtitles */    psz_subtitle = strndup( (const char *)p_block->p_buffer,                            p_block->i_buffer );    if( psz_subtitle == NULL )        return NULL;    /* USF Subtitles are mandated to be UTF-8 -- make sure it is */    if (EnsureUTF8( psz_subtitle ) == NULL)    {        msg_Err( p_dec, "USF subtitles must be in UTF-8 format.\n"                 "This stream contains USF subtitles which aren't." );    }    /* Create the subpicture unit */    p_spu = p_dec->pf_spu_buffer_new( p_dec );    if( !p_spu )    {        msg_Warn( p_dec, "can't get spu buffer" );        free( psz_subtitle );        return NULL;    }    p_spu->b_pausable = true;    /* Decode USF strings */    p_spu->p_region = ParseUSFString( p_dec, psz_subtitle, p_spu );    p_spu->i_start = p_block->i_pts;    p_spu->i_stop = p_block->i_pts + p_block->i_length;    p_spu->b_ephemer = (p_block->i_length == 0);    p_spu->b_absolute = false;    p_spu->i_original_picture_width = p_sys->i_original_width;    p_spu->i_original_picture_height = p_sys->i_original_height;    free( psz_subtitle );    return p_spu;}static char *GrabAttributeValue( const char *psz_attribute,                                 const char *psz_tag_start ){    if( psz_attribute && psz_tag_start )    {        char *psz_tag_end = strchr( psz_tag_start, '>' );        char *psz_found   = strcasestr( psz_tag_start, psz_attribute );        if( psz_found )        {            psz_found += strlen( psz_attribute );            if(( *(psz_found++) == '=' ) &&               ( *(psz_found++) == '\"' ))            {                if( psz_found < psz_tag_end )                {                    int   i_len = strcspn( psz_found, "\"" );                    return strndup( psz_found, i_len );                }            }        }    }    return NULL;}static ssa_style_t *ParseStyle( decoder_sys_t *p_sys, char *psz_subtitle ){    ssa_style_t *p_style   = NULL;    char        *psz_style = GrabAttributeValue( "style", psz_subtitle );    if( psz_style )    {        int i;        for( i = 0; i < p_sys->i_ssa_styles; i++ )        {            if( !strcmp( p_sys->pp_ssa_styles[i]->psz_stylename, psz_style ) )                p_style = p_sys->pp_ssa_styles[i];        }        free( psz_style );    }    return p_style;}static int ParsePositionAttributeList( char *psz_subtitle, int *i_align,                                       int *i_x, int *i_y ){    int   i_mask = 0;    char *psz_align    = GrabAttributeValue( "alignment", psz_subtitle );    char *psz_margin_x = GrabAttributeValue( "horizontal-margin", psz_subtitle );    char *psz_margin_y = GrabAttributeValue( "vertical-margin", psz_subtitle );    /* -- UNSUPPORTED    char *psz_relative = GrabAttributeValue( "relative-to", psz_subtitle );    char *psz_rotate_x = GrabAttributeValue( "rotate-x", psz_subtitle );    char *psz_rotate_y = GrabAttributeValue( "rotate-y", psz_subtitle );    char *psz_rotate_z = GrabAttributeValue( "rotate-z", psz_subtitle );    */    *i_align = SUBPICTURE_ALIGN_BOTTOM;    *i_x = 0;    *i_y = 0;    if( psz_align )    {        if( !strcasecmp( "TopLeft", psz_align ) )            *i_align = SUBPICTURE_ALIGN_TOP | SUBPICTURE_ALIGN_LEFT;        else if( !strcasecmp( "TopCenter", psz_align ) )            *i_align = SUBPICTURE_ALIGN_TOP;        else if( !strcasecmp( "TopRight", psz_align ) )            *i_align = SUBPICTURE_ALIGN_TOP | SUBPICTURE_ALIGN_RIGHT;

⌨️ 快捷键说明

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