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

📄 subsdec.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* Create a new subpicture region */    memset( &fmt, 0, sizeof(video_format_t) );    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" );        free( psz_subtitle );        p_dec->pf_spu_buffer_del( p_dec, p_spu );        return NULL;    }    /* Decode and format the subpicture unit */    if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','s','a',' ') )    {        /* Normal text subs, easy markup */        p_spu->p_region->i_align = SUBPICTURE_ALIGN_BOTTOM | p_sys->i_align;        p_spu->i_x = p_sys->i_align ? 20 : 0;        p_spu->i_y = 10;        /* Remove formatting from string */        p_spu->p_region->psz_text = StripTags( psz_subtitle );        if( var_CreateGetBool( p_dec, "subsdec-formatted" ) )        {            p_spu->p_region->psz_html = CreateHtmlSubtitle( psz_subtitle );        }        p_spu->i_start = p_block->i_pts;        p_spu->i_stop = p_block->i_pts + p_block->i_length;        p_spu->b_ephemer = (p_block->i_length == 0);        p_spu->b_absolute = false;    }    else    {        /* Decode SSA/USF strings */        if( p_dec->fmt_in.i_codec == VLC_FOURCC('s','s','a',' ') )            ParseSSAString( p_dec, psz_subtitle, p_spu );        p_spu->i_start = p_block->i_pts;        p_spu->i_stop = p_block->i_pts + p_block->i_length;        p_spu->b_ephemer = (p_block->i_length == 0);        p_spu->b_absolute = false;        p_spu->i_original_picture_width = p_sys->i_original_width;        p_spu->i_original_picture_height = p_sys->i_original_height;    }    free( psz_subtitle );    return p_spu;}char* GotoNextLine( char *psz_text ){    char *p_newline = psz_text;    while( p_newline[0] != '\0' )    {        if( p_newline[0] == '\n' || p_newline[0] == '\r' )        {            p_newline++;            while( p_newline[0] == '\n' || p_newline[0] == '\r' )                p_newline++;            break;        }        else p_newline++;    }    return p_newline;}/* Function now handles tags with attribute values, and tries * to deal with &' commands too. It no longer modifies the string * in place, so that the original text can be reused */static char *StripTags( char *psz_subtitle ){    char *psz_text_start;    char *psz_text;    psz_text = psz_text_start = malloc( strlen( psz_subtitle ) + 1 );    if( !psz_text_start )        return NULL;    while( *psz_subtitle )    {        if( *psz_subtitle == '<' )        {            if( strncasecmp( psz_subtitle, "<br/>", 5 ) == 0 )                *psz_text++ = '\n';            psz_subtitle += strcspn( psz_subtitle, ">" );        }        else if( *psz_subtitle == '&' )        {            if( !strncasecmp( psz_subtitle, "&lt;", 4 ))            {                *psz_text++ = '<';                psz_subtitle += strcspn( psz_subtitle, ";" );            }            else if( !strncasecmp( psz_subtitle, "&gt;", 4 ))            {                *psz_text++ = '>';                psz_subtitle += strcspn( psz_subtitle, ";" );            }            else if( !strncasecmp( psz_subtitle, "&amp;", 5 ))            {                *psz_text++ = '&';                psz_subtitle += strcspn( psz_subtitle, ";" );            }            else if( !strncasecmp( psz_subtitle, "&quot;", 6 ))            {                *psz_text++ = '\"';                psz_subtitle += strcspn( psz_subtitle, ";" );            }            else            {                /* Assume it is just a normal ampersand */                *psz_text++ = '&';            }        }        else        {            *psz_text++ = *psz_subtitle;        }        psz_subtitle++;    }    *psz_text = '\0';    psz_text_start = realloc( psz_text_start, strlen( psz_text_start ) + 1 );    return psz_text_start;}/* Try to respect any style tags present in the subtitle string. The main * problem here is a lack of adequate specs for the subtitle formats. * SSA/ASS and USF are both detail spec'ed -- but they are handled elsewhere. * SAMI has a detailed spec, but extensive rework is needed in the demux * code to prevent all this style information being excised, as it presently * does. * That leaves the others - none of which were (I guess) originally intended * to be carrying style information. Over time people have used them that way. * In the absence of specifications from which to work, the tags supported * have been restricted to the simple set permitted by the USF DTD, ie. : *  Basic: <br>, <i>, <b>, <u> *  Extended: <font> *    Attributes: face *                family *                size *                color *                outline-color *                shadow-color *                outline-level *                shadow-level *                back-color *                alpha * There is also the further restriction that the subtitle be well-formed * as an XML entity, ie. the HTML sentence: *        <b><i>Bold and Italics</b></i> * doesn't qualify because the tags aren't nested one inside the other. * <text> tags are automatically added to the output to ensure * well-formedness. * If the text doesn't qualify for any reason, a NULL string is * returned, and the rendering engine will fall back to the * plain text version of the subtitle. */static void HtmlNPut( char **ppsz_html, const char *psz_text, int i_max ){    const int i_len = strlen(psz_text);    strncpy( *ppsz_html, psz_text, i_max );    *ppsz_html += __MIN(i_max,i_len);}static void HtmlPut( char **ppsz_html, const char *psz_text ){    strcpy( *ppsz_html, psz_text );    *ppsz_html += strlen(psz_text);}static void HtmlCopy( char **ppsz_html, char **ppsz_subtitle, const char *psz_text ){    HtmlPut( ppsz_html, psz_text );    *ppsz_subtitle += strlen(psz_text);}static char *CreateHtmlSubtitle( char *psz_subtitle ){    char   *psz_tag = malloc( ( strlen( psz_subtitle ) / 3 ) + 1 );    if( !psz_tag ) return NULL;    size_t  i_buf_size     = strlen( psz_subtitle ) + 100;    char   *psz_html_start = malloc( i_buf_size );    psz_tag[ 0 ] = '\0';    if( psz_html_start == NULL )    {        free( psz_tag );        return NULL;    }        char *psz_html = psz_html_start;    strcpy( psz_html, "<text>" );    psz_html += 6;    while( *psz_subtitle )    {        if( *psz_subtitle == '\n' )        {            HtmlPut( &psz_html, "<br/>" );            psz_subtitle++;        }        else if( *psz_subtitle == '<' )        {            if( !strncasecmp( psz_subtitle, "<br/>", 5 ))            {                HtmlCopy( &psz_html, &psz_subtitle, "<br/>" );            }            else if( !strncasecmp( psz_subtitle, "<b>", 3 ) )            {                HtmlCopy( &psz_html, &psz_subtitle, "<b>" );                strcat( psz_tag, "b" );            }            else if( !strncasecmp( psz_subtitle, "<i>", 3 ) )            {                HtmlCopy( &psz_html, &psz_subtitle, "<i>" );                strcat( psz_tag, "i" );            }            else if( !strncasecmp( psz_subtitle, "<u>", 3 ) )            {                HtmlCopy( &psz_html, &psz_subtitle, "<u>" );                strcat( psz_tag, "u" );            }            else if( !strncasecmp( psz_subtitle, "<font ", 6 ))            {                const char *psz_attribs[] = { "face=", "family=", "size=",                        "color=", "outline-color=", "shadow-color=",                        "outline-level=", "shadow-level=", "back-color=",                        "alpha=", NULL };                HtmlCopy( &psz_html, &psz_subtitle, "<font " );                strcat( psz_tag, "f" );                while( *psz_subtitle != '>' )                {                    int  k;                    for( k=0; psz_attribs[ k ]; k++ )                    {                        int i_len = strlen( psz_attribs[ k ] );                        if( !strncasecmp( psz_subtitle, psz_attribs[k], i_len ) )                        {                            /* */                            HtmlPut( &psz_html, psz_attribs[k] );                            psz_subtitle += i_len;                            /* */                            if( *psz_subtitle == '"' )                            {                                psz_subtitle++;                                i_len = strcspn( psz_subtitle, "\"" );                            }                            else                            {                                i_len = strcspn( psz_subtitle, " \t>" );                            }                            HtmlPut( &psz_html, "\"" );                            if( !strcmp( psz_attribs[ k ], "color=" ) && *psz_subtitle >= '0' && *psz_subtitle <= '9' )                                HtmlPut( &psz_html, "#" );                            HtmlNPut( &psz_html, psz_subtitle, i_len );                            HtmlPut( &psz_html, "\"" );                            psz_subtitle += i_len;                            if( *psz_subtitle == '\"' )                                psz_subtitle++;                            break;                        }                    }                    if( psz_attribs[ k ] == NULL )                    {                        /* Jump over unrecognised tag */                        int i_len = strcspn( psz_subtitle, "\"" ) + 1;                        i_len += strcspn( psz_subtitle + i_len, "\"" ) + 1;                        psz_subtitle += i_len;                    }                    while (*psz_subtitle == ' ')                        *psz_html++ = *psz_subtitle++;                }                *psz_html++ = *psz_subtitle++;            }            else if( !strncmp( psz_subtitle, "</", 2 ))            {                bool   b_match     = false;                int    i_len       = strlen( psz_tag ) - 1;                char  *psz_lastTag = NULL;                if( i_len >= 0 )                {                    psz_lastTag = psz_tag + i_len;                    i_len = 0;                    switch( *psz_lastTag )                    {                    case 'b':                        b_match = !strncasecmp( psz_subtitle, "</b>", 4 );                        i_len   = 4;                        break;                    case 'i':                        b_match = !strncasecmp( psz_subtitle, "</i>", 4 );                        i_len   = 4;                        break;                    case 'u':                        b_match = !strncasecmp( psz_subtitle, "</u>", 4 );                        i_len   = 4;                        break;                    case 'f':                        b_match = !strncasecmp( psz_subtitle, "</font>", 7 );                        i_len   = 7;                        break;                    }                }                if( ! b_match )                {                    /* Not well formed -- kill everything */                    free( psz_html_start );                    psz_html_start = NULL;                    break;                }                *psz_lastTag = '\0';                strncpy( psz_html, psz_subtitle, i_len );                psz_html += i_len;                psz_subtitle += i_len;            }            else            {                psz_subtitle += strcspn( psz_subtitle, ">" );            }        }        else if( *psz_subtitle == '&' )        {            if( !strncasecmp( psz_subtitle, "&lt;", 4 ))            {                HtmlCopy( &psz_html, &psz_subtitle, "&lt;" );            }            else if( !strncasecmp( psz_subtitle, "&gt;", 4 ))            {                HtmlCopy( &psz_html, &psz_subtitle, "&gt;" );            }            else if( !strncasecmp( psz_subtitle, "&amp;", 5 ))            {                HtmlCopy( &psz_html, &psz_subtitle, "&amp;" );            }            else            {                HtmlPut( &psz_html, "&amp;" );                psz_subtitle++;            }        }        else        {            *psz_html = *psz_subtitle;            if( psz_html > psz_html_start )            {                /* Check for double whitespace */                if( ( *psz_html == ' '  || *psz_html == '\t' ) &&                    ( *(psz_html-1) == ' ' || *(psz_html-1) == '\t' ) )                {                    HtmlPut( &psz_html, NO_BREAKING_SPACE );                    psz_html--;                }            }            psz_html++;            psz_subtitle++;        }        if( ( size_t )( psz_html - psz_html_start ) > i_buf_size - 50 )        {            int i_len = psz_html - psz_html_start;            i_buf_size += 200;            psz_html_start = realloc( psz_html_start, i_buf_size );            psz_html = psz_html_start + i_len;            *psz_html = '\0';        }    }    strcpy( psz_html, "</text>" );    psz_html += 7;    if( psz_tag[ 0 ] != '\0' )    {        /* Not well formed -- kill everything */        free( psz_html_start );        psz_html_start = NULL;    }    else if( psz_html_start )    {        /* Shrink the memory requirements */        psz_html_start = realloc( psz_html_start,  psz_html - psz_html_start + 1 );    }    free( psz_tag );    return psz_html_start;}

⌨️ 快捷键说明

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