[MPlayer-dev-eng] [RFC] subtitle cleanup

Reimar Döffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Thu Dec 21 19:19:47 CET 2006


Hello,
attached patch moves subtitle stuff (only mov for now) to mplayer.c.
Biggest problem right now is that it breaks vobsubs embedded in mp4
(http://samples.mplayerhq.hu/sub/NeroMP4/unsupported-embedded-subs-2.mp4),
it seems that the vobsub code ignores pts values or something like
this...

Greetings,
Reimar Döffinger
-------------- next part --------------
Index: mplayer.c
===================================================================
--- mplayer.c	(revision 21713)
+++ mplayer.c	(working copy)
@@ -2892,6 +2894,9 @@
 
 static void update_subtitles(void)
 {
+    unsigned char *packet=NULL;
+    int len;
+    char type = d_dvdsub->sh ? ((sh_sub_t *)d_dvdsub->sh)->type : 'v';
     // find sub
     if (subdata) {
 	double pts = sh_video->pts;
@@ -2907,9 +2912,8 @@
     }
 
     // DVD sub:
-    if (vo_config_count && vo_spudec) {
-	unsigned char* packet=NULL;
-	int len, timestamp;
+    if (vo_config_count && vo_spudec && 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
@@ -2952,6 +2956,39 @@
 
 	if (spudec_changed(vo_spudec))
 	    vo_osd_changed(OSDTYPE_SPU);
+    } else if (dvdsub_id >= 0 && type == 't') {
+      double pts = MP_NOPTS_VALUE;
+      while (1) {
+        double nextpts = ds_get_next_pts(d_dvdsub);
+        if (nextpts == MP_NOPTS_VALUE || nextpts - sub_delay > sh_video->pts)
+          break;
+        len = ds_get_packet_sub(d_dvdsub, &packet);
+        pts = nextpts;
+      }
+#define MAX_SUBLEN 1024
+      if (pts != MP_NOPTS_VALUE) {
+        static subtitle subs;
+        static char subtext[MAX_SUBLEN + 1];
+        int i, pos = 0;
+        len = FFMIN(FFMAX(len, 0), MAX_SUBLEN);
+        subs.text[0] = subtext;
+        subs.lines = 0;
+        for (i = 0; i < len; i++) {
+          char c = packet[i];
+          if (c == '\n' && subs.lines < SUB_MAX_TEXT - 1) {
+            subtext[pos++] = 0;
+            subs.lines++;
+            subs.text[subs.lines] = &subtext[pos];
+          } else
+            subtext[pos++] = c;
+        }
+        subtext[pos] = 0;
+        if (subs.lines < SUB_MAX_TEXT &&
+          strlen(subs.text[subs.lines]))
+        subs.lines++;
+        vo_sub = &subs;
+        vo_osd_changed(OSDTYPE_SUBTITLE);
+      }
     }
     current_module=NULL;
 }
Index: libmpdemux/demux_mov.c
===================================================================
--- libmpdemux/demux_mov.c	(revision 21713)
+++ libmpdemux/demux_mov.c	(working copy)
@@ -2138,6 +2147,11 @@
     x=trak->samples[frame].size;
     pos=trak->samples[frame].pos;
 }
+if (ds == demuxer->sub && ((sh_sub_t *)ds->sh)->type == 't') {
+  stream_skip(demuxer->stream, 2); // size
+  x -= 2;
+  if (x < 0) x = 0;
+}
 if(trak->pos==0 && trak->stream_header_len>0){
     // we have to append the stream header...
     demux_packet_t* dp=new_demux_packet(x+trak->stream_header_len);
@@ -2155,48 +2169,6 @@
     
     ++trak->pos;
 
-    if (demuxer->sub->id >= 0) {
-      int samplenr = 0;
-      trak = priv->tracks[demuxer->sub->id];
-      while (samplenr < trak->samples_size) {
-        double subpts = (double)trak->samples[samplenr].pts / (double)trak->timescale;
-        if (subpts >= pts) break;
-        samplenr++;
-      }
-      samplenr--;
-      if (samplenr < 0)
-        vo_sub = NULL;
-      else if (samplenr != priv->current_sub) {
-        sh_sub_t *sh = demuxer->sub->sh;
-        off_t pos = trak->samples[samplenr].pos;
-        int len = trak->samples[samplenr].size;
-        double subpts = (double)trak->samples[samplenr].pts / (double)trak->timescale;
-        stream_seek(demuxer->stream, pos);
-        if (sh->type == 'v')
-          ds_read_packet(demuxer->sub, demuxer->stream, len, subpts, pos, 0);
-        else {
-          int i;
-          char *line = priv->subtext;
-          stream_skip(demuxer->stream, 2); // size
-          len -= 2;
-          if (len < 0) len = 0;
-          if (len > MOV_MAX_SUBLEN) len = MOV_MAX_SUBLEN;
-          stream_read(demuxer->stream, priv->subtext, len);
-          priv->subtext[len] = 0;
-          priv->subs.lines = 1;
-          priv->subs.text[0] = &priv->subtext;
-          while ((line = strchr(line, '\n'))) {
-            *line++ = 0;
-            priv->subs.text[priv->subs.lines] = line;
-            priv->subs.lines++;
-          }
-          vo_sub = &priv->subs;
-        }
-        priv->current_sub = samplenr;
-      }
-      vo_osd_changed (OSDTYPE_SUBTITLE);
-    }
-
     return 1;
     
 }


More information about the MPlayer-dev-eng mailing list