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

📄 dvbsub.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * dvbsub.c : DVB subtitles decoder *            DVB subtitles encoder (developed for Anevia, www.anevia.com) ***************************************************************************** * Copyright (C) 2003 ANEVIA * Copyright (C) 2003-2005 the VideoLAN team * $Id: dvbsub.c 19610 2007-04-01 01:37:01Z hartman $ * * Authors: Gildas Bazin <gbazin@videolan.org> *          Damien LUCAS <damien.lucas@anevia.com> *          Laurent Aimar <fenrir@via.ecp.fr> *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl> * * 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 * * FIXME: * DVB subtitles coded as strings of characters are not handled correctly. * The character codes in the string should actually be indexes refering to a * character table identified in the subtitle descriptor. *****************************************************************************/#include <vlc/vlc.h>#include <vlc/vout.h>#include <vlc/decoder.h>#include <vlc/sout.h>#include "vlc_bits.h"/* #define DEBUG_DVBSUB 1 */#define POSX_TEXT N_("Decoding X coordinate")#define POSX_LONGTEXT N_("X coordinate of the rendered subtitle")#define POSY_TEXT N_("Decoding Y coordinate")#define POSY_LONGTEXT N_("Y coordinate of the rendered subtitle") #define POS_TEXT N_("Subpicture position")#define POS_LONGTEXT N_( \  "You can enforce the subpicture position on the video " \  "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \  "also use combinations of these values, e.g. 6=top-right).")#define ENC_POSX_TEXT N_("Encoding X coordinate")#define ENC_POSX_LONGTEXT N_("X coordinate of the encoded subtitle" )#define ENC_POSY_TEXT N_("Encoding Y coordinate")#define ENC_POSY_LONGTEXT N_("Y coordinate of the encoded subtitle" )static int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };static char *ppsz_pos_descriptions[] ={ N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),  N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };/***************************************************************************** * Module descriptor. *****************************************************************************/static int  Open ( vlc_object_t * );static void Close( vlc_object_t * );static subpicture_t *Decode( decoder_t *, block_t ** );static int OpenEncoder  ( vlc_object_t * );static void CloseEncoder( vlc_object_t * );static block_t *Encode  ( encoder_t *, subpicture_t * );vlc_module_begin();#   define DVBSUB_CFG_PREFIX "dvbsub-"    set_description( _("DVB subtitles decoder") );    set_capability( "decoder", 50 );    set_category( CAT_INPUT );    set_subcategory( SUBCAT_INPUT_SCODEC );    set_callbacks( Open, Close );    add_integer( DVBSUB_CFG_PREFIX "position", 8, NULL, POS_TEXT, POS_LONGTEXT, VLC_TRUE );        change_integer_list( pi_pos_values, ppsz_pos_descriptions, 0 );    add_integer( DVBSUB_CFG_PREFIX "x", -1, NULL, POSX_TEXT, POSX_LONGTEXT, VLC_FALSE );    add_integer( DVBSUB_CFG_PREFIX "y", -1, NULL, POSY_TEXT, POSY_LONGTEXT, VLC_FALSE );#   define ENC_CFG_PREFIX "sout-dvbsub-"    add_submodule();    set_description( _("DVB subtitles encoder") );    set_capability( "encoder", 100 );    set_callbacks( OpenEncoder, CloseEncoder );    add_integer( ENC_CFG_PREFIX "x", -1, NULL, ENC_POSX_TEXT, ENC_POSX_LONGTEXT, VLC_FALSE );    add_integer( ENC_CFG_PREFIX "y", -1, NULL, ENC_POSY_TEXT, ENC_POSY_LONGTEXT, VLC_FALSE );    add_suppressed_integer( ENC_CFG_PREFIX "timeout" ); /* Suppressed since 0.8.5 */vlc_module_end();static const char *ppsz_enc_options[] = { "x", "y", NULL };/**************************************************************************** * Local structures **************************************************************************** * Those structures refer closely to the ETSI 300 743 Object model ****************************************************************************//* The object definition gives the position of the object in a region */typedef struct dvbsub_objectdef_s{    int i_id;    int i_type;    int i_x;    int i_y;    int i_fg_pc;    int i_bg_pc;    char *psz_text; /* for string of characters objects */} dvbsub_objectdef_t;/* The entry in the palette CLUT */typedef struct{    uint8_t                 Y;    uint8_t                 Cr;    uint8_t                 Cb;    uint8_t                 T;} dvbsub_color_t;/* */typedef struct dvbsub_clut_s{    uint8_t                 i_id;    uint8_t                 i_version;    dvbsub_color_t          c_2b[4];    dvbsub_color_t          c_4b[16];    dvbsub_color_t          c_8b[256];    struct dvbsub_clut_s    *p_next;} dvbsub_clut_t;/* The Region is an aera on the image * with a list of the object definitions associated and a CLUT */typedef struct dvbsub_region_s{    int i_id;    int i_version;    int i_x;    int i_y;    int i_width;    int i_height;    int i_level_comp;    int i_depth;    int i_clut;    uint8_t *p_pixbuf;    int                    i_object_defs;    dvbsub_objectdef_t     *p_object_defs;    struct dvbsub_region_s *p_next;} dvbsub_region_t;/* The object definition gives the position of the object in a region */typedef struct dvbsub_regiondef_s{    int i_id;    int i_x;    int i_y;} dvbsub_regiondef_t;/* The page defines the list of regions */typedef struct{    int i_id;    int i_timeout; /* in seconds */    int i_state;    int i_version;    int                i_region_defs;    dvbsub_regiondef_t *p_region_defs;} dvbsub_page_t;struct decoder_sys_t{    bs_t            bs;    /* Decoder internal data */    int             i_id;    int             i_ancillary_id;    mtime_t         i_pts;    vlc_bool_t      b_absolute;    int             i_spu_position;    int             i_spu_x;    int             i_spu_y;    vlc_bool_t      b_page;    dvbsub_page_t   *p_page;    dvbsub_region_t *p_regions;    dvbsub_clut_t   *p_cluts;    dvbsub_clut_t   default_clut;};/* List of different SEGMENT TYPES *//* According to EN 300-743, table 2 */#define DVBSUB_ST_PAGE_COMPOSITION      0x10#define DVBSUB_ST_REGION_COMPOSITION    0x11#define DVBSUB_ST_CLUT_DEFINITION       0x12#define DVBSUB_ST_OBJECT_DATA           0x13#define DVBSUB_ST_ENDOFDISPLAY          0x80#define DVBSUB_ST_STUFFING              0xff/* List of different OBJECT TYPES *//* According to EN 300-743, table 6 */#define DVBSUB_OT_BASIC_BITMAP          0x00#define DVBSUB_OT_BASIC_CHAR            0x01#define DVBSUB_OT_COMPOSITE_STRING      0x02/* Pixel DATA TYPES *//* According to EN 300-743, table 9 */ #define DVBSUB_DT_2BP_CODE_STRING       0x10#define DVBSUB_DT_4BP_CODE_STRING       0x11#define DVBSUB_DT_8BP_CODE_STRING       0x12#define DVBSUB_DT_24_TABLE_DATA         0x20#define DVBSUB_DT_28_TABLE_DATA         0x21#define DVBSUB_DT_48_TABLE_DATA         0x22#define DVBSUB_DT_END_LINE              0xf0/* List of different Page Composition Segment state *//* According to EN 300-743, 7.2.1 table 3 */#define DVBSUB_PCS_STATE_ACQUISITION    0x01#define DVBSUB_PCS_STATE_CHANGE         0x02/***************************************************************************** * Local prototypes *****************************************************************************/static void decode_segment( decoder_t *, bs_t * );static void decode_page_composition( decoder_t *, bs_t * );static void decode_region_composition( decoder_t *, bs_t * );static void decode_object( decoder_t *, bs_t * );static void decode_clut( decoder_t *, bs_t * );static void free_all( decoder_t * );static void default_clut_init( decoder_t * );static subpicture_t *render( decoder_t * );/***************************************************************************** * Open: probe the decoder and return score ***************************************************************************** * Tries to launch a decoder and return score so that the interface is able * to chose. *****************************************************************************/static int Open( vlc_object_t *p_this ){    decoder_t     *p_dec = (decoder_t *) p_this;    decoder_sys_t *p_sys;    vlc_value_t    val;    int i_posx, i_posy;    if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','b','s') )    {        return VLC_EGENERIC;    }    p_dec->pf_decode_sub = Decode;    p_sys = p_dec->p_sys = malloc( sizeof(decoder_sys_t) );    memset( p_sys, 0, sizeof(decoder_sys_t) );    p_sys->i_pts          = (mtime_t) 0;        p_sys->i_id           = p_dec->fmt_in.subs.dvb.i_id & 0xFFFF;    p_sys->i_ancillary_id = p_dec->fmt_in.subs.dvb.i_id >> 16;    p_sys->p_regions      = NULL;    p_sys->p_cluts        = NULL;    p_sys->p_page         = NULL;    var_Create( p_this, DVBSUB_CFG_PREFIX "position",                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    var_Get( p_this, DVBSUB_CFG_PREFIX "position", &val );    p_sys->i_spu_position = val.i_int;    var_Create( p_this, DVBSUB_CFG_PREFIX "x",                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    var_Get( p_this, DVBSUB_CFG_PREFIX "x", &val );    i_posx = val.i_int;    var_Create( p_this, DVBSUB_CFG_PREFIX "y",                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    var_Get( p_this, DVBSUB_CFG_PREFIX "y", &val );    i_posy = val.i_int;    /* Check if subpicture position was overridden */    p_sys->b_absolute = VLC_TRUE;    p_sys->i_spu_x = p_sys->i_spu_y = 0;    if( i_posx >= 0 && i_posy >= 0 )    {        p_sys->b_absolute = VLC_FALSE;        p_sys->i_spu_x = i_posx;        p_sys->i_spu_y = i_posy;    }    es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'd','v','b','s' ) );    default_clut_init( p_dec );    return VLC_SUCCESS;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t *p_this ){    decoder_t     *p_dec = (decoder_t*) p_this;    decoder_sys_t *p_sys = p_dec->p_sys;    var_Destroy( p_this, DVBSUB_CFG_PREFIX "x" );    var_Destroy( p_this, DVBSUB_CFG_PREFIX "y" );    var_Destroy( p_this, DVBSUB_CFG_PREFIX "position" );        free_all( p_dec );    free( p_sys );}/***************************************************************************** * Decode: *****************************************************************************/static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ){    decoder_sys_t *p_sys = p_dec->p_sys;    block_t       *p_block;    subpicture_t  *p_spu = NULL;    if( pp_block == NULL || *pp_block == NULL ) return NULL;    p_block = *pp_block;    *pp_block = NULL;    p_sys->i_pts = p_block->i_pts;    if( p_sys->i_pts <= 0 )    {#ifdef DEBUG_DVBSUB        /* Some DVB channels send stuffing segments in non-dated packets so         * don't complain too loudly. */        msg_Warn( p_dec, "non dated subtitle" );#endif        block_Release( p_block );        return NULL;    }    bs_init( &p_sys->bs, p_block->p_buffer, p_block->i_buffer );    if( bs_read( &p_sys->bs, 8 ) != 0x20 ) /* Data identifier */    {        msg_Dbg( p_dec, "invalid data identifier" );        block_Release( p_block );        return NULL;    }    if( bs_read( &p_sys->bs, 8 ) ) /* Subtitle stream id */    {        msg_Dbg( p_dec, "invalid subtitle stream id" );        block_Release( p_block );        return NULL;    }#ifdef DEBUG_DVBSUB    msg_Dbg( p_dec, "subtitle packet received: "I64Fd, p_sys->i_pts );#endif    p_sys->b_page = VLC_FALSE;    while( bs_show( &p_sys->bs, 8 ) == 0x0f ) /* Sync byte */    {        decode_segment( p_dec, &p_sys->bs );    }    if( bs_read( &p_sys->bs, 8 ) != 0xff ) /* End marker */    {        msg_Warn( p_dec, "end marker not found (corrupted subtitle ?)" );        block_Release( p_block );        return NULL;    }    /* Check if the page is to be displayed */    if( p_sys->p_page && p_sys->b_page ) p_spu = render( p_dec );    block_Release( p_block );    return p_spu;}/* following functions are local *//***************************************************************************** * default_clut_init: default clut as defined in EN 300-743 section 10 *****************************************************************************/static void default_clut_init( decoder_t *p_dec ){    decoder_sys_t *p_sys = p_dec->p_sys;    uint8_t i;#define RGB_TO_Y(r, g, b) ((int16_t) 77 * r + 150 * g + 29 * b) / 256;#define RGB_TO_U(r, g, b) ((int16_t) -44 * r - 87 * g + 131 * b) / 256;#define RGB_TO_V(r, g, b) ((int16_t) 131 * r - 110 * g - 21 * b) / 256;    /* 4 entries CLUT */    for( i = 0; i < 4; i++ )

⌨️ 快捷键说明

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