sub.c

来自「VLC媒体播放程序」· C语言 代码 · 共 1,224 行 · 第 1/3 页

C
1,224
字号
                if( ( s = text_get_line( txt ) ) == NULL )                {                    return( VLC_EGENERIC );                }                i_len = strlen( s );                if( i_len <= 1 )                {                    /* empty line -> end of this subtitle */                    buffer_text[__MAX( i_buffer_text - 1, 0 )] = '\0';                    p_subtitle->i_start = i_start;                    p_subtitle->i_stop = i_stop;                    p_subtitle->psz_text = strdup( buffer_text );                    return( 0 );                }                else                {                    if( i_buffer_text + i_len + 1 < 10 * MAX_LINE )                    {                        memcpy( buffer_text + i_buffer_text,                                s,                                i_len );                        i_buffer_text += i_len;                        buffer_text[i_buffer_text] = '\n';                        i_buffer_text++;                    }                }            }        }    }}static int  sub_SSARead( subtitle_demux_t *p_sub, text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe ){    char buffer_text[ 10 * MAX_LINE];    char *s;    mtime_t     i_start;    mtime_t     i_stop;    p_subtitle->i_start = 0;    p_subtitle->i_stop  = 0;    p_subtitle->i_vobsub_location  = 0;    p_subtitle->psz_text = NULL;    for( ;; )    {        int h1, m1, s1, c1, h2, m2, s2, c2;        int i_dummy;        if( ( s = text_get_line( txt ) ) == NULL )        {            return( VLC_EGENERIC );        }        p_subtitle->psz_text = malloc( strlen( s ) );        if( sscanf( s,                    "Dialogue: Marked=%d,%d:%d:%d.%d,%d:%d:%d.%d%[^\r\n]",                    &i_dummy,                    &h1, &m1, &s1, &c1,                    &h2, &m2, &s2, &c2,                    buffer_text ) == 10 )        {            i_start = ( (mtime_t)h1 * 3600*1000 +                        (mtime_t)m1 * 60*1000 +                        (mtime_t)s1 * 1000 +                        (mtime_t)c1 * 10 ) * 1000;            i_stop  = ( (mtime_t)h2 * 3600*1000 +                        (mtime_t)m2 * 60*1000 +                        (mtime_t)s2 * 1000 +                        (mtime_t)c2 * 10 ) * 1000;            /* The dec expects: ReadOrder, Layer, Style, Name, MarginL, MarginR, MarginV, Effect, Text */            if( p_sub->i_sub_type == SUB_TYPE_SSA1 )            {                sprintf( p_subtitle->psz_text, ",%d%s", i_dummy, strdup( buffer_text) );            }            else            {                sprintf( p_subtitle->psz_text, ",%d,%s", i_dummy, strdup( buffer_text) );            }            p_subtitle->i_start = i_start;            p_subtitle->i_stop = i_stop;            return( 0 );        }        else        {            /* All the other stuff we add to the header field */            if( p_sub->psz_header != NULL )            {                if( !( p_sub->psz_header = realloc( p_sub->psz_header,                          strlen( p_sub->psz_header ) + strlen( s ) + 2 ) ) )                {                    msg_Err( p_sub, "out of memory");                    return VLC_ENOMEM;                }                p_sub->psz_header = strcat( p_sub->psz_header, strdup( s ) );                p_sub->psz_header = strcat( p_sub->psz_header, "\n" );            }            else            {                if( !( p_sub->psz_header = malloc( strlen( s ) + 2 ) ) )                {                    msg_Err( p_sub, "out of memory");                    return VLC_ENOMEM;                }                p_sub->psz_header = strdup( s );                p_sub->psz_header = strcat( p_sub->psz_header, "\n" );            }        }    }}static int  sub_Vplayer( subtitle_demux_t *p_sub, text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe){    /*     * each line:     *  h:m:s:Line1|Line2|Line3....     *  or     *  h:m:s Line1|Line2|Line3....     * where n1 and n2 are the video frame number...     *     */    char *p;    char buffer_text[MAX_LINE + 1];    mtime_t    i_start;    unsigned int i;        p_subtitle->i_start = 0;    p_subtitle->i_stop  = 0;    p_subtitle->i_vobsub_location  = 0;    p_subtitle->psz_text = NULL;    for( ;; )    {        int h, m, s;        char c;        if( ( p = text_get_line( txt ) ) == NULL )        {            return( VLC_EGENERIC );        }        i_start = 0;        memset( buffer_text, '\0', MAX_LINE );        if( sscanf( p, "%d:%d:%d%[ :]%[^\r\n]", &h, &m, &s, &c, buffer_text ) == 5 )        {            i_start = ( (mtime_t)h * 3600*1000 +                        (mtime_t)m * 60*1000 +                        (mtime_t)s * 1000 ) * 1000;            break;        }    }    /* replace | by \n */    for( i = 0; i < strlen( buffer_text ); i++ )    {        if( buffer_text[i] == '|' )        {            buffer_text[i] = '\n';        }    }    p_subtitle->i_start = i_start;    p_subtitle->i_stop  = 0;    p_subtitle->psz_text = strndup( buffer_text, MAX_LINE );    return( 0 );}static char *sub_SamiSearch( text_t *txt, char *psz_start, char *psz_str ){    if( psz_start )    {        if( local_stristr( psz_start, psz_str ) )        {            char *s = local_stristr( psz_start, psz_str );            s += strlen( psz_str );            return( s );        }    }    for( ;; )    {        char *p;        if( ( p = text_get_line( txt ) ) == NULL )        {            return NULL;        }        if( local_stristr( p, psz_str ) )        {            char *s = local_stristr( p, psz_str );            s += strlen( psz_str );            return(  s);        }    }}static int  sub_Sami( subtitle_demux_t *p_sub, text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe ){    char *p;    int i_start;    int  i_text;    char buffer_text[10*MAX_LINE + 1];    p_subtitle->i_start = 0;    p_subtitle->i_stop  = 0;    p_subtitle->i_vobsub_location  = 0;    p_subtitle->psz_text = NULL;#define ADDC( c ) \    if( i_text < 10*MAX_LINE )      \    {                               \        buffer_text[i_text++] = c;  \        buffer_text[i_text] = '\0'; \    }    /* search "Start=" */    if( !( p = sub_SamiSearch( txt, NULL, "Start=" ) ) )    {        return VLC_EGENERIC;    }    /* get start value */    i_start = strtol( p, &p, 0 );    /* search <P */    if( !( p = sub_SamiSearch( txt, p, "<P" ) ) )    {        return VLC_EGENERIC;    }    /* search > */    if( !( p = sub_SamiSearch( txt, p, ">" ) ) )    {        return VLC_EGENERIC;    }    i_text = 0;    buffer_text[0] = '\0';    /* now get all txt until  a "Start=" line */    for( ;; )    {        if( *p )        {            if( *p == '<' )            {                if( !strncasecmp( p, "<br", 3 ) )                {                    ADDC( '\n' );                }                else if( local_stristr( p, "Start=" ) )                {                    text_previous_line( txt );                    break;                }                p = sub_SamiSearch( txt, p, ">" );            }            else if( !strncmp( p, "&nbsp;", 6 ) )            {                ADDC( ' ' );                p += 6;            }            else if( *p == '\t' )            {                ADDC( ' ' );                p++;            }            else            {                ADDC( *p );                p++;            }        }        else        {            p = text_get_line( txt );        }        if( p == NULL )        {            break;        }    }    p_subtitle->i_start = i_start * 1000;    p_subtitle->i_stop  = 0;    p_subtitle->psz_text = strndup( buffer_text, 10*MAX_LINE );    return( VLC_SUCCESS );#undef ADDC}static int  sub_VobSubIDX( subtitle_demux_t *p_sub, text_t *txt, subtitle_t *p_subtitle, mtime_t i_microsecperframe){    /*     * Parse the idx file. Each line:     * timestamp: hh:mm:ss:mss, filepos: loc     * hexint is the hex location of the vobsub in the .sub file     *     */    char *p;    char buffer_text[MAX_LINE + 1];    unsigned int    i_start, i_location;    p_subtitle->i_start = 0;    p_subtitle->i_stop  = 0;    p_subtitle->i_vobsub_location  = 0;    p_subtitle->psz_text = NULL;    for( ;; )    {        unsigned int h, m, s, ms, loc;        if( ( p = text_get_line( txt ) ) == NULL )        {            return( VLC_EGENERIC );        }        i_start = 0;        memset( buffer_text, '\0', MAX_LINE );        if( sscanf( p, "timestamp: %d:%d:%d:%d, filepos: %x%[^\r\n]",                    &h, &m, &s, &ms, &loc, buffer_text ) == 5 )        {            i_start = ( (mtime_t)h * 3600*1000 +                        (mtime_t)m * 60*1000 +                        (mtime_t)s * 1000 +                        (mtime_t)ms ) * 1000;            i_location = loc;            break;        }    }    p_subtitle->i_start = (mtime_t)i_start;    p_subtitle->i_stop  = 0;    p_subtitle->psz_text = NULL;    p_subtitle->i_vobsub_location = i_location;    fprintf( stderr, "time: %x, location: %x\n", i_start, i_location );    return( 0 );}static int  DemuxVobSub( subtitle_demux_t *p_demux, block_t *p_bk ){    uint8_t     *p = p_bk->p_buffer;    uint8_t     *p_end = &p_bk->p_buffer[p_bk->i_buffer];    while( p < p_end )    {        int i_size = ps_pkt_size( p, p_end - p );        block_t *p_pkt;        int      i_id;        int      i_spu;        if( i_size <= 0 )        {            break;        }        if( p[0] != 0 || p[1] != 0 || p[2] != 0x01 )        {            msg_Warn( p_demux, "invalid PES" );            break;        }        if( p[3] != 0xbd )        {            msg_Dbg( p_demux, "we don't need these ps packets (id=0x1%2.2x)", p[3] );            p += i_size;            continue;        }        /* Create a block */        p_pkt = block_New( p_demux, i_size );        memcpy( p_pkt->p_buffer, p, i_size);        p += i_size;        i_id = ps_pkt_id( p_pkt );        if( (i_id&0xffe0) != 0xbd20 ||            ps_pkt_parse_pes( p_pkt, 1 ) )        {            block_Release( p_pkt );            continue;        }        i_spu = i_id&0x1f;        msg_Dbg( p_demux, "SPU track %d size %d", i_spu, i_size );        /* FIXME i_spu == determines which of the spu tracks we will show. */        if( p_demux->p_es && i_spu == 0 )        {            p_pkt->i_pts = p_bk->i_pts;            p_pkt->i_dts = 0;            es_out_Send( p_demux->p_input->p_es_out, p_demux->p_es, p_pkt );            p_bk->i_pts = 0;    /* only first packet has a pts */        }        else        {            block_Release( p_pkt );            continue;        }    }    return VLC_SUCCESS;}

⌨️ 快捷键说明

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