changeset 25322:078bdfd44751

Fix spudec to display current vobsub immediately after a seek.
author ulion
date Tue, 11 Dec 2007 10:12:58 +0000
parents 6b90fc097785
children 8855a2568281
files mpcommon.c spudec.c spudec.h vobsub.c
diffstat 4 files changed, 37 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/mpcommon.c	Tue Dec 11 08:17:49 2007 +0000
+++ b/mpcommon.c	Tue Dec 11 10:12:58 2007 +0000
@@ -97,7 +97,7 @@
 		}
 	    }
 	    if (len<=0 || !packet) break;
-	    if (timestamp >= 0)
+	    if (vo_vobsub || timestamp >= 0)
 		spudec_assemble(vo_spudec, packet, len, timestamp);
 	}
 
--- a/spudec.c	Tue Dec 11 08:17:49 2007 +0000
+++ b/spudec.c	Tue Dec 11 10:12:58 2007 +0000
@@ -69,7 +69,7 @@
   size_t packet_reserve;	/* size of the memory pointed to by packet */
   unsigned int packet_offset;	/* end of the currently assembled fragment */
   unsigned int packet_size;	/* size of the packet once all fragments are assembled */
-  unsigned int packet_pts;	/* PTS for this packet */
+  int packet_pts;		/* PTS for this packet */
   unsigned int palette[4];
   unsigned int alpha[4];
   unsigned int cuspal[4];
@@ -341,7 +341,7 @@
   }
 }
 
-static void spudec_process_control(spudec_handle_t *this, unsigned int pts100)
+static void spudec_process_control(spudec_handle_t *this, int pts100)
 {
   int a,b; /* Temporary vars */
   unsigned int date, type;
@@ -376,7 +376,7 @@
 	/* Menu ID, 1 byte */
 	mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Menu ID\n");
         /* shouldn't a Menu ID type force display start? */
-	start_pts = pts100 + date;
+	start_pts = pts100 < 0 && -pts100 >= date ? 0 : pts100 + date;
 	end_pts = UINT_MAX;
 	display = 1;
 	this->is_forced_sub=~0; // current subtitle is forced
@@ -384,7 +384,7 @@
       case 0x01:
 	/* Start display */
 	mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Start display!\n");
-	start_pts = pts100 + date;
+	start_pts = pts100 < 0 && -pts100 >= date ? 0 : pts100 + date;
 	end_pts = UINT_MAX;
 	display = 1;
 	this->is_forced_sub=0;
@@ -392,7 +392,7 @@
       case 0x02:
 	/* Stop display */
 	mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Stop display!\n");
-	end_pts = pts100 + date;
+	end_pts = pts100 < 0 && -pts100 >= date ? 0 : pts100 + date;
 	break;
       case 0x03:
 	/* Palette */
@@ -450,14 +450,17 @@
       }
     }
   next_control:
-    if (display) {
+    if (!display)
+      continue;
+    if (end_pts == UINT_MAX && start_off != next_off) {
+      end_pts = get_be16(this->packet + next_off) * 1024;
+      end_pts = 1 - pts100 >= end_pts ? 0 : pts100 + end_pts - 1;
+    }
+    if (end_pts > 0) {
       packet_t *packet = calloc(1, sizeof(packet_t));
       int i;
       packet->start_pts = start_pts;
-      if (end_pts == UINT_MAX && start_off != next_off) {
-	start_pts = pts100 + get_be16(this->packet + next_off) * 1024;
-        packet->end_pts = start_pts - 1;
-      } else packet->end_pts = end_pts;
+      packet->end_pts = end_pts;
       packet->current_nibble[0] = current_nibble[0];
       packet->current_nibble[1] = current_nibble[1];
       packet->start_row = start_row;
@@ -479,17 +482,18 @@
   }
 }
 
-static void spudec_decode(spudec_handle_t *this, unsigned int pts100)
+static void spudec_decode(spudec_handle_t *this, int pts100)
 {
-  if(this->hw_spu) {
+  if (!this->hw_spu)
+    spudec_process_control(this, pts100);
+  else if (pts100 >= 0) {
     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);
+  }
 }
 
 int spudec_changed(void * this)
@@ -498,7 +502,7 @@
     return (spu->spu_changed || spu->now_pts > spu->end_pts);
 }
 
-void spudec_assemble(void *this, unsigned char *packet, unsigned int len, unsigned int pts100)
+void spudec_assemble(void *this, unsigned char *packet, unsigned int len, int pts100)
 {
   spudec_handle_t *spu = (spudec_handle_t*)this;
 //  spudec_heartbeat(this, pts100);
--- a/spudec.h	Tue Dec 11 08:17:49 2007 +0000
+++ b/spudec.h	Tue Dec 11 10:12:58 2007 +0000
@@ -4,7 +4,7 @@
 #include "libvo/video_out.h"
 
 void spudec_heartbeat(void *this, unsigned int pts100);
-void spudec_assemble(void *this, unsigned char *packet, unsigned int len, unsigned int pts100);
+void spudec_assemble(void *this, unsigned char *packet, unsigned int len, int pts100);
 void spudec_draw(void *this, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
 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);
--- a/vobsub.c	Tue Dec 11 08:17:49 2007 +0000
+++ b/vobsub.c	Tue Dec 11 10:12:58 2007 +0000
@@ -1297,6 +1297,22 @@
   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;
+
+    int reseek_count = 0;
+    unsigned int lastpts = 0;
+    while (queue->current_index < queue->packets_size
+            && queue->packets[queue->current_index].pts100 <= pts100) {
+      lastpts = queue->packets[queue->current_index].pts100;
+      ++queue->current_index;
+      ++reseek_count;
+    }
+    while (reseek_count--) {
+      --queue->current_index;
+      if (queue->packets[queue->current_index-1].pts100 != UINT_MAX &&
+          queue->packets[queue->current_index-1].pts100 != lastpts)
+        break;
+    }
+
     while (queue->current_index < queue->packets_size) {
       packet_t *pkt = queue->packets + queue->current_index;
       if (pkt->pts100 != UINT_MAX)