changeset 9870:09d630a4f991

support for multiple subtitle files by Marcin Wojdyr <wojdyr@unipress.waw.pl>
author henry
date Mon, 07 Apr 2003 16:04:02 +0000
parents 49f639c73367
children 62389c1ecf22
files DOCS/en/mplayer.1 Gui/interface.c cfg-common.h find_sub.c mencoder.c mplayer.c mplayer.h subreader.c subreader.h
diffstat 9 files changed, 533 insertions(+), 238 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/en/mplayer.1	Mon Apr 07 14:28:00 2003 +0000
+++ b/DOCS/en/mplayer.1	Mon Apr 07 16:04:02 2003 +0000
@@ -946,11 +946,13 @@
 output.
 .TP
 .B \-slang <two\ letter\ country\ code> (also see \-sid option)
-Works only for DVD playback.
-Turns on/\:selects DVD subtitle language.
+For DVD playback, turns on/\:selects DVD subtitle language.
 For the list of available subtitles, use with the \-v option and look at the
 output.
 
+Otherwise, determines an optional subtitle suffix which gets a higher
+priority when searching for subtitles.
+
 .I EXAMPLE:
 .PD 0
 .RSs
@@ -960,8 +962,9 @@
 .PD 1
 .
 .TP
-.B \-sub <subtitle\ file>
-Use/\:display this subtitle file.
+.B \-sub <subtitle\-file1,subtitle\-file2,...>
+Use/\:display these subtitle files. Only one file can be displayed 
+at the same time and the files can be switched with 'j'. 
 .TP
 .B \-sub-bg-alpha <0\-255>
 Specify the alpha channel value for subtitles and OSD backgrounds.
--- a/Gui/interface.c	Mon Apr 07 14:28:00 2003 +0000
+++ b/Gui/interface.c	Mon Apr 07 16:04:02 2003 +0000
@@ -328,7 +328,7 @@
 
  if ( filename ) mplSetFileName( NULL,filename,STREAMTYPE_FILE );
  if ( plCurrent && !filename ) mplSetFileName( plCurrent->path,plCurrent->name,STREAMTYPE_FILE );
- if ( sub_name ) guiSetFilename( guiIntfStruct.Subtitlename,sub_name );
+ if ( subdata ) guiSetFilename( guiIntfStruct.Subtitlename, subdata->filename );
 #if defined( USE_OSD ) || defined( USE_SUB )
  guiLoadFont();
 #endif
@@ -416,19 +416,20 @@
 #ifdef USE_SUB
 extern mp_osd_obj_t* vo_osd_list;
 
+extern char **sub_name;
+
 void guiLoadSubtitle( char * name )
 {
  if ( guiIntfStruct.Playing == 0 )
   {
-   guiIntfStruct.SubtitleChanged=1;
+   guiIntfStruct.SubtitleChanged=1; //what is this for? (mw)
    return;
   }
- if ( subtitles )
+ if ( subdata )
   {
    mp_msg( MSGT_GPLAYER,MSGL_INFO,"[gui] Delete subtitles.\n" );
-   sub_free( subtitles );
-   subtitles=NULL;
-   gfree( (void **)&sub_name );
+   sub_free( subdata );
+   subdata=NULL;
    vo_sub=NULL;
    if ( vo_osd_list )
     {
@@ -449,11 +450,15 @@
   }
  if ( name )
   {
-   mp_msg( MSGT_GPLAYER,MSGL_INFO,"[gui] Delete Load subtitle: %s\n",name );
-   sub_name=gstrdup( name );
-   subtitles=sub_read_file( sub_name,guiIntfStruct.FPS );
-   if ( !subtitles ) mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_CantLoadSub,name );
+   mp_msg( MSGT_GPLAYER,MSGL_INFO,"[gui] Load subtitle: %s\n",name );
+   subdata=sub_read_file( gstrdup( name ), guiIntfStruct.FPS );
+   if ( !subdata ) mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_CantLoadSub,name );
+   sub_name = (malloc(2 * sizeof(char*))); //when mplayer will be restarted 
+   sub_name[0] = strdup(name);             //sub_name[0] will be read 
+   sub_name[1] = NULL;  
   }
+ update_set_of_subtitles();
+
 }
 #endif
 
@@ -797,7 +802,7 @@
 #endif
 // -- subtitle
 #ifdef USE_SUB
-	sub_name=gstrdup( guiIntfStruct.Subtitlename );
+	//subdata->filename=gstrdup( guiIntfStruct.Subtitlename );
 	stream_dump_type=0;
 	if ( gtkSubDumpMPSub ) stream_dump_type=4;
 	if ( gtkSubDumpSrt ) stream_dump_type=6;
--- a/cfg-common.h	Mon Apr 07 14:28:00 2003 +0000
+++ b/cfg-common.h	Mon Apr 07 16:04:02 2003 +0000
@@ -21,10 +21,10 @@
 	{"dvdangle", &dvd_angle, CONF_TYPE_INT, CONF_RANGE, 1, 99, NULL},
 	{"chapter", dvd_parse_chapter_range, CONF_TYPE_FUNC_PARAM, 0, 0, 0, NULL},
 	{"alang", &audio_lang, CONF_TYPE_STRING, 0, 0, 0, NULL},
-	{"slang", &dvdsub_lang, CONF_TYPE_STRING, 0, 0, 0, NULL},
 #else
 	{"dvd", "MPlayer was compiled WITHOUT libdvdread support!\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
 #endif
+	{"slang", &dvdsub_lang, CONF_TYPE_STRING, 0, 0, 0, NULL},
 
 #ifdef HAVE_LIBCSS
         {"dvdauth", &dvd_auth_device, CONF_TYPE_STRING, 0, 0, 0, NULL},
@@ -192,7 +192,7 @@
 // ------------------------- subtitles options --------------------
 
 #ifdef USE_SUB
-	{"sub", &sub_name, CONF_TYPE_STRING, 0, 0, 0, NULL},
+	{"sub", &sub_name, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
 #ifdef USE_ICONV
 	{"subcp", &sub_cp, CONF_TYPE_STRING, 0, 0, 0, NULL},
 #endif	
--- a/find_sub.c	Mon Apr 07 14:28:00 2003 +0000
+++ b/find_sub.c	Mon Apr 07 16:04:02 2003 +0000
@@ -21,11 +21,12 @@
 extern float sub_delay;
 extern float  sub_fps;
 
-void step_sub(subtitle *subtitles, float pts, int movement) {
-    int key = sub_uses_time ? (100*(pts+sub_delay)) : ((pts+sub_delay)*sub_fps);
+void step_sub(sub_data *subd, float pts, int movement) {
+    subtitle *subs; 
+    int key = (pts+sub_delay) * (subd->sub_uses_time ? 100 : sub_fps);
 
-    if (subtitles == NULL)
-    	return;
+    if (subd == NULL) return;
+    subs = subd->subtitles;
 
     /* Tell the OSD subsystem that the OSD contents will change soon */
     vo_osd_changed(OSDTYPE_SUBTITLE);
@@ -33,25 +34,27 @@
     /* If we are moving forward, don't count the next (current) subtitle
      * if we haven't displayed it yet. Same when moving other direction.
      */
-    if (movement > 0 && key < subtitles[current_sub].start)
+    if (movement > 0 && key < subs[current_sub].start)
     	movement--;
-    if (movement < 0 && key >= subtitles[current_sub].end)
+    if (movement < 0 && key >= subs[current_sub].end)
     	movement++;
 
     /* Never move beyond first or last subtitle. */
     if (current_sub+movement < 0)
     	movement = 0-current_sub;
-    if (current_sub+movement >= sub_num)
-    	movement = sub_num-current_sub-1;
+    if (current_sub+movement >= subd->sub_num)
+    	movement = subd->sub_num - current_sub - 1;
 
     current_sub += movement;
-    sub_delay = subtitles[current_sub].start/(sub_uses_time ? 100 : sub_fps) - pts;
+    sub_delay = subs[current_sub].start / (subd->sub_uses_time ? 100 : sub_fps) - pts;
 }
 
-void find_sub(subtitle* subtitles,int key){
+void find_sub(sub_data* subd,int key){
+    subtitle *subs;
     int i,j;
     
-    if ( !subtitles ) return;
+    if ( !subd || subd->sub_num == 0) return;
+    subs = subd->subtitles;
     
     if(vo_sub){
       if(key>=vo_sub->start && key<=vo_sub->end) return; // OK!
@@ -71,28 +74,29 @@
 //    printf("\r---- sub changed ----\n");
     
     // check next sub.
-    if(current_sub>=0 && current_sub+1<sub_num){
-      if(key>subtitles[current_sub].end && key<subtitles[current_sub+1].start){
+    if(current_sub>=0 && current_sub+1 < subd->sub_num){
+      if(key>subs[current_sub].end && key<subs[current_sub+1].start){
           // no sub
-          nosub_range_start=subtitles[current_sub].end;
-          nosub_range_end=subtitles[current_sub+1].start;
+          nosub_range_start=subs[current_sub].end;
+          nosub_range_end=subs[current_sub+1].start;
           vo_sub=NULL;
           return;
       }
       // next sub?
       ++current_sub;
-      vo_sub=&subtitles[current_sub];
+      vo_sub=&subs[current_sub];
       if(key>=vo_sub->start && key<=vo_sub->end) return; // OK!
     }
 
 //    printf("\r---- sub log search... ----\n");
     
     // use logarithmic search:
-    i=0;j=sub_num-1;
-//    printf("Searching %d in %d..%d\n",key,subtitles[i].start,subtitles[j].end);
+    i=0; 
+    j = subd->sub_num - 1;
+//    printf("Searching %d in %d..%d\n",key,subs[i].start,subs[j].end);
     while(j>=i){
         current_sub=(i+j+1)/2;
-        vo_sub=&subtitles[current_sub];
+        vo_sub=&subs[current_sub];
         if(key<vo_sub->start) j=current_sub-1;
         else if(key>vo_sub->end) i=current_sub+1;
         else return; // found!
@@ -110,10 +114,10 @@
           return;
       }
       --current_sub;
-      if(key>subtitles[current_sub].end && key<subtitles[current_sub+1].start){
+      if(key>subs[current_sub].end && key<subs[current_sub+1].start){
           // no sub
-          nosub_range_start=subtitles[current_sub].end;
-          nosub_range_end=subtitles[current_sub+1].start;
+          nosub_range_start=subs[current_sub].end;
+          nosub_range_end=subs[current_sub+1].start;
 //          printf("No sub... 1 \n");
           vo_sub=NULL;
           return;
@@ -121,7 +125,7 @@
       printf("HEH????  ");
     } else {
       if(key<=vo_sub->end) printf("JAJJ!  "); else
-      if(current_sub+1>=sub_num){
+      if(current_sub+1 >= subd->sub_num){
           // at the end?
           nosub_range_start=vo_sub->end;
           nosub_range_end=0x7FFFFFFF; // MAXINT
@@ -129,10 +133,10 @@
           vo_sub=NULL;
           return;
       } else
-      if(key>subtitles[current_sub].end && key<subtitles[current_sub+1].start){
+      if(key>subs[current_sub].end && key<subs[current_sub+1].start){
           // no sub
-          nosub_range_start=subtitles[current_sub].end;
-          nosub_range_end=subtitles[current_sub+1].start;
+          nosub_range_start=subs[current_sub].end;
+          nosub_range_end=subs[current_sub+1].start;
 //          printf("No sub... 2 \n");
           vo_sub=NULL;
           return;
--- a/mencoder.c	Mon Apr 07 14:28:00 2003 +0000
+++ b/mencoder.c	Mon Apr 07 16:04:02 2003 +0000
@@ -100,7 +100,7 @@
 int dvdsub_id=-1;
 int vobsub_id=-1;
 static char* audio_lang=NULL;
-static char* dvdsub_lang=NULL;
+char* dvdsub_lang=NULL;
 static char* spudec_ifo=NULL;
 
 static char** audio_codec_list=NULL;  // override audio codec
@@ -163,7 +163,7 @@
 // sub:
 char *font_name=NULL;
 float font_factor=0.75;
-char *sub_name=NULL;
+char **sub_name=NULL;
 float sub_delay=0;
 float sub_fps=0;
 int   sub_auto = 0;
@@ -171,7 +171,7 @@
 int   suboverlap_enabled = 1;
 
 #ifdef USE_SUB
-static subtitle* subtitles=NULL;
+static sub_data* subdata=NULL;
 float sub_last_pts = -303;
 #endif
 
@@ -588,12 +588,12 @@
 // we know fps so now we can adjust subtitles time to ~6 seconds AST
 // check .sub
 //  current_module="read_subtitles_file";
-  if(sub_name){
-    subtitles=sub_read_file(sub_name, sh_video->fps);
-    if(!subtitles) mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadSub,sub_name);
+  if(sub_name && sub_name[0]){
+    subdata=sub_read_file(sub_name[0], sh_video->fps);
+    if(!subdata) mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadSub,sub_name[0]);
   } else
   if(sub_auto) { // auto load sub file ...
-    subtitles=sub_read_file( filename ? sub_filename( get_path("sub/"), filename )
+    subdata=sub_read_file( filename ? sub_filenames( get_path("sub/"), filename )[0]
 	                              : "default.sub", sh_video->fps );
   }
 #endif	
@@ -1226,11 +1226,13 @@
 
 #ifdef USE_SUB
   // find sub
-  if(subtitles && sh_video->pts>0){
+  if(subdata && sh_video->pts>0){
       float pts=sh_video->pts;
       if(sub_fps==0) sub_fps=sh_video->fps;
       if (pts > sub_last_pts || pts < sub_last_pts-1.0 ) {
-         find_sub(subtitles,sub_uses_time?(100*(pts+sub_delay)):((pts+sub_delay)*sub_fps)); // FIXME! frame counter...
+         find_sub(subdata, (pts+sub_delay) * 
+				 (subdata->sub_uses_time? 100. : sub_fps)); 
+	 // FIXME! frame counter...
          sub_last_pts = pts;
       }
   }
--- a/mplayer.c	Mon Apr 07 14:28:00 2003 +0000
+++ b/mplayer.c	Mon Apr 07 16:04:02 2003 +0000
@@ -231,7 +231,7 @@
 int dvdsub_id=-1;
 int vobsub_id=-1;
 static char* audio_lang=NULL;
-static char* dvdsub_lang=NULL;
+char* dvdsub_lang=NULL;
 static char* spudec_ifo=NULL;
 char* filename=NULL; //"MI2-Trailer.avi";
 
@@ -275,7 +275,7 @@
 // sub:
 char *font_name=NULL;
 float font_factor=0.75;
-char *sub_name=NULL;
+char **sub_name=NULL;
 float sub_delay=0;
 float sub_fps=0;
 int   sub_auto = 1;
@@ -284,7 +284,9 @@
 int   subcc_enabled=0;
 int suboverlap_enabled = 1;
 #ifdef USE_SUB
-subtitle* subtitles=NULL;
+sub_data* set_of_subtitles[MAX_SUBTITLE_FILES];
+int set_of_sub_size = 0;
+int set_of_sub_pos = -1;
 float sub_last_pts = -303;
 #endif
 
@@ -637,6 +639,56 @@
 
 static int play_tree_step = 1;
 
+#ifdef USE_SUB
+
+sub_data* subdata = NULL;
+
+void add_subtitles(char *filename, float fps, int silent)
+{
+    sub_data *subd;
+
+    if (filename == NULL) {
+	subd = (sub_data*)malloc(sizeof(sub_data));
+	subd->filename = strdup("none");
+	subd->subtitles = NULL;
+	subd->sub_uses_time = 1;
+	subd->sub_num = 0;
+	subd->sub_errs = 0;
+	set_of_subtitles[set_of_sub_size] = subd;
+	++set_of_sub_size;
+	return;
+    }
+
+    subd = sub_read_file(filename, fps);
+    if(!subd && !silent) 
+        mp_msg(MSGT_CPLAYER, MSGL_ERR, MSGTR_CantLoadSub, filename);
+    if (subd == NULL || set_of_sub_size >= MAX_SUBTITLE_FILES) return;
+    set_of_subtitles[set_of_sub_size] = subd;
+    ++set_of_sub_size;
+    printf("SUB: added subtitle file (%d): %s\n", set_of_sub_size, filename);
+}
+
+void update_set_of_subtitles()
+    // subdata was changed, set_of_sub... have to be updated.
+{
+    int i;
+    if (set_of_sub_size > 0 && subdata == NULL) { // *subdata was deleted
+        for (i = set_of_sub_pos + 1; i < set_of_sub_size; ++i)
+            set_of_subtitles[i-1] = set_of_subtitles[i];
+        set_of_subtitles[set_of_sub_size-1] = NULL;
+        --set_of_sub_size;
+        if (set_of_sub_size > 0) subdata = set_of_subtitles[set_of_sub_pos=0];
+    }
+    else if (set_of_sub_size > 0 && subdata != NULL) { // *subdata was changed
+        set_of_subtitles[set_of_sub_pos] = subdata;
+    }
+    else if (set_of_sub_size <= 0 && subdata != NULL) { // *subdata was added
+        set_of_subtitles[set_of_sub_pos=set_of_sub_size] = subdata;
+        ++set_of_sub_size;
+    }
+}
+#endif
+
 /*
  * In Mac OS X the SDL-lib is built upon Cocoa. The easiest way to
  * make it all work is to use the builtin SDL-bootstrap code, which 
@@ -670,6 +722,7 @@
 int osd_show_sub_visibility = 0;
 int osd_show_sub_alignment = 0;
 int osd_show_vobsub_changed = 0;
+int osd_show_sub_changed = 0;
 int osd_show_percentage = 0;
 int osd_show_tv_channel = 25;
 
@@ -678,6 +731,7 @@
 //float a_frame=0;    // Audio
 
 int i;
+char *tmp;
 
 int gui_no_filename=0;
 
@@ -1485,19 +1539,31 @@
 // check .sub
   current_module="read_subtitles_file";
   if(sub_name){
-    subtitles=sub_read_file(sub_name, sh_video->fps);
-    if(!subtitles) mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadSub,sub_name);
-  } else
+    for (i = 0; sub_name[i] != NULL; ++i) 
+        add_subtitles (sub_name[i], sh_video->fps, 0); 
+  } 
   if(sub_auto) { // auto load sub file ...
-    subtitles=sub_read_file( filename ? sub_filename( get_path("sub/"), filename )
-                                     : "default.sub", sh_video->fps );
+    char **tmp = sub_filenames(get_path("sub/"), filename);
+    char **tmp2 = tmp;
+    while (*tmp2)
+        add_subtitles (*tmp2++, sh_video->fps, 0);
+    free(tmp);
+    if (set_of_sub_size == 0)
+        add_subtitles (get_path("default.sub"), sh_video->fps, 1);
+    if (set_of_sub_size > 0)
+        add_subtitles (NULL, sh_video->fps, 1);
   }
-  if(subtitles && stream_dump_type==3) list_sub_file(subtitles);
-  if(subtitles && stream_dump_type==4) dump_mpsub(subtitles, sh_video->fps);
-  if(subtitles && stream_dump_type==6) dump_srt(subtitles, sh_video->fps);
-  if(subtitles && stream_dump_type==7) dump_microdvd(subtitles, sh_video->fps);
-  if(subtitles && stream_dump_type==8) dump_jacosub(subtitles, sh_video->fps);
-  if(subtitles && stream_dump_type==9) dump_sami(subtitles, sh_video->fps);
+  if (set_of_sub_size > 0)  {
+      osd_show_sub_changed = sh_video->fps;
+      subdata = set_of_subtitles[set_of_sub_pos=0];
+  
+      if(stream_dump_type==3) list_sub_file(subdata);
+      if(stream_dump_type==4) dump_mpsub(subdata, sh_video->fps);
+      if(stream_dump_type==6) dump_srt(subdata, sh_video->fps);
+      if(stream_dump_type==7) dump_microdvd(subdata, sh_video->fps);
+      if(stream_dump_type==8) dump_jacosub(subdata, sh_video->fps);
+      if(stream_dump_type==9) dump_sami(subdata, sh_video->fps);
+  }
 }
 #endif
 
@@ -2415,7 +2481,7 @@
     } break;
     case MP_CMD_SUB_STEP : {
       int movement = cmd->args[0].v.i;
-      step_sub(subtitles, sh_video->pts, movement);
+      step_sub(subdata, sh_video->pts, movement);
       osd_show_sub_delay = 9; // show the subdelay in OSD
     } break;
     case MP_CMD_OSD : 
@@ -2787,8 +2853,17 @@
         if(new_id != vobsub_id)
 	    osd_show_vobsub_changed = 9;
 	vobsub_id = new_id;
-	break;
     }
+#ifdef USE_SUB  
+    else if (set_of_sub_size > 0){ //change subtitle file  
+        set_of_sub_pos = (set_of_sub_pos + 1) % set_of_sub_size;
+        subdata = set_of_subtitles[set_of_sub_pos];
+        osd_show_sub_changed = sh_video->fps;
+        vo_sub = NULL;
+        vo_osd_changed(OSDTYPE_SUBTITLE); 
+    }
+#endif
+        break;
     case MP_CMD_SCREENSHOT :
       if(vo_config_count) video_out->control(VOCTRL_SCREENSHOT, NULL);
       break;
@@ -3199,6 +3274,20 @@
 	  snprintf(osd_text_tmp, 63, "Subtitles: (%d) %s", vobsub_id, language ? language : "unknown");
 	  osd_show_vobsub_changed--;
       } else
+#ifdef USE_SUB
+      if (osd_show_sub_changed) {
+          tmp = subdata->filename;
+	  char *tmp2;
+	  if (tmp2 = strrchr(tmp, '/')) {
+	      tmp = tmp2+1;
+	  }
+	  snprintf(osd_text_tmp, 63, "Sub: (%d) %s%s", 
+                                  set_of_sub_pos + 1,
+                                  strlen(tmp) < 20 ? "" : "...",
+                                  strlen(tmp) < 20 ? tmp : tmp+strlen(tmp)-19);
+	  osd_show_sub_changed--;
+      } else
+#endif
       if (osd_show_sub_delay) {
 	  snprintf(osd_text_tmp, 63, "Sub delay: %d ms", ROUND(sub_delay*1000));
 	  osd_show_sub_delay--;
@@ -3250,12 +3339,14 @@
   
 #ifdef USE_SUB
   // find sub
-  if(subtitles && sh_video->pts>0){
+  if(subdata && sh_video->pts>0){
       float pts=sh_video->pts;
       if(sub_fps==0) sub_fps=sh_video->fps;
       current_module="find_sub";
       if (pts > sub_last_pts || pts < sub_last_pts-1.0 ) {
-         find_sub(subtitles,sub_uses_time?(100*(pts+sub_delay)):((pts+sub_delay)*sub_fps)); // FIXME! frame counter...
+         find_sub(subdata, (pts+sub_delay) * 
+				 (subdata->sub_uses_time ? 100. : sub_fps)); 
+	 // FIXME! frame counter...
          sub_last_pts = pts;
       }
       current_module=NULL;
@@ -3350,14 +3441,14 @@
 uninit_player(INITED_ALL-(INITED_GUI+INITED_INPUT+(fixed_vo?INITED_VO:0)));
 
 #ifdef USE_SUB  
-  if ( subtitles ) 
+  if ( set_of_sub_size > 0 ) 
    {
     current_module="sub_free";
-    sub_free( subtitles );
-    if ( sub_name ) free( sub_name );
-    sub_name=NULL;
+    for (i = 0; i < set_of_sub_size; ++i)
+        sub_free( set_of_subtitles[i] );
+    set_of_sub_size = 0;
     vo_sub=NULL;
-    subtitles=NULL;
+    subdata=NULL;
    }
 #endif
 
--- a/mplayer.h	Mon Apr 07 14:28:00 2003 +0000
+++ b/mplayer.h	Mon Apr 07 16:04:02 2003 +0000
@@ -27,14 +27,14 @@
 extern float movie_aspect;
 extern float force_fps;
 
-extern char * sub_name;
+//extern char **sub_name;
 extern float  sub_delay;
 extern float  sub_fps;
 extern int    sub_auto;
 extern int    sub_pos;
 extern int    sub_unicode;
 extern char * sub_cp;
-extern subtitle* subtitles;
+extern sub_data* subdata; //currently used subtitles  
 extern subtitle* vo_sub;
 extern int    suboverlap_enabled;
 
@@ -59,5 +59,6 @@
 extern int vobsub_id;
 
 extern void exit_player(char* how);
+extern void update_set_of_subtitles();
 
 #endif
--- a/subreader.c	Mon Apr 07 14:28:00 2003 +0000
+++ b/subreader.c	Mon Apr 07 16:04:02 2003 +0000
@@ -12,6 +12,9 @@
 #include <string.h>
 #include <ctype.h>
 
+#include <sys/types.h>
+#include <dirent.h>
+
 #include "config.h"
 #include "mp_msg.h"
 #include "subreader.h"
@@ -26,15 +29,14 @@
 #include <fribidi/fribidi.h>
 #endif
 
+extern char* dvdsub_lang;
+
 /* Maximal length of line of a subtitle */
 #define LINE_LEN 1000
-
 static float mpsub_position=0;
+static float mpsub_multiplier=1.;
+static int sub_slacktime = 20000; //20 sec
 
-int sub_uses_time=0;
-int sub_errs=0;
-int sub_num=0;          // number of subtitle structs
-int sub_slacktime=2000; // 20 seconds
 int sub_no_text_pp=0;   // 1 => do not apply text post-processing
                         // like {\...} elimination in SSA format.
 
@@ -87,7 +89,8 @@
 
 	case 0: /* find "START=" or "Slacktime:" */
 	    slacktime_s = strstr (s, "Slacktime:");
-	    if (slacktime_s) sub_slacktime = strtol (slacktime_s + 10, NULL, 0) / 10;
+	    if (slacktime_s) 
+                sub_slacktime = strtol (slacktime_s+10, NULL, 0) / 10;
 
 	    s = strstr (s, "Start=");
 	    if (s) {
@@ -532,9 +535,9 @@
 		if (!fgets(line, LINE_LEN, fd)) return NULL;
 	} while (sscanf (line, "%f %f", &a, &b) !=2);
 
-	mpsub_position += a*(sub_uses_time ? 100.0 : 1.0);
+	mpsub_position += a*mpsub_multiplier; 
 	current->start=(int) mpsub_position;
-	mpsub_position += b*(sub_uses_time ? 100.0 : 1.0);
+	mpsub_position += b*mpsub_multiplier; 
 	current->end=(int) mpsub_position;
 
 	while (num < SUB_MAX_TEXT) {
@@ -860,7 +863,7 @@
     return current;
 }
 
-int sub_autodetect (FILE *fd) {
+int sub_autodetect (FILE *fd, int *uses_time) {
     char line[LINE_LEN+1];
     int i,j=0;
     char p;
@@ -871,44 +874,44 @@
 	    return SUB_INVALID;
 
 	if (sscanf (line, "{%d}{%d}", &i, &i)==2)
-		{sub_uses_time=0;return SUB_MICRODVD;}
+		{*uses_time=0;return SUB_MICRODVD;}
 	if (sscanf (line, "{%d}{}", &i)==1)
-		{sub_uses_time=0;return SUB_MICRODVD;}
+		{*uses_time=0;return SUB_MICRODVD;}
 	if (sscanf (line, "%d:%d:%d.%d,%d:%d:%d.%d",     &i, &i, &i, &i, &i, &i, &i, &i)==8)
-		{sub_uses_time=1;return SUB_SUBRIP;}
+		{*uses_time=1;return SUB_SUBRIP;}
 	if (sscanf (line, "%d:%d:%d%[,.:]%d --> %d:%d:%d%[,.:]%d", &i, &i, &i, (char *)&i, &i, &i, &i, &i, (char *)&i, &i)==10)
-		{sub_uses_time=1;return SUB_SUBVIEWER;}
+		{*uses_time=1;return SUB_SUBVIEWER;}
 	if (sscanf (line, "{T %d:%d:%d:%d",&i, &i, &i, &i))
-		{sub_uses_time=1;return SUB_SUBVIEWER2;}
+		{*uses_time=1;return SUB_SUBVIEWER2;}
 	if (strstr (line, "<SAMI>"))
-		{sub_uses_time=1; return SUB_SAMI;}
+		{*uses_time=1; return SUB_SAMI;}
 	if (sscanf(line, "%d:%d:%d.%d %d:%d:%d.%d", &i, &i, &i, &i, &i, &i, &i, &i) == 8)
-		{sub_uses_time = 1; return SUB_JACOSUB;}
+		{*uses_time = 1; return SUB_JACOSUB;}
 	if (sscanf(line, "@%d @%d", &i, &i) == 2)
-		{sub_uses_time = 1; return SUB_JACOSUB;}
+		{*uses_time = 1; return SUB_JACOSUB;}
 	if (sscanf (line, "%d:%d:%d:",     &i, &i, &i )==3)
-		{sub_uses_time=1;return SUB_VPLAYER;}
+		{*uses_time=1;return SUB_VPLAYER;}
 	if (sscanf (line, "%d:%d:%d ",     &i, &i, &i )==3)
-		{sub_uses_time=1;return SUB_VPLAYER;}
+		{*uses_time=1;return SUB_VPLAYER;}
 	//TODO: just checking if first line of sub starts with "<" is WAY
 	// too weak test for RT
 	// Please someone who knows the format of RT... FIX IT!!!
 	// It may conflict with other sub formats in the future (actually it doesn't)
 	if ( *line == '<' )
-		{sub_uses_time=1;return SUB_RT;}
+		{*uses_time=1;return SUB_RT;}
 
 	if (!memcmp(line, "Dialogue: Marked", 16))
-		{sub_uses_time=1; return SUB_SSA;}
+		{*uses_time=1; return SUB_SSA;}
 	if (sscanf (line, "%d,%d,\"%c", &i, &i, (char *) &i) == 3)
-		{sub_uses_time=0;return SUB_DUNNOWHAT;}
+		{*uses_time=0;return SUB_DUNNOWHAT;}
 	if (sscanf (line, "FORMAT=%d", &i) == 1)
-		{sub_uses_time=0; return SUB_MPSUB;}
+		{*uses_time=0; return SUB_MPSUB;}
 	if (sscanf (line, "FORMAT=TIM%c", &p)==1 && p=='E')
-		{sub_uses_time=1; return SUB_MPSUB;}
+		{*uses_time=1; return SUB_MPSUB;}
 	if (strstr (line, "-->>"))
-		{sub_uses_time=0; return SUB_AQTITLE;}
+		{*uses_time=0; return SUB_AQTITLE;}
 	if (sscanf (line, "[%d:%d:%d]", &i, &i, &i)==3)
-		{sub_uses_time=1;return SUB_SUBRIP09;}
+		{*uses_time=1;return SUB_SUBRIP09;}
     }
 
     return SUB_INVALID;  // too many bad lines
@@ -1071,7 +1074,8 @@
 
 #endif
 
-static void adjust_subs_time(subtitle* sub, float subtime, float fps, int block){
+static void adjust_subs_time(subtitle* sub, float subtime, float fps, int block,
+                             int sub_num, int sub_uses_time) {
 	int n,m;
 	subtitle* nextsub;
 	int i = sub_num;
@@ -1133,10 +1137,13 @@
     const char *name;
 };
 
-subtitle* sub_read_file (char *filename, float fps) {
+sub_data* sub_read_file (char *filename, float fps) {
+        //filename is assumed to be malloc'ed,  free() is used in sub_free()
     FILE *fd;
     int n_max, n_first, i, j, sub_first, sub_orig;
-    subtitle *first, *second, *sub;
+    subtitle *first, *second, *sub, *return_sub;
+    sub_data *subt_data;
+    int uses_time = 0, sub_num = 0, sub_errs = 0;
     struct subreader sr[]=
     {
 	    { sub_read_line_microdvd, NULL, "microdvd" },
@@ -1158,7 +1165,8 @@
     if(filename==NULL) return NULL; //qnx segfault
     fd=fopen (filename, "r"); if (!fd) return NULL;
 
-    sub_format=sub_autodetect (fd);
+    sub_format=sub_autodetect (fd, &uses_time);
+    mpsub_multiplier = (uses_time ? 100.0 : 1.0);
     if (sub_format==SUB_INVALID) {mp_msg(MSGT_SUBREADER,MSGL_WARN,"SUB: Could not determine file format\n");return NULL;}
     srp=sr+sub_format;
     mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Detected subtitle file format: %s\n", srp->name);
@@ -1254,7 +1262,7 @@
     subcp_close();
 #endif
 
-//    printf ("SUB: Subtitle format %s time.\n", sub_uses_time?"uses":"doesn't use");
+//    printf ("SUB: Subtitle format %s time.\n", uses_time?"uses":"doesn't use");
     mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Read %i subtitles", sub_num);
     if (sub_errs) mp_msg(MSGT_SUBREADER,MSGL_INFO,", %i bad line(s).\n", sub_errs);
     else 	  mp_msg(MSGT_SUBREADER,MSGL_INFO,".\n");
@@ -1270,7 +1278,7 @@
     // while in others they are probably result of bad timing
 if ((suboverlap_enabled == 2) ||
     ((suboverlap_enabled) && ((sub_format == SUB_JACOSUB) || (sub_format == SUB_SSA)))) {
-    adjust_subs_time(first, 6.0, fps, 0);	/* ~6 secs AST */
+    adjust_subs_time(first, 6.0, fps, 0, sub_num, uses_time);/*~6 secs AST*/
 // here we manage overlapping subtitles
     sub_orig = sub_num;
     n_first = sub_num;
@@ -1468,12 +1476,19 @@
     }
     free(first);
 
-    return second;
+    return_sub = second;
 } else { //if(suboverlap_enabled)
-    adjust_subs_time(first, 6.0, fps, 1);	/* ~6 secs AST */
-
-    return first;
+    adjust_subs_time(first, 6.0, fps, 1, sub_num, uses_time);/*~6 secs AST*/
+    return_sub = first;
 }
+    if (return_sub == NULL) return NULL;
+    subt_data = (sub_data *)malloc(sizeof(sub_data));
+    subt_data->filename = filename;
+    subt_data->sub_uses_time = uses_time;
+    subt_data->sub_num = sub_num;
+    subt_data->sub_errs = sub_errs;
+    subt_data->subtitles = return_sub;
+    return subt_data;
 }
 
 #if 0
@@ -1489,80 +1504,243 @@
 }
 #endif
 
-char * sub_filename(char* path,  char * fname )
+
+static void strcpy_trim(char *d, char *s)
 {
- char * sub_name1;
- char * sub_name2;
- char * aviptr1, * aviptr2, * tmp;
- int    i,j;
- FILE * f;
- int pos=0;
- char * sub_exts[] = 
-  { ".utf",
-    ".UTF",
-    ".sub",
-    ".SUB",
-    ".srt",
-    ".SRT",
-    ".smi",
-    ".SMI",
-    ".rt",
-    ".RT",
-    ".txt",
-    ".TXT",
-    ".ssa",
-    ".SSA",
-    ".aqt",
-    ".AQT",
-    ".jss",
-    ".JSS" };
-
-
- if ( fname == NULL ) return NULL;
+    // skip leading whitespace
+    while (*s && !isalnum(*s)) {
+	s++;
+    }
+    for (;;) {
+	// copy word
+	while (*s && isalnum(*s)) {
+	    *d = tolower(*s);
+	    s++; d++;
+	}
+	if (*s == 0) break;
+	// trim excess whitespace
+	while (*s && !isalnum(*s)) {
+	    s++;
+	}
+	if (*s == 0) break;
+	*d++ = ' ';
+    }
+    *d = 0;
+}
  
- sub_name1=strrchr(fname,'.');
- if (!sub_name1) return NULL;
- pos=sub_name1-fname;
- 
- sub_name1=malloc(strlen(fname)+8);
- strcpy(sub_name1,fname);
-
- sub_name2=malloc (strlen(path) + strlen(fname) + 8);
- if ((tmp=strrchr(fname,'/')))
-	 sprintf (sub_name2, "%s%s", path, tmp+1);
- else
-	 sprintf (sub_name2, "%s%s", path, fname);
- 
- aviptr1=strrchr(sub_name1,'.');
- aviptr2=strrchr(sub_name2,'.');
+static void strcpy_strip_ext(char *d, char *s)
+{
+    char *tmp = strrchr(s,'.');
+    if (!tmp) {
+	strcpy(d, s);
+	return;
+    } else {
+	strncpy(d, s, tmp-s);
+	d[tmp-s] = 0;
+    }
+    while (*d) {
+	*d = tolower(*d);
+	d++;
+    }
+}
  
- for(j=0;j<=1;j++){
-  char* sub_name=j?sub_name1:sub_name2;
-#ifdef USE_ICONV
-  for ( i=(sub_cp?2:0);i<(sizeof(sub_exts)/sizeof(char*));i++ ) {
-#else
-  for ( i=0;i<(sizeof(sub_exts)/sizeof(char*));i++ ) {
-#endif	  
-   strcpy(j?aviptr1:aviptr2,sub_exts[i]);
-//   printf("trying: '%s'\n",sub_name);
-   if((f=fopen( sub_name,"rt" ))) {
-     fclose( f );
-     mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Detected sub file: %s\n",sub_name );
-     if (i<2) sub_utf8=1;
-     return sub_name;
+static void strcpy_get_ext(char *d, char *s)
+{
+    char *tmp = strrchr(s,'.');
+    if (!tmp) {
+	strcpy(d, "");
+	return;
+    } else {
+	strcpy(d, tmp+1);
    }
+}
+
+static int whiteonly(char *s)
+{
+    while (*s) {
+	if (isalnum(*s)) return 0;
+	s++;
   }
- }
- 
- free(sub_name2);
- free(sub_name1);
- return NULL;
+    return 1;
+}
+
+typedef struct _subfn 
+{
+    int priority;
+    char *fname;
+} subfn;
+
+static int compare_sub_priority(const void *a, const void *b)
+{
+    return ((subfn*)a)->priority < ((subfn*)b)->priority;
 }
 
-void list_sub_file(subtitle* subs){
+char** sub_filenames(char* path, char *fname)
+{
+    char *f_dir, *f_fname, *f_fname_noext, *f_fname_trim, *tmp, *tmp_sub_id;
+    char *tmp_fname_noext, *tmp_fname_trim, *tmp_fname_ext, *tmpresult;
+ 
+    int len, pos, found, i, j;
+    char * sub_exts[] = { "utf", "sub", "srt", "smi", "rt", "txt", "ssa", "aqt", "jss", NULL};
+    subfn *result;
+    char **result2;
+    
+    int subcnt;
+ 
+    FILE *f;
+
+    DIR *d;
+    struct dirent *de;
+
+    len = (strlen(fname) > 256 ? strlen(fname) : 256)
+	+(strlen(path) > 256 ? strlen(path) : 256)+2;
+
+    f_dir = (char*)malloc(len);
+    f_fname = (char*)malloc(len);
+    f_fname_noext = (char*)malloc(len);
+    f_fname_trim = (char*)malloc(len);
+
+    tmp_fname_noext = (char*)malloc(len);
+    tmp_fname_trim = (char*)malloc(len);
+    tmp_fname_ext = (char*)malloc(len);
+
+    tmpresult = (char*)malloc(len);
+
+    result = (subfn*)malloc(sizeof(subfn)*MAX_SUBTITLE_FILES);
+    memset(result, 0, sizeof(subfn)*MAX_SUBTITLE_FILES);
+    
+    subcnt = 0;
+    
+    tmp = strrchr(fname,'/');
+    
+    // extract filename & dirname from fname
+    if (tmp) {
+	strcpy(f_fname, tmp+1);
+	pos = tmp - fname;
+	strncpy(f_dir, fname, pos+1);
+	f_dir[pos+1] = 0;
+    } else {
+	strcpy(f_fname, fname);
+	strcpy(f_dir, "./");
+    }
+ 
+    strcpy_strip_ext(f_fname_noext, f_fname);
+    strcpy_trim(f_fname_trim, f_fname_noext);
+
+    tmp_sub_id = NULL;
+    if (dvdsub_lang && !whiteonly(dvdsub_lang)) {
+	tmp_sub_id = (char*)malloc(strlen(dvdsub_lang)+1);
+	strcpy_trim(tmp_sub_id, dvdsub_lang);
+    }
+
+    // 0 = nothing
+    // 1 = any subtitle file
+    // 2 = any sub file containing movie name
+    // 3 = sub file containing movie name and the lang extension
+    for (j = 0; j <= 1; j++) {
+	d = opendir(j == 0 ? f_dir : path);
+	if (d) {
+	    while (de = readdir(d)) {
+		// retrieve various parts of the filename
+		strcpy_strip_ext(tmp_fname_noext, de->d_name);
+		strcpy_get_ext(tmp_fname_ext, de->d_name);
+		strcpy_trim(tmp_fname_trim, tmp_fname_noext);
+
+		// does it end with a subtitle extension?
+		found = 0;
+		for (i = (sub_cp ? 1 : 0); sub_exts[i]; i++) {
+		    if (strcmp(sub_exts[i], tmp_fname_ext) == 0) {
+			found = 1;
+			break;
+		    }
+		}
+ 
+		// we have a (likely) subtitle file
+		if (found) {
+		    // does it contain the movie name?
+		    tmp = strstr(tmp_fname_trim, f_fname_trim);
+		    if (tmp) {
+			tmp += strlen(f_fname_trim);
+			if (tmp_sub_id && strstr(tmp, tmp_sub_id)) {
+			    // with sub_id specified prefer localized subtitles
+			    sprintf(tmpresult, "%s%s", f_dir, de->d_name);
+			    if ((f = fopen(tmpresult, "rt"))) {
+				fclose(f);
+				result[subcnt].priority = 3;
+				result[subcnt].fname = strdup(tmpresult);
+				subcnt++;
+			    }
+			} else if ((tmp_sub_id == NULL) && whiteonly(tmp)) {
+			    // without sub_id prefer "plain" name
+			    sprintf(tmpresult, "%s%s", f_dir, de->d_name);
+			    if ((f = fopen(tmpresult, "rt"))) {
+				fclose(f);
+				result[subcnt].priority = 3;
+				result[subcnt].fname = strdup(tmpresult);
+				subcnt++;
+			    }
+			} else {
+			    // with no localized subs found, try any else instead
+			    sprintf(tmpresult, "%s%s", f_dir, de->d_name);
+			    if ((f = fopen(tmpresult, "rt"))) {
+				fclose(f);
+				result[subcnt].priority = 2;
+				result[subcnt].fname = strdup(tmpresult);
+				subcnt++;
+			    }
+			}
+		    } else {
+			// doesn't contain the movie name
+			// don't try in the mplayer subtitle directory
+			if (j == 0) {
+			    sprintf(tmpresult, "%s%s", f_dir, de->d_name);
+			    if ((f = fopen(tmpresult, "rt"))) {
+				fclose(f);
+				result[subcnt].priority = 1;
+				result[subcnt].fname = strdup(tmpresult);
+				subcnt++;
+			    }
+			}
+		    }
+		}
+		if (subcnt >= MAX_SUBTITLE_FILES) break;
+	    }
+	    closedir(d);
+	}
+ 
+    }
+
+    if (tmp_sub_id) free(tmp_sub_id);
+    
+    free(f_dir);
+    free(f_fname);
+    free(f_fname_noext);
+    free(f_fname_trim);
+
+    free(tmp_fname_noext);
+    free(tmp_fname_trim);
+    free(tmp_fname_ext);
+
+    free(tmpresult);
+
+    qsort(result, subcnt, sizeof(subfn), compare_sub_priority);
+
+    result2 = (char**)malloc(sizeof(char*)*(subcnt+1));
+    memset(result2, 0, sizeof(char*)*(subcnt+1));
+
+    for (i = 0; i < subcnt; i++) {
+	result2[i] = result[i].fname;
+    }
+    result2[subcnt] = NULL;
+
+    return result2;
+}
+
+void list_sub_file(sub_data* subd){
     int i,j;
+    subtitle *subs = subd->subtitles;
 
-    for(j=0;j<sub_num;j++){
+    for(j=0; j < subd->sub_num; j++){
 	subtitle* egysub=&subs[j];
         printf ("%i line%c (%li-%li)\n",
 		    egysub->lines,
@@ -1575,18 +1753,20 @@
 	printf ("\n");
     }
 
-    printf ("Subtitle format %s time.\n", sub_uses_time?"uses":"doesn't use");
-    printf ("Read %i subtitles, %i errors.\n", sub_num, sub_errs);
-
+    printf ("Subtitle format %s time.\n", 
+                                  subd->sub_uses_time ? "uses":"doesn't use");
+    printf ("Read %i subtitles, %i errors.\n", subd->sub_num, subd->sub_errs);
 }
-void dump_srt(subtitle* subs, float fps){
-int i,j;
-int h,m,s,ms;
-FILE * fd;
-subtitle * onesub;
-unsigned long temp;
 
-    if (!sub_uses_time && sub_fps == 0)
+void dump_srt(sub_data* subd, float fps){
+    int i,j;
+    int h,m,s,ms;
+    FILE * fd;
+    subtitle * onesub;
+    unsigned long temp;
+    subtitle *subs = subd->subtitles;
+
+    if (!subd->sub_uses_time && sub_fps == 0)
 	sub_fps = fps;
     fd=fopen("dumpsub.srt","w");
     if(!fd)
@@ -1594,13 +1774,13 @@
 	perror("dump_srt: fopen");
 	return;
     }
-    for(i=0;i<sub_num;i++)
+    for(i=0; i < subd->sub_num; i++)
     {
         onesub=subs+i;    //=&subs[i];
 	fprintf(fd,"%d\n",i+1);//line number
 
 	temp=onesub->start;
-	if (!sub_uses_time)
+	if (!subd->sub_uses_time)
 	    temp = temp * 100 / sub_fps;
 	temp -= sub_delay * 100;
 	h=temp/360000;temp%=360000;	//h =1*100*60*60
@@ -1610,7 +1790,7 @@
 	fprintf(fd,"%02d:%02d:%02d,%03d --> ",h,m,s,ms);
 
 	temp=onesub->end;
-	if (!sub_uses_time)
+	if (!subd->sub_uses_time)
 	    temp = temp * 100 / sub_fps;
 	temp -= sub_delay * 100;
 	h=temp/360000;temp%=360000;
@@ -1628,12 +1808,13 @@
     mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Subtitles dumped in \'dumpsub.srt\'.\n");
 }
 
-void dump_mpsub(subtitle* subs, float fps){
+void dump_mpsub(sub_data* subd, float fps){
 	int i,j;
 	FILE *fd;
 	float a,b;
+        subtitle *subs = subd->subtitles;
 
-	mpsub_position=sub_uses_time?(sub_delay*100):(sub_delay*fps);
+	mpsub_position = subd->sub_uses_time? (sub_delay*100) : (sub_delay*fps);
 	if (sub_fps==0) sub_fps=fps;
 
 	fd=fopen ("dump.mpsub", "w");
@@ -1643,12 +1824,12 @@
 	}
 	
 
-	if (sub_uses_time) fprintf (fd,"FORMAT=TIME\n\n");
+	if (subd->sub_uses_time) fprintf (fd,"FORMAT=TIME\n\n");
 	else fprintf (fd, "FORMAT=%5.2f\n\n", fps);
 
-	for(j=0;j<sub_num;j++){
+	for(j=0; j < subd->sub_num; j++){
 		subtitle* egysub=&subs[j];
-		if (sub_uses_time) {
+		if (subd->sub_uses_time) {
 			a=((egysub->start-mpsub_position)/100.0);
 			b=((egysub->end-egysub->start)/100.0);
 			if ( (float)((int)a) == a)
@@ -1675,9 +1856,10 @@
 	mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Subtitles dumped in \'dump.mpsub\'.\n");
 }
 
-void dump_microdvd(subtitle* subs, float fps) {
+void dump_microdvd(sub_data* subd, float fps) {
     int i, delay;
     FILE *fd;
+    subtitle *subs = subd->subtitles;
     if (sub_fps == 0)
 	sub_fps = fps;
     fd = fopen("dumpsub.txt", "w");
@@ -1686,11 +1868,11 @@
 	return;
     }
     delay = sub_delay * sub_fps;
-    for (i = 0; i < sub_num; ++i) {
+    for (i = 0; i < subd->sub_num; ++i) {
 	int j, start, end;
 	start = subs[i].start;
 	end = subs[i].end;
-	if (sub_uses_time) {
+	if (subd->sub_uses_time) {
 	    start = start * sub_fps / 100 ;
 	    end = end * sub_fps / 100;
 	}
@@ -1709,14 +1891,15 @@
     mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Subtitles dumped in \'dumpsub.txt\'.\n");
 }
 
-void dump_jacosub(subtitle* subs, float fps) {
+void dump_jacosub(sub_data* subd, float fps) {
     int i,j;
     int h,m,s,cs;
     FILE * fd;
     subtitle * onesub;
     unsigned long temp;
+    subtitle *subs = subd->subtitles;
 
-    if (!sub_uses_time && sub_fps == 0)
+    if (!subd->sub_uses_time && sub_fps == 0)
 	sub_fps = fps;
     fd=fopen("dumpsub.jss","w");
     if(!fd)
@@ -1724,13 +1907,13 @@
 	perror("dump_jacosub: fopen");
 	return;
     }
-    fprintf(fd, "#TIMERES %d\n", (sub_uses_time) ? 100 : (int)sub_fps);    
-    for(i=0;i<sub_num;i++)
+    fprintf(fd, "#TIMERES %d\n", (subd->sub_uses_time) ? 100 : (int)sub_fps); 
+    for(i=0; i < subd->sub_num; i++)
     {
         onesub=subs+i;    //=&subs[i];
 
 	temp=onesub->start;
-	if (!sub_uses_time)
+	if (!subd->sub_uses_time)
 	    temp = temp * 100 / sub_fps;
 	temp -= sub_delay * 100;
 	h=temp/360000;temp%=360000;	//h =1*100*60*60
@@ -1740,7 +1923,7 @@
 	fprintf(fd,"%02d:%02d:%02d.%02d ",h,m,s,cs);
 
 	temp=onesub->end;
-	if (!sub_uses_time)
+	if (!subd->sub_uses_time)
 	    temp = temp * 100 / sub_fps;
 	temp -= sub_delay * 100;
 	h=temp/360000;temp%=360000;
@@ -1758,13 +1941,14 @@
     mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Subtitles dumped in \'dumpsub.js\'.\n");
 }
 
-void dump_sami(subtitle* subs, float fps) {
+void dump_sami(sub_data* subd, float fps) {
     int i,j;
     FILE * fd;
     subtitle * onesub;
     unsigned long temp;
+    subtitle *subs = subd->subtitles;
 
-    if (!sub_uses_time && sub_fps == 0)
+    if (!subd->sub_uses_time && sub_fps == 0)
 	sub_fps = fps;
     fd=fopen("dumpsub.smi","w");
     if(!fd)
@@ -1782,12 +1966,12 @@
 		"	</STYLE>\n"
 		"</HEAD>\n"
 		"<BODY>\n");
-    for(i=0;i<sub_num;i++)
+    for(i=0; i < subd->sub_num; i++)
     {
         onesub=subs+i;    //=&subs[i];
 
 	temp=onesub->start;
-	if (!sub_uses_time)
+	if (!subd->sub_uses_time)
 	    temp = temp * 100 / sub_fps;
 	temp -= sub_delay * 100;
 	fprintf(fd,"\t<SYNC Start=%lu>\n"
@@ -1799,7 +1983,7 @@
 	fprintf(fd,"\n");
 
 	temp=onesub->end;
-	if (!sub_uses_time)
+	if (!subd->sub_uses_time)
 	    temp = temp * 100 / sub_fps;
 	temp -= sub_delay * 100;
 	fprintf(fd,"\t<SYNC Start=%lu>\n"
@@ -1811,38 +1995,36 @@
     mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Subtitles dumped in \'dumpsub.smi\'.\n");
 }
 
-void sub_free( subtitle * subs )
+void sub_free( sub_data * subd )
 {
  int i;
  
- if ( !subs ) return;
+    if ( !subd ) return;
  
- sub_num=0;
- sub_errs=0;
- for ( i=0;i<subs->lines;i++ ) free( subs->text[i] );
- free( subs );
- subs=NULL;
+    if (subd->subtitles) {
+	for (i=0; i < subd->subtitles->lines; i++) free( subd->subtitles->text[i] );
+	free( subd->subtitles );
+    }
+    if (subd->filename) free( subd->filename );
+    free( subd );
 }
 
 #ifdef DUMPSUBS
 int main(int argc, char **argv) {  // for testing
-
-    int i,j;
-    subtitle *subs;
-    subtitle *egysub;
+    sub_data *subd;
     
     if(argc<2){
         printf("\nUsage: subreader filename.sub\n\n");
         exit(1);
     }
     sub_cp = argv[2]; 
-    subs=sub_read_file(argv[1]);
-    if(!subs){
+    subd = sub_read_file(argv[1]);
+    if(!subd){
         printf("Couldn't load file.\n");
         exit(1);
     }
     
-    list_sub_file(subs);
+    list_sub_file(subd);
 
     return 0;
 }
--- a/subreader.h	Mon Apr 07 14:28:00 2003 +0000
+++ b/subreader.h	Mon Apr 07 16:04:02 2003 +0000
@@ -1,9 +1,6 @@
 #ifndef __MPLAYER_SUBREADER_H
 #define __MPLAYER_SUBREADER_H
 
-extern int sub_uses_time;
-extern int sub_errs;
-extern int sub_num;         // number of subtitle structs
 extern int suboverlap_enabled;
 extern int sub_no_text_pp;  // disable text post-processing
 
@@ -26,6 +23,8 @@
 // One of the SUB_* constant above
 extern int sub_format;
 
+#define MAX_SUBTITLE_FILES 128
+
 #define SUB_MAX_TEXT 10
 
 typedef struct {
@@ -38,18 +37,26 @@
     char *text[SUB_MAX_TEXT];
 } subtitle;
 
-subtitle* sub_read_file (char *filename, float pts);
+typedef struct {
+    subtitle *subtitles;
+    char *filename;
+    int sub_uses_time; 
+    int sub_num;          // number of subtitle structs
+    int sub_errs;
+} sub_data;
+
+sub_data* sub_read_file (char *filename, float pts);
 subtitle* subcp_recode1 (subtitle *sub);
 void subcp_open (void); /* for demux_ogg.c */
 void subcp_close (void); /* for demux_ogg.c */
-char * sub_filename(char *path, char * fname);
-void list_sub_file(subtitle* subs);
-void dump_srt(subtitle* subs, float fps);
-void dump_mpsub(subtitle* subs, float fps);
-void dump_microdvd(subtitle* subs, float fps);
-void dump_jacosub(subtitle* subs, float fps);
-void dump_sami(subtitle* subs, float fps);
-void sub_free( subtitle * subs );
-void find_sub(subtitle* subtitles,int key);
-void step_sub(subtitle *subtitles, float pts, int movement);
+char ** sub_filenames(char *path, char *fname);
+void list_sub_file(sub_data* subd);
+void dump_srt(sub_data* subd, float fps);
+void dump_mpsub(sub_data* subd, float fps);
+void dump_microdvd(sub_data* subd, float fps);
+void dump_jacosub(sub_data* subd, float fps);
+void dump_sami(sub_data* subd, float fps);
+void sub_free( sub_data * subd );
+void find_sub(sub_data* subd,int key);
+void step_sub(sub_data *subd, float pts, int movement);
 #endif