changeset 31558:a3a50df246f8

Move the subtitle pts handling code to demuxer.c This also fixes endpts using first->endpts instead of current->endpts and the move should avoid missing such fixes in the future by having all related code in one place.
author reimar
date Fri, 02 Jul 2010 21:14:42 +0000
parents 84f43ca3fad1
children 631f813874f0
files libmpdemux/demuxer.c libmpdemux/demuxer.h mencoder.c mpcommon.c
diffstat 4 files changed, 36 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/demuxer.c	Fri Jul 02 19:59:02 2010 +0000
+++ b/libmpdemux/demuxer.c	Fri Jul 02 21:14:42 2010 +0000
@@ -794,16 +794,42 @@
     return len;
 }
 
-int ds_get_packet_sub(demux_stream_t *ds, unsigned char **start)
+/**
+ * Get a subtitle packet. In particular avoid reading the stream.
+ * \param pts input: maximum pts value of subtitle packet. NOPTS or NULL for any.
+ *            output: start/referece pts of subtitle
+ *            May be NULL.
+ * \param endpts output: pts for end of display time. May be NULL.
+ * \return -1 if no packet is available
+ */
+int ds_get_packet_sub(demux_stream_t *ds, unsigned char **start,
+                      double *pts, double *endpts)
 {
     int len;
+    *start = NULL;
+    // initialize pts
+    if (pts)
+        *pts    = MP_NOPTS_VALUE;
+    if (endpts)
+        *endpts = MP_NOPTS_VALUE;
     if (ds->buffer_pos >= ds->buffer_size) {
-        *start = NULL;
         if (!ds->packs)
             return -1;  // no sub
         if (!ds_fill_buffer(ds))
             return -1;  // EOF
     }
+    // only start of buffer has valid pts
+    if (ds->buffer_pos == 0) {
+        if (endpts)
+            *endpts = ds->current->endpts;
+        if (pts) {
+            *pts    = ds->current->pts;
+            // check if we are too early
+            if (*pts != MP_NOPTS_VALUE && ds->current->pts != MP_NOPTS_VALUE &&
+                ds->current->pts > *pts)
+                return -1;
+        }
+    }
     len = ds->buffer_size - ds->buffer_pos;
     *start = &ds->buffer[ds->buffer_pos];
     ds->buffer_pos += len;
--- a/libmpdemux/demuxer.h	Fri Jul 02 19:59:02 2010 +0000
+++ b/libmpdemux/demuxer.h	Fri Jul 02 21:14:42 2010 +0000
@@ -396,7 +396,8 @@
 void ds_free_packs(demux_stream_t *ds);
 int ds_get_packet(demux_stream_t *ds,unsigned char **start);
 int ds_get_packet_pts(demux_stream_t *ds, unsigned char **start, double *pts);
-int ds_get_packet_sub(demux_stream_t *ds,unsigned char **start);
+int ds_get_packet_sub(demux_stream_t *ds,unsigned char **start,
+                      double *pts, double *endpts);
 double ds_get_next_pts(demux_stream_t *ds);
 int ds_parse(demux_stream_t *sh, uint8_t **buffer, int *len, double pts, off_t pos);
 void ds_clear_parser(demux_stream_t *sh);
--- a/mencoder.c	Fri Jul 02 19:59:02 2010 +0000
+++ b/mencoder.c	Fri Jul 02 21:14:42 2010 +0000
@@ -1659,7 +1659,7 @@
  if(vobsub_writer){
      unsigned char* packet=NULL;
      int len;
-     while((len=ds_get_packet_sub(d_dvdsub,&packet))>0){
+     while((len=ds_get_packet_sub(d_dvdsub,&packet, NULL, NULL))>0){
 	 mp_msg(MSGT_MENCODER,MSGL_V,"\rDVD sub: len=%d  v_pts=%5.3f  s_pts=%5.3f  \n",len,sh_video->pts,d_dvdsub->pts);
 	     vobsub_out_output(vobsub_writer,packet,len,mux_v->timer + d_dvdsub->pts - sh_video->pts);
      }
--- a/mpcommon.c	Fri Jul 02 19:59:02 2010 +0000
+++ b/mpcommon.c	Fri Jul 02 21:14:42 2010 +0000
@@ -136,7 +136,7 @@
                 }
             } else {
                 // DVD sub
-                len = ds_get_packet_sub(d_dvdsub, (unsigned char**)&packet);
+                len = ds_get_packet_sub(d_dvdsub, (unsigned char**)&packet, NULL, NULL);
                 if (len > 0) {
                     // XXX This is wrong, sh_video->pts can be arbitrarily
                     // much behind demuxing position. Unfortunately using
@@ -171,12 +171,11 @@
         }
         if (d_dvdsub->non_interleaved)
             ds_get_next_pts(d_dvdsub);
-        while (d_dvdsub->first) {
-            double subpts = ds_get_next_pts(d_dvdsub);
-            if (subpts > curpts)
+        while (1) {
+            double subpts = curpts;
+            len = ds_get_packet_sub(d_dvdsub, &packet, &subpts, &endpts);
+            if (len < 0)
                 break;
-            endpts = d_dvdsub->first->endpts;
-            len = ds_get_packet_sub(d_dvdsub, &packet);
             if (type == 'm') {
                 if (len < 2) continue;
                 len = FFMIN(len - 2, AV_RB16(packet));