Changeset 236ca7aea13a438f92c245565208c9bb6ff9e11c

Show
Ignore:
Timestamp:
08/02/05 18:00:18 (4 years ago)
Author:
Laurent Aimar <fenrir@videolan.org>
git-committer:
Laurent Aimar <fenrir@videolan.org> 1107882018 +0000
git-parent:

[ed0b82ee3b77a147c25977e38909a820c29d2f29]

git-author:
Laurent Aimar <fenrir@videolan.org> 1107882018 +0000
Message:
  • all: added a --audio-language and --spu-language to select tracks based
    on language code.
    Both options accepts a list (comma separated) of country code(2/3 letters)

or name (english/native).

For demuxers that doesn't provide language info, they are ignored.

Support for dvdnav isn't complete (only first language is tried) and untested.

Ex: --spu-language en,fr will try to select english track and if none
then french one (and if none, no subtitle).
(you can also use --spu-language english,french or english,francais)


Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/access/dvdnav.c

    rd5eacbe r236ca7a  
    4646#include "iso_lang.h" 
    4747 
     48/* FIXME we should find a better way than including that */ 
     49#include "../../src/misc/iso-639_def.h" 
     50 
     51 
    4852#include <dvdnav/dvdnav.h> 
    4953 
     
    6569    "Allows you to start the DVD directly in the main menu. This "\ 
    6670    "will try to skip all the useless warnings introductions." ) 
     71 
     72#define LANGUAGE_DEFAULT ("en") 
    6773 
    6874static int  Open ( vlc_object_t * ); 
     
    146152static int ProbeDVD( demux_t *, char * ); 
    147153 
     154static char *DemuxGetLanguageCode( demux_t *p_demux, char *psz_var ); 
     155 
    148156/***************************************************************************** 
    149157 * DemuxOpen: 
     
    156164    int         i_angle; 
    157165    char        *psz_name; 
     166    char        *psz_code; 
    158167    vlc_value_t val; 
    159168 
     
    234243    } 
    235244 
    236     if( dvdnav_menu_language_select (p_sys->dvdnav,"en") != DVDNAV_STATUS_OK || 
    237         dvdnav_audio_language_select(p_sys->dvdnav,"en") != DVDNAV_STATUS_OK || 
    238         dvdnav_spu_language_select  (p_sys->dvdnav,"en") != DVDNAV_STATUS_OK ) 
    239     { 
    240         msg_Warn( p_demux, "something failed while setting en language (%s)", 
     245    /* Set menu language ("en") 
     246     * XXX: maybe it would be better to set it like audio/spu or to create a --menu-language option */ 
     247    if( dvdnav_menu_language_select( p_sys->dvdnav,LANGUAGE_DEFAULT ) != DVDNAV_STATUS_OK ) 
     248    { 
     249        msg_Warn( p_demux, "something failed while setting menu '%s' language (%s)", 
     250                  LANGUAGE_DEFAULT, 
    241251                  dvdnav_err_to_string( p_sys->dvdnav ) ); 
    242252    } 
     253 
     254    /* Set audio language */ 
     255    psz_code = DemuxGetLanguageCode( p_demux, "audio-language" ); 
     256    if( dvdnav_audio_language_select(p_sys->dvdnav, psz_code ) != DVDNAV_STATUS_OK ) 
     257    { 
     258        msg_Warn( p_demux, "something failed while setting audio '%s' language (%s)", 
     259                  psz_code, 
     260                  dvdnav_err_to_string( p_sys->dvdnav ) ); 
     261        /* We try to fall back to 'en' */ 
     262        if( strcmp( psz_code, LANGUAGE_DEFAULT ) ) 
     263            dvdnav_audio_language_select(p_sys->dvdnav, LANGUAGE_DEFAULT ); 
     264    } 
     265    free( psz_code ); 
     266 
     267    /* Set spu language */ 
     268    psz_code = DemuxGetLanguageCode( p_demux, "spu-language" ); 
     269    if( dvdnav_spu_language_select( p_sys->dvdnav,psz_code ) != DVDNAV_STATUS_OK ) 
     270    { 
     271        msg_Warn( p_demux, "something failed while setting spu '%s' language (%s)", 
     272                  psz_code, 
     273                  dvdnav_err_to_string( p_sys->dvdnav ) ); 
     274        /* We try to fall back to 'en' */ 
     275        if( strcmp( psz_code, LANGUAGE_DEFAULT ) ) 
     276            dvdnav_spu_language_select(p_sys->dvdnav, LANGUAGE_DEFAULT ); 
     277    } 
     278    free( psz_code ); 
    243279 
    244280    DemuxTitles( p_demux ); 
     
    733769} 
    734770 
     771/* Get a 2 char code 
     772 * FIXME: partiallyy duplicated from src/input/es_out.c 
     773 */ 
     774static char *DemuxGetLanguageCode( demux_t *p_demux, char *psz_var ) 
     775{ 
     776    const iso639_lang_t *pl; 
     777    char *psz_lang; 
     778    char *p; 
     779 
     780    psz_lang = var_CreateGetString( p_demux, psz_var ); 
     781    /* XXX: we will use only the first value (and ignore other ones in case of a list) */ 
     782    if( ( p = strchr( psz_lang, "," ) ) ) 
     783        *p = '\0'; 
     784 
     785    for( pl = p_languages; pl->psz_iso639_1 != NULL; pl++ ) 
     786    { 
     787        if( !strcasecmp( pl->psz_eng_name, psz_lang ) || 
     788            !strcasecmp( pl->psz_native_name, psz_lang ) || 
     789            !strcasecmp( pl->psz_iso639_1, psz_lang ) || 
     790            !strcasecmp( pl->psz_iso639_2T, psz_lang ) || 
     791            !strcasecmp( pl->psz_iso639_2B, psz_lang ) ) 
     792            break; 
     793    } 
     794 
     795    free( psz_lang ); 
     796 
     797    if( pl->psz_iso639_1 != NULL ) 
     798        return strdup( pl->psz_iso639_1 ); 
     799 
     800    return strdup(LANGUAGE_DEFAULT); 
     801} 
     802 
    735803static void DemuxTitles( demux_t *p_demux ) 
    736804{ 
  • src/input/es_out.c

    r47cc1b2 r236ca7a  
    1  
    21/***************************************************************************** 
    32 * es_out.c: Es Out handler for input. 
     
    3635#include "vlc_playlist.h" 
    3736#include "iso_lang.h" 
     37/* FIXME we should find a better way than including that */ 
     38#include "../misc/iso-639_def.h" 
    3839 
    3940/***************************************************************************** 
     
    6566    es_format_t fmt; 
    6667    char        *psz_language; 
     68    char        *psz_language_code; 
    6769    decoder_t   *p_dec; 
    6870}; 
     
    9597    int         i_audio_last; 
    9698    int         i_sub_last; 
     99    char        **ppsz_audio_language; 
     100    char        **ppsz_sub_language; 
    97101 
    98102    /* current main es */ 
     
    117121static void EsUnselect( es_out_t *out, es_out_id_t *es, vlc_bool_t b_update ); 
    118122static char *LanguageGetName( const char *psz_code ); 
     123static char *LanguageGetCode( const char *psz_lang ); 
     124static char **LanguageSplit( const char *psz_langs ); 
     125static int LanguageArrayIndex( char **ppsz_langs, char *psz_lang ); 
    119126 
    120127/***************************************************************************** 
     
    126133    es_out_sys_t *p_sys = malloc( sizeof( es_out_sys_t ) ); 
    127134    vlc_value_t  val; 
     135    int i; 
    128136 
    129137    out->pf_add     = EsOutAdd; 
     
    151159    p_sys->i_sub   = 0; 
    152160 
     161    /* */ 
    153162    var_Get( p_input, "audio-channel", &val ); 
    154163    p_sys->i_audio_last = val.i_int; 
     
    157166    p_sys->i_sub_last = val.i_int; 
    158167 
     168    var_Get( p_input, "audio-language", &val ); 
     169    p_sys->ppsz_audio_language = LanguageSplit(val.psz_string); 
     170    if( p_sys->ppsz_audio_language ) 
     171    { 
     172        for( i = 0; p_sys->ppsz_audio_language[i]; i++ ) 
     173            msg_Dbg( p_input, "Select audio in language[%d] %s", 
     174                     i, p_sys->ppsz_audio_language[i] ); 
     175    } 
     176 
     177    var_Get( p_input, "spu-language", &val ); 
     178    p_sys->ppsz_sub_language = LanguageSplit(val.psz_string); 
     179    if( p_sys->ppsz_sub_language ) 
     180    { 
     181        for( i = 0; p_sys->ppsz_sub_language[i]; i++ ) 
     182            msg_Dbg( p_input, "Select subtitle in language[%d] %s", 
     183                     i, p_sys->ppsz_sub_language[i] ); 
     184    } 
     185 
     186    /* */ 
    159187    p_sys->p_es_audio = NULL; 
    160188    p_sys->p_es_video = NULL; 
     
    183211        if( p_sys->es[i]->psz_language ) 
    184212            free( p_sys->es[i]->psz_language ); 
     213        if( p_sys->es[i]->psz_language_code ) 
     214            free( p_sys->es[i]->psz_language_code ); 
    185215        es_format_Clean( &p_sys->es[i]->fmt ); 
    186216 
    187217        free( p_sys->es[i] ); 
    188218    } 
     219    if( p_sys->ppsz_audio_language ) 
     220    { 
     221        for( i = 0; p_sys->ppsz_audio_language[i]; i++ ) 
     222            free( p_sys->ppsz_audio_language[i] ); 
     223        free( p_sys->ppsz_audio_language ); 
     224    } 
     225    if( p_sys->ppsz_sub_language ) 
     226    { 
     227        for( i = 0; p_sys->ppsz_sub_language[i]; i++ ) 
     228            free( p_sys->ppsz_sub_language[i] ); 
     229        free( p_sys->ppsz_sub_language ); 
     230    } 
     231 
    189232    if( p_sys->es ) 
    190233        free( p_sys->es ); 
     
    306349    { 
    307350        if( es->psz_language && *es->psz_language ) 
    308    
    309        text.psz_string = malloc( strlen( es->fmt.psz_description) + strlen( es->psz_language ) + 10 ); 
    310        sprintf( text.psz_string, "%s - [%s]", es->fmt.psz_description, es->psz_language ); 
    311    
    312    else text.psz_string = strdup( es->fmt.psz_description ); 
     351       
     352            text.psz_string = malloc( strlen( es->fmt.psz_description) + strlen( es->psz_language ) + 10 ); 
     353            sprintf( text.psz_string, "%s - [%s]", es->fmt.psz_description, es->psz_language ); 
     354       
     355        else text.psz_string = strdup( es->fmt.psz_description ); 
    313356    } 
    314357    else 
     
    494537    } 
    495538    es->psz_language = LanguageGetName( fmt->psz_language ); /* remember so we only need to do it once */ 
     539    es->psz_language_code = LanguageGetCode( fmt->psz_language ); 
    496540    es->p_dec = NULL; 
    497541 
     
    668712        if( i_cat == AUDIO_ES ) 
    669713        { 
     714            int idx1 = LanguageArrayIndex( p_sys->ppsz_audio_language, 
     715                                     es->psz_language_code ); 
     716 
    670717            if( p_sys->p_es_audio && 
    671718                p_sys->p_es_audio->fmt.i_priority >= es->fmt.i_priority ) 
    672719            { 
    673                 return; 
    674             } 
    675             i_wanted  = p_sys->i_audio_last >= 0 ? 
    676                             p_sys->i_audio_last : es->i_channel; 
     720                int idx2 = LanguageArrayIndex( p_sys->ppsz_audio_language, 
     721                                         p_sys->p_es_audio->psz_language_code ); 
     722 
     723                if( idx1 < 0 || ( idx2 >= 0 && idx2 <= idx1 ) ) 
     724                    return; 
     725                i_wanted = es->i_channel; 
     726            } 
     727            else 
     728            { 
     729                /* Select audio if (no audio selected yet) 
     730                 * - no audio-language 
     731                 * - no audio code for the ES 
     732                 * - audio code in the requested list */ 
     733                if( idx1 >= 0 || 
     734                    !strcmp( es->psz_language_code, "??" ) || 
     735                    !p_sys->ppsz_audio_language ) 
     736                    i_wanted = es->i_channel; 
     737            } 
     738 
     739            if( p_sys->i_audio_last >= 0 ) 
     740                i_wanted = p_sys->i_audio_last; 
    677741        } 
    678742        else if( i_cat == SPU_ES ) 
    679743        { 
     744            int idx1 = LanguageArrayIndex( p_sys->ppsz_sub_language, 
     745                                     es->psz_language_code ); 
     746 
    680747            if( p_sys->p_es_sub && 
    681                 p_sys->p_es_sub->fmt.i_priority >= 
    682                     es->fmt.i_priority ) 
    683             { 
    684                 return; 
    685             } 
    686             i_wanted  = p_sys->i_sub_last; 
     748                p_sys->p_es_sub->fmt.i_priority >= es->fmt.i_priority ) 
     749            { 
     750                int idx2 = LanguageArrayIndex( p_sys->ppsz_sub_language, 
     751                                         p_sys->p_es_sub->psz_language_code ); 
     752 
     753                msg_Dbg( p_sys->p_input, "idx1=%d(%s) idx2=%d(%s)", 
     754                        idx1, es->psz_language_code, idx2, 
     755                        p_sys->p_es_sub->psz_language_code ); 
     756 
     757                if( idx1 < 0 || ( idx2 >= 0 && idx2 <= idx1 ) ) 
     758                    return; 
     759                /* We found a SPU that matches our language request */ 
     760                i_wanted  = es->i_channel; 
     761            } 
     762            else if( idx1 >= 0 ) 
     763            { 
     764                msg_Dbg( p_sys->p_input, "idx1=%d(%s)", 
     765                        idx1, es->psz_language_code ); 
     766 
     767                i_wanted  = es->i_channel; 
     768            } 
     769            if( p_sys->i_sub_last >= 0 ) 
     770                i_wanted  = p_sys->i_sub_last; 
    687771        } 
    688772        else if( i_cat == VIDEO_ES ) 
     
    833917    if( es->psz_language ) 
    834918        free( es->psz_language ); 
     919    if( es->psz_language_code ) 
     920        free( es->psz_language_code ); 
    835921 
    836922    es_format_Clean( &es->fmt ); 
     
    11331219} 
    11341220 
     1221/* Get a 2 char code */ 
     1222static char *LanguageGetCode( const char *psz_lang ) 
     1223{ 
     1224    const iso639_lang_t *pl; 
     1225 
     1226    if( psz_lang == NULL || *psz_lang == '\0' ) 
     1227        return strdup("??"); 
     1228 
     1229    for( pl = p_languages; pl->psz_iso639_1 != NULL; pl++ ) 
     1230    { 
     1231        if( !strcasecmp( pl->psz_eng_name, psz_lang ) || 
     1232            !strcasecmp( pl->psz_native_name, psz_lang ) || 
     1233            !strcasecmp( pl->psz_iso639_1, psz_lang ) || 
     1234            !strcasecmp( pl->psz_iso639_2T, psz_lang ) || 
     1235            !strcasecmp( pl->psz_iso639_2B, psz_lang ) ) 
     1236            break; 
     1237    } 
     1238 
     1239    if( pl->psz_iso639_1 != NULL ) 
     1240        return strdup( pl->psz_iso639_1 ); 
     1241 
     1242    return strdup("??"); 
     1243} 
     1244 
     1245static char **LanguageSplit( const char *psz_langs ) 
     1246{ 
     1247    char *psz_dup; 
     1248    char *psz_parser; 
     1249    char **ppsz = NULL; 
     1250    int i_psz = 0; 
     1251 
     1252    if( psz_langs == NULL ) 
     1253        return NULL; 
     1254 
     1255    psz_parser = psz_dup = strdup(psz_langs); 
     1256 
     1257    while( psz_parser && *psz_parser ) 
     1258    { 
     1259        char *psz; 
     1260        char *psz_code; 
     1261 
     1262        psz = strchr(psz_parser, ',' ); 
     1263        if( psz ) 
     1264        { 
     1265            *psz++ = '\0'; 
     1266        } 
     1267 
     1268        psz_code = LanguageGetCode( psz_parser ); 
     1269        if( strcmp( psz_code, "??" ) ) 
     1270        { 
     1271            TAB_APPEND( i_psz, ppsz, psz_code ); 
     1272        } 
     1273 
     1274        psz_parser = psz; 
     1275    } 
     1276 
     1277    if( i_psz ) 
     1278    { 
     1279        TAB_APPEND( i_psz, ppsz, NULL ); 
     1280    } 
     1281 
     1282    return ppsz; 
     1283} 
     1284 
     1285static int LanguageArrayIndex( char **ppsz_langs, char *psz_lang ) 
     1286{ 
     1287    int i; 
     1288 
     1289    if( !ppsz_langs || !psz_lang ) 
     1290        return -1; 
     1291 
     1292    for( i = 0; ppsz_langs[i]; i++ ) 
     1293        if( !strcasecmp( ppsz_langs[i], psz_lang ) ) 
     1294            return i; 
     1295 
     1296    return -1; 
     1297} 
     1298 
    11351299/**************************************************************************** 
    11361300 * EsOutAddInfo: 
  • src/input/var.c

    r534a812 r236ca7a  
    401401    var_Create( p_input, "spu-channel", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); 
    402402 
     403    var_Create( p_input, "audio-language", VLC_VAR_STRING|VLC_VAR_DOINHERIT ); 
     404    var_Create( p_input, "spu-language", VLC_VAR_STRING|VLC_VAR_DOINHERIT ); 
     405 
    403406    var_Create( p_input, "sub-file", VLC_VAR_FILE | VLC_VAR_DOINHERIT ); 
    404407    var_Create( p_input, "sub-autodetect-file", VLC_VAR_BOOL | 
  • src/libvlc.h

    r44d19ee r236ca7a  
    328328 
    329329#define INPUT_SUB_TEXT N_("Choose subtitles track") 
     330#define INPUT_CHAN_LANG_TEXT N_("Choose audio language") 
     331#define INPUT_CHAN_LANG_LONGTEXT N_( \ 
     332    "Give the language of the audio channel you want to use " \ 
     333    "(comma separted, two or tree letter country code).") 
     334#define INPUT_SUB_LANG_TEXT N_("Choose subtitle track") 
     335#define INPUT_SUB_LANG_LONGTEXT N_( \ 
     336    "Give the language of the subtitle channel you want to use " \ 
     337    "(comma separted, two or tree letter country code).") 
     338 
     339 
    330340#define INPUT_SUB_LONGTEXT N_( \ 
    331341    "Give the stream number of the subtitle channel you want to use " \ 
     
    980990    add_integer( "spu-channel", -1, NULL, 
    981991                 INPUT_SUB_TEXT, INPUT_SUB_LONGTEXT, VLC_FALSE ); 
     992    add_string( "audio-language", "", NULL, 
     993                 INPUT_CHAN_LANG_TEXT, INPUT_CHAN_LANG_LONGTEXT, VLC_FALSE ); 
     994    add_string( "spu-language", "", NULL, 
     995                 INPUT_SUB_LANG_TEXT, INPUT_SUB_LANG_LONGTEXT, VLC_FALSE ); 
     996 
    982997 
    983998    set_section( N_( "Playback control" ) , NULL);