[MPlayer-dev-eng] [RFC] moving more subtitle code

Reimar Döffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Sun Jan 7 17:32:54 CET 2007


Hello,
attached patch moves most non-ass subtitle rendering and enables -ass
with mov demuxer.
I'd expect it to have some problems e.g. with seeking and might also
need a bit more cleanup, still, any comments?
Also I wonder if there is any way to create ass events that do not have
a duration but instead will be cleared when the next event becomes
active?

Greetings,
Reimar Döffinger
-------------- next part --------------
Index: mplayer.c
===================================================================
--- mplayer.c	(revision 21852)
+++ mplayer.c	(working copy)
@@ -2896,6 +2897,11 @@
     unsigned char *packet=NULL;
     int len;
     char type = d_dvdsub->sh ? ((sh_sub_t *)d_dvdsub->sh)->type : 'v';
+    if (type == 'a')
+#ifdef USE_ASS
+      if (!ass_enabled)
+#endif
+      type = 't';
     // find sub
     if (subdata) {
 	double pts = sh_video->pts;
@@ -2956,21 +2962,43 @@
 	if (spudec_changed(vo_spudec))
 	    vo_osd_changed(OSDTYPE_SPU);
     } else if (dvdsub_id >= 0 && type == 't') {
+      static subtitle subs;
+      double curpts = sh_video->pts + sub_delay;
       double pts = MP_NOPTS_VALUE;
+      double endpts;
+      vo_sub = &subs;
       while (d_dvdsub->first) {
         double nextpts = ds_get_next_pts(d_dvdsub);
-        if (nextpts == MP_NOPTS_VALUE || nextpts - sub_delay > sh_video->pts)
+        if (nextpts == MP_NOPTS_VALUE || nextpts > curpts)
           break;
+        endpts = d_dvdsub->first->endpts;
         len = ds_get_packet_sub(d_dvdsub, &packet);
-        pts = nextpts - sub_delay;
+        pts = nextpts;
       }
+#ifdef USE_ASS
+      if (ass_enabled) {
+        static global_ass_track = NULL;
+        sh_sub_t *sh = (sh_sub_t *)d_dvdsub->sh;
+        if (!global_ass_track) global_ass_track = ass_default_track(ass_library);
+        ass_track = global_ass_track;
+        vo_sub = NULL;
+        if (pts != MP_NOPTS_VALUE) {
+          if (endpts == MP_NOPTS_VALUE) endpts = pts + 3;
+          sub_clear_text(&subs, MP_NOPTS_VALUE);
+          sub_add_text(&subs, packet, len, endpts);
+          subs.start = pts * 100;
+          subs.end = endpts * 100;
+          ass_process_subtitle(ass_track, &subs);
+        }
+      } else
+#endif
       if (pts != MP_NOPTS_VALUE) {
-        static subtitle subs;
+        if (endpts == MP_NOPTS_VALUE)
         sub_clear_text(&subs, MP_NOPTS_VALUE);
-        sub_add_text(&subs, packet, len, MP_NOPTS_VALUE);
-        vo_sub = &subs;
+        sub_add_text(&subs, packet, len, endpts);
         vo_osd_changed(OSDTYPE_SUBTITLE);
-      }
+      } else if (sub_clear_text(&subs, curpts))
+        vo_osd_changed(OSDTYPE_SUBTITLE);
     }
     current_module=NULL;
 }
Index: libmpdemux/demuxer.h
===================================================================
--- libmpdemux/demuxer.h	(revision 21852)
+++ libmpdemux/demuxer.h	(working copy)
@@ -85,6 +85,7 @@
 typedef struct demux_packet_st {
   int len;
   double pts;
+  double endpts;
   double stream_pts;
   off_t pos;  // position in index (AVI) or file (MPG)
   unsigned char* buffer;
@@ -212,6 +213,7 @@
   // still using 0 by default in case there is some code that uses 0 for both
   // unknown and a valid pts value
   dp->pts=correct_pts ? MP_NOPTS_VALUE : 0;
+  dp->endpts=MP_NOPTS_VALUE;
   dp->stream_pts = MP_NOPTS_VALUE;
   dp->pos=0;
   dp->flags=0;
Index: libmpdemux/demux_mkv.c
===================================================================
--- libmpdemux/demux_mkv.c	(revision 21852)
+++ libmpdemux/demux_mkv.c	(working copy)
@@ -166,8 +166,6 @@
   uint64_t tc_scale, cluster_tc, first_tc;
   int has_first_tc;
 
-  subtitle subs;
-
   uint64_t cluster_size;
   uint64_t blockgroup_size;
 
@@ -523,7 +521,6 @@
     return 0;
   memcpy(buf, t->private_data, t->private_size);
   buf[t->private_size] = 0;
-  t->sh_sub.type = 'v';
   t->sh_sub.has_palette = 0;
 
   pos = buf;
@@ -2379,8 +2376,6 @@
           track->subtitle_type == MATROSKA_SUBTYPE_VOBSUB)
         continue;
 
-      track->sh_sub.type = 'a';
-
       if (track->subtitle_type == MATROSKA_SUBTYPE_SSA)
         {
           track->sh_sub.ass_track = ass_new_track(ass_library);
@@ -2394,10 +2389,6 @@
             }
           ass_process_codec_private(track->sh_sub.ass_track, track->private_data, track->private_size);
         }
-      else
-        {
-          track->sh_sub.ass_track = ass_default_track(ass_library);
-        }
     }
 }
 #endif
@@ -2408,15 +2399,13 @@
   if (track->subtitle_type != MATROSKA_SUBTYPE_UNKNOWN)
     {
       sh_sub_t *sh = new_sh_sub_sid(demuxer, track->tnum, sid);
-      if ((track->subtitle_type == MATROSKA_SUBTYPE_VOBSUB) ||
-          (track->subtitle_type == MATROSKA_SUBTYPE_SSA))
-        {
-          if (track->private_data != NULL)
-            {
+      track->sh_sub.type = 't';
+      if (track->subtitle_type == MATROSKA_SUBTYPE_VOBSUB)
+        track->sh_sub.type = 'v';
+      if (track->subtitle_type == MATROSKA_SUBTYPE_SSA)
+        track->sh_sub.type = 'a';
               if (sh)
                 memcpy(sh, &track->sh_sub, sizeof(sh_sub_t));
-            }
-        }
     }
   else
     {
@@ -2721,9 +2710,6 @@
 }
 
 static void
-clear_subtitles(demuxer_t *demuxer, uint64_t timecode, int clear_all);
-
-static void
 demux_close_mkv (demuxer_t *demuxer)
 {
   mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
@@ -2734,7 +2720,6 @@
 #ifdef USE_ICONV
       subcp_close();
 #endif
-      clear_subtitles(demuxer, 0, 1);
       free_cached_dps (demuxer);
       if (mkv_d->tracks)
         {
@@ -2856,6 +2841,7 @@
                  int64_t size, uint64_t block_duration, uint64_t timecode)
 {
   mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
+  demux_packet_t *dp;
   char *ptr1;
   int i;
 
@@ -2871,9 +2857,6 @@
     ass_process_chunk(track->sh_sub.ass_track, block, size, (long long)timecode, (long long)block_duration);
     return;
   }
-  // Use code below only to parse this single sub, old subs timed in libass
-  if (ass_enabled)
-      clear_subtitles(demuxer, timecode, 1);
 #endif
 
   ptr1 = block;
@@ -2888,29 +2871,14 @@
     }
 
   sub_utf8 = 1;
-  sub_add_text(&mkv_d->subs, ptr1, size - (ptr1 - block),
-                 (timecode + block_duration) / 1000.0f);
-#ifdef USE_ASS
-  if (ass_enabled) {
-    mkv_d->subs.start = timecode / 10;
-    mkv_d->subs.end = (timecode + block_duration) / 10;
-    ass_process_subtitle(track->sh_sub.ass_track, &mkv_d->subs);
-    return;
-  }
-#endif
-  vo_sub = &mkv_d->subs;
-  vo_osd_changed (OSDTYPE_SUBTITLE);
+  size -= ptr1 - block;
+  dp = new_demux_packet(size);
+  memcpy(dp->buffer, ptr1, size);
+  dp->pts = timecode / 1000.0f;
+  dp->endpts = (timecode + block_duration) / 1000.0f;
+  ds_add_packet(demuxer->sub, dp);
 }
 
-static void
-clear_subtitles(demuxer_t *demuxer, uint64_t timecode, int clear_all)
-{
-  mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
-  double pts = clear_all ? MP_NOPTS_VALUE : (timecode / 1000.0f);
-  if (sub_clear_text(&mkv_d->subs, pts))
-    vo_osd_changed(OSDTYPE_SUBTITLE);
-}
-
 // Taken from demux_real.c. Thanks to the original developpers :)
 #define SKIP_BITS(n) buffer <<= n
 #define SHOW_BITS(n) ((buffer) >> (32 - (n)))
@@ -3244,8 +3212,6 @@
   }
   current_pts = tc / 1000.0;
 
-  clear_subtitles(demuxer, tc, 0);
-
   for (i=0; i<mkv_d->num_tracks; i++)
     if (mkv_d->tracks[i]->tnum == num) {
       track = mkv_d->tracks[i];
@@ -3630,10 +3596,6 @@
         mkv_d->skip_to_timecode = target_timecode;
       mkv_d->a_skip_to_keyframe = 1;
 
-      /* Clear subtitles. */
-      if (target_timecode <= mkv_d->last_pts * 1000)
-        clear_subtitles(demuxer, 0, 1);
-
       demux_mkv_fill_buffer(demuxer, NULL);
     }
   else if ((demuxer->movi_end <= 0) || !(flags & 1))
@@ -3672,10 +3634,6 @@
       mkv_d->skip_to_timecode = index->timecode;
       mkv_d->a_skip_to_keyframe = 1;
 
-      /* Clear subtitles. */
-      if (index->timecode <= mkv_d->last_pts * 1000)
-        clear_subtitles(demuxer, 0, 1);
-
       demux_mkv_fill_buffer(demuxer, NULL);
     }
 }


More information about the MPlayer-dev-eng mailing list