Changeset 25d2a663a98c0adc49d95e3ad5612f76da954953
- Timestamp:
- 21/08/04 01:37:40 (4 years ago)
- git-parent:
- Files:
-
- include/vlc_input.h (modified) (2 diffs)
- modules/access/cdda.c (modified) (7 diffs)
- modules/access/dvdnav.c (modified) (10 diffs)
- modules/access/dvdread.c (modified) (19 diffs)
- src/input/input.c (modified) (22 diffs)
- src/input/var.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
include/vlc_input.h
rc7ceea8 r25d2a66 202 202 input_title_t **title; 203 203 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 204 212 /* Properties */ 205 213 vlc_bool_t b_can_pace_control; … … 253 261 int i_title; 254 262 input_title_t **title; 263 264 int i_title_offset; 265 int i_seekpoint_offset; 255 266 256 267 /* User bookmarks FIXME won't be easy with multiples input */ modules/access/cdda.c
r59045db r25d2a66 73 73 input_title_t *title[99]; /* No more that 99 track in a cd-audio */ 74 74 75 int i_title_start;76 int i_title_end;77 78 75 /* Current position */ 79 76 int i_sector; /* Current Sector */ … … 91 88 /***************************************************************************** 92 89 * Open: open cdda 93 * MRL syntax: [dev_path][@[title-start][-[title-end]]]94 90 *****************************************************************************/ 95 91 static int Open( vlc_object_t *p_this ) … … 98 94 access_sys_t *p_sys; 99 95 100 char *psz_dup, *psz;101 int i, i_title_start = -1, i_title_end = -1;102 96 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 ) 112 107 { 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 ); 129 109 return VLC_EGENERIC; 130 110 } 131 111 } 112 else psz_name = strdup( p_access->psz_path ); 132 113 133 114 /* 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 ); 138 119 return VLC_EGENERIC; 139 120 } 140 free( psz_ dup);121 free( psz_name ); 141 122 142 123 /* Set up p_access */ … … 185 166 } 186 167 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; 198 170 199 171 /* Build a WAV header for the output data */ … … 267 239 while( p_sys->i_sector >= p_sys->p_sectors[p_access->info.i_title + 1] ) 268 240 { 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 ) 272 242 { 273 243 p_access->info.b_eof = VLC_TRUE; … … 372 342 ppp_title = (input_title_t***)va_arg( args, input_title_t*** ); 373 343 pi_int = (int*)va_arg( args, int* ); 344 *((int*)va_arg( args, int* )) = 1; /* Title offset */ 374 345 375 346 /* Duplicate title infos */ … … 395 366 /* Next sector to read */ 396 367 p_sys->i_sector = p_sys->p_sectors[i]; 397 398 /* User tries to access another title so better reset399 * the end title */400 p_sys->i_title_end = -1;401 368 } 402 369 break; modules/access/dvdnav.c
r2b8ade3 r25d2a66 53 53 * Module descriptor 54 54 *****************************************************************************/ 55 #define ANGLE_TEXT N_("DVD angle") 56 #define ANGLE_LONGTEXT N_( \ 57 "Allows you to select the default DVD angle." ) 58 55 59 #define CACHING_TEXT N_("Caching value in ms") 56 60 #define CACHING_LONGTEXT N_( \ … … 67 71 vlc_module_begin(); 68 72 set_description( _("DVDnav Input") ); 73 add_integer( "dvdnav-angle", 1, NULL, ANGLE_TEXT, 74 ANGLE_LONGTEXT, VLC_FALSE ); 69 75 add_integer( "dvdnav-caching", DEFAULT_PTS_DELAY / 1000, NULL, 70 76 CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE ); … … 83 89 * Local prototypes 84 90 *****************************************************************************/ 85 static char *ParseCL( vlc_object_t *, char *, vlc_bool_t, int *, int *, int *);86 87 91 typedef struct 88 92 { … … 147 151 demux_sys_t *p_sys; 148 152 dvdnav_t *p_dvdnav; 149 int i_ title, i_chapter, i_angle;153 int i_angle; 150 154 char *psz_name; 151 155 vlc_value_t val; 152 156 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 159 175 160 176 /* Try some simple probing to avoid going through dvdnav_open too often */ … … 164 180 return VLC_EGENERIC; 165 181 } 166 167 msg_Dbg( p_this, "dvdroot=%s title=%d chapter=%d angle=%d",168 psz_name, i_title, i_chapter, i_angle );169 182 170 183 /* Open dvdnav */ … … 228 241 DemuxTitles( p_demux ); 229 242 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 else239 {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 else254 {255 p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;256 p_demux->info.i_seekpoint = i_chapter;257 }258 }259 260 243 var_Create( p_demux, "dvdnav-menu", VLC_VAR_BOOL|VLC_VAR_DOINHERIT ); 261 244 var_Get( p_demux, "dvdnav-menu", &val ); 262 if( (i_title < 0 && val.b_bool) || i_title == 0)245 if( val.b_bool ) 263 246 { 264 247 msg_Dbg( p_demux, "trying to go to dvd menu" ); … … 274 257 msg_Warn( p_demux, "cannot go to dvd menu" ); 275 258 } 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; 284 264 285 265 /* Update default_pts to a suitable value for dvdnav access */ … … 427 407 ppp_title = (input_title_t***)va_arg( args, input_title_t*** ); 428 408 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 */ 429 411 430 412 /* Duplicate title infos */ … … 733 715 } 734 716 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,1753 * (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 WIN32792 if( psz_source[0] && psz_source[1] == ':' &&793 psz_source[2] == '\\' && psz_source[3] == '\0' )794 {795 psz_source[2] = '\0';796 }797 #endif798 799 return psz_source;800 }801 802 717 static void DemuxTitles( demux_t *p_demux ) 803 718 { … … 856 771 { 857 772 s = vlc_seekpoint_New(); 858 s->psz_name = malloc( strlen( _("Chapter %i") ) + 20 );859 sprintf( s->psz_name, _("Chapter %i"), j + 1 );860 773 TAB_APPEND( t->i_seekpoint, t->seekpoint, s ); 861 774 } modules/access/dvdread.c
rcefad26 r25d2a66 55 55 * Module descriptor 56 56 *****************************************************************************/ 57 #define ANGLE_TEXT N_("DVD angle") 58 #define ANGLE_LONGTEXT N_( \ 59 "Allows you to select the default DVD angle." ) 60 57 61 #define CACHING_TEXT N_("Caching value in ms") 58 62 #define CACHING_LONGTEXT N_( \ … … 85 89 vlc_module_begin(); 86 90 set_description( _("DVDRead Input") ); 91 add_integer( "dvdread-angle", 1, NULL, ANGLE_TEXT, 92 ANGLE_LONGTEXT, VLC_FALSE ); 87 93 add_integer( "dvdread-caching", DEFAULT_PTS_DELAY / 1000, NULL, 88 94 CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE ); … … 91 97 change_string_list( psz_css_list, psz_css_list_text, 0 ); 92 98 set_capability( "access_demux", 0 ); 93 //add_shortcut( "dvd" );99 add_shortcut( "dvd" ); 94 100 add_shortcut( "dvdread" ); 95 101 add_shortcut( "dvdsimple" ); … … 151 157 }; 152 158 153 static char *ParseCL( vlc_object_t *, char *, vlc_bool_t, int *, int *, int *);154 155 159 static int Control ( demux_t *, int, va_list ); 156 160 static int Demux ( demux_t * ); 157 161 static int DemuxBlock( demux_t *, uint8_t *, int ); 158 162 159 static void DemuxTitles( demux_t *, int * , int *, int *);163 static void DemuxTitles( demux_t *, int * ); 160 164 static void ESNew( demux_t *, int, int ); 161 165 … … 172 176 demux_t *p_demux = (demux_t*)p_this; 173 177 demux_sys_t *p_sys; 174 int i_title, i_chapter, i_angle;175 178 char *psz_name; 176 179 char *psz_dvdcss_env; 177 180 dvd_reader_t *p_dvdread; 178 181 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 186 202 187 203 /* Override environment variable DVDCSS_METHOD with config option … … 194 210 psz_env = malloc( strlen("DVDCSS_METHOD=") + 195 211 strlen( psz_dvdcss_env ) + 1 ); 196 197 212 if( !psz_env ) 198 213 { … … 240 255 241 256 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 ); 247 264 248 265 /* Update default_pts to a suitable value for dvdread access */ … … 351 368 ppp_title = (input_title_t***)va_arg( args, input_title_t*** ); 352 369 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 */ 353 372 354 373 /* Duplicate title infos */ … … 434 453 if( p_sys->i_next_vobu > p_sys->i_title_end_block ) 435 454 { 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 } 437 459 438 460 DvdReadSetArea( p_demux, p_sys->i_title + 1, 0, -1 ); … … 441 463 if( p_sys->i_pack_len >= 1024 ) 442 464 { 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 ); 444 467 return 0; /* EOF */ 445 468 } … … 455 478 if( p_sys->i_cur_block > p_sys->i_title_end_block ) 456 479 { 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 } 458 484 459 485 DvdReadSetArea( p_demux, p_sys->i_title + 1, 0, -1 ); … … 902 928 */ 903 929 904 if( i_chapter >= 0 && i_chapter < =p_sys->i_chapters )930 if( i_chapter >= 0 && i_chapter < p_sys->i_chapters ) 905 931 { 906 932 pgc_id = p_vts->vts_ptt_srpt->title[ … … 1053 1079 */ 1054 1080 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; 1055 1082 1056 1083 /* … … 1061 1088 * really happy. 1062 1089 */ 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 ) 1064 1096 { 1065 1097 switch( ( p_sys->dsi_pack.sml_pbi.category & 0xf000 ) >> 12 ) … … 1077 1109 p_sys->i_next_vobu = p_sys->i_cur_block + 1078 1110 p_sys->dsi_pack.dsi_gi.vobu_ea + 1; 1079 p_sys->i_pack_len = p_sys->dsi_pack.dsi_gi.vobu_ea;1080 1111 } 1081 1112 break; … … 1101 1132 p_sys->i_next_vobu = p_sys->i_cur_block + 1102 1133 ( p_sys->dsi_pack.vobu_sri.next_vobu & 0x7fffffff ); 1103 p_sys->i_pack_len = p_sys->dsi_pack.dsi_gi.vobu_ea;1104 1134 break; 1105 1135 } 1106 1136 } 1107 else 1137 else if( p_sys->dsi_pack.vobu_sri.next_vobu == SRI_END_OF_CELL ) 1108 1138 { 1109 1139 p_sys->i_cur_cell = p_sys->i_next_cell; 1110 1140 DvdReadFindCell( p_demux ); 1111 1141 1112 p_sys->i_pack_len = p_sys->dsi_pack.dsi_gi.vobu_ea;1113 1142 p_sys->i_next_vobu = 1114 1143 p_sys->p_cur_pgc->cell_playback[p_sys->i_cur_cell].first_sector; … … 1188 1217 * DemuxTitles: get the titles/chapters structure 1189 1218 *****************************************************************************/ 1190 static void DemuxTitles( demux_t *p_demux, 1191 int *pi_title, int *pi_chapter, int *pi_angle ) 1219 static void DemuxTitles( demux_t *p_demux, int *pi_angle ) 1192 1220 { 1193 1221 demux_sys_t *p_sys = p_demux->p_sys; … … 1212 1240 1213 1241 t = vlc_input_title_New(); 1214 t->psz_name = malloc( strlen( _("Title %i") ) + 20 );1215 sprintf( t->psz_name, _("Title %i"), i + 1 );1216 1242 1217 1243 for( j = 0; j < __MAX( i_chapters, 1 ); j++ ) 1218 1244 { 1219 1245 s = vlc_seekpoint_New(); 1220 s->psz_name = malloc( strlen( _("Chapter %i") ) + 20 );1221 sprintf( s->psz_name, _("Chapter %i"), j + 1 );1222 1246 TAB_APPEND( t->i_seekpoint, t->seekpoint, s ); 1223 1247 } … … 1225 1249 TAB_APPEND( p_sys->i_titles, p_sys->titles, t ); 1226 1250 } 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;1232 1251 1233 1252 #undef tt_srpt 1234 1253 } 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,11253 * (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 WIN321292 if( psz_source[0] && psz_source[1] == ':' &&1293 psz_source[2] == '\\' && psz_source[3] == '\0' )1294 {1295 psz_source[2] = '\0';1296 }1297 #endif1298 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 54 54 55 55 56 static voidUpdateFromAccess( input_thread_t * );57 static voidUpdateFromDemux( input_thread_t * );56 static int UpdateFromAccess( input_thread_t * ); 57 static int UpdateFromDemux( input_thread_t * ); 58 58 59 59 static void UpdateItemLength( input_thread_t *, int64_t i_length ); … … 63 63 static void DecodeUrl ( char * ); 64 64 static void MRLSplit( input_thread_t *, char *, char **, char **, char ** ); 65 static void MRLSections( input_thread_t *, char *, int *, int *, int *, int *); 65 66 66 67 static input_source_t *InputSourceNew( input_thread_t *); … … 124 125 p_input->i_title = 0; 125 126 p_input->title = NULL; 127 p_input->i_title_offset = p_input->i_seekpoint_offset = 0; 126 128 p_input->i_state = INIT_S; 127 129 p_input->i_rate = INPUT_RATE_DEFAULT; … … 133 135 p_input->i_pts_delay = 0; 134 136 135 136 137 /* Init Input fields */ 137 138 p_input->input.p_item = p_item; … … 142 143 p_input->input.i_title = 0; 143 144 p_input->input.title = NULL; 145 p_input->input.i_title_offset = p_input->input.i_seekpoint_offset = 0; 144 146 p_input->input.b_can_pace_control = VLC_TRUE; 145 147 p_input->input.b_eof = VLC_FALSE; … … 345 347 p_input->input.p_demux->info.i_update ) 346 348 { 347 UpdateFromDemux( p_input );349 i_ret = UpdateFromDemux( p_input ); 348 350 b_force_update = VLC_TRUE; 349 351 } … … 352 354 p_input->input.p_access->info.i_update ) 353 355 { 354 UpdateFromAccess( p_input );356 i_ret = UpdateFromAccess( p_input ); 355 357 b_force_update = VLC_TRUE; 356 358 } 357 359 } 358 else if( i_ret == 0 ) /* EOF */ 360 361 if( i_ret == 0 ) /* EOF */ 359 362 { 360 363 vlc_value_t repeat; … … 378 381 } 379 382 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 */ 383 398 if( p_input->i_start > 0 ) 384 399 { … … 422 437 vlc_mutex_unlock( &p_input->lock_control ); 423 438 424 if( b_force_update || 425 i_intf_update < mdate() ) 439 if( b_force_update || i_intf_update < mdate() ) 426 440 { 427 441 vlc_value_t val; … … 530 544 p_input->i_title = p_input->input.i_title; 531 545 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; 532 548 if( p_input->i_title > 0 ) 533 549 { … … 548 564 * cache more data. */ 549 565 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); 552 567 553 568 /* Load master infos */ … … 560 575 UpdateItemLength( p_input, val.i_time ); 561 576 } 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 562 588 /* Start time*/ 563 589 /* Set start time */ … … 1345 1371 * UpdateFromDemux: 1346 1372 *****************************************************************************/ 1347 static voidUpdateFromDemux( input_thread_t *p_input )1373 static int UpdateFromDemux( input_thread_t *p_input ) 1348 1374 { 1349 1375 demux_t *p_demux = p_input->input.p_demux; … … 1367 1393 } 1368 1394 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; 1369 1421 } 1370 1422 … … 1372 1424 * UpdateFromAccess: 1373 1425 *****************************************************************************/ 1374 static voidUpdateFromAccess( input_thread_t *p_input )1426 static int UpdateFromAccess( input_thread_t *p_input ) 1375 1427 { 1376 1428 access_t *p_access = p_input->input.p_access; … … 1396 1448 } 1397 1449 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; 1398 1476 } 1399 1477 … … 1453 1531 psz_mrl, psz_access, psz_demux, psz_path ); 1454 1532 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 1455 1537 if( psz_forced_demux && *psz_forced_demux ) 1456 1538 psz_demux = psz_forced_demux; … … 1473 1555 1474 1556 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 ) ) 1478 1560 { 1479 1561 in->i_title = 0; … … 1538 1620 1539 1621 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 1543 1626 { 1544 1627 in->i_title = 0; … … 1579 1662 { 1580 1663 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 )) 1582 1666 { 1583 1667 in->i_title = 0; … … 1872 1956 } 1873 1957 1958 /***************************************************************************** 1959 * MRLSplit: parse the access, demux and url part of the 1960 * Media Resource Locator. 1961 *****************************************************************************/ 1874 1962 static void MRLSplit( input_thread_t *p_input, char *psz_dup, 1875 1963 char **ppsz_access, char **ppsz_demux, char **ppsz_path ) … … 1929 2017 *ppsz_path = psz_path; 1930 2018 } 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 *****************************************************************************/ 2026 static 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,
