Changeset 25d2a663a98c0adc49d95e3ad5612f76da954953

Show
Ignore:
Timestamp:
21/08/04 01:37:40 (4 years ago)
Author:
Gildas Bazin <gbazin@videolan.org>
git-committer:
Gildas Bazin <gbazin@videolan.org> 1093045060 +0000
git-parent:

[235b3bcb3cc58024302fe3eecd8d65efc6bba113]

git-author:
Gildas Bazin <gbazin@videolan.org> 1093045060 +0000
Message:

* src/input/*, include/vlc_input.h: the MRL is now parsed for titles/chapters directly in the core.

  • syntax is: [url][@[title-start][,chapter-start][-[title-end][,chapter-end]]]
  • core also handles start/end boundaries itself (simplifies the access plugins).

* modules/access/dvdread.c,dvdnav.c,cdda.c: removed MRL parsing code.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/vlc_input.h

    rc7ceea8 r25d2a66  
    202202    input_title_t **title; 
    203203 
     204    int i_title_offset; 
     205    int i_seekpoint_offset; 
     206 
     207    int i_title_start; 
     208    int i_title_end; 
     209    int i_seekpoint_start; 
     210    int i_seekpoint_end; 
     211 
    204212    /* Properties */ 
    205213    vlc_bool_t b_can_pace_control; 
     
    253261    int          i_title; 
    254262    input_title_t **title; 
     263 
     264    int i_title_offset; 
     265    int i_seekpoint_offset; 
    255266 
    256267    /* User bookmarks FIXME won't be easy with multiples input */ 
  • modules/access/cdda.c

    r59045db r25d2a66  
    7373    input_title_t *title[99];         /* No more that 99 track in a cd-audio */ 
    7474 
    75     int i_title_start; 
    76     int i_title_end; 
    77  
    7875    /* Current position */ 
    7976    int         i_sector;                                  /* Current Sector */ 
     
    9188/***************************************************************************** 
    9289 * Open: open cdda 
    93  * MRL syntax: [dev_path][@[title-start][-[title-end]]] 
    9490 *****************************************************************************/ 
    9591static int Open( vlc_object_t *p_this ) 
     
    9894    access_sys_t *p_sys; 
    9995 
    100     char *psz_dup, *psz; 
    101     int  i, i_title_start = -1, i_title_end = -1; 
    10296    vcddev_t *vcddev; 
    103  
    104     /* Command line: [dev_path][@[title-start][-[title-end]]] */ 
    105     psz_dup = p_access->psz_path? strdup( p_access->psz_path ) : 0; 
    106     if( psz_dup && ( psz = strchr( psz_dup, '@' ) ) ) 
    107     { 
    108         *psz++ = 0; 
    109         i_title_start = i_title_end = strtol( psz, NULL, 0 ); 
    110  
    111         if( ( psz = strchr( psz, '-' ) ) ) 
     97    char *psz_name; 
     98    int  i; 
     99 
     100    if( !p_access->psz_path || !*p_access->psz_path ) 
     101    { 
     102        /* Only when selected */ 
     103        if( !p_this->b_force ) return VLC_EGENERIC; 
     104 
     105        psz_name = var_CreateGetString( p_this, "cd-audio" ); 
     106        if( !psz_name || !*psz_name ) 
    112107        { 
    113             *psz++; 
    114             i_title_end = strtol( psz, NULL, 0 ); 
    115         } 
    116     } 
    117  
    118     if( !psz_dup || !*psz_dup ) 
    119     { 
    120         if( psz_dup ) free( psz_dup ); 
    121  
    122         /* Only when selected */ 
    123         if( !p_access->b_force ) return VLC_EGENERIC; 
    124  
    125         psz_dup = var_CreateGetString( p_access, "cd-audio" ); 
    126         if( !psz_dup || !*psz_dup ) 
    127         { 
    128             if( psz_dup ) free( psz_dup ); 
     108            if( psz_name ) free( psz_name ); 
    129109            return VLC_EGENERIC; 
    130110        } 
    131111    } 
     112    else psz_name = strdup( p_access->psz_path ); 
    132113 
    133114    /* Open CDDA */ 
    134     if( (vcddev = ioctl_Open( VLC_OBJECT(p_access), psz_dup )) == NULL ) 
    135     { 
    136         msg_Warn( p_access, "could not open %s", psz_dup ); 
    137         free( psz_dup ); 
     115    if( (vcddev = ioctl_Open( VLC_OBJECT(p_access), psz_name )) == NULL ) 
     116    { 
     117        msg_Warn( p_access, "could not open %s", psz_name ); 
     118        free( psz_name ); 
    138119        return VLC_EGENERIC; 
    139120    } 
    140     free( psz_dup ); 
     121    free( psz_name ); 
    141122 
    142123    /* Set up p_access */ 
     
    185166    } 
    186167 
    187     /* Starting title and sector */ 
    188     if( i_title_start < 1 || i_title_start > p_sys->i_titles ) 
    189         p_sys->i_title_start = 1; 
    190     else p_sys->i_title_start = i_title_start; 
    191     if( i_title_end < 1 || i_title_end > p_sys->i_titles ) 
    192         p_sys->i_title_end = -1; 
    193     else p_sys->i_title_end = i_title_end; 
    194  
    195     p_sys->i_sector = p_sys->p_sectors[p_sys->i_title_start-1]; 
    196     p_access->info.i_title = p_sys->i_title_start-1; 
    197     p_access->info.i_size = p_sys->title[p_sys->i_title_start-1]->i_size; 
     168    p_sys->i_sector = p_sys->p_sectors[0]; 
     169    p_access->info.i_size = p_sys->title[0]->i_size; 
    198170 
    199171    /* Build a WAV header for the output data */ 
     
    267239    while( p_sys->i_sector >= p_sys->p_sectors[p_access->info.i_title + 1] ) 
    268240    { 
    269         if( p_access->info.i_title + 1 >= p_sys->i_titles || 
    270             ( p_sys->i_title_end > 0 && 
    271               p_access->info.i_title + 1 >= p_sys->i_title_end ) ) 
     241        if( p_access->info.i_title + 1 >= p_sys->i_titles ) 
    272242        { 
    273243            p_access->info.b_eof = VLC_TRUE; 
     
    372342            ppp_title = (input_title_t***)va_arg( args, input_title_t*** ); 
    373343            pi_int    = (int*)va_arg( args, int* ); 
     344        *((int*)va_arg( args, int* )) = 1; /* Title offset */ 
    374345 
    375346            /* Duplicate title infos */ 
     
    395366                /* Next sector to read */ 
    396367                p_sys->i_sector = p_sys->p_sectors[i]; 
    397  
    398                 /* User tries to access another title so better reset 
    399                  * the end title */ 
    400                 p_sys->i_title_end = -1; 
    401368            } 
    402369            break; 
  • modules/access/dvdnav.c

    r2b8ade3 r25d2a66  
    5353 * Module descriptor 
    5454 *****************************************************************************/ 
     55#define ANGLE_TEXT N_("DVD angle") 
     56#define ANGLE_LONGTEXT N_( \ 
     57    "Allows you to select the default DVD angle." ) 
     58 
    5559#define CACHING_TEXT N_("Caching value in ms") 
    5660#define CACHING_LONGTEXT N_( \ 
     
    6771vlc_module_begin(); 
    6872    set_description( _("DVDnav Input") ); 
     73    add_integer( "dvdnav-angle", 1, NULL, ANGLE_TEXT, 
     74        ANGLE_LONGTEXT, VLC_FALSE ); 
    6975    add_integer( "dvdnav-caching", DEFAULT_PTS_DELAY / 1000, NULL, 
    7076        CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE ); 
     
    8389 * Local prototypes 
    8490 *****************************************************************************/ 
    85 static char *ParseCL( vlc_object_t *, char *, vlc_bool_t, int *, int *, int *); 
    86  
    8791typedef struct 
    8892{ 
     
    147151    demux_sys_t *p_sys; 
    148152    dvdnav_t    *p_dvdnav; 
    149     int         i_title, i_chapter, i_angle; 
     153    int         i_angle; 
    150154    char        *psz_name; 
    151155    vlc_value_t val; 
    152156 
    153     psz_name = ParseCL( VLC_OBJECT(p_demux), p_demux->psz_path, VLC_TRUE, 
    154                         &i_title, &i_chapter, &i_angle ); 
    155     if( !psz_name ) 
    156     { 
    157         return VLC_EGENERIC; 
    158     } 
     157    if( !p_demux->psz_path || !*p_demux->psz_path ) 
     158    { 
     159        /* Only when selected */ 
     160        if( !p_this->b_force ) return VLC_EGENERIC; 
     161 
     162        psz_name = var_CreateGetString( p_this, "dvd" ); 
     163        if( !psz_name || !*psz_name ) 
     164        { 
     165            if( psz_name ) free( psz_name ); 
     166            return VLC_EGENERIC; 
     167        } 
     168    } 
     169    else psz_name = strdup( p_demux->psz_path ); 
     170 
     171#ifdef WIN32 
     172    if( psz_name[0] && psz_name[1] == ':' && 
     173        psz_name[2] == '\\' && psz_name[3] == '\0' ) psz_name[2] = '\0'; 
     174#endif 
    159175 
    160176    /* Try some simple probing to avoid going through dvdnav_open too often */ 
     
    164180        return VLC_EGENERIC; 
    165181    } 
    166  
    167     msg_Dbg( p_this, "dvdroot=%s title=%d chapter=%d angle=%d", 
    168              psz_name, i_title, i_chapter, i_angle ); 
    169182 
    170183    /* Open dvdnav */ 
     
    228241    DemuxTitles( p_demux ); 
    229242 
    230     /* Set forced title/chapter */ 
    231     if( i_title > 0 ) 
    232     { 
    233         if( dvdnav_title_play( p_sys->dvdnav, i_title ) != DVDNAV_STATUS_OK ) 
    234         { 
    235             msg_Warn( p_demux, "cannot set title" ); 
    236             i_title = 0; 
    237         } 
    238         else 
    239         { 
    240             p_demux->info.i_update |= INPUT_UPDATE_TITLE; 
    241             p_demux->info.i_title = i_title; 
    242         } 
    243     } 
    244  
    245     if( i_chapter > 1 && i_title > 0 ) 
    246     { 
    247         if( dvdnav_part_play( p_sys->dvdnav, i_title, i_chapter ) != 
    248             DVDNAV_STATUS_OK ) 
    249         { 
    250             msg_Warn( p_demux, "cannot set chapter" ); 
    251             i_chapter = 1; 
    252         } 
    253         else 
    254         { 
    255             p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT; 
    256             p_demux->info.i_seekpoint = i_chapter; 
    257         } 
    258     } 
    259  
    260243    var_Create( p_demux, "dvdnav-menu", VLC_VAR_BOOL|VLC_VAR_DOINHERIT ); 
    261244    var_Get( p_demux, "dvdnav-menu", &val ); 
    262     if( (i_title < 0 && val.b_bool) || i_title == 0
     245    if( val.b_bool
    263246    { 
    264247        msg_Dbg( p_demux, "trying to go to dvd menu" ); 
     
    274257            msg_Warn( p_demux, "cannot go to dvd menu" ); 
    275258        } 
    276         else 
    277         { 
    278             p_demux->info.i_update |= 
    279                 INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT; 
    280             p_demux->info.i_title = 0; 
    281             p_demux->info.i_seekpoint = 0; 
    282         } 
    283     } 
     259    } 
     260 
     261    var_Create( p_demux, "dvdnav-angle", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); 
     262    var_Get( p_demux, "dvdnav-angle", &val ); 
     263    i_angle = val.i_int > 0 ? val.i_int : 1; 
    284264 
    285265    /* Update default_pts to a suitable value for dvdnav access */ 
     
    427407            ppp_title = (input_title_t***)va_arg( args, input_title_t*** ); 
    428408            pi_int    = (int*)va_arg( args, int* ); 
     409        *((int*)va_arg( args, int* )) = 0; /* Title offset */ 
     410        *((int*)va_arg( args, int* )) = 1; /* Chapter offset */ 
    429411 
    430412            /* Duplicate title infos */ 
     
    733715} 
    734716 
    735 /***************************************************************************** 
    736  * ParseCL: parse command line. 
    737  * Titles start from 0 (menu), chapters and angles start from 1. 
    738  *****************************************************************************/ 
    739 static char *ParseCL( vlc_object_t *p_this, char *psz_name, vlc_bool_t b_force, 
    740                       int *i_title, int *i_chapter, int *i_angle ) 
    741 { 
    742     char *psz_parser, *psz_source, *psz_next; 
    743  
    744     psz_source = strdup( psz_name ); 
    745     if( psz_source == NULL ) return NULL; 
    746  
    747     *i_title = -1; 
    748     *i_chapter = 1; 
    749     *i_angle = 1; 
    750  
    751     /* Start with the end, because you could have : 
    752      * dvdnav:/Volumes/my@toto/VIDEO_TS@1,1 
    753      * (yes, this is kludgy). */ 
    754     for( psz_parser = psz_source + strlen(psz_source) - 1; 
    755          psz_parser >= psz_source && *psz_parser != '@'; 
    756          psz_parser-- ); 
    757  
    758     if( psz_parser >= psz_source && *psz_parser == '@' ) 
    759     { 
    760         /* Found options */ 
    761         *psz_parser = '\0'; 
    762         ++psz_parser; 
    763  
    764         *i_title = (int)strtol( psz_parser, &psz_next, 10 ); 
    765         if( *psz_next ) 
    766         { 
    767             psz_parser = psz_next + 1; 
    768             *i_chapter = (int)strtol( psz_parser, &psz_next, 10 ); 
    769             if( *psz_next ) 
    770             { 
    771                 *i_angle = (int)strtol( psz_next + 1, NULL, 10 ); 
    772             } 
    773         } 
    774     } 
    775  
    776     *i_title   = *i_title >= 0 ? *i_title : -1; 
    777     *i_chapter = *i_chapter > 0 ? *i_chapter : 1; 
    778     *i_angle   = *i_angle > 0 ? *i_angle : 1; 
    779  
    780     if( !*psz_source ) 
    781     { 
    782         free( psz_source ); 
    783         if( !b_force ) 
    784         { 
    785             return NULL; 
    786         } 
    787         psz_source = config_GetPsz( p_this, "dvd" ); 
    788         if( !psz_source ) return NULL; 
    789     } 
    790  
    791 #ifdef WIN32 
    792     if( psz_source[0] && psz_source[1] == ':' && 
    793         psz_source[2] == '\\' && psz_source[3] == '\0' ) 
    794     { 
    795         psz_source[2] = '\0'; 
    796     } 
    797 #endif 
    798  
    799     return psz_source; 
    800 } 
    801  
    802717static void DemuxTitles( demux_t *p_demux ) 
    803718{ 
     
    856771        { 
    857772            s = vlc_seekpoint_New(); 
    858             s->psz_name = malloc( strlen( _("Chapter %i") ) + 20 ); 
    859             sprintf( s->psz_name, _("Chapter %i"), j + 1 ); 
    860773            TAB_APPEND( t->i_seekpoint, t->seekpoint, s ); 
    861774        } 
  • modules/access/dvdread.c

    rcefad26 r25d2a66  
    5555 * Module descriptor 
    5656 *****************************************************************************/ 
     57#define ANGLE_TEXT N_("DVD angle") 
     58#define ANGLE_LONGTEXT N_( \ 
     59    "Allows you to select the default DVD angle." ) 
     60 
    5761#define CACHING_TEXT N_("Caching value in ms") 
    5862#define CACHING_LONGTEXT N_( \ 
     
    8589vlc_module_begin(); 
    8690    set_description( _("DVDRead Input") ); 
     91    add_integer( "dvdread-angle", 1, NULL, ANGLE_TEXT, 
     92        ANGLE_LONGTEXT, VLC_FALSE ); 
    8793    add_integer( "dvdread-caching", DEFAULT_PTS_DELAY / 1000, NULL, 
    8894        CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE ); 
     
    9197        change_string_list( psz_css_list, psz_css_list_text, 0 ); 
    9298    set_capability( "access_demux", 0 ); 
    93     //add_shortcut( "dvd" ); 
     99    add_shortcut( "dvd" ); 
    94100    add_shortcut( "dvdread" ); 
    95101    add_shortcut( "dvdsimple" ); 
     
    151157}; 
    152158 
    153 static char *ParseCL( vlc_object_t *, char *, vlc_bool_t, int *, int *, int *); 
    154  
    155159static int Control   ( demux_t *, int, va_list ); 
    156160static int Demux     ( demux_t * ); 
    157161static int DemuxBlock( demux_t *, uint8_t *, int ); 
    158162 
    159 static void DemuxTitles( demux_t *, int *, int *, int * ); 
     163static void DemuxTitles( demux_t *, int * ); 
    160164static void ESNew( demux_t *, int, int ); 
    161165 
     
    172176    demux_t      *p_demux = (demux_t*)p_this; 
    173177    demux_sys_t  *p_sys; 
    174     int          i_title, i_chapter, i_angle; 
    175178    char         *psz_name; 
    176179    char         *psz_dvdcss_env; 
    177180    dvd_reader_t *p_dvdread; 
    178181    ifo_handle_t *p_vmg_file; 
    179  
    180     psz_name = ParseCL( VLC_OBJECT(p_demux), p_demux->psz_path, VLC_TRUE, 
    181                         &i_title, &i_chapter, &i_angle ); 
    182     if( !psz_name ) 
    183     { 
    184         return VLC_EGENERIC; 
    185     } 
     182    vlc_value_t  val; 
     183 
     184    if( !p_demux->psz_path || !*p_demux->psz_path ) 
     185    { 
     186        /* Only when selected */ 
     187        if( !p_this->b_force ) return VLC_EGENERIC; 
     188 
     189        psz_name = var_CreateGetString( p_this, "dvd" ); 
     190        if( !psz_name || !*psz_name ) 
     191        { 
     192            if( psz_name ) free( psz_name ); 
     193            return VLC_EGENERIC; 
     194        } 
     195    } 
     196    else psz_name = strdup( p_demux->psz_path ); 
     197 
     198#ifdef WIN32 
     199    if( psz_name[0] && psz_name[1] == ':' && 
     200        psz_name[2] == '\\' && psz_name[3] == '\0' ) psz_name[2] = '\0'; 
     201#endif 
    186202 
    187203    /* Override environment variable DVDCSS_METHOD with config option 
     
    194210        psz_env = malloc( strlen("DVDCSS_METHOD=") + 
    195211                          strlen( psz_dvdcss_env ) + 1 ); 
    196  
    197212        if( !psz_env ) 
    198213        { 
     
    240255 
    241256    p_sys->i_title = p_sys->i_chapter = -1; 
    242     p_sys->i_angle = i_angle; 
    243  
    244     DemuxTitles( p_demux, &i_title, &i_chapter, &i_angle ); 
    245  
    246     DvdReadSetArea( p_demux, i_title, i_chapter, i_angle ); 
     257 
     258    var_Create( p_demux, "dvdread-angle", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); 
     259    var_Get( p_demux, "dvdread-angle", &val ); 
     260    p_sys->i_angle = val.i_int > 0 ? val.i_int : 1; 
     261 
     262    DemuxTitles( p_demux, &p_sys->i_angle ); 
     263    DvdReadSetArea( p_demux, 0, 0, p_sys->i_angle ); 
    247264 
    248265    /* Update default_pts to a suitable value for dvdread access */ 
     
    351368            ppp_title = (input_title_t***)va_arg( args, input_title_t*** ); 
    352369            pi_int    = (int*)va_arg( args, int* ); 
     370            *((int*)va_arg( args, int* )) = 1; /* Title offset */ 
     371            *((int*)va_arg( args, int* )) = 1; /* Chapter offset */ 
    353372 
    354373            /* Duplicate title infos */ 
     
    434453        if( p_sys->i_next_vobu > p_sys->i_title_end_block ) 
    435454        { 
    436             if( p_sys->i_title + 1 >= p_sys->i_titles ) return 0; /* EOF */ 
     455            if( p_sys->i_title + 1 >= p_sys->i_titles ) 
     456            { 
     457                return 0; /* EOF */ 
     458            } 
    437459 
    438460            DvdReadSetArea( p_demux, p_sys->i_title + 1, 0, -1 ); 
     
    441463        if( p_sys->i_pack_len >= 1024 ) 
    442464        { 
    443             msg_Err( p_demux, "i_pack_len >= 1024. This shouldn't happen!" ); 
     465            msg_Err( p_demux, "i_pack_len >= 1024 (%i). " 
     466                     "This shouldn't happen!", p_sys->i_pack_len ); 
    444467            return 0; /* EOF */ 
    445468        } 
     
    455478    if( p_sys->i_cur_block > p_sys->i_title_end_block ) 
    456479    { 
    457         if( p_sys->i_title + 1 >= p_sys->i_titles ) return 0; /* EOF */ 
     480        if( p_sys->i_title + 1 >= p_sys->i_titles ) 
     481        { 
     482            return 0; /* EOF */ 
     483        } 
    458484 
    459485        DvdReadSetArea( p_demux, p_sys->i_title + 1, 0, -1 ); 
     
    902928     */ 
    903929 
    904     if( i_chapter >= 0 && i_chapter <= p_sys->i_chapters ) 
     930    if( i_chapter >= 0 && i_chapter < p_sys->i_chapters ) 
    905931    { 
    906932        pgc_id = p_vts->vts_ptt_srpt->title[ 
     
    10531079     */ 
    10541080    p_sys->i_cur_block = p_sys->dsi_pack.dsi_gi.nv_pck_lbn; 
     1081    p_sys->i_pack_len = p_sys->dsi_pack.dsi_gi.vobu_ea; 
    10551082 
    10561083    /* 
     
    10611088     * really happy. 
    10621089     */ 
    1063     if( p_sys->dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL ) 
     1090 
     1091    p_sys->i_next_vobu = p_sys->i_cur_block + 
     1092        ( p_sys->dsi_pack.vobu_sri.next_vobu & 0x7fffffff ); 
     1093 
     1094    if( p_sys->dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL 
     1095        && p_sys->i_angle > 1 ) 
    10641096    { 
    10651097        switch( ( p_sys->dsi_pack.sml_pbi.category & 0xf000 ) >> 12 ) 
     
    10771109                p_sys->i_next_vobu = p_sys->i_cur_block + 
    10781110                    p_sys->dsi_pack.dsi_gi.vobu_ea + 1; 
    1079                 p_sys->i_pack_len = p_sys->dsi_pack.dsi_gi.vobu_ea; 
    10801111            } 
    10811112            break; 
     
    11011132            p_sys->i_next_vobu = p_sys->i_cur_block + 
    11021133                ( p_sys->dsi_pack.vobu_sri.next_vobu & 0x7fffffff ); 
    1103             p_sys->i_pack_len = p_sys->dsi_pack.dsi_gi.vobu_ea; 
    11041134            break; 
    11051135        } 
    11061136    } 
    1107     else 
     1137    else if( p_sys->dsi_pack.vobu_sri.next_vobu == SRI_END_OF_CELL ) 
    11081138    { 
    11091139        p_sys->i_cur_cell = p_sys->i_next_cell; 
    11101140        DvdReadFindCell( p_demux ); 
    11111141 
    1112         p_sys->i_pack_len = p_sys->dsi_pack.dsi_gi.vobu_ea; 
    11131142        p_sys->i_next_vobu = 
    11141143            p_sys->p_cur_pgc->cell_playback[p_sys->i_cur_cell].first_sector; 
     
    11881217 * DemuxTitles: get the titles/chapters structure 
    11891218 *****************************************************************************/ 
    1190 static void DemuxTitles( demux_t *p_demux, 
    1191                          int *pi_title, int *pi_chapter, int *pi_angle ) 
     1219static void DemuxTitles( demux_t *p_demux, int *pi_angle ) 
    11921220{ 
    11931221    demux_sys_t *p_sys = p_demux->p_sys; 
     
    12121240 
    12131241        t = vlc_input_title_New(); 
    1214         t->psz_name = malloc( strlen( _("Title %i") ) + 20 ); 
    1215         sprintf( t->psz_name, _("Title %i"), i + 1 ); 
    12161242 
    12171243        for( j = 0; j < __MAX( i_chapters, 1 ); j++ ) 
    12181244        { 
    12191245            s = vlc_seekpoint_New(); 
    1220             s->psz_name = malloc( strlen( _("Chapter %i") ) + 20 ); 
    1221             sprintf( s->psz_name, _("Chapter %i"), j + 1 ); 
    12221246            TAB_APPEND( t->i_seekpoint, t->seekpoint, s ); 
    12231247        } 
     
    12251249        TAB_APPEND( p_sys->i_titles, p_sys->titles, t ); 
    12261250    } 
    1227  
    1228     /* Set forced title/chapter/angle */ 
    1229     *pi_title = (*pi_title >= 0 && *pi_title < i_titles) ? *pi_title : 0; 
    1230     *pi_chapter = (*pi_chapter >= 0 && *pi_chapter < 
    1231         tt_srpt->title[*pi_title].nr_of_ptts) ? *pi_chapter : 0; 
    12321251 
    12331252#undef tt_srpt 
    12341253} 
    1235  
    1236 /***************************************************************************** 
    1237  * ParseCL: parse command line. Titles, chapters and angles start from 1. 
    1238  *****************************************************************************/ 
    1239 static char *ParseCL( vlc_object_t *p_this, char *psz_name, vlc_bool_t b_force, 
    1240                       int *i_title, int *i_chapter, int *i_angle ) 
    1241 { 
    1242     char *psz_parser, *psz_source, *psz_next; 
    1243  
    1244     psz_source = strdup( psz_name ); 
    1245     if( psz_source == NULL ) return NULL; 
    1246  
    1247     *i_title = 1; 
    1248     *i_chapter = 1; 
    1249     *i_angle = 1; 
    1250  
    1251     /* Start with the end, because you could have : 
    1252      * dvdnav:/Volumes/my@toto/VIDEO_TS@1,1 
    1253      * (yes, this is kludgy). */ 
    1254     for( psz_parser = psz_source + strlen(psz_source) - 1; 
    1255          psz_parser >= psz_source && *psz_parser != '@'; 
    1256          psz_parser-- ); 
    1257  
    1258     if( psz_parser >= psz_source && *psz_parser == '@' ) 
    1259     { 
    1260         /* Found options */ 
    1261         *psz_parser = '\0'; 
    1262         ++psz_parser; 
    1263  
    1264         *i_title = (int)strtol( psz_parser, &psz_next, 10 ); 
    1265         if( *psz_next ) 
    1266         { 
    1267             psz_parser = psz_next + 1; 
    1268             *i_chapter = (int)strtol( psz_parser, &psz_next, 10 ); 
    1269             if( *psz_next ) 
    1270             { 
    1271                 *i_angle = (int)strtol( psz_next + 1, NULL, 10 ); 
    1272             } 
    1273         } 
    1274     } 
    1275  
    1276     *i_title   = *i_title > 0 ? *i_title : 1; 
    1277     *i_chapter = *i_chapter > 0 ? *i_chapter : 1; 
    1278     *i_angle   = *i_angle > 0 ? *i_angle : 1; 
    1279  
    1280     if( !*psz_source ) 
    1281     { 
    1282         free( psz_source ); 
    1283         if( !b_force ) 
    1284         { 
    1285             return NULL; 
    1286         } 
    1287         psz_source = config_GetPsz( p_this, "dvd" ); 
    1288         if( !psz_source ) return NULL; 
    1289     } 
    1290  
    1291 #ifdef WIN32 
    1292     if( psz_source[0] && psz_source[1] == ':' && 
    1293         psz_source[2] == '\\' && psz_source[3] == '\0' ) 
    1294     { 
    1295         psz_source[2] = '\0'; 
    1296     } 
    1297 #endif 
    1298  
    1299     msg_Dbg( p_this, "dvdroot=%s title=%d chapter=%d angle=%d", 
    1300              psz_source, *i_title, *i_chapter, *i_angle ); 
    1301  
    1302     /* Get back to a 0-based offset */ 
    1303     (*i_title)--; 
    1304     (*i_chapter)--; 
    1305  
    1306     return psz_source; 
    1307 } 
  • src/input/input.c

    rc33b49c r25d2a66  
    5454 
    5555 
    56 static void UpdateFromAccess( input_thread_t * ); 
    57 static void UpdateFromDemux( input_thread_t * ); 
     56static int UpdateFromAccess( input_thread_t * ); 
     57static int UpdateFromDemux( input_thread_t * ); 
    5858 
    5959static void UpdateItemLength( input_thread_t *, int64_t i_length ); 
     
    6363static void DecodeUrl  ( char * ); 
    6464static void MRLSplit( input_thread_t *, char *, char **, char **, char ** ); 
     65static void MRLSections( input_thread_t *, char *, int *, int *, int *, int *); 
    6566 
    6667static input_source_t *InputSourceNew( input_thread_t *); 
     
    124125    p_input->i_title = 0; 
    125126    p_input->title   = NULL; 
     127    p_input->i_title_offset = p_input->i_seekpoint_offset = 0; 
    126128    p_input->i_state = INIT_S; 
    127129    p_input->i_rate  = INPUT_RATE_DEFAULT; 
     
    133135    p_input->i_pts_delay = 0; 
    134136 
    135  
    136137    /* Init Input fields */ 
    137138    p_input->input.p_item = p_item; 
     
    142143    p_input->input.i_title  = 0; 
    143144    p_input->input.title    = NULL; 
     145    p_input->input.i_title_offset = p_input->input.i_seekpoint_offset = 0; 
    144146    p_input->input.b_can_pace_control = VLC_TRUE; 
    145147    p_input->input.b_eof = VLC_FALSE; 
     
    345347                    p_input->input.p_demux->info.i_update ) 
    346348                { 
    347                     UpdateFromDemux( p_input ); 
     349                    i_ret = UpdateFromDemux( p_input ); 
    348350                    b_force_update = VLC_TRUE; 
    349351                } 
     
    352354                          p_input->input.p_access->info.i_update ) 
    353355                { 
    354                     UpdateFromAccess( p_input ); 
     356                    i_ret = UpdateFromAccess( p_input ); 
    355357                    b_force_update = VLC_TRUE; 
    356358                } 
    357359            } 
    358             else if( i_ret == 0 )    /* EOF */ 
     360 
     361            if( i_ret == 0 )    /* EOF */ 
    359362            { 
    360363                vlc_value_t repeat; 
     
    378381                    } 
    379382 
    380                     /* Seek to title 0 position 0(start) */ 
    381                     val.i_int = 0; 
    382                     input_ControlPush( p_input, INPUT_CONTROL_SET_TITLE, &val ); 
     383                    /* Seek to start title/seekpoint */ 
     384                    val.i_int = p_input->input.i_title_start - 
     385                        p_input->input.i_title_offset; 
     386                    if( val.i_int < 0 || val.i_int >= p_input->input.i_title ) 
     387                        val.i_int = 0; 
     388                    input_ControlPush( p_input, 
     389                                       INPUT_CONTROL_SET_TITLE, &val ); 
     390 
     391                    val.i_int = p_input->input.i_seekpoint_start - 
     392                        p_input->input.i_seekpoint_offset; 
     393                    if( val.i_int > 0 /* TODO: check upper boundary */ ) 
     394                        input_ControlPush( p_input, 
     395                                           INPUT_CONTROL_SET_SEEKPOINT, &val ); 
     396 
     397                    /* Seek to start position */ 
    383398                    if( p_input->i_start > 0 ) 
    384399                    { 
     
    422437        vlc_mutex_unlock( &p_input->lock_control ); 
    423438 
    424         if( b_force_update || 
    425             i_intf_update < mdate() ) 
     439        if( b_force_update || i_intf_update < mdate() ) 
    426440        { 
    427441            vlc_value_t val; 
     
    530544    p_input->i_title = p_input->input.i_title; 
    531545    p_input->title   = p_input->input.title; 
     546    p_input->i_title_offset = p_input->input.i_title_offset; 
     547    p_input->i_seekpoint_offset = p_input->input.i_seekpoint_offset; 
    532548    if( p_input->i_title > 0 ) 
    533549    { 
     
    548564     * cache more data. */ 
    549565    var_Get( p_input, "audio-desync", &val ); 
    550     if( val.i_int < 0 ) 
    551         p_input->i_pts_delay -= (val.i_int * 1000); 
     566    if( val.i_int < 0 ) p_input->i_pts_delay -= (val.i_int * 1000); 
    552567 
    553568    /* Load master infos */ 
     
    560575        UpdateItemLength( p_input, val.i_time ); 
    561576    } 
     577 
     578    /* Start title/chapter */ 
     579    val.i_int = p_input->input.i_title_start - 
     580        p_input->input.i_title_offset; 
     581    if( val.i_int > 0 && val.i_int < p_input->input.i_title ) 
     582        input_ControlPush( p_input, INPUT_CONTROL_SET_TITLE, &val ); 
     583    val.i_int = p_input->input.i_seekpoint_start - 
     584        p_input->input.i_seekpoint_offset; 
     585    if( val.i_int > 0 /* TODO: check upper boundary */ ) 
     586        input_ControlPush( p_input, INPUT_CONTROL_SET_SEEKPOINT, &val ); 
     587 
    562588    /* Start time*/ 
    563589    /* Set start time */ 
     
    13451371 * UpdateFromDemux: 
    13461372 *****************************************************************************/ 
    1347 static void UpdateFromDemux( input_thread_t *p_input ) 
     1373static int UpdateFromDemux( input_thread_t *p_input ) 
    13481374{ 
    13491375    demux_t *p_demux = p_input->input.p_demux; 
     
    13671393    } 
    13681394    p_demux->info.i_update &= ~INPUT_UPDATE_SIZE; 
     1395 
     1396    /* Hmmm only works with master input */ 
     1397    if( p_input->input.p_demux == p_demux ) 
     1398    { 
     1399        int i_title_end = p_input->input.i_title_end - 
     1400            p_input->input.i_title_offset; 
     1401        int i_seekpoint_end = p_input->input.i_seekpoint_end - 
     1402            p_input->input.i_seekpoint_offset; 
     1403 
     1404        if( i_title_end >= 0 && i_seekpoint_end >=0 ) 
     1405        { 
     1406            if( p_demux->info.i_title > i_title_end || 
     1407                ( p_demux->info.i_title == i_title_end && 
     1408                  p_demux->info.i_seekpoint > i_seekpoint_end ) ) return 0; 
     1409        } 
     1410        else if( i_seekpoint_end >=0 ) 
     1411        { 
     1412            if( p_demux->info.i_seekpoint > i_seekpoint_end ) return 0; 
     1413        } 
     1414        else if( i_title_end >= 0 ) 
     1415        { 
     1416            if( p_demux->info.i_title > i_title_end ) return 0; 
     1417        } 
     1418    } 
     1419 
     1420    return 1; 
    13691421} 
    13701422 
     
    13721424 * UpdateFromAccess: 
    13731425 *****************************************************************************/ 
    1374 static void UpdateFromAccess( input_thread_t *p_input ) 
     1426static int UpdateFromAccess( input_thread_t *p_input ) 
    13751427{ 
    13761428    access_t *p_access = p_input->input.p_access; 
     
    13961448    } 
    13971449    p_access->info.i_update &= ~INPUT_UPDATE_SIZE; 
     1450 
     1451    /* Hmmm only works with master input */ 
     1452    if( p_input->input.p_access == p_access ) 
     1453    { 
     1454        int i_title_end = p_input->input.i_title_end - 
     1455            p_input->input.i_title_offset; 
     1456        int i_seekpoint_end = p_input->input.i_seekpoint_end - 
     1457            p_input->input.i_seekpoint_offset; 
     1458 
     1459        if( i_title_end >= 0 && i_seekpoint_end >=0 ) 
     1460        { 
     1461            if( p_access->info.i_title > i_title_end || 
     1462                ( p_access->info.i_title == i_title_end && 
     1463                  p_access->info.i_seekpoint > i_seekpoint_end ) ) return 0; 
     1464        } 
     1465        else if( i_seekpoint_end >=0 ) 
     1466        { 
     1467            if( p_access->info.i_seekpoint > i_seekpoint_end ) return 0; 
     1468        } 
     1469        else if( i_title_end >= 0 ) 
     1470        { 
     1471            if( p_access->info.i_title > i_title_end ) return 0; 
     1472        } 
     1473    } 
     1474 
     1475    return 1; 
    13981476} 
    13991477 
     
    14531531             psz_mrl, psz_access, psz_demux, psz_path ); 
    14541532 
     1533    /* Find optional titles and seekpoints */ 
     1534    MRLSections( p_input, psz_path, &in->i_title_start, &in->i_title_end, 
     1535                 &in->i_seekpoint_start, &in->i_seekpoint_end ); 
     1536 
    14551537    if( psz_forced_demux && *psz_forced_demux ) 
    14561538        psz_demux = psz_forced_demux; 
     
    14731555 
    14741556        in->b_title_demux = VLC_TRUE; 
    1475         if( demux2_Control( in->p_demux, 
    1476                             DEMUX_GET_TITLE_INFO
    1477                             &in->title, &in->i_title ) ) 
     1557        if( demux2_Control( in->p_demux, DEMUX_GET_TITLE_INFO, 
     1558                            &in->title, &in->i_title
     1559                            &in->i_title_offset, &in->i_seekpoint_offset ) ) 
    14781560        { 
    14791561            in->i_title = 0; 
     
    15381620 
    15391621        in->b_title_demux = VLC_FALSE; 
    1540         if( access2_Control( in->p_access, 
    1541                              ACCESS_GET_TITLE_INFO, 
    1542                              &in->title, &in->i_title ) ) 
     1622        if( access2_Control( in->p_access, ACCESS_GET_TITLE_INFO, 
     1623                             &in->title, &in->i_title, 
     1624                             &in->i_title_offset, &in->i_seekpoint_offset ) ) 
     1625 
    15431626        { 
    15441627            in->i_title = 0; 
     
    15791662        { 
    15801663            if( demux2_Control( in->p_demux, DEMUX_GET_TITLE_INFO, 
    1581                                 &in->title, &in->i_title ) ) 
     1664                                &in->title, &in->i_title, 
     1665                                &in->i_title_offset, &in->i_seekpoint_offset )) 
    15821666            { 
    15831667                in->i_title = 0; 
     
    18721956} 
    18731957 
     1958/***************************************************************************** 
     1959 * MRLSplit: parse the access, demux and url part of the 
     1960 *           Media Resource Locator. 
     1961 *****************************************************************************/ 
    18741962static void MRLSplit( input_thread_t *p_input, char *psz_dup, 
    18751963                      char **ppsz_access, char **ppsz_demux, char **ppsz_path ) 
     
    19292017        *ppsz_path = psz_path; 
    19302018} 
     2019 
     2020/***************************************************************************** 
     2021 * MRLSections: parse title and seekpoint info from the Media Resource Locator. 
     2022 * 
     2023 * Syntax: 
     2024 * [url][@[title-start][,chapter-start][-[title-end][,chapter-end]]] 
     2025 *****************************************************************************/ 
     2026static void MRLSections( input_thread_t *p_input, char *psz_source, 
     2027                         int *pi_title_start, int *pi_title_end, 
     2028                         int *pi_chapter_start, int *pi_chapter_end ) 
     2029{ 
     2030    char *psz, *psz_end, *psz_next; 
     2031 
     2032    *pi_title_start = *pi_title_end = -1; 
     2033    *pi_chapter_start = *pi_chapter_end = -1; 
     2034 
     2035    /* Start by parsing titles and chapters */ 
     2036    if( !psz_source || !( psz = strrchr( psz_source, '@' ) ) ) return; 
     2037 
     2038    *psz++ = 0; 
     2039 
     2040    /* Separate start and end */ 
     2041    if( ( psz_end = strchr( psz, '-' ) ) ) *psz_end++ = 0; 
     2042 
     2043    /* Look for the start title */ 
     2044    *pi_title_start = strtol( psz, &psz_next, 0 ); 
     2045    if( !*pi_title_start && psz == psz_next ) *pi_title_start = -1; 
     2046    *pi_title_end = *pi_title_start; 
     2047    psz = psz_next; 
     2048 
     2049    /* Look for the start chapter */ 
     2050    if( *psz ) psz++; 
     2051    *pi_chapter_start = strtol( psz, &psz_next, 0 ); 
     2052    if( !*pi_chapter_start && psz == psz_next ) *pi_chapter_start = -1; 
     2053    *pi_chapter_end = *pi_chapter_start; 
     2054 
     2055    if( psz_end ) 
     2056    { 
     2057        /* Look for the end title */ 
     2058        *pi_title_end = strtol( psz_end, &psz_next, 0 ); 
     2059        if( !*pi_title_end && psz_end == psz_next ) *pi_title_end = -1; 
     2060        psz_end = psz_next; 
     2061 
     2062        /* Look for the end chapter */ 
     2063        if( *psz_end ) psz_end++; 
     2064        *pi_chapter_end = strtol( psz_end, &psz_next, 0 ); 
     2065        if( !*pi_chapter_end && psz_end == psz_next ) *pi_chapter_end = -1; 
     2066    } 
     2067 
     2068    msg_Dbg( p_input,