]> git.sesse.net Git - vlc/commitdiff
Fixed input slave reading of a52/dts/flac/m4a/mpga (close #1818).
authorLaurent Aimar <fenrir@videolan.org>
Fri, 22 Aug 2008 15:57:59 +0000 (17:57 +0200)
committerLaurent Aimar <fenrir@videolan.org>
Fri, 22 Aug 2008 15:57:59 +0000 (17:57 +0200)
Input slave method needs that PCR of master and slave input use the same origin.

modules/demux/a52.c
modules/demux/dts.c
modules/demux/flac.c
modules/demux/mpeg/m4a.c
modules/demux/mpeg/mpga.c

index defb32b3b579a9f1e8b19781512d98f1ea3df044..e2263f05d67f920d422d89725c9c71de0a42d5fd 100644 (file)
@@ -66,6 +66,9 @@ struct demux_sys_t
     /* Packetizer */
     decoder_t *p_packetizer;
 
+    mtime_t i_pts;
+    mtime_t i_time_offset;
+
     int i_mux_rate;
     bool b_big_endian;
 };
@@ -73,7 +76,8 @@ struct demux_sys_t
 static int CheckSync( const uint8_t *p_peek, bool *p_big_endian );
 
 #define PCM_FRAME_SIZE (1536 * 4)
-#define A52_PACKET_SIZE (4 * PCM_FRAME_SIZE)
+#define A52_PACKET_SIZE (1024)
+#define A52_PEEK_SIZE (4 * PCM_FRAME_SIZE)
 #define A52_PROBE_SIZE (512*1024)
 #define A52_MAX_HEADER_SIZE 10
 
@@ -109,7 +113,7 @@ static int Open( vlc_object_t * p_this )
 
         /* Some A52 wav files don't begin with a sync code so we do a more
          * extensive search */
-        int i_size = stream_Peek( p_demux->s, &p_peek, i_peek + A52_PACKET_SIZE * 2);
+        int i_size = stream_Peek( p_demux->s, &p_peek, i_peek + A52_PEEK_SIZE * 2);
         i_size -= (PCM_FRAME_SIZE + A52_MAX_HEADER_SIZE);
 
         while( i_peek < i_size )
@@ -150,6 +154,8 @@ static int Open( vlc_object_t * p_this )
     p_sys->b_start = true;
     p_sys->i_mux_rate = 0;
     p_sys->b_big_endian = b_big_endian;
+    p_sys->i_pts = 0;
+    p_sys->i_time_offset = 0;
 
     /* Load the A52 packetizer */
     INIT_APACKETIZER( p_sys->p_packetizer, 'a', '5', '2', ' ' );
@@ -233,6 +239,11 @@ static int Demux( demux_t *p_demux )
                 p_sys->i_mux_rate =
                     p_block_out->i_buffer * INT64_C(1000000)/p_block_out->i_length;
             }
+            p_sys->i_pts = p_block_out->i_pts;
+
+            /* Correct timestamp */
+            p_block_out->i_pts += p_sys->i_time_offset;
+            p_block_out->i_dts += p_sys->i_time_offset;
 
             /* set PCR */
             es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
@@ -252,21 +263,39 @@ static int Demux( demux_t *p_demux )
 static int Control( demux_t *p_demux, int i_query, va_list args )
 {
     demux_sys_t *p_sys  = p_demux->p_sys;
-    if( i_query == DEMUX_SET_TIME )
-    {
-        return VLC_EGENERIC;
-    }
-    else if( i_query == DEMUX_HAS_UNSUPPORTED_META )
+    bool *pb_bool;
+    int64_t *pi64;
+    int i_ret;
+
+    switch( i_query )
     {
-        bool *pb_bool = (bool*)va_arg( args, bool* );
+    case DEMUX_HAS_UNSUPPORTED_META:
+        pb_bool = (bool*)va_arg( args, bool* );
         *pb_bool = true;
         return VLC_SUCCESS;
-    }
-    else
-    {
-        return demux_vaControlHelper( p_demux->s,
+
+    case DEMUX_GET_TIME:
+        pi64 = (int64_t*)va_arg( args, int64_t * );
+        *pi64 = p_sys->i_pts + p_sys->i_time_offset;
+        return VLC_SUCCESS;
+
+    case DEMUX_SET_TIME: /* TODO implement a high precicsion seek */
+    default:
+        i_ret = demux_vaControlHelper( p_demux->s,
                                        0, -1,
                                        8*p_sys->i_mux_rate, 1, i_query, args );
+        if( !i_ret && p_sys->i_mux_rate > 0 &&
+            ( i_query == DEMUX_SET_POSITION || i_query == DEMUX_SET_TIME ) )
+        {
+
+            const int64_t i_time = INT64_C(1000000) * stream_Tell(p_demux->s) /
+                                        p_sys->i_mux_rate;
+
+            /* Fix time_offset */
+            if( i_time >= 0 )
+                p_sys->i_time_offset = i_time - p_sys->i_pts;
+        }
+        return i_ret;
     }
 }
 
index 914c77b3786fd97e2df2c4408edaa1fb4f9cf7f9..3193588aa5c1ab27f200deafe1ab806ca1ee9636 100644 (file)
@@ -62,6 +62,9 @@ struct demux_sys_t
     /* Packetizer */
     decoder_t *p_packetizer;
 
+    mtime_t i_pts;
+    mtime_t i_time_offset;
+
     int i_mux_rate;
 };
 
@@ -156,6 +159,9 @@ static int Open( vlc_object_t * p_this )
     }
 
     DEMUX_INIT_COMMON(); p_sys = p_demux->p_sys;
+    p_sys->i_mux_rate = 0;
+    p_sys->i_pts = 0;
+    p_sys->i_time_offset = 0;
  
     INIT_APACKETIZER( p_sys->p_packetizer, 'd','t','s',' ' );
     LOAD_PACKETIZER_OR_FAIL( p_sys->p_packetizer, "DTS" );
@@ -214,6 +220,10 @@ static int Demux( demux_t *p_demux )
                     p_block_out->i_buffer * INT64_C(1000000) / p_block_out->i_length;
             }
 
+            /* Correct timestamp */
+            p_block_out->i_pts += p_sys->i_time_offset;
+            p_block_out->i_dts += p_sys->i_time_offset;
+
             /* set PCR */
             es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
 
@@ -232,12 +242,40 @@ static int Demux( demux_t *p_demux )
 static int Control( demux_t *p_demux, int i_query, va_list args )
 {
     demux_sys_t *p_sys  = p_demux->p_sys;
-    if( i_query == DEMUX_SET_TIME )
-        return VLC_EGENERIC;
-    else
-        return demux_vaControlHelper( p_demux->s,
+    bool *pb_bool;
+    int64_t *pi64;
+    int i_ret;
+
+    switch( i_query )
+    {
+    case DEMUX_HAS_UNSUPPORTED_META:
+        pb_bool = (bool*)va_arg( args, bool* );
+        *pb_bool = true;
+        return VLC_SUCCESS;
+
+    case DEMUX_GET_TIME:
+        pi64 = (int64_t*)va_arg( args, int64_t * );
+        *pi64 = p_sys->i_pts + p_sys->i_time_offset;
+        return VLC_SUCCESS;
+
+    case DEMUX_SET_TIME: /* TODO implement a high precicsion seek */
+    default:
+        i_ret = demux_vaControlHelper( p_demux->s,
                                        0, -1,
                                        8*p_sys->i_mux_rate, 1, i_query, args );
+        if( !i_ret && p_sys->i_mux_rate > 0 &&
+            ( i_query == DEMUX_SET_POSITION || i_query == DEMUX_SET_TIME ) )
+        {
+
+            const int64_t i_time = INT64_C(1000000) * stream_Tell(p_demux->s) /
+                                        p_sys->i_mux_rate;
+
+            /* Fix time_offset */
+            if( i_time >= 0 )
+                p_sys->i_time_offset = i_time - p_sys->i_pts;
+        }
+        return i_ret;
+    }
 }
 
 /*****************************************************************************
index da9fbf4c8dbd2c5658fa4ca635770580cdee8b6d..4d6c24c42b33ed293b1998f9f404c0215cb7bd11 100644 (file)
@@ -230,13 +230,18 @@ static int Demux( demux_t *p_demux )
                 p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out);
             }
 
+            p_sys->i_pts = p_block_out->i_dts;
+
+            /* Correct timestamp */
+            p_block_out->i_pts += p_sys->i_time_offset;
+            p_block_out->i_dts += p_sys->i_time_offset;
+
             /* set PCR */
-            if( p_block_out->i_dts >= p_sys->i_pts_start )
+            if( p_block_out->i_dts >= p_sys->i_pts_start + p_sys->i_time_offset )
                 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
             else
                 es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
 
-            p_sys->i_pts = p_block_out->i_dts;
             es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
 
             p_block_out = p_next;
@@ -309,7 +314,7 @@ static int ControlSetTime( demux_t *p_demux, int64_t i_time )
 
         p_sys->i_time_offset = p_sys->seekpoint[i]->i_time_offset - p_sys->i_pts;
         p_sys->i_pts_start = p_sys->i_pts+i_delta_time;
-        es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, p_sys->p_es, p_sys->i_pts_start );
+        es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, p_sys->p_es, p_sys->i_pts_start + p_sys->i_time_offset );
     }
     else
     {
index f1aa237ef9b6874e747094bbca24f08a5a06420d..a54f793b82c5b4a4c185eee340c051562733a59f 100644 (file)
@@ -160,16 +160,20 @@ static int Demux( demux_t *p_demux)
                                           &p_sys->p_packetizer->fmt_out);
             }
 
-            es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
-
-            p_block_out->p_next = NULL;
-
             p_sys->i_pts = p_block_out->i_pts;
             if( p_sys->i_pts > M4A_PTS_START + INT64_C(500000) )
                 p_sys->i_bitrate_avg =
                     8*INT64_C(1000000)*p_sys->i_bytes/(p_sys->i_pts-M4A_PTS_START);
 
             p_sys->i_bytes += p_block_out->i_buffer;
+
+            /* Correct timestamp */
+            p_block_out->i_pts += p_sys->i_time_offset;
+            p_block_out->i_dts += p_sys->i_time_offset;
+
+            /* */
+            es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
+
             es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
 
             p_block_out = p_next;
index 9e0dbf48bc3612021f8dc65c4af6b40880a836a3..3e45ce54caec3b4771679c1bcdff81a391f53e61 100644 (file)
@@ -303,10 +303,14 @@ static int Demux( demux_t *p_demux )
         {
             block_t *p_next = p_block_out->p_next;
 
+            p_sys->i_pts = p_block_out->i_pts;
+
+            /* Correct timestamp */
+            p_block_out->i_pts += p_sys->i_time_offset;
+            p_block_out->i_dts += p_sys->i_time_offset;
+
             es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
 
-            p_block_out->p_next = NULL;
-            p_sys->i_pts = p_block_out->i_pts;
             es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
 
             p_block_out = p_next;
@@ -393,7 +397,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                     p_sys->i_bitrate_avg;
 
                 /* Fix time_offset */
-                if( i_time >= 0 ) p_sys->i_time_offset = i_time - p_sys->i_pts;
+                if( i_time >= 0 )
+                    p_sys->i_time_offset = i_time - p_sys->i_pts;
             }
             return i_ret;
     }