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

📄 kate.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * kate.c : a decoder for the kate bitstream format ***************************************************************************** * Copyright (C) 2000-2006 the VideoLAN team * $Id: 09f2ed29fc0fb1089471f297f56593109a64ba8b $ * * Authors: Vincent Penquerc'h <ogg.k.ogg.k@googlemail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_input.h>#include <vlc_codec.h>#include <vlc_osd.h>#include <kate/kate.h>/* #define ENABLE_PACKETIZER */#define ENABLE_FORMATTING#define ENABLE_BITMAPS/***************************************************************************** * decoder_sys_t : decoder descriptor *****************************************************************************/struct decoder_sys_t{#ifdef ENABLE_PACKETIZER    /* Module mode */    bool b_packetizer;#endif    /*     * Input properties     */    int i_num_headers;    int i_headers;    /*     * Kate properties     */    bool           b_ready;    kate_info      ki;    kate_comment   kc;    kate_state     k;    /*     * Common properties     */    mtime_t i_pts;    /*     * Options     */#ifdef ENABLE_FORMATTING    bool   b_formatted;#endif};/***************************************************************************** * Local prototypes *****************************************************************************/static int  OpenDecoder   ( vlc_object_t * );static void CloseDecoder  ( vlc_object_t * );#ifdef ENABLE_PACKETIZERstatic int OpenPacketizer( vlc_object_t *p_this );#endifstatic subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block );static int ProcessHeaders( decoder_t *p_dec );static subpicture_t *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,                            block_t **pp_block );static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp,                            block_t *p_block );static void ParseKateComments( decoder_t * );#define DEFAULT_NAME "Default"#define MAX_LINE 8192/***************************************************************************** * Module descriptor. *****************************************************************************/#ifdef ENABLE_FORMATTING#define FORMAT_TEXT N_("Formatted Subtitles")#define FORMAT_LONGTEXT N_("Kate streams allow for text formatting. " \ "VLC partly implements this, but you can choose to disable all formatting.")#endifvlc_module_begin();    set_shortname( N_("Kate"));    set_description( N_("Kate text subtitles decoder") );    set_capability( "decoder", 50 );    set_callbacks( OpenDecoder, CloseDecoder );    set_category( CAT_INPUT );    set_subcategory( SUBCAT_INPUT_SCODEC );    add_shortcut( "kate" );#ifdef ENABLE_PACKETIZER    add_submodule();    set_description( N_("Kate text subtitles packetizer") );    set_capability( "packetizer", 100 );    set_callbacks( OpenPacketizer, CloseDecoder );    add_shortcut( "kate" );#endif#ifdef ENABLE_FORMATTING    add_bool( "kate-formatted", true, NULL, FORMAT_TEXT, FORMAT_LONGTEXT,              true );#endifvlc_module_end();/***************************************************************************** * OpenDecoder: probe the decoder and return score ***************************************************************************** * Tries to launch a decoder and return score so that the interface is able * to chose. *****************************************************************************/static int OpenDecoder( vlc_object_t *p_this ){    decoder_t     *p_dec = (decoder_t*)p_this;    decoder_sys_t *p_sys;    msg_Dbg( p_dec, "kate: OpenDecoder");    if( p_dec->fmt_in.i_codec != VLC_FOURCC('k','a','t','e') )    {        return VLC_EGENERIC;    }    /* Set callbacks */    p_dec->pf_decode_sub = (subpicture_t *(*)(decoder_t *, block_t **))        DecodeBlock;    p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))        DecodeBlock;    /* Allocate the memory needed to store the decoder's structure */    if( ( p_dec->p_sys = p_sys =          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )        return VLC_ENOMEM;    /* init of p_sys */#ifdef ENABLE_PACKETIZER    p_sys->b_packetizer = false;#endif    p_sys->b_ready = false;    p_sys->i_pts = 0;    kate_comment_init( &p_sys->kc );    kate_info_init( &p_sys->ki );    p_sys->i_num_headers = 0;    p_sys->i_headers = 0;    /* retrieve options */#ifdef ENABLE_FORMATTING    p_sys->b_formatted = var_CreateGetBool( p_dec, "kate-formatted" );#endif    return VLC_SUCCESS;}#ifdef ENABLE_PACKETIZERstatic int OpenPacketizer( vlc_object_t *p_this ){    decoder_t *p_dec = (decoder_t*)p_this;    int i_ret = OpenDecoder( p_this );    if( i_ret == VLC_SUCCESS )    {        p_dec->p_sys->b_packetizer = true;        p_dec->fmt_out.i_codec = VLC_FOURCC( 'k', 'a', 't', 'e' );    }    return i_ret;}#endif/**************************************************************************** * DecodeBlock: the whole thing **************************************************************************** * This function must be fed with kate packets. ****************************************************************************/static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ){    decoder_sys_t *p_sys = p_dec->p_sys;    block_t *p_block;    kate_packet kp;    if( !pp_block || !*pp_block )        return NULL;    p_block = *pp_block;    if( p_block->i_rate != 0 )        p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT;    /* Block to Kate packet */    kate_packet_wrap(&kp, p_block->i_buffer, p_block->p_buffer);    if( p_sys->i_headers == 0 && p_dec->fmt_in.i_extra )    {        /* Headers already available as extra data */        p_sys->i_num_headers = ((unsigned char*)p_dec->fmt_in.p_extra)[0];        p_sys->i_headers = p_sys->i_num_headers;    }    else if( kp.nbytes && (p_sys->i_headers==0 || p_sys->i_headers < p_sys->ki.num_headers ))    {        /* Backup headers as extra data */        uint8_t *p_extra;        p_dec->fmt_in.p_extra =            realloc( p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra + kp.nbytes + 2 );        p_extra = (void*)(((unsigned char*)p_dec->fmt_in.p_extra) + p_dec->fmt_in.i_extra);        *(p_extra++) = kp.nbytes >> 8;        *(p_extra++) = kp.nbytes & 0xFF;        memcpy( p_extra, kp.data, kp.nbytes );        p_dec->fmt_in.i_extra += kp.nbytes + 2;        block_Release( *pp_block );        p_sys->i_num_headers = ((unsigned char*)p_dec->fmt_in.p_extra)[0];        p_sys->i_headers++;        return NULL;    }    if( p_sys->i_headers == p_sys->i_num_headers && p_sys->i_num_headers>0 )    {        if( ProcessHeaders( p_dec ) != VLC_SUCCESS )        {            p_sys->i_headers = 0;            p_dec->fmt_in.i_extra = 0;            block_Release( *pp_block );            return NULL;        }        else p_sys->i_headers++;    }    return ProcessPacket( p_dec, &kp, pp_block );}/***************************************************************************** * ProcessHeaders: process Kate headers. *****************************************************************************/static int ProcessHeaders( decoder_t *p_dec ){    decoder_sys_t *p_sys = p_dec->p_sys;    kate_packet kp;    uint8_t *p_extra;    int i_extra;    int headeridx;    int ret;    if( !p_dec->fmt_in.i_extra ) return VLC_EGENERIC;    p_extra = p_dec->fmt_in.p_extra;    i_extra = p_dec->fmt_in.i_extra;    /* skip number of headers */    ++p_extra;    --i_extra;    /* Take care of the initial Kate header */    kp.nbytes = *(p_extra++) << 8;    kp.nbytes |= (*(p_extra++) & 0xFF);    kp.data = p_extra;    p_extra += kp.nbytes;    i_extra -= (kp.nbytes + 2);    if( i_extra < 0 )    {        msg_Err( p_dec, "header data corrupted");        return VLC_EGENERIC;    }    ret = kate_decode_headerin( &p_sys->ki, &p_sys->kc, &kp );    if( ret < 0 )    {        msg_Err( p_dec, "this bitstream does not contain Kate data (%d)", ret );        return VLC_EGENERIC;    }    msg_Dbg( p_dec, "%s %s text, granule rate %f, granule shift %d",             p_sys->ki.language, p_sys->ki.category,             (double)p_sys->ki.gps_numerator/p_sys->ki.gps_denominator,             p_sys->ki.granule_shift);    /* parse all remaining header packets */    for (headeridx=1; headeridx<p_sys->ki.num_headers; ++headeridx)    {        kp.nbytes = *(p_extra++) << 8;        kp.nbytes |= (*(p_extra++) & 0xFF);        kp.data = p_extra;        p_extra += kp.nbytes;        i_extra -= (kp.nbytes + 2);        if( i_extra < 0 )        {            msg_Err( p_dec, "header %d data corrupted", headeridx);            return VLC_EGENERIC;        }        ret = kate_decode_headerin( &p_sys->ki, &p_sys->kc, &kp );        if( ret < 0 )        {            msg_Err( p_dec, "Kate header %d is corrupted: %d", headeridx, ret);            return VLC_EGENERIC;        }        /* header 1 is comments */        if( headeridx == 1 )        {            ParseKateComments( p_dec );        }    }#ifdef ENABLE_PACKETIZER    if( !p_sys->b_packetizer )#endif    {        /* We have all the headers, initialize decoder */        msg_Dbg( p_dec, "we have all headers, initialize libkate for decoding" );        ret = kate_decode_init( &p_sys->k, &p_sys->ki );        if (ret < 0)        {            msg_Err( p_dec, "Kate failed to initialize for decoding: %d", ret );            return VLC_EGENERIC;        }        p_sys->b_ready = true;    }#ifdef ENABLE_PACKETIZER    else    {        p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;        p_dec->fmt_out.p_extra =            realloc( p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra );        memcpy( p_dec->fmt_out.p_extra,                p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );    }#endif    return VLC_SUCCESS;}/***************************************************************************** * ProcessPacket: processes a kate packet. *****************************************************************************/static subpicture_t *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,                            block_t **pp_block ){    decoder_sys_t *p_sys = p_dec->p_sys;    block_t *p_block = *pp_block;    subpicture_t *p_buf = NULL;    /* Date management */    if( p_block->i_pts > 0 && p_block->i_pts != p_sys->i_pts )    {        p_sys->i_pts = p_block->i_pts;    }

⌨️ 快捷键说明

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