]> git.sesse.net Git - vlc/blobdiff - src/video_parser/vpar_synchro.c
The motion compensation routines are now modules as well ; choose your
[vlc] / src / video_parser / vpar_synchro.c
index 1ee0d5f8b64a86547b6b759853dbf660844798c2..d96433e64db3f6e492a8dd620d2268df07da40db 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_synchro.c : frame dropping routines
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_synchro.c,v 1.70 2001/01/10 19:48:26 sam Exp $
+ * $Id: vpar_synchro.c,v 1.78 2001/01/18 05:13:23 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Samuel Hocevar <sam@via.ecp.fr>
 #include "video.h"
 #include "video_output.h"
 
+#include "video_decoder.h"
+#include "vdec_motion.h"
 #include "../video_decoder/vdec_idct.h"
-#include "../video_decoder/video_decoder.h"
-#include "../video_decoder/vdec_motion.h"
 
-#include "../video_decoder/vpar_blocks.h"
+#include "vpar_blocks.h"
 #include "../video_decoder/vpar_headers.h"
 #include "../video_decoder/vpar_synchro.h"
 #include "../video_decoder/video_parser.h"
@@ -130,7 +130,6 @@ static int  SynchroType( void );
 
 /* Error margins */
 #define DELTA                   (int)(0.040*CLOCK_FREQ)
-#define PTS_THRESHOLD           (int)(0.030*CLOCK_FREQ)
 
 #define DEFAULT_NB_P            5
 #define DEFAULT_NB_B            1
@@ -152,6 +151,7 @@ void vpar_SynchroInit( vpar_thread_t * p_vpar )
     p_vpar->synchro.b_dropped_last = 0;
     p_vpar->synchro.current_pts = mdate() + DEFAULT_PTS_DELAY;
     p_vpar->synchro.backward_pts = 0;
+    p_vpar->synchro.i_current_period = p_vpar->synchro.i_backward_period = 0;
 #ifdef STATS
     p_vpar->synchro.i_trashed_pic = p_vpar->synchro.i_not_chosen_pic = 
         p_vpar->synchro.i_pic = 0;
@@ -229,7 +229,7 @@ boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type,
 #endif
 
         now = mdate();
-        period = 1000000 / (p_vpar->sequence.i_frame_rate) * 1001;
+        period = 1000000 * 1001 / p_vpar->sequence.i_frame_rate;
 
         vlc_mutex_lock( &p_vpar->p_vout->change_lock );
         tau_yuv = p_vpar->p_vout->render_time;
@@ -419,10 +419,9 @@ mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
  * vpar_SynchroNewPicture: Update stream structure and PTS
  *****************************************************************************/
 void vpar_SynchroNewPicture( vpar_thread_t * p_vpar, int i_coding_type,
-                             boolean_t b_repeat_field )
+                             int i_repeat_field )
 {
-    pes_packet_t *  p_pes;
-    mtime_t         period = 1000000 / (p_vpar->sequence.i_frame_rate) * 1001;
+    mtime_t         period = 1000000 * 1001 / p_vpar->sequence.i_frame_rate;
 
     switch( i_coding_type )
     {
@@ -470,49 +469,51 @@ void vpar_SynchroNewPicture( vpar_thread_t * p_vpar, int i_coding_type,
         break;
     }
 
-    /* FIXME: use decoder_fifo callback */
-    p_pes = DECODER_FIFO_START( *p_vpar->bit_stream.p_decoder_fifo );
-
-    if( b_repeat_field )
-    {
-        /* MPEG-2 repeat_first_field */
-        /* FIXME : this is not exactly what we should do, repeat_first_field
-         * only regards the next picture */
-        p_vpar->synchro.current_pts += period + (period >> 1);
-    }
-    else
-    {
-        p_vpar->synchro.current_pts += period;
-    }
+    p_vpar->synchro.current_pts += p_vpar->synchro.i_current_period
+                                        * (period >> 1);
 
+#define PTS_THRESHOLD   (period >> 2)
     if( i_coding_type == B_CODING_TYPE )
     {
-        if( p_pes->i_pts )
+        /* A video frame can be displayed 1, 2 or 3 times, according to
+         * repeat_first_field, top_field_first, progressive_sequence and
+         * progressive_frame. */
+        p_vpar->synchro.i_current_period = i_repeat_field;
+
+        if( p_vpar->sequence.next_pts )
         {
-            if( p_pes->i_pts - p_vpar->synchro.current_pts > PTS_THRESHOLD
-                 || p_vpar->synchro.current_pts - p_pes->i_pts > PTS_THRESHOLD )
+            if( p_vpar->sequence.next_pts - p_vpar->synchro.current_pts
+                    > PTS_THRESHOLD
+                 || p_vpar->synchro.current_pts - p_vpar->sequence.next_pts
+                    > PTS_THRESHOLD )
             {
                 intf_WarnMsg( 2,
                         "vpar synchro warning: pts != current_date (%lld)",
-                        p_vpar->synchro.current_pts - p_pes->i_pts );
+                        p_vpar->synchro.current_pts
+                            - p_vpar->sequence.next_pts );
             }
-            p_vpar->synchro.current_pts = p_pes->i_pts;
-            p_pes->i_pts = 0;
+            p_vpar->synchro.current_pts = p_vpar->sequence.next_pts;
+            p_vpar->sequence.next_pts = 0;
         }
     }
     else
     {
+        p_vpar->synchro.i_current_period = p_vpar->synchro.i_backward_period;
+        p_vpar->synchro.i_backward_period = i_repeat_field;
+
         if( p_vpar->synchro.backward_pts )
         {
-            if( p_pes->i_dts && 
-                (p_pes->i_dts - p_vpar->synchro.backward_pts > PTS_THRESHOLD
-              || p_vpar->synchro.backward_pts - p_pes->i_dts > PTS_THRESHOLD) )
+            if( p_vpar->sequence.next_dts && 
+                (p_vpar->sequence.next_dts - p_vpar->synchro.backward_pts
+                    > PTS_THRESHOLD
+              || p_vpar->synchro.backward_pts - p_vpar->sequence.next_dts
+                    > PTS_THRESHOLD) )
             {
                 intf_WarnMsg( 2,
                         "vpar synchro warning: backward_pts != dts (%lld)",
-                        p_vpar->synchro.backward_pts - p_pes->i_dts );
+                        p_vpar->sequence.next_dts
+                            - p_vpar->synchro.backward_pts );
             }
-
             if( p_vpar->synchro.backward_pts - p_vpar->synchro.current_pts
                     > PTS_THRESHOLD
                  || p_vpar->synchro.current_pts - p_vpar->synchro.backward_pts
@@ -525,45 +526,31 @@ void vpar_SynchroNewPicture( vpar_thread_t * p_vpar, int i_coding_type,
             p_vpar->synchro.current_pts = p_vpar->synchro.backward_pts;
             p_vpar->synchro.backward_pts = 0;
         }
-        else if( p_pes->i_dts )
+        else if( p_vpar->sequence.next_dts )
         {
-            if( p_pes->i_dts - p_vpar->synchro.current_pts > PTS_THRESHOLD
-                 || p_vpar->synchro.current_pts - p_pes->i_dts > PTS_THRESHOLD )
+            if( p_vpar->sequence.next_dts - p_vpar->synchro.current_pts
+                    > PTS_THRESHOLD
+                 || p_vpar->synchro.current_pts - p_vpar->sequence.next_dts
+                    > PTS_THRESHOLD )
             {
                 intf_WarnMsg( 2,
                         "vpar synchro warning: dts != current_pts (%lld)",
-                        p_vpar->synchro.current_pts - p_pes->i_dts );
+                        p_vpar->synchro.current_pts
+                            - p_vpar->sequence.next_dts );
             }
             /* By definition of a DTS. */
-            p_vpar->synchro.current_pts = p_pes->i_dts;
-            p_pes->i_dts = 0;
+            p_vpar->synchro.current_pts = p_vpar->sequence.next_dts;
+            p_vpar->sequence.next_dts = 0;
         }
 
-        if( p_pes->i_pts )
+        if( p_vpar->sequence.next_pts )
         {
-#if 0
-            int     i_n_b;
-#endif
-
             /* Store the PTS for the next time we have to date an I picture. */
-            p_vpar->synchro.backward_pts = p_pes->i_pts;
-            p_pes->i_pts = 0;
-            /* FIXME : disabled because it conflicts with streams having
-             * b_repeat_first_field */
-#if 0
-            i_n_b = (p_vpar->synchro.backward_pts
-                        - p_vpar->synchro.current_pts) / period - 1;
-            if( i_n_b != p_vpar->synchro.i_n_b )
-            {
-                intf_WarnMsg( 1,
-                        "Anticipating a stream periodicity change from"
-                        " B[%d] to B[%d]",
-                              p_vpar->synchro.i_n_b, i_n_b );
-                p_vpar->synchro.i_n_b = i_n_b;
-            }
-#endif
+            p_vpar->synchro.backward_pts = p_vpar->sequence.next_pts;
+            p_vpar->sequence.next_pts = 0;
         }
     }
+#undef PTS_THRESHOLD
 
 #ifdef STATS
     p_vpar->synchro.i_pic++;