changeset 21055:bc2cf8eb55b3

Move subtitle updating to a separate function, fix inverted condition which caused timing of DVD subtitles to be ignored so that they were shown as soon as they were demuxed rather than in their timed position.
author uau
date Sun, 19 Nov 2006 17:55:38 +0000
parents 7d5035aafcc6
children d2d209f455fc
files mplayer.c
diffstat 1 files changed, 73 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/mplayer.c	Sun Nov 19 17:41:31 2006 +0000
+++ b/mplayer.c	Sun Nov 19 17:55:38 2006 +0000
@@ -344,7 +344,7 @@
 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;
+double sub_last_pts = -303;
 #endif
 int global_sub_size = 0; // this encompasses all subtitle sources
 int global_sub_pos = -1; // this encompasses all subtitle sources
@@ -2867,6 +2867,73 @@
 	audio_out->get_delay();
 }
 
+static void update_subtitles(void)
+{
+#ifdef USE_SUB
+    // find sub
+    if (subdata) {
+	double 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(subdata, (pts+sub_delay) *
+		     (subdata->sub_uses_time ? 100. : sub_fps)); 
+	    if (vo_sub) vo_sub_last = vo_sub;
+	    // FIXME! frame counter...
+	    sub_last_pts = pts;
+	}
+    }
+#endif
+
+    // DVD sub:
+    if (vo_config_count && vo_spudec) {
+	unsigned char* packet=NULL;
+	int len, 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 */
+	while(1) {
+	    // Vobsub
+	    len = 0;
+	    if (vo_vobsub) {
+		if (sh_video->pts+sub_delay >= 0) {
+		    len = vobsub_get_packet(vo_vobsub, sh_video->pts+sub_delay,
+					    (void**)&packet, &timestamp);
+		    if (len > 0) {
+			timestamp -= (sh_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,sh_video->pts,sh_video->timer,timestamp / 90000.0,timestamp);
+		    }
+		}
+	    } else {
+		// DVD sub
+		len = ds_get_packet_sub(d_dvdsub, (unsigned char**)&packet);
+		if (len > 0) {
+		    // XXX This is wrong, sh_video->pts can be arbitrarily
+		    // much behind demuxing position. Unfortunately using
+		    // d_video->pts which would have been the simplest
+		    // improvement doesn't work because mpeg specific hacks
+		    // in video.c set d_video->pts to 0.
+		    float x = d_dvdsub->pts - sh_video->pts;
+		    if (x > -20 && x < 20) // prevent missing subs on pts reset
+			timestamp = 90000*(sh_video->timer + d_dvdsub->pts
+					   + sub_delay - sh_video->pts);
+		    else timestamp = 90000*(sh_video->timer + sub_delay);
+		    mp_dbg(MSGT_CPLAYER, MSGL_V, "\rDVD sub: len=%d  "
+			   "v_pts=%5.3f  s_pts=%5.3f  ts=%d \n", len,
+			   sh_video->pts, d_dvdsub->pts, timestamp);
+		}
+	    }
+	    if (len<=0 || !packet) break;
+	    if (timestamp >= 0)
+		spudec_assemble(vo_spudec, packet, len, timestamp);
+	}
+
+	if (spudec_changed(vo_spudec))
+	    vo_osd_changed(OSDTYPE_SPU);
+    }
+    current_module=NULL;
+}
 
 static int generate_video_frame(sh_video_t *sh_video, demux_stream_t *d_video)
 {
@@ -2897,7 +2964,9 @@
 	current_module = "decode video";
 	decoded_frame = decode_video(sh_video, start, in_size, 0, pts);
 	if (decoded_frame) {
+	    update_subtitles();
 	    update_osd_msg();
+	    current_module = "filter video";
 	    if (filter_video(sh_video, decoded_frame, sh_video->pts))
 		break;
 	}
@@ -4500,10 +4569,12 @@
 	    ++total_frame_cnt;
 	}
 	// decode:
-	current_module="decode_video";
 //	printf("Decode! %p  %d  \n",start,in_size);
+	update_subtitles();
 	update_osd_msg();
+	current_module = "decode_video";
 	decoded_frame = decode_video(sh_video,start,in_size,drop_frame, sh_video->pts);
+	current_module = "filter video";
 	blit_frame = (decoded_frame && filter_video(sh_video, decoded_frame,
 						    sh_video->pts));
 	break;
@@ -5553,68 +5624,6 @@
       }
 #endif /* HAVE_NEW_GUI */
 
-
-//================= Update OSD ====================
-  
-#ifdef USE_SUB
-  // find sub
-  if(subdata &&  sh_video && 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(subdata, (pts+sub_delay) * 
-				 (subdata->sub_uses_time ? 100. : sub_fps)); 
-	 if (vo_sub) vo_sub_last = vo_sub;
-	 // FIXME! frame counter...
-         sub_last_pts = pts;
-      }
-      current_module=NULL;
-  }
-#endif
-
-  // DVD sub:
-if(vo_config_count && vo_spudec) {
-  unsigned char* packet=NULL;
-  int len,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 */
-  while(1) {
-    // Vobsub
-    len = 0;
-    if(vo_vobsub) {
-      if(sh_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,sh_video->pts+sub_delay+next_frame_time,(void**)&packet,&timestamp);
-	if(len > 0) {
-	  timestamp -= (sh_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,sh_video->pts,sh_video->timer,timestamp / 90000.0,timestamp);
-	}
-      }
-    } else {
-      // DVD sub
-      len = ds_get_packet_sub(d_dvdsub,(unsigned char**)&packet);
-      if(len > 0) {
-	float x = d_dvdsub->pts - sh_video->pts;
-	if (x < -10 || x > 10) // prevent missing subs on pts reset
-	  timestamp = 90000*(sh_video->timer + d_dvdsub->pts + sub_delay - sh_video->pts);
-	else timestamp = 90000*(sh_video->timer + sub_delay);
-	mp_dbg(MSGT_CPLAYER,MSGL_V,"\rDVD sub: len=%d  v_pts=%5.3f  s_pts=%5.3f  ts=%d \n",len,sh_video->pts,d_dvdsub->pts,timestamp);
-      }
-    }
-      if(len<=0 || !packet) break;
-      if(timestamp < 0) timestamp = 0;
-      else spudec_assemble(vo_spudec,packet,len,timestamp);
-  }
-  
-  /* detect wether the sub has changed or not */
-  if(spudec_changed(vo_spudec))
-    vo_osd_changed(OSDTYPE_SPU);
-  current_module=NULL;
-}
-  
 } // while(!eof)
 
 mp_msg(MSGT_GLOBAL,MSGL_V,"EOF code: %d  \n",eof);