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

📄 dvbsub.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    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 );    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 );        p_region->i_object_defs--;    }    p_region->p_object_defs = NULL;    /* Extra sanity checks */    if( p_region->i_width != i_width || p_region->i_height != i_height )    {        if( p_region->p_pixbuf )        {            msg_Dbg( p_dec, "region size changed (not allowed)" );            free( p_region->p_pixbuf );        }        p_region->p_pixbuf = malloc( i_height * i_width );        p_region->i_depth = 0;        b_fill = VLC_TRUE;    }    if( p_region->i_depth && (p_region->i_depth != i_depth ||        p_region->i_level_comp != i_level_comp || p_region->i_clut != i_clut) )    {        msg_Dbg( p_dec, "region parameters changed (not allowed)" );    }    /* Erase background of region */    if( b_fill )    {        int i_background = (p_region->i_depth == 1) ? i_2_bg :            (p_region->i_depth == 2) ? i_4_bg : i_8_bg;        memset( p_region->p_pixbuf, i_background, i_width * i_height );    }    p_region->i_width = i_width;    p_region->i_height = i_height;    p_region->i_level_comp = i_level_comp;    p_region->i_depth = i_depth;    p_region->i_clut = i_clut;    /* List of objects in the region */    i_processed_length = 10;    while( i_processed_length < i_segment_length )    {        dvbsub_objectdef_t *p_obj;        /* We create a new object */        p_region->i_object_defs++;        p_region->p_object_defs =            realloc( p_region->p_object_defs,                     sizeof(dvbsub_objectdef_t) * p_region->i_object_defs );        /* We parse object properties */        p_obj = &p_region->p_object_defs[p_region->i_object_defs - 1];        p_obj->i_id         = bs_read( s, 16 );        p_obj->i_type       = bs_read( s, 2 );        bs_skip( s, 2 ); /* Provider */        p_obj->i_x          = bs_read( s, 12 );        bs_skip( s, 4 ); /* Reserved */        p_obj->i_y          = bs_read( s, 12 );        p_obj->psz_text     = 0;        i_processed_length += 6;        if( p_obj->i_type == DVBSUB_OT_BASIC_CHAR ||            p_obj->i_type == DVBSUB_OT_COMPOSITE_STRING )        {            p_obj->i_fg_pc =  bs_read( s, 8 );            p_obj->i_bg_pc =  bs_read( s, 8 );            i_processed_length += 2;        }    }}static void dvbsub_render_pdata( decoder_t *, dvbsub_region_t *, int, int,                                 uint8_t *, int );static void dvbsub_pdata2bpp( bs_t *, uint8_t *, int, int * );static void dvbsub_pdata4bpp( bs_t *, uint8_t *, int, int * );static void dvbsub_pdata8bpp( bs_t *, uint8_t *, int, int * );static void decode_object( decoder_t *p_dec, bs_t *s ){    decoder_sys_t *p_sys = p_dec->p_sys;    dvbsub_region_t *p_region;    int i_segment_length, i_coding_method, i_version, i_id, i;    vlc_bool_t b_non_modify_color;    i_segment_length = bs_read( s, 16 );

⌨️ 快捷键说明

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