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

📄 dvbsub.c

📁 video linux conference
💻 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 VideoLAN * $Id: dvbsub.c 10585 2005-04-07 04:58:36Z rocky $ * * Authors: Gildas Bazin <gbazin@videolan.org> *          Damien LUCAS <damien.lucas@anevia.com> *          Laurent Aimar <fenrir@via.ecp.fr> * * 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 * * 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/***************************************************************************** * 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();    set_description( _("DVB subtitles decoder") );    set_capability( "decoder", 50 );    set_category( CAT_INPUT );    set_subcategory( SUBCAT_INPUT_SCODEC );    set_callbacks( Open, Close );#   define ENC_CFG_PREFIX "sout-dvbsub-"    add_submodule();    set_description( _("DVB subtitles encoder") );    set_capability( "encoder", 100 );    set_callbacks( OpenEncoder, CloseEncoder );vlc_module_end();static const char *ppsz_enc_options[] = { 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;    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_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         0x10/***************************************************************************** * 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;    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          = 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;    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;    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++ )    {        uint8_t R = 0, G = 0, B = 0, T = 0;        if( !(i & 0x2) && !(i & 0x1) ) T = 0xFF;        else if( !(i & 0x2) && (i & 0x1) ) R = G = B = 0xFF;        else if( (i & 0x2) && !(i & 0x1) ) R = G = B = 0;        else R = G = B = 0x7F;        p_sys->default_clut.c_2b[i].Y = RGB_TO_Y(R,G,B);        p_sys->default_clut.c_2b[i].Cr = RGB_TO_U(R,G,B);        p_sys->default_clut.c_2b[i].Cb = RGB_TO_V(R,G,B);        p_sys->default_clut.c_2b[i].T = T;    }    /* 16 entries CLUT */    for( i = 0; i < 16; i++ )    {        uint8_t R = 0, G = 0, B = 0, T = 0;        if( !(i & 0x8) )        {            if( !(i & 0x4) && !(i & 0x2) && !(i & 0x1) )            {                T = 0xFF;            }            else            {                R = (i & 0x1) ? 0xFF : 0;                G = (i & 0x2) ? 0xFF : 0;                B = (i & 0x4) ? 0xFF : 0;            }        }        else        {            R = (i & 0x1) ? 0x7F : 0;            G = (i & 0x2) ? 0x7F : 0;            B = (i & 0x4) ? 0x7F : 0;        }        p_sys->default_clut.c_4b[i].Y = RGB_TO_Y(R,G,B);        p_sys->default_clut.c_4b[i].Cr = RGB_TO_U(R,G,B);        p_sys->default_clut.c_4b[i].Cb = RGB_TO_V(R,G,B);        p_sys->default_clut.c_4b[i].T = T;    }    /* 256 entries CLUT (TODO) */    memset( p_sys->default_clut.c_8b, 0xFF, 256 * sizeof(dvbsub_color_t) );}static void decode_segment( decoder_t *p_dec, bs_t *s ){    decoder_sys_t *p_sys = p_dec->p_sys;    int i_type;    int i_page_id;    int i_size;    /* sync_byte (already checked) */    bs_skip( s, 8 );    /* segment type */    i_type = bs_read( s, 8 );    /* page id */    i_page_id = bs_read( s, 16 );    /* segment size */    i_size = bs_show( s, 16 );    if( i_page_id != p_sys->i_id && i_page_id != p_sys->i_ancillary_id )    {#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "subtitle skipped (page id: %i, %i)",                 i_page_id, p_sys->i_id );#endif        bs_skip( s,  8 * ( 2 + i_size ) );        return;

⌨️ 快捷键说明

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