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

📄 dvbsub.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    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].Cb = RGB_TO_V(R,G,B);        p_sys->default_clut.c_2b[i].Cr = RGB_TO_U(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_V(R,G,B);        p_sys->default_clut.c_4b[i].Cb = RGB_TO_U(R,G,B);        p_sys->default_clut.c_4b[i].T = T;    }    /* 256 entries CLUT */    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;    }    if( ( p_sys->i_ancillary_id != p_sys->i_id ) &&        ( i_type == DVBSUB_ST_PAGE_COMPOSITION ) &&        ( i_page_id == p_sys->i_ancillary_id ) )    {#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "skipped invalid ancillary subtitle packet" );#endif        bs_skip( s,  8 * ( 2 + i_size ) );        return;    }#ifdef DEBUG_DVBSUB    if( i_page_id == p_sys->i_id )        msg_Dbg( p_dec, "segment (id: %i)", i_page_id );    else        msg_Dbg( p_dec, "ancillary segment (id: %i)", i_page_id );#endif    switch( i_type )    {    case DVBSUB_ST_PAGE_COMPOSITION:#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "decode_page_composition" );#endif        decode_page_composition( p_dec, s );        break;    case DVBSUB_ST_REGION_COMPOSITION:#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "decode_region_composition" );#endif        decode_region_composition( p_dec, s );        break;    case DVBSUB_ST_CLUT_DEFINITION:#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "decode_clut" );#endif        decode_clut( p_dec, s );        break;    case DVBSUB_ST_OBJECT_DATA:#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "decode_object" );#endif        decode_object( p_dec, s );        break;    case DVBSUB_ST_DISPLAY_DEFINITION:#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "decode_display_definition" );#endif        decode_display_definition( p_dec, s );        break;    case DVBSUB_ST_ENDOFDISPLAY:#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "end of display" );#endif        bs_skip( s,  8 * ( 2 + i_size ) );        break;    case DVBSUB_ST_STUFFING:#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "skip stuffing" );#endif        bs_skip( s,  8 * ( 2 + i_size ) );        break;    default:        msg_Warn( p_dec, "unsupported segment type: (%04x)", i_type );        bs_skip( s,  8 * ( 2 + i_size ) );        break;    }}static void decode_clut( decoder_t *p_dec, bs_t *s ){    decoder_sys_t *p_sys = p_dec->p_sys;    uint16_t      i_segment_length;    uint16_t      i_processed_length;    dvbsub_clut_t *p_clut, *p_next;    int           i_id, i_version;    i_segment_length = bs_read( s, 16 );    i_id             = bs_read( s, 8 );    i_version        = bs_read( s, 4 );    /* Check if we already have this clut */    for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut->p_next )    {        if( p_clut->i_id == i_id ) break;    }    /* Check version number */    if( p_clut && ( p_clut->i_version == i_version ) )    {        /* Nothing to do */        bs_skip( s, 8 * i_segment_length - 12 );        return;    }    if( !p_clut )    {#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "new clut: %i", i_id );#endif        p_clut = malloc( sizeof( dvbsub_clut_t ) );        if( !p_clut )            return;        p_clut->p_next = p_sys->p_cluts;        p_sys->p_cluts = p_clut;    }    /* Initialize to default clut */    p_next = p_clut->p_next;    *p_clut = p_sys->default_clut;    p_clut->p_next = p_next;    /* We don't have this version of the CLUT: Parse it */    p_clut->i_version = i_version;    p_clut->i_id = i_id;    bs_skip( s, 4 ); /* Reserved bits */    i_processed_length = 2;    while( i_processed_length < i_segment_length )    {        uint8_t y, cb, cr, t;        uint8_t i_id;        uint8_t i_type;        i_id = bs_read( s, 8 );        i_type = bs_read( s, 3 );        bs_skip( s, 4 );        if( bs_read( s, 1 ) )        {            y  = bs_read( s, 8 );            cr = bs_read( s, 8 );            cb = bs_read( s, 8 );            t  = bs_read( s, 8 );            i_processed_length += 6;        }        else        {            y  = bs_read( s, 6 ) << 2;            cr = bs_read( s, 4 ) << 4;            cb = bs_read( s, 4 ) << 4;            t  = bs_read( s, 2 ) << 6;            i_processed_length += 4;        }        /* We are not entirely compliant here as full transparency is indicated         * with a luma value of zero, not a transparency value of 0xff         * (full transparency would actually be 0xff + 1). */        if( y == 0 )        {            cr = cb = 0;            t  = 0xff;        }        /* According to EN 300-743 section 7.2.3 note 1, type should         * not have more than 1 bit set to one, but some streams don't         * respect this note. */        if( ( i_type & 0x04 ) && ( i_id < 4 ) )        {            p_clut->c_2b[i_id].Y = y;            p_clut->c_2b[i_id].Cr = cr;            p_clut->c_2b[i_id].Cb = cb;            p_clut->c_2b[i_id].T = t;        }        if( ( i_type & 0x02 ) && ( i_id < 16 ) )        {            p_clut->c_4b[i_id].Y = y;            p_clut->c_4b[i_id].Cr = cr;            p_clut->c_4b[i_id].Cb = cb;            p_clut->c_4b[i_id].T = t;        }        if( i_type & 0x01 )        {            p_clut->c_8b[i_id].Y = y;            p_clut->c_8b[i_id].Cr = cr;            p_clut->c_8b[i_id].Cb = cb;            p_clut->c_8b[i_id].T = t;        }    }}static void decode_page_composition( decoder_t *p_dec, bs_t *s ){    decoder_sys_t *p_sys = p_dec->p_sys;    int i_version, i_state, i_segment_length, i_timeout, i;    /* A page is composed by 0 or more region */    i_segment_length = bs_read( s, 16 );    i_timeout = bs_read( s, 8 );    i_version = bs_read( s, 4 );    i_state = bs_read( s, 2 );    bs_skip( s, 2 ); /* Reserved */    if( i_state == DVBSUB_PCS_STATE_CHANGE )    {        /* End of an epoch, reset decoder buffer */#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "page composition mode change" );#endif        free_all( p_dec );    }    else if( !p_sys->p_page && ( i_state != DVBSUB_PCS_STATE_ACQUISITION ) &&             ( i_state != DVBSUB_PCS_STATE_CHANGE ) )    {        /* Not a full PCS, we need to wait for one */        msg_Dbg( p_dec, "didn't receive an acquisition page yet" );#if 0        /* Try to start decoding even without an acquisition page */        bs_skip( s,  8 * (i_segment_length - 2) );        return;#endif    }#ifdef DEBUG_DVBSUB    if( i_state == DVBSUB_PCS_STATE_ACQUISITION )        msg_Dbg( p_dec, "acquisition page composition" );#endif    /* Check version number */    if( p_sys->p_page && ( p_sys->p_page->i_version == i_version ) )    {        bs_skip( s,  8 * (i_segment_length - 2) );        return;    }    else if( p_sys->p_page )    {        if( p_sys->p_page->i_region_defs )            free( p_sys->p_page->p_region_defs );        p_sys->p_page->p_region_defs = NULL;        p_sys->p_page->i_region_defs = 0;    }    if( !p_sys->p_page )    {#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "new page" );#endif        /* Allocate a new page */        p_sys->p_page = malloc( sizeof(dvbsub_page_t) );        if( !p_sys->p_page )            return;    }    p_sys->p_page->i_version = i_version;    p_sys->p_page->i_timeout = i_timeout;    p_sys->b_page = true;    /* Number of regions */    p_sys->p_page->i_region_defs = (i_segment_length - 2) / 6;    if( p_sys->p_page->i_region_defs == 0 ) return;    p_sys->p_page->p_region_defs =        malloc( p_sys->p_page->i_region_defs * sizeof(dvbsub_region_t) );    if( p_sys->p_page->p_region_defs )    {        for( i = 0; i < p_sys->p_page->i_region_defs; i++ )        {            p_sys->p_page->p_region_defs[i].i_id = bs_read( s, 8 );            bs_skip( s, 8 ); /* Reserved */            p_sys->p_page->p_region_defs[i].i_x = bs_read( s, 16 );            p_sys->p_page->p_region_defs[i].i_y = bs_read( s, 16 );#ifdef DEBUG_DVBSUB            msg_Dbg( p_dec, "page_composition, region %i (%i,%i)",                    i, p_sys->p_page->p_region_defs[i].i_x,                    p_sys->p_page->p_region_defs[i].i_y );#endif        }    }}static void decode_region_composition( decoder_t *p_dec, bs_t *s ){    decoder_sys_t *p_sys = p_dec->p_sys;    dvbsub_region_t *p_region, **pp_region = &p_sys->p_regions;    int i_segment_length, i_processed_length, i_id, i_version;    int i_width, i_height, i_level_comp, i_depth, i_clut;    int i_8_bg, i_4_bg, i_2_bg;    bool b_fill;    i_segment_length = bs_read( s, 16 );    i_id = bs_read( s, 8 );    i_version = bs_read( s, 4 );    /* Check if we already have this region */    for( p_region = p_sys->p_regions; p_region != NULL;         p_region = p_region->p_next )    {        pp_region = &p_region->p_next;        if( p_region->i_id == i_id ) break;    }

⌨️ 快捷键说明

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