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

📄 dvbsub.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 5 页
字号:
    i_id             = bs_read( s, 16 );    i_version        = bs_read( s, 4 );    i_coding_method  = bs_read( s, 2 );    if( i_coding_method > 1 )    {        msg_Dbg( p_dec, "DVB subtitling method is not handled!" );        bs_skip( s, 8 * (i_segment_length - 2) - 6 );        return;    }    /* Check if the object needs to be rendered in at least one     * of the regions */    for( p_region = p_sys->p_regions; p_region != NULL;         p_region = p_region->p_next )    {        for( i = 0; i < p_region->i_object_defs; i++ )            if( p_region->p_object_defs[i].i_id == i_id ) break;        if( i != p_region->i_object_defs ) break;    }    if( !p_region )    {        bs_skip( s, 8 * (i_segment_length - 2) - 6 );        return;    }#ifdef DEBUG_DVBSUB    msg_Dbg( p_dec, "new object: %i", i_id );#endif    b_non_modify_color = bs_read( s, 1 );    bs_skip( s, 1 ); /* Reserved */    if( i_coding_method == 0x00 )    {        int i_topfield, i_bottomfield;        uint8_t *p_topfield, *p_bottomfield;        i_topfield    = bs_read( s, 16 );        i_bottomfield = bs_read( s, 16 );        p_topfield    = s->p_start + bs_pos( s ) / 8;        p_bottomfield = p_topfield + i_topfield;        bs_skip( s, 8 * (i_segment_length - 7) );        /* Sanity check */        if( i_segment_length < i_topfield + i_bottomfield + 7 ||            p_topfield + i_topfield + i_bottomfield > s->p_end )        {            msg_Dbg( p_dec, "corrupted object data" );            return;        }        for( p_region = p_sys->p_regions; p_region != NULL;             p_region = p_region->p_next )        {            for( i = 0; i < p_region->i_object_defs; i++ )            {                if( p_region->p_object_defs[i].i_id != i_id ) continue;                dvbsub_render_pdata( p_dec, p_region,                                     p_region->p_object_defs[i].i_x,                                     p_region->p_object_defs[i].i_y,                                     p_topfield, i_topfield );                if( i_bottomfield )                {                    dvbsub_render_pdata( p_dec, p_region,                                         p_region->p_object_defs[i].i_x,                                         p_region->p_object_defs[i].i_y + 1,                                         p_bottomfield, i_bottomfield );                }                else                {                    /* Duplicate the top field */                    dvbsub_render_pdata( p_dec, p_region,                                         p_region->p_object_defs[i].i_x,                                         p_region->p_object_defs[i].i_y + 1,                                         p_topfield, i_topfield );                }            }        }    }    else    {        /* DVB subtitling as characters */        int i_number_of_codes = bs_read( s, 8 );        uint8_t* p_start = s->p_start + bs_pos( s ) / 8;        /* Sanity check */        if( i_segment_length <  i_number_of_codes*2 + 4 ||            p_start + i_number_of_codes*2 > s->p_end )        {            msg_Dbg( p_dec, "corrupted object data" );            return;        }        for( p_region = p_sys->p_regions; p_region != NULL;             p_region = p_region->p_next )        {            for( i = 0; i < p_region->i_object_defs; i++ )            {                int j;                if( p_region->p_object_defs[i].i_id != i_id ) continue;                p_region->p_object_defs[i].psz_text =                    realloc( p_region->p_object_defs[i].psz_text,                             i_number_of_codes + 1 );                for( j = 0; j < i_number_of_codes; j++ )                {                    p_region->p_object_defs[i].psz_text[j] = bs_read( s, 16 );                }                p_region->p_object_defs[i].psz_text[j] = 0;            }        }    }#ifdef DEBUG_DVBSUB    msg_Dbg( p_dec, "end object: %i", i_id );#endif}static void dvbsub_render_pdata( decoder_t *p_dec, dvbsub_region_t *p_region,                                 int i_x, int i_y,                                 uint8_t *p_field, int i_field ){    uint8_t *p_pixbuf;    int i_offset = 0;    bs_t bs;    /* Sanity check */    if( !p_region->p_pixbuf )    {        msg_Err( p_dec, "region %i has no pixel buffer!", p_region->i_id );        return;    }    if( i_y < 0 || i_x < 0 || i_y >= p_region->i_height ||        i_x >= p_region->i_width )    {        msg_Dbg( p_dec, "invalid offset (%i,%i)", i_x, i_y );        return;    }    p_pixbuf = p_region->p_pixbuf + i_y * p_region->i_width;    bs_init( &bs, p_field, i_field );    while( !bs_eof( &bs ) )    {        /* Sanity check */        if( i_y >= p_region->i_height ) return;        switch( bs_read( &bs, 8 ) )        {        case 0x10:            dvbsub_pdata2bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,                              &i_offset );            break;        case 0x11:            dvbsub_pdata4bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,                              &i_offset );            break;        case 0x12:            dvbsub_pdata8bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,                              &i_offset );            break;        case 0x20:        case 0x21:        case 0x22:            /* We don't use map tables */            break;        case 0xf0: /* End of line code */            p_pixbuf += 2*p_region->i_width;            i_offset = 0; i_y += 2;            break;        }    }}static void dvbsub_pdata2bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off ){    vlc_bool_t b_stop = 0;    while( !b_stop && !bs_eof( s ) )    {        int i_count = 0, i_color = 0;        if( (i_color = bs_read( s, 2 )) != 0x00 )        {            i_count = 1;        }        else        {            if( bs_read( s, 1 ) == 0x01 )         // Switch1            {                i_count = 3 + bs_read( s, 3 );                i_color = bs_read( s, 2 );            }            else            {                if( bs_read( s, 1 ) == 0x00 )     //Switch2                {                    switch( bs_read( s, 2 ) )     //Switch3                    {                    case 0x00:                        b_stop = 1;                        break;                    case 0x01:                        i_count = 2;                        break;                    case 0x02:                        i_count =  12 + bs_read( s, 4 );                        i_color = bs_read( s, 2 );                        break;                    case 0x03:                        i_count =  29 + bs_read( s, 8 );                        i_color = bs_read( s, 2 );                        break;                    default:                        break;                    }                }                else                {                    /* 1 pixel color 0 */                    i_count = 1;                }            }        }        if( !i_count ) continue;        /* Sanity check */        if( i_count + *pi_off > i_width ) break;        if( i_count == 1 ) p[*pi_off] = i_color;        else memset( p + *pi_off, i_color, i_count );        (*pi_off) += i_count;    }    bs_align( s );}static void dvbsub_pdata4bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off ){    vlc_bool_t b_stop = 0;    while( !b_stop && !bs_eof( s ) )    {        int i_count = 0, i_color = 0;        if( (i_color = bs_read( s, 4 )) != 0x00 )        {            /* Add 1 pixel */            i_count = 1;        }        else        {            if( bs_read( s, 1 ) == 0x00 )           // Switch1            {                if( bs_show( s, 3 ) != 0x00 )                {                    i_count = 2 + bs_read( s, 3 );                }                else                {                    bs_skip( s, 3 );                    b_stop = 1;                }            }            else            {                if( bs_read( s, 1 ) == 0x00)        //Switch2                {                    i_count =  4 + bs_read( s, 2 );                    i_color = bs_read( s, 4 );                }                else                {                    switch ( bs_read( s, 2 ) )     //Switch3                    {                    case 0x0:                        i_count = 1;                        break;                    case 0x1:                        i_count = 2;                        break;                    case 0x2:                        i_count = 9 + bs_read( s, 4 );                        i_color = bs_read( s, 4 );                        break;                    case 0x3:                        i_count= 25 + bs_read( s, 8 );                        i_color = bs_read( s, 4 );                        break;                    }                }            }        }        if( !i_count ) continue;        /* Sanity check */        if( i_count + *pi_off > i_width ) break;        if( i_count == 1 ) p[*pi_off] = i_color;        else memset( p + *pi_off, i_color, i_count );        (*pi_off) += i_count;    }    bs_align( s );}static void dvbsub_pdata8bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off ){    vlc_bool_t b_stop = 0;    while( !b_stop && !bs_eof( s ) )    {        int i_count = 0, i_color = 0;        if( (i_color = bs_read( s, 8 )) != 0x00 )        {            /* Add 1 pixel */            i_count = 1;        }        else        {            if( bs_read( s, 1 ) == 0x00 )           // Switch1            {                if( bs_show( s, 7 ) != 0x00 )                {                    i_count = bs_read( s, 7 );                }                else                {                    bs_skip( s, 7 );                    b_stop = 1;                }            }            else            {                i_count = bs_read( s, 7 );                i_color = bs_read( s, 8 );            }        }        if( !i_count ) continue;        /* Sanity check */        if( i_count + *pi_off > i_width ) break;        if( i_count == 1 ) p[*pi_off] = i_color;        else memset( p + *pi_off, i_color, i_count );        (*pi_off) += i_count;    }    bs_align( s );}static void free_all( decoder_t *p_dec ){    decoder_sys_t *p_sys = p_dec->p_sys;    dvbsub_region_t *p_reg, *p_reg_next;    dvbsub_clut_t *p_clut, *p_clut_next;    for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut_next )    {        p_clut_next = p_clut->p_next;        free( p_clut );    }    p_sys->p_cluts = NULL;    for( p_reg = p_sys->p_regions; p_reg != NULL; p_reg = p_reg_next )    {        int i;        p_reg_next = p_reg->p_next;        for( i = 0; i < p_reg->i_object_defs; i++ )            if( p_reg->p_object_defs[i].psz_text )                free( p_reg->p_object_defs[i].psz_text );        if( p_reg->i_object_defs ) free( p_reg->p_object_defs );        if( p_reg->p_pixbuf ) free( p_reg->p_pixbuf );        free( p_reg );    }    p_sys->p_regions = NULL;    if( p_sys->p_page )    {        if( p_sys->p_page->i_region_defs )            free( p_sys->p_page->p_region_defs );        free( p_sys->p_page );    }    p_sys->p_page = NULL;}static subpicture_t *render( decoder_t *p_dec ){    decoder_sys_t *p_sys = p_dec->p_sys;    subpicture_t *p_spu;    subpicture_region_t **pp_spu_region;    int i, j, i_timeout = 0;    /* Allocate the subpicture internal data. */    p_spu = p_dec->pf_spu_buffer_new( p_dec );    if( !p_spu ) return NULL;    pp_spu_region = &p_spu->p_region;    /* Loop on region definitions */#ifdef DEBUG_DVBSUB

⌨️ 快捷键说明

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