* vpar_synchro.c : frame dropping routines
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_synchro.c,v 1.80 2001/01/24 19:05:55 massiot Exp $
+ * $Id: vpar_synchro.c,v 1.91 2001/07/11 02:01:05 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
*****************************************************************************/
#include "defs.h"
+#include <string.h> /* memcpy(), memset() */
+
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
-#include "plugins.h"
#include "intf_msg.h"
#include "video_decoder.h"
#include "vdec_motion.h"
-#include "../video_decoder/vdec_idct.h"
#include "vpar_blocks.h"
-#include "../video_decoder/vpar_headers.h"
-#include "../video_decoder/vpar_synchro.h"
-#include "../video_decoder/video_parser.h"
+#include "vpar_headers.h"
+#include "vpar_synchro.h"
+#include "video_parser.h"
#include "main.h"
mtime_t now, period, tau_yuv;
mtime_t pts = 0;
boolean_t b_decode = 0;
-#ifdef DEBUG_VPAR
+#ifdef TRACE_VPAR
char p_date[MSTRTIME_MAX_SIZE];
#endif
vlc_mutex_lock( &p_vpar->p_vout->change_lock );
tau_yuv = p_vpar->p_vout->render_time;
vlc_mutex_unlock( &p_vpar->p_vout->change_lock );
-
+#ifdef VDEC_SMP
vlc_mutex_lock( &p_vpar->synchro.fifo_lock );
+#endif
switch( i_coding_type )
{
b_decode = (pts - now) > (TAU_PRIME(I_CODING_TYPE) + DELTA);
}
if( !b_decode )
- intf_WarnMsg( 3, "vpar synchro warning: trashing I (%lld)",
+ intf_WarnMsg( 1, "vpar synchro warning: trashing I (%lld)",
pts - now);
break;
}
}
+#ifdef VDEC_SMP
vlc_mutex_unlock( &p_vpar->synchro.fifo_lock );
-#ifdef DEBUG_VPAR
+#endif
+#ifdef TRACE_VPAR
intf_DbgMsg("vpar synchro debug: %s picture scheduled for %s, %s (%lld)",
i_coding_type == B_CODING_TYPE ? "B" :
(i_coding_type == P_CODING_TYPE ? "P" : "I"),
void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type,
int i_structure )
{
+#ifdef VDEC_SMP
vlc_mutex_lock( &p_vpar->synchro.fifo_lock );
+#endif
if( ((p_vpar->synchro.i_end + 1 - p_vpar->synchro.i_start)
% MAX_DECODING_PIC) )
else
{
/* FIFO full, panic() */
- intf_ErrMsg("vpar error: synchro fifo full, estimations will be biased");
+ intf_ErrMsg("vpar error: synchro fifo full, estimations will be biased (%d:%d)",
+ p_vpar->synchro.i_start, p_vpar->synchro.i_end);
}
+#ifdef VDEC_SMP
vlc_mutex_unlock( &p_vpar->synchro.fifo_lock );
+#endif
}
/*****************************************************************************
mtime_t tau;
int i_coding_type;
+#ifdef VDEC_SMP
vlc_mutex_lock( &p_vpar->synchro.fifo_lock );
+#endif
- if (!i_garbage)
+ i_coding_type = p_vpar->synchro.pi_coding_types[p_vpar->synchro.i_start];
+
+ if( !i_garbage )
{
tau = mdate() - p_vpar->synchro.p_date_fifo[p_vpar->synchro.i_start];
- i_coding_type = p_vpar->synchro.pi_coding_types[p_vpar->synchro.i_start];
-
- /* Mean with average tau, to ensure stability. */
- p_vpar->synchro.p_tau[i_coding_type] =
- (p_vpar->synchro.pi_meaningful[i_coding_type]
- * p_vpar->synchro.p_tau[i_coding_type] + tau)
- / (p_vpar->synchro.pi_meaningful[i_coding_type] + 1);
- if( p_vpar->synchro.pi_meaningful[i_coding_type] < MAX_PIC_AVERAGE )
+
+ /* If duration too high, something happened (pause ?), so don't
+ * take it into account. */
+ if( tau < 3 * p_vpar->synchro.p_tau[i_coding_type]
+ || !p_vpar->synchro.pi_meaningful[i_coding_type] )
{
- p_vpar->synchro.pi_meaningful[i_coding_type]++;
+ /* Mean with average tau, to ensure stability. */
+ p_vpar->synchro.p_tau[i_coding_type] =
+ (p_vpar->synchro.pi_meaningful[i_coding_type]
+ * p_vpar->synchro.p_tau[i_coding_type] + tau)
+ / (p_vpar->synchro.pi_meaningful[i_coding_type] + 1);
+ if( p_vpar->synchro.pi_meaningful[i_coding_type] < MAX_PIC_AVERAGE )
+ {
+ p_vpar->synchro.pi_meaningful[i_coding_type]++;
+ }
}
-#ifdef DEBUG_VPAR
+
+#ifdef TRACE_VPAR
intf_DbgMsg("vpar synchro debug: finished decoding %s (%lld)",
i_coding_type == B_CODING_TYPE ? "B" :
(i_coding_type == P_CODING_TYPE ? "P" : "I"), tau);
#endif
}
+ else
+ {
+ intf_DbgMsg("vpar synchro debug: aborting %s",
+ i_coding_type == B_CODING_TYPE ? "B" :
+ (i_coding_type == P_CODING_TYPE ? "P" : "I"));
+ }
FIFO_INCREMENT( i_start );
+#ifdef VDEC_SMP
vlc_mutex_unlock( &p_vpar->synchro.fifo_lock );
+#endif
}
/*****************************************************************************
{
mtime_t period = 1000000 * 1001 / p_vpar->sequence.i_frame_rate
* p_vpar->sequence.i_current_rate / DEFAULT_RATE;
+#if 0
+ mtime_t now = mdate();
+#endif
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 )
+ && p_vpar->synchro.i_eta_p != p_vpar->synchro.i_n_p )
{
- intf_WarnMsg( 1, "Stream periodicity changed from P[%d] to P[%d]",
+ intf_WarnMsg( 3, "vpar info: 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;
}
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 )
+ && p_vpar->synchro.i_eta_b != p_vpar->synchro.i_n_b )
{
- intf_WarnMsg( 1, "Stream periodicity changed from B[%d] to B[%d]",
+ intf_WarnMsg( 3, "vpar info: 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.current_pts += p_vpar->synchro.i_current_period
* (period >> 1);
-
+
#define PTS_THRESHOLD (period >> 2)
if( i_coding_type == B_CODING_TYPE )
{
}
#undef PTS_THRESHOLD
+#if 0
+ /* Removed for incompatibility with slow motion */
+ if( p_vpar->synchro.current_pts + DEFAULT_PTS_DELAY < now )
+ {
+ /* We cannot be _that_ late, something must have happened, reinit
+ * the dates. */
+ intf_WarnMsg( 2, "PTS << now (%lld), resetting",
+ now - p_vpar->synchro.current_pts - DEFAULT_PTS_DELAY );
+ p_vpar->synchro.current_pts = now + DEFAULT_PTS_DELAY;
+ }
+ if( p_vpar->synchro.backward_pts
+ && p_vpar->synchro.backward_pts + DEFAULT_PTS_DELAY < now )
+ {
+ /* The same. */
+ p_vpar->synchro.backward_pts = 0;
+ }
+#endif
+
#ifdef STATS
p_vpar->synchro.i_pic++;
#endif