Changeset f3bd025005bca6b75665db4471819ede04684ce1

Show
Ignore:
Timestamp:
05/12/08 16:29:58 (2 months ago)
Author:
Jean-Baptiste Kempf <jb@videolan.org>
git-committer:
Jean-Baptiste Kempf <jb@videolan.org> 1210602598 -0700
git-parent:

[2cc99c5cbbd3de7f5ad677539af1b5c29dc8defe]

git-author:
Jean-Baptiste Kempf <jb@videolan.org> 1210602574 -0700
Message:

Support for both types of MPSub
Basic parsing and support of JacoSub? (the parsing doesn't work yet with multi-lines and the directives are ignored but the text works)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/demux/subtitle.c

    r27d483e rf3bd025  
    2626 * Preamble 
    2727 *****************************************************************************/ 
     28 
    2829#ifdef HAVE_CONFIG_H 
    2930# include "config.h" 
     
    3334#include <vlc_plugin.h> 
    3435#include <vlc_input.h> 
    35  
    3636 
    3737#include <errno.h> 
     
    100100    SUB_TYPE_VPLAYER, 
    101101    SUB_TYPE_SAMI, 
    102     SUB_TYPE_SUBVIEWER, 
     102    SUB_TYPE_SUBVIEWER, //SUBVIEWER 2! 
    103103    SUB_TYPE_DVDSUBTITLE, 
    104104    SUB_TYPE_MPL2, 
    105105    SUB_TYPE_AQT, 
    106106    SUB_TYPE_PJS, 
    107     SUB_TYPE_MPSUB 
     107    SUB_TYPE_MPSUB, 
     108    SUB_TYPE_JACOSUB 
    108109}; 
    109110 
     
    114115    char    **line; 
    115116} text_t; 
     117 
    116118static int  TextLoad( text_t *, stream_t *s ); 
    117119static void TextUnload( text_t * ); 
     
    153155static int  ParseAQT        ( demux_t *, subtitle_t *, int ); 
    154156static int  ParsePJS        ( demux_t *, subtitle_t *, int ); 
    155 static int  ParseMPSub        ( demux_t *, subtitle_t *, int ); 
     157static int  ParseMPSub      ( demux_t *, subtitle_t *, int ); 
     158static int  ParseJSS        ( demux_t *, subtitle_t *, int ); 
    156159 
    157160static struct 
     
    176179    { "pjs",        SUB_TYPE_PJS,         "PhoenixSub",  ParsePJS }, 
    177180    { "mpsub",      SUB_TYPE_MPSUB,       "MPSub",       ParseMPSub }, 
     181    { "jacosub",    SUB_TYPE_JACOSUB,     "JacoSub",     ParseJSS }, 
    178182    { NULL,         SUB_TYPE_UNKNOWN,     "Unknown",     NULL } 
    179183}; 
     184 
     185/* Missing Detect 
     186    SubViewer 1 
     187    JSS 
     188    RealText 
     189    Subrip09 
     190   */ 
     191 
    180192 
    181193static int Demux( demux_t * ); 
     
    259271        { 
    260272            int i_dummy; 
    261             float f_dummy; 
     273            char p_dummy; 
    262274 
    263275            if( ( s = stream_ReadLine( p_demux->s ) ) == NULL ) 
     
    313325                break; 
    314326            } 
     327            else if( sscanf( s, "%d:%d:%d.%d %d:%d:%d", &i_dummy, &i_dummy, &i_dummy, &i_dummy, &i_dummy, &i_dummy, &i_dummy ) == 7 || 
     328                    sscanf( s, "@%d @%d", &i_dummy, &i_dummy) == 2) 
     329            { 
     330                p_sys->i_type = SUB_TYPE_JACOSUB; 
     331            } 
    315332            else if( sscanf( s, "%d:%d:%d:", &i_dummy, &i_dummy, &i_dummy ) == 3 || 
    316333                     sscanf( s, "%d:%d:%d ", &i_dummy, &i_dummy, &i_dummy ) == 3 ) 
     
    331348                break; 
    332349            } 
    333             else if( sscanf( s, "%f %f", &f_dummy, &f_dummy ) == 2 ) 
     350            else if( sscanf (s, "FORMAT=%d", &i_dummy) == 1 || 
     351                     ( sscanf (s, "FORMAT=TIM%c", &p_dummy) == 1 
     352                       && p_dummy =='E' ) ) 
    334353            { 
    335354                p_sys->i_type = SUB_TYPE_MPSUB; 
     
    13261345            p_subtitle->i_stop = 10 * t2; 
    13271346            /* Remove latest " */ 
    1328             psz_text[ strlen(psz_text) - 1 ] = '\0 '; 
     1347            psz_text[ strlen(psz_text) - 1 ] = '\0'; 
    13291348 
    13301349            break; 
     
    13371356} 
    13381357 
    1339 static float mpsub_total = 0; 
     1358static float mpsub_total = 0.0; 
     1359static float mpsub_factor = 0.0; 
    13401360 
    13411361static int ParseMPSub( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx ) 
     
    13491369        const char *s = TextGetLine( txt ); 
    13501370        float f1, f2; 
     1371        char p_dummy; 
     1372        char *psz_temp; 
    13511373 
    13521374        if( !s ) 
    13531375            return VLC_EGENERIC; 
    13541376 
     1377        if( sscanf (s, "FORMAT=TIM%c", &p_dummy ) == 1 && p_dummy == 'E') 
     1378        { 
     1379            mpsub_factor = 100.0; 
     1380            break; 
     1381        } 
     1382 
     1383        psz_temp = malloc( strlen(s) - 6 ); 
     1384        if( sscanf( s, "FORMAT=%[^\r\n]", psz_temp ) ) 
     1385        { 
     1386            float f_fps; 
     1387            f_fps = us_strtod( psz_temp, NULL ); 
     1388            if( f_fps > 0.0 && var_GetFloat( p_demux, "sub-fps" ) <= 0.0 ) 
     1389                var_SetFloat( p_demux, "sub-fps", f_fps ); 
     1390 
     1391            mpsub_factor = 1.0; 
     1392            free( psz_temp ); 
     1393            break; 
     1394        } 
     1395        free( psz_temp ); 
     1396 
    13551397        /* Data Lines */ 
    13561398        if( sscanf (s, "%f %f", &f1, &f2 ) == 2 ) 
    13571399        { 
    1358             mpsub_total += f1
    1359             p_subtitle->i_start = (int64_t)(1000000.0 * mpsub_total); 
    1360             mpsub_total += f2
    1361             p_subtitle->i_stop = (int64_t)(1000000.0 * mpsub_total); 
     1400            mpsub_total += f1 * mpsub_factor
     1401            p_subtitle->i_start = (int64_t)(10000.0 * mpsub_total); 
     1402            mpsub_total += f2 * mpsub_factor
     1403            p_subtitle->i_stop = (int64_t)(10000.0 * mpsub_total); 
    13621404            break; 
    13631405        } 
     
    13891431} 
    13901432 
     1433static int ParseJSS( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx ) 
     1434{ 
     1435    demux_sys_t  *p_sys = p_demux->p_sys; 
     1436    text_t       *txt = &p_sys->txt; 
     1437    char         *psz_text, *psz_orig; 
     1438    char         *psz_text2, *psz_orig2; 
     1439    int h1, h2, m1, m2, s1, s2, f1, f2; 
     1440    static int i_comment = 0; 
     1441 
     1442    static int jss_time_resolution = 30; 
     1443    static int jss_time_shift = 0; 
     1444 
     1445    /* Parse the main lines */ 
     1446    for( ;; ) 
     1447    { 
     1448        const char *s = TextGetLine( txt ); 
     1449        if( !s ) 
     1450            return VLC_EGENERIC; 
     1451 
     1452        psz_text = malloc( strlen( s ) + 1 ); 
     1453        psz_orig = psz_text; 
     1454 
     1455        if( sscanf( s, "%d:%d:%d.%d %d:%d:%d.%d %[^\n\r]", 
     1456                    &h1, &m1, &s1, &f1, &h2, &m2, &s2, &f2, psz_text ) == 9 ) 
     1457        { 
     1458            p_subtitle->i_start = ( (int64_t)( h1 *3600 + m1 * 60 + s1 ) + 
     1459                (int64_t)( ( f1 +  jss_time_shift ) /  jss_time_resolution ) ) 
     1460                * 1000000; 
     1461            p_subtitle->i_stop = ( (int64_t)( h2 *3600 + m2 * 60 + s2 ) + 
     1462                (int64_t)( ( f2 +  jss_time_shift ) /  jss_time_resolution ) ) 
     1463                * 1000000; 
     1464        } 
     1465        else if( sscanf( s, "@%d @%d %[^\n\r]", &f1, &f2, psz_text ) == 3 ) 
     1466        { 
     1467            p_subtitle->i_start = (int64_t)( 
     1468                    ( f1 + jss_time_shift ) / jss_time_resolution * 1000000.0 ); 
     1469            p_subtitle->i_stop = (int64_t)( 
     1470                    ( f2 + jss_time_shift ) / jss_time_resolution * 1000000.0 ); 
     1471        } 
     1472        else if( s[0] == '#' ) 
     1473        { 
     1474            int h = 0, m =0, sec = 1, f = 1; 
     1475            unsigned shift = 1; 
     1476            int inv = 1; 
     1477 
     1478            strcpy( psz_text, s ); 
     1479 
     1480            switch( toupper( psz_text[1] ) ) 
     1481            { 
     1482                case 'S': 
     1483                     shift = isalpha( psz_text[2] ) ? 6 : 2 ; 
     1484 
     1485                     if( sscanf( &psz_text[shift], "%d", &h ) ) 
     1486                     { 
     1487                         /* Negative shifting */ 
     1488                         if( h < 0 ) 
     1489                         { 
     1490                             h *= -1; 
     1491                             inv = -1; 
     1492                         } 
     1493 
     1494                         if( sscanf( &psz_text[shift], "%*d:%d", &m ) ) 
     1495                         { 
     1496                             if( sscanf( &psz_text[shift], "%*d:%*d:%d", &sec ) ) 
     1497                             { 
     1498                                 sscanf( &psz_text[shift], "%*d:%*d:%*d.%d", &f ); 
     1499                             } 
     1500                             else 
     1501                             { 
     1502                                 h = 0; 
     1503                                 sscanf( &psz_text[shift], "%d:%d.%d", &m, &sec, &f ); 
     1504                                 m *= inv; 
     1505                             } 
     1506                         } 
     1507                         else 
     1508                         { 
     1509                             h = m = 0; 
     1510                             sscanf( &psz_text[shift], "%d.%d", &sec, &f); 
     1511                             sec *= inv; 
     1512                         } 
     1513                         jss_time_shift = ( ( h * 3600 + m * 60 + sec ) 
     1514                             * jss_time_resolution + f ) * inv; 
     1515                     } 
     1516                     break; 
     1517 
     1518                case 'T': 
     1519                    shift = isalpha( psz_text[2] ) ? 8 : 2 ; 
     1520 
     1521                    sscanf( &psz_text[shift], "%d", &jss_time_resolution ); 
     1522                    break; 
     1523            } 
     1524            free( psz_text ); 
     1525            continue; 
     1526        } 
     1527        else 
     1528            /* Unkown line */ 
     1529        { 
     1530            free( psz_text ); 
     1531            continue; 
     1532        } 
     1533 
     1534        /* Skip the blanks */ 
     1535        while( *psz_text == ' ' || *psz_text == '\t' ) psz_text++; 
     1536 
     1537        /* Parse the directives */ 
     1538        if( isalpha( *psz_text ) || *psz_text == '[' ) 
     1539        { 
     1540            while( *psz_text != ' ' ) 
     1541            { psz_text++ ;}; 
     1542 
     1543            /* Directives are NOT parsed yet */ 
     1544            /* directive = malloc( strlen( psz_text ) + 1 ); 
     1545            if( sscanf( psz_text, "%s %[^\n\r]", directive, psz_text2 ) == 2 )*/ 
     1546        } 
     1547 
     1548        /* Skip the blanks after directives */ 
     1549        while( *psz_text == ' ' || *psz_text == '\t' ) psz_text++; 
     1550 
     1551        psz_text2 = calloc( strlen( psz_text) + 1, 1 ); 
     1552        psz_orig2 = psz_text2; 
     1553 
     1554        for( ; *psz_text != '\0' && *psz_text != '\n' && *psz_text != '\r'; ) 
     1555        { 
     1556            switch( *psz_text ) 
     1557            { 
     1558            case '{': 
     1559                i_comment++; 
     1560                break; 
     1561            case '}': 
     1562                if( i_comment ) 
     1563                { 
     1564                    i_comment = 0; 
     1565                    if( (*(psz_text + 1 ) ) == ' ' ) psz_text++; 
     1566                } 
     1567                break; 
     1568            case '~': 
     1569                if( !i_comment ) 
     1570                { 
     1571                    *psz_text2 = ' '; 
     1572                    psz_text2++; 
     1573                } 
     1574                break; 
     1575            case ' ': 
     1576            case '\t': 
     1577                if( (*(psz_text + 1 ) ) == ' ' || (*(psz_text + 1 ) ) == '\t' ) 
     1578                    break; 
     1579                if( !i_comment ) 
     1580                { 
     1581                    *psz_text2 = ' '; 
     1582                    psz_text2++; 
     1583                } 
     1584                break; 
     1585            case '\\': 
     1586                if( (*(psz_text + 1 ) ) == 'n' ) 
     1587                { 
     1588                    *psz_text2 = '\n'; 
     1589                    psz_text++; 
     1590                    psz_text2++; 
     1591                    break; 
     1592                } 
     1593                if( ( toupper(*(psz_text + 1 ) ) == 'C' ) || 
     1594                    ( toupper(*(psz_text + 1 ) ) == 'F' ) ) 
     1595                { 
     1596                    psz_text++; psz_text++; 
     1597                    break; 
     1598                } 
     1599                if( (*(psz_text + 1 ) ) == 'B' || (*(psz_text + 1 ) ) == 'b' || 
     1600                    (*(psz_text + 1 ) ) == 'I' || (*(psz_text + 1 ) ) == 'i' || 
     1601                    (*(psz_text + 1 ) ) == 'U' || (*(psz_text + 1 ) ) == 'u' || 
     1602                    (*(psz_text + 1 ) ) == 'D' || (*(psz_text + 1 ) ) == 'N' ) 
     1603                { 
     1604                    psz_text++; 
     1605                    break; 
     1606                } 
     1607                if( (*(psz_text + 1 ) ) == '~' || (*(psz_text + 1 ) ) == '{' || 
     1608                    (*(psz_text + 1 ) ) == '\\' ) 
     1609                    psz_text++; 
     1610                else if( *(psz_text + 1 ) == '\r' ||  *(psz_text + 1 ) == '\n' 
     1611                         ||  *(psz_text + 1 ) == '\0' ) 
     1612                { 
     1613                    char *s2 = TextGetLine( txt ); 
     1614                    if( !s2 ) 
     1615                        return VLC_EGENERIC; 
     1616 
     1617                    while ( *s2 == ' ' ) s2++; 
     1618 
     1619/*                    int i_len = strlen( psz_orig2 ); 
     1620 
     1621 
     1622                    psz_orig2 = realloc( psz_orig2, strlen( s2 ) +  i_len + 1 ); 
     1623 
     1624 
     1625                    */ 
     1626                } 
     1627            default: 
     1628                if( !i_comment ) 
     1629                { 
     1630                    *psz_text2 = *psz_text; 
     1631                    psz_text2++; 
     1632                } 
     1633            } 
     1634            psz_text++; 
     1635        } 
     1636 
     1637        p_subtitle->psz_text = psz_orig2; 
     1638        free( psz_orig ); 
     1639        return VLC_SUCCESS; 
     1640    } 
     1641}