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

📄 dvbsub.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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    if( p_sys->p_page )        msg_Dbg( p_dec, "rendering %i regions", p_sys->p_page->i_region_defs );#endif    for( i = 0; p_sys->p_page && i < p_sys->p_page->i_region_defs; i++ )    {        dvbsub_region_t     *p_region;        dvbsub_regiondef_t  *p_regiondef;        dvbsub_clut_t       *p_clut;        dvbsub_color_t      *p_color;        subpicture_region_t *p_spu_region;        uint8_t *p_src, *p_dst;        video_format_t fmt;        int i_pitch;        i_timeout = p_sys->p_page->i_timeout;        p_regiondef = &p_sys->p_page->p_region_defs[i];#ifdef DEBUG_DVBSUB        msg_Dbg( p_dec, "rendering region %i (%i,%i)", i,                 p_regiondef->i_x, p_regiondef->i_y );#endif        /* Find associated region */        for( p_region = p_sys->p_regions; p_region != NULL;             p_region = p_region->p_next )        {            if( p_regiondef->i_id == p_region->i_id ) break;        }        if( !p_region )        {            msg_Dbg( p_dec, "region %i not found", p_regiondef->i_id );            continue;        }        /* Find associated CLUT */        for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut->p_next )        {            if( p_region->i_clut == p_clut->i_id ) break;        }        if( !p_clut )        {            msg_Dbg( p_dec, "clut %i not found", p_region->i_clut );            continue;        }        /* Create new SPU region */        memset( &fmt, 0, sizeof(video_format_t) );        fmt.i_chroma = VLC_FOURCC('Y','U','V','P');        fmt.i_aspect = 0; /* 0 means use aspect ratio of background video */        fmt.i_width = fmt.i_visible_width = p_region->i_width;        fmt.i_height = fmt.i_visible_height = p_region->i_height;        fmt.i_x_offset = fmt.i_y_offset = 0;        p_spu_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );        if( !p_spu_region )        {            msg_Err( p_dec, "cannot allocate SPU region" );            continue;        }        p_spu_region->i_x = p_regiondef->i_x;        p_spu_region->i_y = p_regiondef->i_y;        *pp_spu_region = p_spu_region;        pp_spu_region = &p_spu_region->p_next;        /* Build palette */        fmt.p_palette->i_entries = p_region->i_depth == 1 ? 4 :            p_region->i_depth == 2 ? 16 : 256;        p_color = (p_region->i_depth == 1) ? p_clut->c_2b :            (p_region->i_depth == 2) ? p_clut->c_4b : p_clut->c_8b;        for( j = 0; j < fmt.p_palette->i_entries; j++ )        {            fmt.p_palette->palette[j][0] = p_color[j].Y;            fmt.p_palette->palette[j][1] = p_color[j].Cb; /* U == Cb */            fmt.p_palette->palette[j][2] = p_color[j].Cr; /* V == Cr */            fmt.p_palette->palette[j][3] = 0xff - p_color[j].T;        }        p_src = p_region->p_pixbuf;        p_dst = p_spu_region->picture.Y_PIXELS;        i_pitch = p_spu_region->picture.Y_PITCH;        /* Copy pixel buffer */        for( j = 0; j < p_region->i_height; j++ )        {            memcpy( p_dst, p_src, p_region->i_width );            p_src += p_region->i_width;            p_dst += i_pitch;        }        /* Check subtitles encoded as strings of characters         * (since there are not rendered in the pixbuffer) */        for( j = 0; j < p_region->i_object_defs; j++ )        {            dvbsub_objectdef_t *p_object_def = &p_region->p_object_defs[j];            if( p_object_def->i_type != 1 || !p_object_def->psz_text )                continue;            /* Create new SPU region */            memset( &fmt, 0, sizeof(video_format_t) );            fmt.i_chroma = VLC_FOURCC('T','E','X','T');            fmt.i_aspect = VOUT_ASPECT_FACTOR;            fmt.i_width = fmt.i_visible_width = p_region->i_width;            fmt.i_height = fmt.i_visible_height = p_region->i_height;            fmt.i_x_offset = fmt.i_y_offset = 0;            p_spu_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );            if( !p_region )            {                msg_Err( p_dec, "cannot allocate SPU region" );                continue;            }            p_spu_region->psz_text = strdup( p_object_def->psz_text );            p_spu_region->i_x = p_regiondef->i_x + p_object_def->i_x;            p_spu_region->i_y = p_regiondef->i_y + p_object_def->i_y;            *pp_spu_region = p_spu_region;            pp_spu_region = &p_spu_region->p_next;        }    }    /* Set the pf_render callback */    p_spu->i_start = p_sys->i_pts;    p_spu->i_stop = p_spu->i_start + (mtime_t) (i_timeout * 1000000);    p_spu->b_ephemer = VLC_TRUE;    p_spu->b_fade = VLC_TRUE;    /* Correct positioning of SPU */    p_spu->b_absolute = p_sys->b_absolute;    p_spu->i_flags = p_sys->i_spu_position;    p_spu->i_x = p_sys->i_spu_x;    p_spu->i_y = p_sys->i_spu_y;    p_spu->i_original_picture_width = 720;    p_spu->i_original_picture_height = 576;    return p_spu;}/***************************************************************************** * encoder_sys_t : encoder descriptor *****************************************************************************/typedef struct encoder_region_t{    int i_width;    int i_height;} encoder_region_t;struct encoder_sys_t{    unsigned int i_page_ver;    unsigned int i_region_ver;    unsigned int i_clut_ver;    int i_regions;    encoder_region_t *p_regions;    mtime_t i_pts;    /* subpicture positioning */    int i_offset_x;    int i_offset_y;};static void encode_page_composition( encoder_t *, bs_t *, subpicture_t * );static void encode_clut( encoder_t *, bs_t *, subpicture_t * );static void encode_region_composition( encoder_t *, bs_t *, subpicture_t * );static void encode_object( encoder_t *, bs_t *, subpicture_t * );/***************************************************************************** * OpenEncoder: probe the encoder and return score *****************************************************************************/static int OpenEncoder( vlc_object_t *p_this ){    encoder_t *p_enc = (encoder_t *)p_this;    encoder_sys_t *p_sys;    vlc_value_t val;    if( p_enc->fmt_out.i_codec != VLC_FOURCC('d','v','b','s') &&        !p_enc->b_force )    {        return VLC_EGENERIC;    }    /* Allocate the memory needed to store the decoder's structure */    if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )    {        msg_Err( p_enc, "out of memory" );        return VLC_ENOMEM;    }    p_enc->p_sys = p_sys;    p_enc->pf_encode_sub = Encode;    p_enc->fmt_out.i_codec = VLC_FOURCC('d','v','b','s');    p_enc->fmt_out.subs.dvb.i_id  = 1 << 16 | 1;    sout_CfgParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );    p_sys->i_page_ver = 0;    p_sys->i_region_ver = 0;    p_sys->i_clut_ver = 0;    p_sys->i_regions = 0;    p_sys->p_regions = 0;    var_Create( p_this, ENC_CFG_PREFIX "x", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    var_Get( p_this, ENC_CFG_PREFIX "x", &val );    p_sys->i_offset_x = val.i_int;    var_Create( p_this, ENC_CFG_PREFIX "y", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    var_Get( p_this, ENC_CFG_PREFIX "y", &val );    p_sys->i_offset_y = val.i_int;    return VLC_SUCCESS;}/* FIXME: this routine is a hack to convert VLC_FOURCC('Y','U','V','A')  *        into VLC_FOURCC('Y','U','V','P') */static subpicture_t *YuvaYuvp( encoder_t *p_enc, subpicture_t *p_subpic ){    subpicture_region_t *p_region = NULL;    if( !p_subpic ) return NULL;    for( p_region = p_subpic->p_region; p_region; p_region = p_region->p_next )    {        video_format_t *p_fmt = &p_region->fmt;        int i = 0, j = 0, n = 0, p = 0;        int i_max_entries = 256;#ifdef RANDOM_DITHERING        int i_seed = 0xdeadbeef; /* random seed */#else        int *pi_delta;#endif        int i_pixels = p_region->picture.p[0].i_visible_lines                        * p_region->picture.p[0].i_pitch;        int i_iterator = p_region->picture.p[0].i_visible_lines * 3 / 4                            * p_region->picture.p[0].i_pitch                        + p_region->picture.p[0].i_pitch * 1 / 3;        int i_tolerance = 0;#if DEBUG_DVBSUB        msg_Dbg( p_enc, "YuvaYuvp: i_pixels=%d, i_iterator=%d", i_pixels, i_iterator );#endif        p_fmt->i_chroma = VLC_FOURCC('Y','U','V','P');        p_fmt->p_palette = (video_palette_t *) malloc( sizeof( video_palette_t ) );        if( !p_fmt->p_palette ) break;        p_fmt->p_palette->i_entries = 0;        /* Find best iterator using Euclide’s algorithm */        for( ; i_iterator > 1 ; i_iterator-- )        {            int a = i_pixels;            int b = i_iterator;            int c;            while( b )            {                c = a % b;                a = b;                b = c;            }            if( a == 1 )            {                break;            }        }        /* Count colors, build best palette */        for( i_tolerance = 0; i_tolerance < 128; i_tolerance++ )        {            vlc_bool_t b_success = VLC_TRUE;            p_fmt->p_palette->i_entries = 0;            for( i = 0; i < i_pixels ; )            {                uint8_t y, u, v, a;                y = p_region->picture.p[0].p_pixels[i];                u = p_region->picture.p[1].p_pixels[i];                v = p_region->picture.p[2].p_pixels[i];                a = p_region->picture.p[3].p_pixels[i];                for( j = 0; j < p_fmt->p_palette->i_entries; j++ )                {                    if( abs((int)p_fmt->p_palette->palette[j][0] - (int)y) <= i_tolerance &&                        abs((int)p_fmt->p_palette->palette[j][1] - (int)u) <= i_tolerance &&                        abs((int)p_fmt->p_palette->palette[j][2] - (int)v) <= i_tolerance &&                        abs((int)p_fmt->p_palette->palette[j][3] - (int)a) <= i_tolerance / 2 )                    {                        break;                    }                }                if( j == p_fmt->p_palette->i_entries )                {                    p_fmt->p_palette->palette[j][0] = y;                    p_fmt->p_palette->palette[j][1] = u;                    p_fmt->p_palette->palette[j][2] = v;                    p_fmt->p_palette->palette[j][3] = a;                    p_fmt->p_palette->i_entries++;                }                if( p_fmt->p_palette->i_entries >= i_max_entries )                {                    b_success = VLC_FALSE;                    break;                }                i += i_iterator;                if( i > i_pixels )                {                    i -= i_pixels;                }            }            if( b_success )            {

⌨️ 快捷键说明

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