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

📄 kate.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
    *pp_block = NULL; /* To avoid being fed the same packet again */#ifdef ENABLE_PACKETIZER    if( p_sys->b_packetizer )    {        /* Date management */        p_block->i_dts = p_block->i_pts = p_sys->i_pts;        if( p_sys->i_headers >= p_sys->i_num_headers )            p_block->i_length = p_sys->i_pts - p_block->i_pts;        else            p_block->i_length = 0;        p_buf = p_block;    }    else#endif    {        if( p_sys->i_headers >= p_sys->i_num_headers )            p_buf = DecodePacket( p_dec, p_kp, p_block );        else            p_buf = NULL;        if( p_block ) block_Release( p_block );    }    return p_buf;}#ifdef ENABLE_BITMAPS/* nicked off blend.c */static inline void rgb_to_yuv( uint8_t *y, uint8_t *u, uint8_t *v,                               int r, int g, int b ){    *y = ( ( (  66 * r + 129 * g +  25 * b + 128 ) >> 8 ) + 16 );    *u =   ( ( -38 * r -  74 * g + 112 * b + 128 ) >> 8 ) + 128 ;    *v =   ( ( 112 * r -  94 * g -  18 * b + 128 ) >> 8 ) + 128 ;}#endif/*  This retrieves the size of the video.  The best case is when the original video size is known, as we can then  scale images to match. In this case, since VLC autoscales, we want to  return the original size and let VLC scale everything.  if the original size is not known, then VLC can't resize, so we return  the size of the incoming video. If sizes in the Kate stream are in  relative units, it works fine. If they are absolute, you get what you  ask for. Images aren't rescaled.*/static void GetVideoSize( decoder_t *p_dec, int *w, int *h ){    /* searching for vout to get its size is frowned upon, so we don't and       use a default size if the original canvas size is not specified. */#if 1    decoder_sys_t *p_sys = p_dec->p_sys;    if( p_sys->ki.original_canvas_width > 0 && p_sys->ki.original_canvas_height > 0 )    {        *w = p_sys->ki.original_canvas_width;        *h = p_sys->ki.original_canvas_height;        msg_Dbg( p_dec, "original canvas %zu %zu\n",	         p_sys->ki.original_canvas_width, p_sys->ki.original_canvas_height );    }    else    {        /* nothing, leave defaults */        msg_Dbg( p_dec, "original canvas size unknown\n");    }#else    /* keep this just in case it might be allowed one day ;) */    vout_thread_t *p_vout;    p_vout = vlc_object_find( (vlc_object_t*)p_dec, VLC_OBJECT_VOUT, FIND_CHILD );    if( p_vout )    {        decoder_sys_t *p_sys = p_dec->p_sys;        if( p_sys->ki.original_canvas_width > 0 && p_sys->ki.original_canvas_height > 0 )        {            *w = p_sys->ki.original_canvas_width;            *h = p_sys->ki.original_canvas_height;        }        else        {            *w = p_vout->fmt_in.i_width;            *h = p_vout->fmt_in.i_height;        }        msg_Dbg( p_dec, "video: in %d %d, out %d %d, original canvas %zu %zu\n",                 p_vout->fmt_in.i_width, p_vout->fmt_in.i_height,                 p_vout->fmt_out.i_width, p_vout->fmt_out.i_height,                 p_sys->ki.original_canvas_width, p_sys->ki.original_canvas_height );        vlc_object_release( p_vout );    }#endif}#ifdef ENABLE_BITMAPSstatic void CreateKateBitmap( picture_t *pic, const kate_bitmap *bitmap ){    size_t y;    for( y=0; y<bitmap->height; ++y )    {        uint8_t *dest = pic->Y_PIXELS+pic->Y_PITCH*y;        const uint8_t *src = bitmap->pixels+y*bitmap->width;        memcpy( dest, src, bitmap->width );    }}static void CreateKatePalette( video_palette_t *fmt_palette, const kate_palette *palette ){    size_t n;    fmt_palette->i_entries = palette->ncolors;    for( n=0; n<palette->ncolors; ++n )    {        rgb_to_yuv(            &fmt_palette->palette[n][0], &fmt_palette->palette[n][1], &fmt_palette->palette[n][2],            palette->colors[n].r, palette->colors[n].g, palette->colors[n].b        );        fmt_palette->palette[n][3] = palette->colors[n].a;    }}#endifstatic void SetupText( decoder_t *p_dec, subpicture_t *p_spu, const kate_event *ev ){    decoder_sys_t *p_sys = p_dec->p_sys;    if( ev->text_encoding != kate_utf8 )    {        msg_Warn( p_dec, "Text isn't UTF-8, unsupported, ignored" );        return;    }    switch( ev->text_markup_type )    {        case kate_markup_none:            p_spu->p_region->psz_text = strdup( ev->text ); /* no leak, this actually gets killed by the core */            break;        case kate_markup_simple:            if( p_sys->b_formatted )            {                /* the HTML renderer expects a top level text tag pair */                char *buffer = NULL;                if( asprintf( &buffer, "<text>%s</text>", ev->text ) >= 0 )                {                    p_spu->p_region->psz_html = buffer;                }                break;            }            /* if not formatted, we fall through */        default:            /* we don't know about this one, so remove markup and display as text */            {                char *copy = strdup( ev->text );                size_t len0 = strlen( copy ) + 1;                kate_text_remove_markup( ev->text_encoding, copy, &len0 );                p_spu->p_region->psz_text = copy;            }            break;    }}/***************************************************************************** * DecodePacket: decodes a Kate packet. *****************************************************************************/static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp, block_t *p_block ){    decoder_sys_t *p_sys = p_dec->p_sys;    const kate_event *ev = NULL;    subpicture_t *p_spu = NULL;    subpicture_region_t *p_bitmap_region = NULL;    int ret;    video_format_t fmt;    kate_tracker kin;    bool tracker_valid = false;    ret = kate_decode_packetin( &p_sys->k, p_kp );    if( ret < 0 )    {        msg_Err( p_dec, "Kate failed to decode packet: %d", ret );        return NULL;    }    ret = kate_decode_eventout( &p_sys->k, &ev );    if( ret < 0 )    {        msg_Err( p_dec, "Kate failed to retrieve event: %d", ret );        return NULL;    }    if( ret > 0 )    {        /* no event to go with this packet, this is normal */        return NULL;    }    /* we have an event */    /* Get a new spu */    p_spu = p_dec->pf_spu_buffer_new( p_dec );    if( !p_spu )    {        msg_Err( p_dec, "Failed to allocate spu buffer" );        return NULL;    }    p_spu->b_pausable = true;    /* these may be 0 for "not specified" */    p_spu->i_original_picture_width = p_sys->ki.original_canvas_width;    p_spu->i_original_picture_height = p_sys->ki.original_canvas_height;    /* Create a new subpicture region */    memset( &fmt, 0, sizeof(video_format_t) );#ifdef ENABLE_FORMATTING    if (p_sys->b_formatted)    {        ret = kate_tracker_init( &kin, &p_sys->ki, ev );        if( ret < 0)        {            msg_Err( p_dec, "failed to initialize kate tracker, event will be unformatted: %d", ret );        }        else        {            int w = 720, h = 576; /* give sensible defaults just in case we fail to get the actual size */            GetVideoSize(p_dec, &w, &h);            ret = kate_tracker_update(&kin, 0, w, h, 0, 0, w, h);            if( ret < 0)            {                kate_tracker_clear(&kin);                msg_Err( p_dec, "failed to update kate tracker, event will be unformatted: %d", ret );            }            else            {                // TODO: parse tracker and set style, init fmt                tracker_valid = true;            }        }    }#endif#ifdef ENABLE_BITMAPS    if (ev->bitmap && ev->bitmap->type==kate_bitmap_type_paletted && ev->palette) {        /* create a separate region for the bitmap */        memset( &fmt, 0, sizeof(video_format_t) );        fmt.i_chroma = VLC_FOURCC('Y','U','V','P');        fmt.i_aspect = 0;        fmt.i_width = fmt.i_visible_width = ev->bitmap->width;        fmt.i_height = fmt.i_visible_height = ev->bitmap->height;        fmt.i_x_offset = fmt.i_y_offset = 0;        p_bitmap_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );        if( !p_bitmap_region )        {            msg_Err( p_dec, "cannot allocate SPU region" );            p_dec->pf_spu_buffer_del( p_dec, p_spu );            return NULL;        }        /* create the palette */        CreateKatePalette( fmt.p_palette, ev->palette );        /* create the bitmap */        CreateKateBitmap( &p_bitmap_region->picture, ev->bitmap );        msg_Dbg(p_dec, "Created bitmap, %zux%zu, %zu colors\n", ev->bitmap->width, ev->bitmap->height, ev->palette->ncolors);    }#endif    /* text region */    fmt.i_chroma = VLC_FOURCC('T','E','X','T');    fmt.i_aspect = 0;    fmt.i_width = fmt.i_height = 0;    fmt.i_x_offset = fmt.i_y_offset = 0;    p_spu->p_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );    if( !p_spu->p_region )    {        msg_Err( p_dec, "cannot allocate SPU region" );        p_dec->pf_spu_buffer_del( p_dec, p_spu );        return NULL;    }    SetupText( p_dec, p_spu, ev );    p_spu->i_start = p_block->i_pts;    p_spu->i_stop = p_block->i_pts + INT64_C(1000000)*ev->duration*p_sys->ki.gps_denominator/p_sys->ki.gps_numerator;    p_spu->b_ephemer = (p_block->i_length == 0);    p_spu->b_absolute = false;    /* default positioning */    p_spu->p_region->i_align = SUBPICTURE_ALIGN_BOTTOM;    if (p_bitmap_region)    {        p_bitmap_region->i_align = SUBPICTURE_ALIGN_BOTTOM;    }    p_spu->i_x = 0;    p_spu->i_y = 10;    /* override if tracker info present */    if (tracker_valid)    {        p_spu->i_flags = 0;        if (kin.has.region)        {            p_spu->i_x = kin.region_x;            p_spu->i_y = kin.region_y;            p_spu->b_absolute = true;        }        kate_tracker_clear(&kin);    }#ifdef ENABLE_BITMAPS    /* if we have a bitmap, chain it before the text */    if (p_bitmap_region)    {        p_bitmap_region->p_next = p_spu->p_region;        p_spu->p_region = p_bitmap_region;    }#endif    return p_spu;}/***************************************************************************** * ParseKateComments: FIXME should be done in demuxer *****************************************************************************/static void ParseKateComments( decoder_t *p_dec ){    input_thread_t *p_input = (input_thread_t *)p_dec->p_parent;    char *psz_name, *psz_value, *psz_comment;    int i = 0;    if( p_input->i_object_type != VLC_OBJECT_INPUT ) return;    while ( i < p_dec->p_sys->kc.comments )    {        psz_comment = strdup( p_dec->p_sys->kc.user_comments[i] );        if( !psz_comment )        {            msg_Warn( p_dec, "out of memory" );            break;        }        psz_name = psz_comment;        psz_value = strchr( psz_comment, '=' );        if( psz_value )        {            *psz_value = '\0';            psz_value++;            input_Control( p_input, INPUT_ADD_INFO, _("Kate comment"),                           psz_name, "%s", psz_value );        }        free( psz_comment );        i++;    }}/***************************************************************************** * CloseDecoder: clean up the decoder *****************************************************************************/static void CloseDecoder( vlc_object_t *p_this ){    decoder_t *p_dec = (decoder_t *)p_this;    decoder_sys_t *p_sys = p_dec->p_sys;    if (p_sys->b_ready)        kate_clear( &p_sys->k );    kate_info_clear( &p_sys->ki );    kate_comment_clear( &p_sys->kc );    free( p_sys );}

⌨️ 快捷键说明

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