changeset 31597:1eb8dc8f96fa

Make subdelay handling work the same way for all subtitle types and also allow changing subtitle delay to work better with vobsubs. This probably breaks vobsub behaviour with timestamp wrapping though.
author reimar
date Sat, 10 Jul 2010 12:53:05 +0000
parents b4a96ea85a71
children 6c3667fb9423
files mpcommon.c spudec.c
diffstat 2 files changed, 9 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mpcommon.c	Sat Jul 10 11:40:40 2010 +0000
+++ b/mpcommon.c	Sat Jul 10 12:53:05 2010 +0000
@@ -87,6 +87,7 @@
 
 void update_subtitles(sh_video_t *sh_video, double refpts, demux_stream_t *d_dvdsub, int reset)
 {
+    double curpts = refpts - sub_delay;
     unsigned char *packet=NULL;
     int len;
     char type = d_dvdsub->sh ? ((sh_sub_t *)d_dvdsub->sh)->type : 'v';
@@ -107,7 +108,7 @@
         if (sub_fps==0) sub_fps = sh_video ? sh_video->fps : 25;
         current_module = "find_sub";
         if (refpts > sub_last_pts || refpts < sub_last_pts-1.0) {
-            find_sub(subdata, (refpts+sub_delay) *
+            find_sub(subdata, curpts *
                      (subdata->sub_uses_time ? 100. : sub_fps));
             if (vo_sub) vo_sub_last = vo_sub;
             // FIXME! frame counter...
@@ -120,18 +121,16 @@
         (vobsub_id >= 0 || (dvdsub_id >= 0 && type == 'v'))) {
         int timestamp;
         current_module = "spudec";
-        spudec_heartbeat(vo_spudec, 90000*sh_video->timer);
-        /* Get a sub packet from the DVD or a vobsub and make a timestamp
-         * relative to sh_video->timer */
+        spudec_heartbeat(vo_spudec, 90000*curpts);
+        /* Get a sub packet from the DVD or a vobsub */
         while(1) {
             // Vobsub
             len = 0;
             if (vo_vobsub) {
-                if (refpts+sub_delay >= 0) {
-                    len = vobsub_get_packet(vo_vobsub, refpts+sub_delay,
+                if (curpts >= 0) {
+                    len = vobsub_get_packet(vo_vobsub, curpts,
                                             (void**)&packet, &timestamp);
                     if (len > 0) {
-                        timestamp -= (refpts + 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,refpts,sh_video->timer,timestamp / 90000.0,timestamp);
                     }
                 }
@@ -146,9 +145,8 @@
                     // in video.c set d_video->pts to 0.
                     float x = d_dvdsub->pts - refpts;
                     if (x > -20 && x < 20) // prevent missing subs on pts reset
-                        timestamp = 90000*(sh_video->timer + d_dvdsub->pts
-                                           + sub_delay - refpts);
-                    else timestamp = 90000*(sh_video->timer + sub_delay);
+                        timestamp = 90000*d_dvdsub->pts;
+                    else timestamp = 90000*curpts;
                     mp_dbg(MSGT_CPLAYER, MSGL_V, "\rDVD sub: len=%d  "
                            "v_pts=%5.3f  s_pts=%5.3f  ts=%d \n", len,
                            refpts, d_dvdsub->pts, timestamp);
@@ -162,7 +160,6 @@
         if (spudec_changed(vo_spudec))
             vo_osd_changed(OSDTYPE_SPU);
     } else if (dvdsub_id >= 0 && text_sub) {
-        double curpts = refpts + sub_delay;
         double endpts;
         if (type == 'd' && !d_dvdsub->demuxer->teletext) {
             tt_stream_props tsp = {0};
--- a/spudec.c	Sat Jul 10 11:40:40 2010 +0000
+++ b/spudec.c	Sat Jul 10 12:53:05 2010 +0000
@@ -624,6 +624,7 @@
   spudec_handle_t *spu = (spudec_handle_t*) this;
   spu->now_pts = pts100;
 
+  // TODO: detect and handle broken timestamps (e.g. due to wrapping)
   while (spu->queue_head != NULL && pts100 >= spu->queue_head->start_pts) {
     packet_t *packet = spudec_dequeue_packet(spu);
     spu->start_pts = packet->start_pts;