changeset 6110:7bea806b9c5f

Improvment for spu subtitles. Removed the integreted spudec in vobsub. Various cleanup/bugfix in vobsub (no more auto palette when a true one is here) HW spu rendering moved in spudec because we first need to reassable the packet before sending them to the hw. Spudec is now created only if nedded.
author albeu
date Fri, 17 May 2002 23:47:27 +0000
parents d43d06d9d658
children 582960ab7cc7
files libvo/sub.c libvo/sub.h libvo/video_out.h mencoder.c mp_msg.h mplayer.c spudec.c spudec.h vobsub.c vobsub.h
diffstat 10 files changed, 192 insertions(+), 159 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/sub.c	Fri May 17 20:55:16 2002 +0000
+++ b/libvo/sub.c	Fri May 17 23:47:27 2002 +0000
@@ -390,12 +390,6 @@
 	    else
 		obj->flags&=~OSDFLAG_VISIBLE;
 	    break;
-	case OSDTYPE_VOBSUB:
-	    if(vo_vobsub)
-		obj->flags|=OSDFLAG_VISIBLE|OSDFLAG_CHANGED;
-	    else
-		obj->flags&=~OSDFLAG_VISIBLE;
-	    break;
 	case OSDTYPE_OSD:
 	    if(vo_font && vo_osd_text && vo_osd_text[0]){
 		vo_update_text_osd(obj,dxs,dys); // update bbox
@@ -443,13 +437,12 @@
 	draw_alpha_init_flag=1;
 	vo_draw_alpha_init();
     }
-    if(vo_osd_list) free_osd_list;
+    if(vo_osd_list) free_osd_list();
     // temp hack, should be moved to mplayer/mencoder later
     new_osd_obj(OSDTYPE_OSD);
     new_osd_obj(OSDTYPE_SUBTITLE);
     new_osd_obj(OSDTYPE_PROGBAR);
     new_osd_obj(OSDTYPE_SPU);
-    new_osd_obj(OSDTYPE_VOBSUB);
 }
 
 int vo_osd_changed_flag=0;
@@ -482,9 +475,6 @@
 	case OSDTYPE_SPU:
 	    spudec_draw_scaled(vo_spudec, dxs, dys, draw_alpha); // FIXME
 	    break;
-	case OSDTYPE_VOBSUB:
-	    vobsub_draw(vo_vobsub, dxs, dys, draw_alpha);  // FIXME
-	    break;
 	case OSDTYPE_OSD:
 	    vo_draw_text_osd(obj,draw_alpha);
 	    break;
--- a/libvo/sub.h	Fri May 17 20:55:16 2002 +0000
+++ b/libvo/sub.h	Fri May 17 23:47:27 2002 +0000
@@ -10,7 +10,6 @@
 #define OSDTYPE_SUBTITLE 2
 #define OSDTYPE_PROGBAR 3
 #define OSDTYPE_SPU 4
-#define OSDTYPE_VOBSUB 5
 
 #define OSDFLAG_VISIBLE 1
 #define OSDFLAG_CHANGED 2
--- a/libvo/video_out.h	Fri May 17 20:55:16 2002 +0000
+++ b/libvo/video_out.h	Fri May 17 23:47:27 2002 +0000
@@ -39,6 +39,7 @@
 /* libmpcodecs direct rendering: */
 #define VOCTRL_GET_IMAGE 9
 #define VOCTRL_DRAW_IMAGE 13
+#define VOCTRL_SET_SPU_PALETTE 14
 /* decoding ahead: */
 #define VOCTRL_GET_NUM_FRAMES 10
 #define VOCTRL_GET_FRAME_NUM  11
--- a/mencoder.c	Fri May 17 20:55:16 2002 +0000
+++ b/mencoder.c	Fri May 17 23:47:27 2002 +0000
@@ -508,7 +508,7 @@
 
 if (spudec_ifo) {
   unsigned int palette[16], width, height;
-  if (vobsub_parse_ifo(spudec_ifo, palette, &width, &height, 1) >= 0)
+  if (vobsub_parse_ifo(NULL,spudec_ifo, palette, &width, &height, 1) >= 0)
     vo_spudec=spudec_new_scaled(palette, sh_video->disp_w, sh_video->disp_h);
 }
 #ifdef USE_DVDREAD
--- a/mp_msg.h	Fri May 17 20:55:16 2002 +0000
+++ b/mp_msg.h	Fri May 17 23:47:27 2002 +0000
@@ -78,6 +78,8 @@
 
 #define MSGT_SWS 34
 
+#define MSGT_VOBSUB 35
+
 #define MSGT_MAX 64
 
 void mp_msg_init();
--- a/mplayer.c	Fri May 17 20:55:16 2002 +0000
+++ b/mplayer.c	Fri May 17 23:47:27 2002 +0000
@@ -279,6 +279,7 @@
 #define INITED_SPUDEC 32
 #define INITED_STREAM 64
 #define INITED_INPUT    128
+#define INITED_VOBSUB  256
 #define INITED_ALL 0xFFFF
 
 void uninit_player(unsigned int mask){
@@ -310,6 +311,13 @@
     getch2_disable();
   }
 
+  if(mask&INITED_VOBSUB){
+    inited_flags&=~INITED_VOBSUB;
+    current_module="uninit_vobsub";
+    vobsub_close(vo_vobsub);
+    vo_vobsub=NULL;
+  }
+
   if (mask&INITED_SPUDEC){
     inited_flags&=~INITED_SPUDEC;
     current_module="uninit_spudec";
@@ -854,7 +862,7 @@
 
     current_module="vobsub";
     if (vobsub_name){
-      vo_vobsub=vobsub_open(vobsub_name,1);
+      vo_vobsub=vobsub_open(vobsub_name,spudec_ifo,1,&vo_spudec);
       if(vo_vobsub==NULL)
         mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadSub,vobsub_name);
     }else if(sub_auto && filename && (strlen(filename)>=5)){
@@ -862,7 +870,7 @@
       char *buf = malloc((strlen(filename)-3) * sizeof(char));
       memset(buf,0,strlen(filename)-3); // make sure string is terminated
       strncpy(buf, filename, strlen(filename)-4); 
-      vo_vobsub=vobsub_open(buf,0);
+      vo_vobsub=vobsub_open(buf,spudec_ifo,0,&vo_spudec);
       free(buf);
     }
     if(vo_vobsub)
@@ -1149,12 +1157,12 @@
 demux_info_print(demuxer);
 
 //================== Read SUBTITLES (DVD & TEXT) ==========================
-if(sh_video){
+if(d_dvdsub->id >= 0 && vo_spudec==NULL && sh_video){
 
 if (spudec_ifo) {
   unsigned int palette[16], width, height;
   current_module="spudec_init_vobsub";
-  if (vobsub_parse_ifo(spudec_ifo, palette, &width, &height, 1) >= 0)
+  if (vobsub_parse_ifo(NULL,spudec_ifo, palette, &width, &height, 1) >= 0)
     vo_spudec=spudec_new_scaled(palette, sh_video->disp_w, sh_video->disp_h);
 }
 
@@ -1177,13 +1185,16 @@
 if (vo_spudec==NULL) {
   current_module="spudec_init_normal";
   vo_spudec=spudec_new_scaled(NULL, sh_video->disp_w, sh_video->disp_h);
-  spudec_set_font_factor(font_factor);
+  spudec_set_font_factor(vo_spudec,font_factor);
 }
 
 if (vo_spudec!=NULL)
   inited_flags|=INITED_SPUDEC;
 
+}
+
 #ifdef USE_SUB
+if(sh_video) {
 // after reading video params we should load subtitles because
 // we know fps so now we can adjust subtitles time to ~6 seconds AST
 // check .sub
@@ -1198,9 +1209,9 @@
   }
   if(subtitles && stream_dump_type==3) list_sub_file(subtitles);
   if(subtitles && stream_dump_type==4) dump_mpsub(subtitles, sh_video->fps);
-#endif	
-
 }
+#endif
+
 //================== Init AUDIO (codec) ==========================
 current_module="find_audio_codec";
 
@@ -1335,6 +1346,9 @@
 	}
    }
 
+   if(vo_flags & 0x08 && vo_spudec)
+      spudec_set_hw_spu(vo_spudec,video_out);
+
 //================== MAIN: ==========================
    main:
 if(!sh_video) osd_level = 0;
@@ -2896,43 +2910,44 @@
   }
 #endif
   
-
-  // VobSub subtitles
-  if(vo_vobsub){
-    current_module="vobsub";
-    if(d_video->pts+sub_delay>=0)
-      vobsub_process(vo_vobsub,d_video->pts+sub_delay);
-    
-    /* Don't know how to detect wether the sub has changed or not */
-    vo_osd_changed(OSDTYPE_VOBSUB);
-    current_module=NULL;
+  // DVD sub:
+if(vo_config_count && vo_spudec) {
+  unsigned char* packet=NULL;
+  int len,timestamp;
+    // Get a sub packet from the dvd or a vobsub and make a timestamp relative to sh_video->timer
+  int get_sub_packet(void) {
+    // Vobsub
+    len = 0;
+    if(vo_vobsub) {
+      if(d_video->pts+sub_delay>=0) {
+	// The + next_frame_time is there because we'll display the sub at the next frame
+	len = vobsub_get_packet(vo_vobsub,d_video->pts+sub_delay+next_frame_time,(void**)&packet,&timestamp);
+	if(len > 0) {
+	  timestamp -= (d_video->pts + sub_delay - sh_video->timer)*90000;
+	  mp_dbg(MSGT_CPLAYER,MSGL_V,"\rVOB sub: len=%d v_pts=%5.3f v_timer=%5.3f sub=%5.3f ts=%d \n",len,d_video->pts,sh_video->timer,timestamp / 90000.0);
+	}
+      }
+    } else {
+      // DVD sub
+      len = ds_get_packet_sub(d_dvdsub,(unsigned char**)&packet);
+      if(len > 0) {
+	timestamp = 90000*(sh_video->timer + d_dvdsub->pts + sub_delay - d_video->pts);
+	mp_dbg(MSGT_CPLAYER,MSGL_V,"\rDVD sub: len=%d  v_pts=%5.3f  s_pts=%5.3f  ts=%d \n",len,d_video->pts,d_dvdsub->pts,timestamp);
+      }
+    }
+    return len;
   }
-
-  // DVD sub:
-  if(vo_flags & 0x08){
-    static vo_mpegpes_t packet;
-    static vo_mpegpes_t *pkg=&packet;
-    packet.timestamp=sh_video->timer*90000.0;
-    packet.id=0x20; /* Subpic */
-    while((packet.size=ds_get_packet_sub(d_dvdsub,&packet.data))>0){
-      mp_msg(MSGT_CPLAYER,MSGL_V,"\rDVD sub: len=%d  v_pts=%5.3f  s_pts=%5.3f  \n",packet.size,d_video->pts,d_dvdsub->pts);
-      if(vo_config_count) video_out->draw_frame(&pkg);
-    }
-  }else if(vo_spudec){
-    unsigned char* packet=NULL;
-    int len;
-    current_module="spudec";
-    while((len=ds_get_packet_sub(d_dvdsub,&packet))>0){
-      mp_msg(MSGT_CPLAYER,MSGL_V,"\rDVD sub: len=%d  v_pts=%5.3f  s_pts=%5.3f  \n",len,d_video->pts,d_dvdsub->pts);
-      spudec_assemble(vo_spudec,packet,len,90000*d_dvdsub->pts);
-    }
-    spudec_heartbeat(vo_spudec,90000*d_video->pts);
-
-    /* Don't know how to detect wether the sub has changed or not */
-    vo_osd_changed(OSDTYPE_SPU);
-    current_module=NULL;
+  current_module="spudec";
+  spudec_heartbeat(vo_spudec,90000*sh_video->timer);
+  while(get_sub_packet()>0 && packet){
+      spudec_assemble(vo_spudec,packet,len,timestamp);
   }
   
+  /* Don't know how to detect wether the sub has changed or not */
+  vo_osd_changed(OSDTYPE_SPU);
+  current_module=NULL;
+}
+  
 } // while(!eof)
 
 mp_msg(MSGT_GLOBAL,MSGL_V,"EOF code: %d  \n",eof);
--- a/spudec.c	Fri May 17 20:55:16 2002 +0000
+++ b/spudec.c	Fri May 17 23:47:27 2002 +0000
@@ -29,6 +29,7 @@
 #if ANTIALIASING_ALGORITHM == 2
 #include <math.h>
 #endif
+#include "libvo/video_out.h"
 #include "spudec.h"
 
 #define MIN(a, b)	((a)<(b)?(a):(b))
@@ -63,12 +64,11 @@
   size_t scaled_image_size;
   unsigned char *scaled_image;
   unsigned char *scaled_aimage;
+  int auto_palette; /* 1 if we lack a palette and must use an heuristic. */
+  int font_start_level;  /* Darkest value used for the computed font */
+  vo_functions_t *hw_spu;
 } spudec_handle_t;
 
-/* 1 if we lack a palette and must use an heuristic. */
-static int auto_palette = 0;
-/* Darkest value used for the computed font */
-static int font_start_level = 0;
 
 static inline unsigned int get_be16(const unsigned char *p)
 {
@@ -219,8 +219,8 @@
     start = 0x80;
     step = 0;
   } else {
-    start = font_start_level;
-    step = (0xF0-font_start_level)/(cused-1);
+    start = this->font_start_level;
+    step = (0xF0-this->font_start_level)/(cused-1);
   }
   memset(used, 0, sizeof(used));
   for (i=0; i<4; i++) {
@@ -286,7 +286,10 @@
 	this->alpha[1] = this->packet[off] & 0xf;
 	this->alpha[2] = this->packet[off + 1] >> 4;
 	this->alpha[3] = this->packet[off + 1] & 0xf;
-	if (auto_palette) compute_palette(this);
+	if (this->auto_palette) { 
+	  compute_palette(this);
+	  this->auto_palette = 0;
+	}
 	mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Alpha %d, %d, %d, %d\n",
 	       this->alpha[0], this->alpha[1], this->alpha[2], this->alpha[3]);
 	off+=2;
@@ -333,8 +336,17 @@
 
 static void spudec_decode(spudec_handle_t *this, unsigned int pts100)
 {
-  spudec_process_control(this, pts100);
-  spudec_process_data(this);
+  if(this->hw_spu) {
+    static vo_mpegpes_t packet = { NULL, 0, 0x20, 0 };
+    static vo_mpegpes_t *pkg=&packet;
+    packet.data = this->packet;
+    packet.size = this->packet_size;
+    packet.timestamp = pts100;
+    this->hw_spu->draw_frame((uint8_t**)&pkg);
+  } else {
+    spudec_process_control(this, pts100);
+    spudec_process_data(this);
+  }
 }
 
 
@@ -721,13 +733,17 @@
 void spudec_update_palette(void * this, unsigned int *palette)
 {
   spudec_handle_t *spu = (spudec_handle_t *) this;
-  if (spu && palette)
+  if (spu && palette) {
     memcpy(spu->global_palette, palette, sizeof(spu->global_palette));
+    if(spu->hw_spu)
+      spu->hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette);
+  }
 }
 
-void spudec_set_font_factor(double factor)
+void spudec_set_font_factor(void * this, double factor)
 {
-  font_start_level = (int)(0xF0-(0xE0*factor));
+  spudec_handle_t *spu = (spudec_handle_t *) this;
+  spu->font_start_level = (int)(0xF0-(0xE0*factor));
 }
 
 void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigned int frame_height)
@@ -736,11 +752,11 @@
   if (this) {
     if (palette) {
       memcpy(this->global_palette, palette, sizeof(this->global_palette));
-      auto_palette = 0;
+      this->auto_palette = 0;
     }
     else {
       /* No palette, compute one */
-      auto_palette = 1;
+      this->auto_palette = 1;
     }
     this->packet = NULL;
     this->image = NULL;
@@ -749,7 +765,7 @@
     this->orig_frame_height = frame_height;
   }
   else
-    perror("FATAL: spudec_init: calloc");
+    mp_msg(MSGT_SPUDEC,MSGL_FATAL, "FATAL: spudec_init: calloc");
   return this;
 }
 
@@ -766,19 +782,19 @@
     this->orig_frame_height = frame_height;
     this->custom = custom;
     // set up palette:
-    auto_palette = 1;
+    this->auto_palette = 1;
     if (palette){
       memcpy(this->global_palette, palette, sizeof(this->global_palette));
-      auto_palette = 0;
+      this->auto_palette = 0;
     }
     this->custom = custom;
     if (custom && cuspal) {
       memcpy(this->cuspal, cuspal, sizeof(this->cuspal));
-      auto_palette = 0;
+      this->auto_palette = 0;
     }
   }
   else
-    perror("FATAL: spudec_init: calloc");
+    mp_msg(MSGT_SPUDEC,MSGL_FATAL, "FATAL: spudec_init: calloc");
   return this;
 }
 
@@ -800,3 +816,12 @@
     free(spu);
   }
 }
+
+void spudec_set_hw_spu(void *this, vo_functions_t *hw_spu)
+{
+  spudec_handle_t *spu = (spudec_handle_t*)this;
+  if (!spu)
+    return;
+  spu->hw_spu = hw_spu;
+  hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette);
+}
--- a/spudec.h	Fri May 17 20:55:16 2002 +0000
+++ b/spudec.h	Fri May 17 23:47:27 2002 +0000
@@ -7,11 +7,12 @@
 void spudec_draw_scaled(void *this, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
 void spudec_update_palette(void *this, unsigned int *palette);
 void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigned int frame_height);
+void *spudec_new_scaled_vobsub(unsigned int *palette, unsigned int *cuspal, unsigned int custom, unsigned int frame_width, unsigned int frame_height);
 void *spudec_new(unsigned int *palette);
 void spudec_free(void *this);
 void spudec_reset(void *this);	// called after seek
 int spudec_visible(void *this); // check if spu is visible
-void spudec_set_font_factor(double factor); // sets the equivalent to ffactor
-
+void spudec_set_font_factor(void * this, double factor); // sets the equivalent to ffactor
+void spudec_set_hw_spu(void *this, vo_functions_t *hw_spu);
 #endif
 
--- a/vobsub.c	Fri May 17 20:55:16 2002 +0000
+++ b/vobsub.c	Fri May 17 23:47:27 2002 +0000
@@ -17,6 +17,7 @@
 
 #include "stream.h"
 #include "vobsub.h"
+#include "libvo/video_out.h"
 #include "spudec.h"
 #include "mp_msg.h"
 
@@ -165,7 +166,7 @@
 	else if ((c & 0xf0) == 0x20)
 	    version = 2;
 	else {
-	    fprintf(stderr, "Unsupported MPEG version: 0x%02x", c);
+	    mp_msg(MSGT_VOBSUB,MSGL_ERR, "Unsupported MPEG version: 0x%02x", c);
 	    return -1;
 	}
 	if (version == 4) {
@@ -214,7 +215,7 @@
 	    hdrlen = c;
 	    dataidx = mpeg_tell(mpeg) + hdrlen;
 	    if (dataidx > idx + len) {
-		fprintf(stderr, "Invalid header length: %d (total length: %d, idx: %d, dataidx: %d)\n",
+		mp_msg(MSGT_VOBSUB,MSGL_ERR, "Invalid header length: %d (total length: %d, idx: %d, dataidx: %d)\n",
 			hdrlen, len, idx, dataidx);
 		return -1;
 	    }
@@ -222,7 +223,7 @@
 		if (stream_read(mpeg->stream, buf, 5) != 5)
 		    return -1;
 		if (!(((buf[0] & 0xf0) == 0x20) && (buf[0] & 1) && (buf[2] & 1) &&  (buf[4] & 1))) {
-		    fprintf(stderr, "vobsub PTS error: 0x%02x %02x%02x %02x%02x \n",
+		    mp_msg(MSGT_VOBSUB,MSGL_ERR, "vobsub PTS error: 0x%02x %02x%02x %02x%02x \n",
 			    buf[0], buf[1], buf[2], buf[3], buf[4]);
 		    mpeg->pts = 0;
 		}
@@ -237,7 +238,7 @@
 	    stream_seek(mpeg->stream, dataidx);
 	    mpeg->aid = stream_read_char(mpeg->stream);
 	    if (mpeg->aid < 0) {
-		fprintf(stderr, "Bogus aid %d\n", mpeg->aid);
+		mp_msg(MSGT_VOBSUB,MSGL_ERR, "Bogus aid %d\n", mpeg->aid);
 		return -1;
 	    }
 	    mpeg->packet_size = len - ((unsigned int) mpeg_tell(mpeg) - idx);
@@ -249,13 +250,13 @@
 		    mpeg->packet_reserve = mpeg->packet_size;
 	    }
 	    if (mpeg->packet == NULL) {
-		perror("malloc failure");
+		mp_msg(MSGT_VOBSUB,MSGL_FATAL,"malloc failure");
 		mpeg->packet_reserve = 0;
 		mpeg->packet_size = 0;
 		return -1;
 	    }
-	    if (stream_read(mpeg->stream, mpeg->packet, mpeg->packet_size) != mpeg->packet_size) {
-		perror("stream_read failure");
+	    if ((unsigned int)stream_read(mpeg->stream, mpeg->packet, mpeg->packet_size) != mpeg->packet_size) {
+		mp_msg(MSGT_VOBSUB,MSGL_ERR,"stream_read failure");
 		mpeg->packet_size = 0;
 		return -1;
 	    }
@@ -280,7 +281,7 @@
 		
 	}
 	else {
-	    fprintf(stderr, "unknown header 0x%02X%02X%02X%02X\n",
+	    mp_msg(MSGT_VOBSUB,MSGL_ERR,"unknown header 0x%02X%02X%02X%02X\n",
 		    buf[0], buf[1], buf[2], buf[3]);
 	    return -1;
 	}
@@ -353,7 +354,7 @@
 	if (queue->packets) {
 	    packet_t *tmp = realloc(queue->packets, 2 * queue->packets_reserve * sizeof(packet_t));
 	    if (tmp == NULL) {
-		perror("realloc failure");
+		mp_msg(MSGT_VOBSUB,MSGL_FATAL,"realloc failure");
 		return -1;
 	    }
 	    queue->packets = tmp;
@@ -362,7 +363,7 @@
 	else {
 	    queue->packets = malloc(sizeof(packet_t));
 	    if (queue->packets == NULL) {
-		perror("malloc failure");
+		mp_msg(MSGT_VOBSUB,MSGL_FATAL,"malloc failure");
 		return -1;
 	    }
 	    queue->packets_reserve = 1;
@@ -407,7 +408,6 @@
  **********************************************************************/
 
 typedef struct {
-    void *spudec;
     unsigned int palette[16];
     unsigned int cuspal[4];
     int delay;
@@ -430,7 +430,7 @@
 	if (vob->spu_streams) {
 	    packet_queue_t *tmp = realloc(vob->spu_streams, (index + 1) * sizeof(packet_queue_t));
 	    if (tmp == NULL) {
-		perror("vobsub_ensure_spu_stream: realloc failure");
+		mp_msg(MSGT_VOBSUB,MSGL_ERR,"vobsub_ensure_spu_stream: realloc failure");
 		return -1;
 	    }
 	    vob->spu_streams = tmp;
@@ -438,7 +438,7 @@
 	else {
 	    vob->spu_streams = malloc((index + 1) * sizeof(packet_queue_t));
 	    if (vob->spu_streams == NULL) {
-		perror("vobsub_ensure_spu_stream: malloc failure");
+		mp_msg(MSGT_VOBSUB,MSGL_ERR,"vobsub_ensure_spu_stream: malloc failure");
 		return -1;
 	    }
 	}
@@ -460,7 +460,7 @@
 	    free(vob->spu_streams[index].id);
 	vob->spu_streams[index].id = malloc(idlen + 1);
 	if (vob->spu_streams[index].id == NULL) {
-	    perror("vobsub_add_id: malloc failure");
+	    mp_msg(MSGT_VOBSUB,MSGL_FATAL,"vobsub_add_id: malloc failure");
 	    return -1;
 	}
 	vob->spu_streams[index].id[idlen] = 0;
@@ -468,7 +468,7 @@
     }
     vob->spu_streams_current = index;
     if (verbose)
-	fprintf(stderr, "[vobsub] subtitle (vobsubid): %d language %s\n",
+	mp_msg(MSGT_VOBSUB,MSGL_V,"[vobsub] subtitle (vobsubid): %d language %s\n",
 		index, vob->spu_streams[index].id);
     return 0;
 }
@@ -479,7 +479,7 @@
     packet_queue_t *queue;
     packet_t *pkt;
     if (vob->spu_streams == 0) {
-	fprintf(stderr, "[vobsub] warning, binning some index entries.  Check your index file\n");
+	mp_msg(MSGT_VOBSUB,MSGL_WARN,"[vobsub] warning, binning some index entries.  Check your index file\n");
 	return -1;
     }
     queue = vob->spu_streams + vob->spu_streams_current;
@@ -676,13 +676,13 @@
 
 /* don't know how to use tridx */
 static int
-vobsub_parse_tridx(vobsub_t *vob, const char *line)
+vobsub_parse_tridx(const char *line)
 {
     //tridx: XXXX
-    int i;
     int tridx;
     tridx = strtoul((line + 26), NULL, 16);
     tridx = ((tridx&0x1000)>>12) | ((tridx&0x100)>>7) | ((tridx&0x10)>>2) | ((tridx&1)<<3);
+    return tridx;
 }
 
 static int
@@ -698,21 +698,21 @@
     	forward = -1;
 	line++;
     }
-    fprintf(stderr, "forward=%d", forward);
+    mp_msg(MSGT_SPUDEC,MSGL_V, "forward=%d", forward);
     h = atoi(line + 7);
-    fprintf(stderr, "h=%d," ,h);
+    mp_msg(MSGT_VOBSUB,MSGL_V, "h=%d," ,h);
     m = atoi(line + 10);
-    fprintf(stderr, "m=%d,", m);
+    mp_msg(MSGT_VOBSUB,MSGL_V, "m=%d,", m);
     s = atoi(line + 13);
-    fprintf(stderr, "s=%d,", s);
+    mp_msg(MSGT_VOBSUB,MSGL_V, "s=%d,", s);
     ms = atoi(line + 16);
-    fprintf(stderr, "ms=%d", ms);
+    mp_msg(MSGT_VOBSUB,MSGL_V, "ms=%d", ms);
     vob->delay = ms + 1000 * (s + 60 * (m + 60 * h)) * forward;
     return 0;
 }
 
 static int
-vobsub_set_lang(vobsub_t *vob, const char *line)
+vobsub_set_lang(const char *line)
 {
     if (vobsub_id == -1)
         vobsub_id = atoi(line + 8);
@@ -736,7 +736,7 @@
 	if (*line == 0 || *line == '\r' || *line == '\n' || *line == '#')
 	    continue;
 	else if (strncmp("langidx:", line, 8) == 0)
-	    res = vobsub_set_lang(vob, line);
+	    res = vobsub_set_lang(line);
 	else if (strncmp("delay:", line, 6) == 0)
 	    res = vobsub_parse_delay(vob, line);
 	else if (strncmp("id:", line, 3) == 0)
@@ -751,36 +751,37 @@
 	    res = vobsub_parse_timestamp(vob, line + 10);
 	else if (strncmp("custom colors:", line, 14) == 0)
 	    //custom colors: ON/OFF, tridx: XXXX, colors: XXXXXX, XXXXXX, XXXXXX,XXXXXX
-	    res = vobsub_parse_cuspal(vob, line) + vobsub_parse_tridx(vob, line) + vobsub_parse_custom(vob, line);
+	    res = vobsub_parse_cuspal(vob, line) + vobsub_parse_tridx(line) + vobsub_parse_custom(vob, line);
 	else {
 	    if (verbose)
-		fprintf(stderr, "vobsub: ignoring %s", line);
+		mp_msg(MSGT_VOBSUB,MSGL_V, "vobsub: ignoring %s", line);
 	    continue;
 	}
 	if (res < 0)
-	    fprintf(stderr, "ERROR in %s", line);
+	    mp_msg(MSGT_VOBSUB,MSGL_ERR,  "ERROR in %s", line);
 	break;
     } while (1);
     return res;
 }
 
 int
-vobsub_parse_ifo(const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force)
+vobsub_parse_ifo(void* this, const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force)
 {
+    vobsub_t *vob = (vobsub_t*)this;
     int res = -1;
     FILE *fd = fopen(name, "rb");
     if (fd == NULL) {
         if (force)
-	    perror("Can't open IFO file");
+	    mp_msg(MSGT_VOBSUB,MSGL_ERR, "Can't open IFO file");
     } else {
 	// parse IFO header
 	unsigned char block[0x800];
 	const char *const ifo_magic = "DVDVIDEO-VTS";
 	if (fread(block, sizeof(block), 1, fd) != 1) {
 	    if (force)
-		perror("Can't read IFO header");
+		mp_msg(MSGT_VOBSUB,MSGL_ERR, "Can't read IFO header");
 	} else if (memcmp(block, ifo_magic, strlen(ifo_magic) + 1))
-	    fprintf(stderr, "Bad magic in IFO header\n");
+	    mp_msg(MSGT_VOBSUB,MSGL_ERR, "Bad magic in IFO header\n");
 	else {
 	    unsigned long pgci_sector = block[0xcc] << 24 | block[0xcd] << 16
 		| block[0xce] << 8 | block[0xcf];
@@ -803,11 +804,11 @@
 		*height /= 2;
 		break;
 	    default:
-		fprintf(stderr, "Unknown resolution %d \n", resolution);
+		mp_msg(MSGT_VOBSUB,MSGL_WARN,"Vobsub: Unknown resolution %d \n", resolution);
 	    }
 	    if (fseek(fd, pgci_sector * sizeof(block), SEEK_SET)
 		|| fread(block, sizeof(block), 1, fd) != 1)
-		perror("Can't read IFO PGCI");
+		mp_msg(MSGT_VOBSUB,MSGL_ERR, "Can't read IFO PGCI");
 	    else {
 		unsigned long idx;
 		unsigned long pgc_offset = block[0xc] << 24 | block[0xd] << 16
@@ -816,7 +817,8 @@
 		    unsigned char *p = block + pgc_offset + 0xa4 + 4 * idx;
 		    palette[idx] = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
 		}
-		//vob->have_palette = 1;
+		if(vob)
+		  vob->have_palette = 1;
 		res = 0;
 	    }
 	}
@@ -826,12 +828,13 @@
 }
 
 void *
-vobsub_open(const char *const name, const int force)
+vobsub_open(const char *const name,const char *const ifo,const int force,void** spu)
 {
     vobsub_t *vob = malloc(sizeof(vobsub_t));
+    if(spu)
+      *spu = NULL;
     if (vob) {
 	char *buf;
-	vob->spudec = NULL;
 	vob->orig_frame_width = 0;
 	vob->orig_frame_height = 0;
 	vob->spu_streams = NULL;
@@ -843,18 +846,24 @@
 	    FILE *fd;
 	    mpeg_t *mpg;
 	    /* read in the info file */
-	    strcpy(buf, name);
-	    strcat(buf, ".ifo");
-	    vobsub_parse_ifo(buf, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force);
+	    if(!ifo) {
+	      strcpy(buf, name);
+	      strcat(buf, ".ifo");
+	      vobsub_parse_ifo(vob,buf, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force);
+	    } else
+	      vobsub_parse_ifo(vob,ifo, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force);
 	    /* read in the index */
 	    strcpy(buf, name);
 	    strcat(buf, ".idx");
 	    fd = fopen(buf, "rb");
 	    if (fd == NULL) {
 		if(force)
-                    perror("VobSub: Can't open IDX file");
-                else
-                    return NULL;
+		  mp_msg(MSGT_VOBSUB,MSGL_ERR,"VobSub: Can't open IDX file");
+		else {
+		  free(buf);
+		  free(vob);
+		  return NULL;
+		}
 	    } else {
 		while (vobsub_parse_one_line(vob, fd) >= 0)
 		    /* NOOP */ ;
@@ -863,23 +872,29 @@
 	    /* if no palette in .idx then use custom colors */
 	    if ((vob->custom == 0)&&(vob->have_palette!=1))
 		vob->custom = 1;
-	    if (vob->orig_frame_width && vob->orig_frame_height)
-		vob->spudec = spudec_new_scaled_vobsub(vob->palette, vob->cuspal, vob->custom, vob->orig_frame_width, vob->orig_frame_height);
+	    if (spu && vob->orig_frame_width && vob->orig_frame_height)
+	      *spu = spudec_new_scaled_vobsub(vob->palette, vob->cuspal, vob->custom, vob->orig_frame_width, vob->orig_frame_height);
 
 	    /* read the indexed mpeg_stream */
 	    strcpy(buf, name);
 	    strcat(buf, ".sub");
 	    mpg = mpeg_open(buf);
 	    if (mpg == NULL) {
-                if(force)
-		    perror("VobSub: Can't open SUB file");
+	      if(force)
+		mp_msg(MSGT_VOBSUB,MSGL_ERR,"VobSub: Can't open SUB file");
+	      else {
+		
+		free(buf);
+		free(vob);
+		return NULL;
+	      }
 	    } else {
 		long last_pts_diff = 0;
 		while (!mpeg_eof(mpg)) {
 		    off_t pos = mpeg_tell(mpg);
 		    if (mpeg_run(mpg) < 0) {
 			if (!mpeg_eof(mpg))
-			    perror("mpeg_run error");
+			    mp_msg(MSGT_VOBSUB,MSGL_ERR,"mpeg_run error");
 			break;
 		    }
 		    if (mpg->packet_size) {
@@ -912,7 +927,7 @@
 				}
 			    }
 			    else
-				fprintf(stderr, "don't know what to do with subtitle #%u\n", sid);
+				mp_msg(MSGT_VOBSUB,MSGL_WARN, "don't know what to do with subtitle #%u\n", sid);
 			}
 		    }
 		}
@@ -931,8 +946,6 @@
 vobsub_close(void *this)
 {
     vobsub_t *vob = (vobsub_t *)this;
-    if (vob->spudec)
-	spudec_free(vob->spudec);
     if (vob->spu_streams) {
 	while (vob->spu_streams_size--)
 	    packet_queue_destroy(vob->spu_streams + vob->spu_streams_size);
@@ -941,34 +954,23 @@
     free(vob);
 }
 
-void vobsub_draw(void *this, int dxs, int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride))
-{
-    vobsub_t *vob = (vobsub_t *)this;
-    if (vob->spudec) {
-	spudec_draw_scaled(vob->spudec, dxs, dys, draw_alpha);
-    }	
-}
-
-void
-vobsub_process(void *vobhandle, float pts)
-{
-    vobsub_t *vob = (vobsub_t *)vobhandle;
-    unsigned int pts100 = 90000 * pts;
-    if (vob->spudec) {
-	spudec_heartbeat(vob->spudec, pts100);
-	if (vob->spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < vob->spu_streams_size) {
-	    packet_queue_t *queue = vob->spu_streams + vobsub_id;
-	    while (queue->current_index < queue->packets_size) {
-		packet_t *pkt = queue->packets + queue->current_index;
-		if (pkt->pts100 <= pts100) {
-		    spudec_assemble(vob->spudec, pkt->data, pkt->size, pkt->pts100);
-		    ++queue->current_index;
-		}
-		else
-		    break;
-	    }
-	}
+int
+vobsub_get_packet(void *vobhandle, float pts,void** data, int* timestamp) {
+  vobsub_t *vob = (vobsub_t *)vobhandle;
+  unsigned int pts100 = 90000 * pts;
+  if (vob->spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < vob->spu_streams_size) {
+    packet_queue_t *queue = vob->spu_streams + vobsub_id;
+    while (queue->current_index < queue->packets_size) {
+      packet_t *pkt = queue->packets + queue->current_index;
+      if (pkt->pts100 <= pts100) {
+	++queue->current_index;
+	*data = pkt->data;
+	*timestamp = pkt->pts100;
+	return pkt->size;
+      } else break;
     }
+  }
+  return -1;
 }
 
 void
@@ -980,6 +982,4 @@
 	while (n-- > 0)
 	    vob->spu_streams[n].current_index = 0;
     }
-    if (vob->spudec)
-	spudec_reset(vob->spudec);
 }
--- a/vobsub.h	Fri May 17 20:55:16 2002 +0000
+++ b/vobsub.h	Fri May 17 23:47:27 2002 +0000
@@ -1,10 +1,10 @@
 #ifndef MPLAYER_VOBSUB_H
 #define MPLAYER_VOBSUB_H
 
-extern void *vobsub_open(const char *subname, const int force);
-extern void vobsub_process(void *vob, float pts);
+extern void *vobsub_open(const char *subname, const char *const ifo, const int force, void** spu);
 extern void vobsub_reset(void *vob);
-extern void vobsub_draw(void *vob, int dxs, int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
-extern int vobsub_parse_ifo(const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force);
+extern int vobsub_parse_ifo(void* this, const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force);
+extern int vobsub_get_packet(void *vobhandle, float pts,void** data, int* timestamp);
+extern void vobsub_close(void *this);
 
 #endif /* MPLAYER_VOBSUB_H */