+ mtime_t period = 1000000 * 1001 / p_vpar->sequence.i_frame_rate;
+
+ switch( i_coding_type )
+ {
+ case I_CODING_TYPE:
+ if( p_vpar->synchro.i_eta_p
+ && p_vpar->synchro.i_eta_p != p_vpar->synchro.i_n_p )
+ {
+ intf_WarnMsg( 1, "Stream periodicity changed from P[%d] to P[%d]",
+ p_vpar->synchro.i_n_p, p_vpar->synchro.i_eta_p );
+ p_vpar->synchro.i_n_p = p_vpar->synchro.i_eta_p;
+ }
+ p_vpar->synchro.i_eta_p = p_vpar->synchro.i_eta_b = 0;
+#ifdef STATS
+ if( p_vpar->synchro.i_type == VPAR_SYNCHRO_DEFAULT )
+ {
+ intf_Msg( "vpar synchro stats: I(%lld) P(%lld)[%d] B(%lld)[%d] YUV(%lld) : trashed %d:%d/%d",
+ p_vpar->synchro.p_tau[I_CODING_TYPE],
+ p_vpar->synchro.p_tau[P_CODING_TYPE],
+ p_vpar->synchro.i_n_p,
+ p_vpar->synchro.p_tau[B_CODING_TYPE],
+ p_vpar->synchro.i_n_b,
+ p_vpar->p_vout->render_time,
+ p_vpar->synchro.i_not_chosen_pic,
+ p_vpar->synchro.i_trashed_pic -
+ p_vpar->synchro.i_not_chosen_pic,
+ p_vpar->synchro.i_pic );
+ p_vpar->synchro.i_trashed_pic = p_vpar->synchro.i_not_chosen_pic
+ = p_vpar->synchro.i_pic = 0;
+ }
+#endif
+ break;
+ case P_CODING_TYPE:
+ p_vpar->synchro.i_eta_p++;
+ if( p_vpar->synchro.i_eta_b
+ && p_vpar->synchro.i_eta_b != p_vpar->synchro.i_n_b )
+ {
+ intf_WarnMsg( 1, "Stream periodicity changed from B[%d] to B[%d]",
+ p_vpar->synchro.i_n_b, p_vpar->synchro.i_eta_b );
+ p_vpar->synchro.i_n_b = p_vpar->synchro.i_eta_b;
+ }
+ p_vpar->synchro.i_eta_b = 0;
+ break;
+ case B_CODING_TYPE:
+ p_vpar->synchro.i_eta_b++;
+ break;
+ }
+
+ 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 )
+ {
+ /* 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_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_vpar->sequence.next_pts );
+ }
+ 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_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->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
+ > PTS_THRESHOLD )
+ {
+ intf_WarnMsg( 2,
+ "vpar synchro warning: backward_pts != current_pts (%lld)",
+ p_vpar->synchro.current_pts - p_vpar->synchro.backward_pts );
+ }
+ p_vpar->synchro.current_pts = p_vpar->synchro.backward_pts;
+ p_vpar->synchro.backward_pts = 0;
+ }
+ else if( p_vpar->sequence.next_dts )
+ {
+ 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_vpar->sequence.next_dts );
+ }
+ /* By definition of a DTS. */
+ p_vpar->synchro.current_pts = p_vpar->sequence.next_dts;
+ p_vpar->sequence.next_dts = 0;
+ }
+
+ if( p_vpar->sequence.next_pts )
+ {
+ /* Store the PTS for the next time we have to date an I picture. */
+ 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++;
+#endif