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

📄 dvbsub.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {        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_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) );        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->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) );    }    p_sys->p_page->i_version = i_version;    p_sys->p_page->i_timeout = i_timeout;    p_sys->b_page = VLC_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) );    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;    vlc_bool_t 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;    }    /* Check version number */    if( p_region && p_region->i_version == i_version )    {        bs_skip( s, 8 * (i_segment_length - 1) - 4 );        return;    }    if( !p_region )    {#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "new region: %i", i_id );#endif        p_region = *pp_region = malloc( sizeof(dvbsub_region_t) );        memset( p_region, 0, sizeof(dvbsub_region_t) );        p_region->p_object_defs = NULL;        p_region->p_pixbuf = NULL;        p_region->p_next = NULL;    }    /* Region attributes */    p_region->i_id = i_id;    p_region->i_version = i_version;    b_fill = bs_read( s, 1 );    bs_skip( s, 3 ); /* Reserved */    i_width = bs_read( s, 16 );    i_height = bs_read( s, 16 );#ifdef DEBUG_DVBSUB    msg_Dbg( p_dec, " width=%d height=%d", i_width, i_height );#endif    i_level_comp = bs_read( s, 3 );    i_depth = bs_read( s, 3 );    bs_skip( s, 2 ); /* Reserved */    i_clut = bs_read( s, 8 );    i_8_bg = bs_read( s, 8 );    i_4_bg = bs_read( s, 4 );    i_2_bg = bs_read( s, 2 );    bs_skip( s, 2 ); /* Reserved */    /* Free old object defs */    while( p_region->i_object_defs )    {        int i = p_region->i_object_defs - 1;        if( p_region->p_object_defs[i].psz_text )            free( p_region->p_object_defs[i].psz_text );        if( !i ) free( p_region->p_object_defs );

⌨️ 快捷键说明

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