Commit bad6f235 authored by Christophe Massiot's avatar Christophe Massiot

* Totally new frame dropping algorithm.

  * Fixed a bug in video_ouput.c which made the stream go backwards
    sometimes.
  * Fixed a bug in video_ouput.c which trashed more late pictures than
    necessary.
  * Fixed the DEBUG mode in the Makefile.
  * Fixed a bug in mwait() which made us wait too long.

Ca va tuer.
parent 7e4135b3
...@@ -8,6 +8,13 @@ ...@@ -8,6 +8,13 @@
mode. mode.
* Added --broadcast option for network input. * Added --broadcast option for network input.
* Screen is now emptied when framebuffer output exits. * Screen is now emptied when framebuffer output exits.
* Totally new frame dropping algorithm.
* Fixed a bug in video_ouput.c which made the stream go backwards
sometimes.
* Fixed a bug in video_ouput.c which trashed more late pictures than
necessary.
* Fixed the DEBUG mode in the Makefile.
* Fixed a bug in mwait() which made us wait too long.
Mon, 28 Aug 2000 02:34:18 +0200 Mon, 28 Aug 2000 02:34:18 +0200
0.1.99i : 0.1.99i :
......
...@@ -106,10 +106,6 @@ endif ...@@ -106,10 +106,6 @@ endif
else else
CFLAGS += -march=pentium CFLAGS += -march=pentium
endif endif
# Eventual MMX optimizations for x86
ifneq (,$(findstring mmx,$(ARCH)))
CFLAGS += -DHAVE_MMX
endif
endif endif
# Optimizations for PowerPC # Optimizations for PowerPC
...@@ -127,9 +123,16 @@ ifneq (,$(findstring sparc,$(ARCH))) ...@@ -127,9 +123,16 @@ ifneq (,$(findstring sparc,$(ARCH)))
CFLAGS += -mhard-float CFLAGS += -mhard-float
endif endif
# End of optimizations # /debug
endif
# Eventual MMX optimizations for x86
ifneq (,$(findstring mmx,$(ARCH)))
CFLAGS += -DHAVE_MMX
endif endif
# End of optimizations
# #
# C compiler flags: dependancies # C compiler flags: dependancies
# #
......
...@@ -343,6 +343,9 @@ ...@@ -343,6 +343,9 @@
/* Number of pictures required to computes the FPS rate */ /* Number of pictures required to computes the FPS rate */
#define VOUT_FPS_SAMPLES 20 #define VOUT_FPS_SAMPLES 20
/* Better be in advance when awakening than late... */
#define VOUT_MWAIT_TOLERANCE ((int)(0.020*CLOCK_FREQ))
/* /*
* Framebuffer settings * Framebuffer settings
*/ */
...@@ -361,7 +364,7 @@ ...@@ -361,7 +364,7 @@
* It should be approximately the time needed to perform a complete picture * It should be approximately the time needed to perform a complete picture
* loop. Since it only happens when the video heap is full, it does not need * loop. Since it only happens when the video heap is full, it does not need
* to be too low, even if it blocks the decoder. */ * to be too low, even if it blocks the decoder. */
#define VPAR_OUTMEM_SLEEP ((int)(0.050*CLOCK_FREQ)) #define VPAR_OUTMEM_SLEEP ((int)(0.020*CLOCK_FREQ))
/* Optimization level, from 0 to 2 - 1 is generally a good compromise. Remember /* Optimization level, from 0 to 2 - 1 is generally a good compromise. Remember
* that raising this level dramatically lengthens the compilation time. */ * that raising this level dramatically lengthens the compilation time. */
...@@ -438,11 +441,3 @@ ...@@ -438,11 +441,3 @@
/* Maximal number of commands which can be saved in history list */ /* Maximal number of commands which can be saved in history list */
#define INTF_CONSOLE_MAX_HISTORY 20 #define INTF_CONSOLE_MAX_HISTORY 20
/*****************************************************************************
* Synchro configuration
*****************************************************************************/
#define VOUT_SYNCHRO_LEVEL_START 5 << 10
#define VOUT_SYNCHRO_LEVEL_MAX 15 << 10
#define VOUT_SYNCHRO_HEAP_IDEAL_SIZE 5
...@@ -135,7 +135,7 @@ typedef struct vout_thread_s ...@@ -135,7 +135,7 @@ typedef struct vout_thread_s
p_vout_sys_t p_sys; /* system output method */ p_vout_sys_t p_sys; /* system output method */
vdec_DecodeMacroblock_t * vdec_DecodeMacroblock_t *
vdec_DecodeMacroblock; /* decoder function to use */ vdec_DecodeMacroblock; /* decoder function to use */
/* Current display properties */ /* Current display properties */
u16 i_changes; /* changes made to the thread */ u16 i_changes; /* changes made to the thread */
int i_width; /* current output method width */ int i_width; /* current output method width */
...@@ -181,6 +181,7 @@ typedef struct vout_thread_s ...@@ -181,6 +181,7 @@ typedef struct vout_thread_s
boolean_t b_info; /* print additional information */ boolean_t b_info; /* print additional information */
boolean_t b_interface; /* render interface */ boolean_t b_interface; /* render interface */
boolean_t b_scale; /* allow picture scaling */ boolean_t b_scale; /* allow picture scaling */
mtime_t render_time; /* last picture render time */
/* Idle screens management */ /* Idle screens management */
mtime_t last_display_date; /* last non idle display date */ mtime_t last_display_date; /* last non idle display date */
...@@ -190,7 +191,6 @@ typedef struct vout_thread_s ...@@ -190,7 +191,6 @@ typedef struct vout_thread_s
#ifdef STATS #ifdef STATS
/* Statistics - these numbers are not supposed to be accurate, but are a /* Statistics - these numbers are not supposed to be accurate, but are a
* good indication of the thread status */ * good indication of the thread status */
mtime_t render_time; /* last picture render time */
count_t c_fps_samples; /* picture counts */ count_t c_fps_samples; /* picture counts */
mtime_t p_fps_sample[VOUT_FPS_SAMPLES]; /* FPS samples dates */ mtime_t p_fps_sample[VOUT_FPS_SAMPLES]; /* FPS samples dates */
#endif #endif
...@@ -208,10 +208,6 @@ typedef struct vout_thread_s ...@@ -208,10 +208,6 @@ typedef struct vout_thread_s
/* Bitmap fonts */ /* Bitmap fonts */
p_vout_font_t p_default_font; /* default font */ p_vout_font_t p_default_font; /* default font */
p_vout_font_t p_large_font; /* large font */ p_vout_font_t p_large_font; /* large font */
/* Synchronization informations - synchro level is updated by the vout
* thread and read by decoder threads */
int i_synchro_level; /* trashing level */
} vout_thread_t; } vout_thread_t;
/* Flags for changes - these flags are set in the i_changes field when another /* Flags for changes - these flags are set in the i_changes field when another
...@@ -224,7 +220,9 @@ typedef struct vout_thread_s ...@@ -224,7 +220,9 @@ typedef struct vout_thread_s
#define VOUT_DEPTH_CHANGE 0x0400 /* depth changed */ #define VOUT_DEPTH_CHANGE 0x0400 /* depth changed */
#define VOUT_GAMMA_CHANGE 0x0010 /* gamma changed */ #define VOUT_GAMMA_CHANGE 0x0010 /* gamma changed */
#define VOUT_YUV_CHANGE 0x0800 /* change yuv tables */ #define VOUT_YUV_CHANGE 0x0800 /* change yuv tables */
#define VOUT_NODISPLAY_CHANGE 0xff00 /* changes which forbidden display */
/* Disabled for thread deadlocks issues --Meuuh */
//#define VOUT_NODISPLAY_CHANGE 0xff00 /* changes which forbidden display */
/***************************************************************************** /*****************************************************************************
* Macros * Macros
......
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* *
* Authors: Samuel Hocevar <sam@via.ecp.fr> * Author: Christophe Massiot <massiot@via.ecp.fr>
* Jean-Marc Dressler <polux@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -35,102 +33,58 @@ ...@@ -35,102 +33,58 @@
* "video_fifo.h" * "video_fifo.h"
*****************************************************************************/ *****************************************************************************/
#define SAM_SYNCHRO
//#define POLUX_SYNCHRO
//#define MEUUH_SYNCHRO
/***************************************************************************** /*****************************************************************************
* video_synchro_t and video_synchro_tab_s : timers for the video synchro * video_synchro_t and video_synchro_tab_s : timers for the video synchro
*****************************************************************************/ *****************************************************************************/
#ifdef SAM_SYNCHRO #define MAX_DECODING_PIC 16
#define MAX_PIC_AVERAGE 8
/* Read the discussion on top of vpar_synchro.c for more information. */
typedef struct video_synchro_s typedef struct video_synchro_s
{ {
/* synchro algorithm */ /* synchro algorithm */
int i_type; int i_type;
/* fifo containing decoding dates */ /* fifo containing decoding dates */
mtime_t i_date_fifo[16]; mtime_t p_date_fifo[MAX_DECODING_PIC];
unsigned int i_start; int pi_coding_types[MAX_DECODING_PIC];
unsigned int i_stop; unsigned int i_start, i_end;
vlc_mutex_t fifo_lock;
/* mean decoding time */
mtime_t i_delay; /* stream properties */
mtime_t i_theorical_delay; unsigned int i_n_p, i_n_b;
/* dates */ /* decoding values */
mtime_t i_last_pts; /* pts of the last displayed image */ mtime_t p_tau[4]; /* average decoding durations */
mtime_t i_last_seen_I_pts; /* date of the last I we decoded */ unsigned int pi_meaningful[4]; /* number of durations read */
mtime_t i_last_kept_I_pts; /* pts of last non-dropped I image */ /* and p_vout->render_time (read with p_vout->change_lock) */
/* P images since the last I */ /* stream context */
unsigned int i_P_seen; unsigned int i_eta_p, i_eta_b;
unsigned int i_P_kept; boolean_t b_dropped_last; /* for special synchros below */
/* B images since the last I */ mtime_t backward_pts, current_pts;
unsigned int i_B_seen;
unsigned int i_B_kept; #ifdef STATS
unsigned int i_B_self, i_B_next, i_B_last, i_B_I;
/* can we display pictures ? */
boolean_t b_all_I;
boolean_t b_all_P;
int displayable_p;
boolean_t b_all_B;
int displayable_b;
boolean_t b_dropped_last;
} video_synchro_t;
#define FIFO_INCREMENT( i_counter ) \
p_vpar->synchro.i_counter = (p_vpar->synchro.i_counter + 1) & 0xf;
#define VPAR_SYNCHRO_DEFAULT 0
#define VPAR_SYNCHRO_I 1
#define VPAR_SYNCHRO_Iplus 2
#define VPAR_SYNCHRO_IP 3
#define VPAR_SYNCHRO_IPplus 4
#define VPAR_SYNCHRO_IPB 5
#endif #endif
#ifdef MEUUH_SYNCHRO
typedef struct video_synchro_s
{
int kludge_level, kludge_p, kludge_b, kludge_nbp, kludge_nbb;
int kludge_nbframes;
mtime_t kludge_date, kludge_prevdate;
int i_coding_type;
} video_synchro_t; } video_synchro_t;
#define SYNC_TOLERATE ((int)(0.010*CLOCK_FREQ)) /* 10 ms */ #define FIFO_INCREMENT( i_counter ) \
#define SYNC_DELAY ((int)(0.500*CLOCK_FREQ)) /* 500 ms */ p_vpar->synchro.i_counter = \
#endif (p_vpar->synchro.i_counter + 1) % MAX_DECODING_PIC;
#ifdef POLUX_SYNCHRO
#define SYNC_AVERAGE_COUNT 10
typedef struct video_synchro_s
{
/* Date Section */
/* Dates needed to compute the date of the current frame
* We also use the stream frame rate (sequence.i_frame_rate) */
mtime_t i_current_frame_date;
mtime_t i_backward_frame_date;
/* Frame Trashing Section */ /* Synchro algorithms */
#define VPAR_SYNCHRO_DEFAULT 0
int i_b_nb, i_p_nb; /* number of decoded P and B between two I */ #define VPAR_SYNCHRO_I 1
float r_b_average, r_p_average; #define VPAR_SYNCHRO_Iplus 2
int i_b_count, i_p_count, i_i_count; #define VPAR_SYNCHRO_IP 3
int i_b_trasher; /* used for brensenham algorithm */ #define VPAR_SYNCHRO_IPplus 4
#define VPAR_SYNCHRO_IPB 5
} video_synchro_t;
#endif
/***************************************************************************** /*****************************************************************************
* Prototypes * Prototypes
*****************************************************************************/ *****************************************************************************/
void vpar_SynchroInit ( struct vpar_thread_s * p_vpar );
boolean_t vpar_SynchroChoose ( struct vpar_thread_s * p_vpar, boolean_t vpar_SynchroChoose ( struct vpar_thread_s * p_vpar,
int i_coding_type, int i_structure ); int i_coding_type, int i_structure );
void vpar_SynchroTrash ( struct vpar_thread_s * p_vpar, void vpar_SynchroTrash ( struct vpar_thread_s * p_vpar,
...@@ -139,7 +93,3 @@ void vpar_SynchroDecode ( struct vpar_thread_s * p_vpar, ...@@ -139,7 +93,3 @@ void vpar_SynchroDecode ( struct vpar_thread_s * p_vpar,
int i_coding_type, int i_structure ); int i_coding_type, int i_structure );
void vpar_SynchroEnd ( struct vpar_thread_s * p_vpar ); void vpar_SynchroEnd ( struct vpar_thread_s * p_vpar );
mtime_t vpar_SynchroDate ( struct vpar_thread_s * p_vpar ); mtime_t vpar_SynchroDate ( struct vpar_thread_s * p_vpar );
#ifndef SAM_SYNCHRO
void vpar_SynchroKludge ( struct vpar_thread_s *, mtime_t );
#endif
...@@ -118,7 +118,9 @@ void mwait( mtime_t date ) ...@@ -118,7 +118,9 @@ void mwait( mtime_t date )
gettimeofday( &tv_date, NULL ); gettimeofday( &tv_date, NULL );
/* calculate delay and check if current date is before wished date */ /* calculate delay and check if current date is before wished date */
delay = date - (mtime_t) tv_date.tv_sec * 1000000 - (mtime_t) tv_date.tv_usec; delay = date - (mtime_t) tv_date.tv_sec * 1000000 - (mtime_t) tv_date.tv_usec - 10000;
/* Linux/i386 has a granularity of 10 ms. It's better to be in advance
* than to be late. */
if( delay <= 0 ) /* wished date is now or already passed */ if( delay <= 0 ) /* wished date is now or already passed */
{ {
return; return;
......
...@@ -74,7 +74,6 @@ static void RenderInterface ( vout_thread_t *p_vout ); ...@@ -74,7 +74,6 @@ static void RenderInterface ( vout_thread_t *p_vout );
static int RenderIdle ( vout_thread_t *p_vout ); static int RenderIdle ( vout_thread_t *p_vout );
static int RenderSplash ( vout_thread_t *p_vout ); static int RenderSplash ( vout_thread_t *p_vout );
static void RenderInfo ( vout_thread_t *p_vout ); static void RenderInfo ( vout_thread_t *p_vout );
static void Synchronize ( vout_thread_t *p_vout, s64 i_delay );
static int Manage ( vout_thread_t *p_vout ); static int Manage ( vout_thread_t *p_vout );
static int Align ( vout_thread_t *p_vout, int *pi_x, static int Align ( vout_thread_t *p_vout, int *pi_x,
int *pi_y, int i_width, int i_height, int *pi_y, int i_width, int i_height,
...@@ -175,10 +174,10 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window, ...@@ -175,10 +174,10 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window,
p_vout->last_display_date = 0; p_vout->last_display_date = 0;
p_vout->last_idle_date = 0; p_vout->last_idle_date = 0;
p_vout->init_display_date = mdate(); p_vout->init_display_date = mdate();
p_vout->render_time = 10000;
#ifdef STATS #ifdef STATS
/* Initialize statistics fields */ /* Initialize statistics fields */
p_vout->render_time = 0;
p_vout->c_fps_samples = 0; p_vout->c_fps_samples = 0;
#endif #endif
...@@ -199,9 +198,6 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window, ...@@ -199,9 +198,6 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window,
} }
p_vout->i_pictures = 0; p_vout->i_pictures = 0;
/* Initialize synchronization information */
p_vout->i_synchro_level = VOUT_SYNCHRO_LEVEL_START;
/* Create and initialize system-dependant method - this function issues its /* Create and initialize system-dependant method - this function issues its
* own error messages */ * own error messages */
if( p_vout->p_sys_create( p_vout, psz_display, i_root_window, p_data ) ) if( p_vout->p_sys_create( p_vout, psz_display, i_root_window, p_data ) )
...@@ -950,10 +946,6 @@ static int InitThread( vout_thread_t *p_vout ) ...@@ -950,10 +946,6 @@ static int InitThread( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void RunThread( vout_thread_t *p_vout) static void RunThread( vout_thread_t *p_vout)
{ {
/* XXX?? welcome to gore land */
static int i_trash_count = 0;
static mtime_t last_display_date = 0;
int i_index; /* index in heap */ int i_index; /* index in heap */
mtime_t current_date; /* current date */ mtime_t current_date; /* current date */
mtime_t display_date; /* display date */ mtime_t display_date; /* display date */
...@@ -1005,12 +997,7 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -1005,12 +997,7 @@ static void RunThread( vout_thread_t *p_vout)
/* Computes FPS rate */ /* Computes FPS rate */
p_vout->p_fps_sample[ p_vout->c_fps_samples++ % VOUT_FPS_SAMPLES ] = display_date; p_vout->p_fps_sample[ p_vout->c_fps_samples++ % VOUT_FPS_SAMPLES ] = display_date;
#endif #endif
/* XXX?? */ if( display_date < current_date )
i_trash_count++;
//fprintf( stderr, "gap : %Ld\n", display_date-last_display_date );
last_display_date = display_date;
#if 1
if( display_date < current_date && i_trash_count > 4 )
{ {
/* Picture is late: it will be destroyed and the thread /* Picture is late: it will be destroyed and the thread
* will sleep and go to next picture */ * will sleep and go to next picture */
...@@ -1025,20 +1012,12 @@ last_display_date = display_date; ...@@ -1025,20 +1012,12 @@ last_display_date = display_date;
p_pic->i_status = DESTROYED_PICTURE; p_pic->i_status = DESTROYED_PICTURE;
p_vout->i_pictures--; p_vout->i_pictures--;
} }
intf_DbgMsg( "warning: late picture %p skipped refcount=%d\n", p_pic, p_pic->i_refcount ); intf_ErrMsg( "warning: late picture skipped (%p)\n", p_pic );
vlc_mutex_unlock( &p_vout->picture_lock ); vlc_mutex_unlock( &p_vout->picture_lock );
/* Update synchronization information as if display delay continue;
* was 0 */
Synchronize( p_vout, display_date - current_date );
p_pic = NULL;
display_date = 0;
i_trash_count = 0;
} }
else else if( display_date > current_date + VOUT_DISPLAY_DELAY )
#endif
if( display_date > current_date + VOUT_DISPLAY_DELAY )
{ {
/* A picture is ready to be rendered, but its rendering date /* A picture is ready to be rendered, but its rendering date
* is far from the current one so the thread will perform an * is far from the current one so the thread will perform an
...@@ -1047,12 +1026,6 @@ last_display_date = display_date; ...@@ -1047,12 +1026,6 @@ last_display_date = display_date;
p_pic = NULL; p_pic = NULL;
display_date = 0; display_date = 0;
} }
else
{
/* Picture will be displayed, update synchronization
* information */
Synchronize( p_vout, display_date - current_date );
}
} }
/* /*
* Find the subpictures to display - this operation does not need * Find the subpictures to display - this operation does not need
...@@ -1070,11 +1043,9 @@ last_display_date = display_date; ...@@ -1070,11 +1043,9 @@ last_display_date = display_date;
} }
} }
/* /*
* Perform rendering, sleep and display rendered picture * Perform rendering, sleep and display rendered picture
*/ */
if( p_pic ) /* picture and perhaps subpicture */ if( p_pic ) /* picture and perhaps subpicture */
{ {
b_display = p_vout->b_active; b_display = p_vout->b_active;
...@@ -1173,18 +1144,28 @@ last_display_date = display_date; ...@@ -1173,18 +1144,28 @@ last_display_date = display_date;
* Sleep, wake up and display rendered picture * Sleep, wake up and display rendered picture
*/ */
#ifdef STATS if( display_date != 0 )
/* Store render time */ {
p_vout->render_time = mdate() - current_date; /* Store render time */
#endif p_vout->render_time += mdate() - current_date;
p_vout->render_time >>= 1;
}
/* Give back change lock */ /* Give back change lock */
vlc_mutex_unlock( &p_vout->change_lock ); vlc_mutex_unlock( &p_vout->change_lock );
#ifdef DEBUG_VIDEO
{
char psz_date[MSTRTIME_MAX_SIZE];
intf_DbgMsg( "picture %p waiting until %s\n", p_pic,
mstrtime(psz_date, display_date),
}
#endif
/* Sleep a while or until a given date */ /* Sleep a while or until a given date */
if( display_date != 0 ) if( display_date != 0 )
{ {
mwait( display_date ); mwait( display_date - VOUT_MWAIT_TOLERANCE );
} }
else else
{ {
...@@ -1196,9 +1177,9 @@ last_display_date = display_date; ...@@ -1196,9 +1177,9 @@ last_display_date = display_date;
vlc_mutex_lock( &p_vout->change_lock ); vlc_mutex_lock( &p_vout->change_lock );
#ifdef DEBUG_VIDEO #ifdef DEBUG_VIDEO
intf_DbgMsg( "picture %p, subpicture %p in buffer %d, display=%d\n", p_pic, p_subpic, intf_DbgMsg( "picture %p, subpicture %p in buffer %d, display=%d\n", p_pic, p_subpic,
p_vout->i_buffer_index, b_display && !(p_vout->i_changes & VOUT_NODISPLAY_CHANGE) ); p_vout->i_buffer_index, b_display /* && !(p_vout->i_changes & VOUT_NODISPLAY_CHANGE) */ );
#endif #endif
if( b_display && !(p_vout->i_changes & VOUT_NODISPLAY_CHANGE) ) if( b_display /* && !(p_vout->i_changes & VOUT_NODISPLAY_CHANGE) */ )
{ {
p_vout->p_sys_display( p_vout ); p_vout->p_sys_display( p_vout );
#ifndef SYS_BEOS #ifndef SYS_BEOS
...@@ -2017,81 +1998,6 @@ static void RenderInterface( vout_thread_t *p_vout ) ...@@ -2017,81 +1998,6 @@ static void RenderInterface( vout_thread_t *p_vout )
SetBufferArea( p_vout, 0, p_vout->i_height - i_height, p_vout->i_width, i_height ); SetBufferArea( p_vout, 0, p_vout->i_height - i_height, p_vout->i_width, i_height );
} }
/*****************************************************************************
* Synchronize: update synchro level depending of heap state
*****************************************************************************
* This function is called during the main vout loop.
*****************************************************************************/
static void Synchronize( vout_thread_t *p_vout, s64 i_delay )
{
int i_synchro_inc = 0;
/* XXX?? gore following */
static int i_panic_count = 0;
static int i_last_synchro_inc = 0;
static int i_synchro_level = VOUT_SYNCHRO_LEVEL_START;
static int i_truc = 10;
if( i_delay < 0 )
{
//fprintf( stderr, "PANIC %d\n", i_panic_count );
i_panic_count++;
}
i_truc *= 2;
if( p_vout->i_pictures > VOUT_SYNCHRO_HEAP_IDEAL_SIZE+1 )
{
i_truc = 40;
i_synchro_inc += p_vout->i_pictures - VOUT_SYNCHRO_HEAP_IDEAL_SIZE - 1;
}
else
{
if( p_vout->i_pictures < VOUT_SYNCHRO_HEAP_IDEAL_SIZE )
{
i_truc = 32;
i_synchro_inc += p_vout->i_pictures - VOUT_SYNCHRO_HEAP_IDEAL_SIZE;
}
}
if( i_truc > VOUT_SYNCHRO_LEVEL_MAX >> 5 ||
i_synchro_inc*i_last_synchro_inc < 0 )
{
i_truc = 32;
}
if( i_delay < 6000 )
{
i_truc = 16;
i_synchro_inc -= 2;
}
else if( i_delay < 70000 )
{
i_truc = 24+(24*i_delay)/70000;
if( i_truc < 16 )
i_truc = 16;
i_synchro_inc -= 1+(5*(70000-i_delay))/70000;
}
else if( i_delay > 100000 )
{
i_synchro_level += 1 << 10;
if( i_delay > 130000 )
i_synchro_level += 1 << 10;
}
i_synchro_level += ( i_synchro_inc << 10 ) / i_truc;
p_vout->i_synchro_level = ( i_synchro_level + (1 << 9) );
if( i_synchro_level > VOUT_SYNCHRO_LEVEL_MAX )
{
i_synchro_level = VOUT_SYNCHRO_LEVEL_MAX;
}
//fprintf( stderr, "synchro level : %d, heap : %d (%d, %d) (%d, %f) - %Ld\n", p_vout->i_synchro_level,
// p_vout->i_pictures, i_last_synchro_inc, i_synchro_inc, i_truc, r_synchro_level, i_delay );
i_last_synchro_inc = i_synchro_inc;
}
/***************************************************************************** /*****************************************************************************
* Manage: manage thread * Manage: manage thread
***************************************************************************** *****************************************************************************
...@@ -2103,7 +2009,7 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -2103,7 +2009,7 @@ static int Manage( vout_thread_t *p_vout )
if( p_vout->i_changes ) if( p_vout->i_changes )
{ {
intf_DbgMsg("changes: 0x%x (no display: 0x%x)\n", p_vout->i_changes, intf_DbgMsg("changes: 0x%x (no display: 0x%x)\n", p_vout->i_changes,
p_vout->i_changes & VOUT_NODISPLAY_CHANGE ); 0 /* p_vout->i_changes & VOUT_NODISPLAY_CHANGE */ );
} }
#endif #endif
......
...@@ -66,7 +66,6 @@ static int InitThread ( vpar_thread_t *p_vpar ); ...@@ -66,7 +66,6 @@ static int InitThread ( vpar_thread_t *p_vpar );
static void RunThread ( vpar_thread_t *p_vpar ); static void RunThread ( vpar_thread_t *p_vpar );
static void ErrorThread ( vpar_thread_t *p_vpar ); static void ErrorThread ( vpar_thread_t *p_vpar );
static void EndThread ( vpar_thread_t *p_vpar ); static void EndThread ( vpar_thread_t *p_vpar );
static int SynchroType ( );
/***************************************************************************** /*****************************************************************************
* vpar_CreateThread: create a generic parser thread * vpar_CreateThread: create a generic parser thread
...@@ -78,7 +77,8 @@ static int SynchroType ( ); ...@@ -78,7 +77,8 @@ static int SynchroType ( );
*****************************************************************************/ *****************************************************************************/
#include "main.h" #include "main.h"
#include "interface.h" #include "interface.h"
extern main_t* p_main; extern main_t * p_main;
vpar_thread_t * vpar_CreateThread( /* video_cfg_t *p_cfg, */ input_thread_t *p_input /*, vpar_thread_t * vpar_CreateThread( /* video_cfg_t *p_cfg, */ input_thread_t *p_input /*,
vout_thread_t *p_vout, int *pi_status */ ) vout_thread_t *p_vout, int *pi_status */ )
{ {
...@@ -277,54 +277,7 @@ static int InitThread( vpar_thread_t *p_vpar ) ...@@ -277,54 +277,7 @@ static int InitThread( vpar_thread_t *p_vpar )
/* /*
* Initialize the synchro properties * Initialize the synchro properties
*/ */
#ifdef SAM_SYNCHRO vpar_SynchroInit( p_vpar );
/* Get an possible synchro algorithm */
p_vpar->synchro.i_type = SynchroType();
/* last seen PTS */
p_vpar->synchro.i_last_pts = 0;
/* for i frames */
p_vpar->synchro.i_last_seen_I_pts = 0;
p_vpar->synchro.i_last_kept_I_pts = 0;
/* the fifo */
p_vpar->synchro.i_start = 0;
p_vpar->synchro.i_stop = 0;
/* mean decoding time - at least 200 ms for a slow machine */
p_vpar->synchro.i_delay = 200000;
p_vpar->synchro.i_theorical_delay = 40000; /* 25 fps */
/* assume we can display all Is and 2 Ps */
p_vpar->synchro.b_all_I = 1 << 10;
p_vpar->synchro.b_all_P = 0;
p_vpar->synchro.displayable_p = 2 << 10;
p_vpar->synchro.b_all_B = 0;
p_vpar->synchro.displayable_b = 0;
p_vpar->synchro.b_dropped_last = 0;
/* assume there were about 3 P and 6 B images between I's */
p_vpar->synchro.i_P_seen = p_vpar->synchro.i_P_kept = 1 << 10;
p_vpar->synchro.i_B_seen = p_vpar->synchro.i_B_kept = 1 << 10;
#endif
#ifdef MEUUH_SYNCHRO
p_vpar->synchro.kludge_level = 5;
p_vpar->synchro.kludge_nbp = p_vpar->synchro.kludge_p = 5;
p_vpar->synchro.kludge_nbb = p_vpar->synchro.kludge_b = 6;
p_vpar->synchro.kludge_b = 0;
p_vpar->synchro.kludge_prevdate = 0;
#endif
#ifdef POLUX_SYNCHRO
p_vpar->synchro.i_current_frame_date = 0;
p_vpar->synchro.i_backward_frame_date = 0;
p_vpar->synchro.r_p_average = p_vpar->synchro.i_p_nb = 6;
p_vpar->synchro.r_b_average = p_vpar->synchro.i_b_nb = 6;
p_vpar->synchro.i_p_count = 0;
p_vpar->synchro.i_b_count = 0;
p_vpar->synchro.i_i_count = 0;
#endif
/* Mark thread as running and return */ /* Mark thread as running and return */
intf_DbgMsg("vpar debug: InitThread(%p) succeeded\n", p_vpar); intf_DbgMsg("vpar debug: InitThread(%p) succeeded\n", p_vpar);
...@@ -476,61 +429,3 @@ static void EndThread( vpar_thread_t *p_vpar ) ...@@ -476,61 +429,3 @@ static void EndThread( vpar_thread_t *p_vpar )
intf_DbgMsg("vpar debug: EndThread(%p)\n", p_vpar); intf_DbgMsg("vpar debug: EndThread(%p)\n", p_vpar);
} }
/*****************************************************************************
* SynchroType: Get the user's synchro type
*****************************************************************************
* This function is called at initialization.
*****************************************************************************/
static int SynchroType( )
{
char * psz_synchro = main_GetPszVariable( VPAR_SYNCHRO_VAR, NULL );
if( psz_synchro == NULL )
{
return VPAR_SYNCHRO_DEFAULT;
}
switch( *psz_synchro++ )
{
case 'i':
case 'I':
switch( *psz_synchro++ )
{
case '\0':
return VPAR_SYNCHRO_I;
case '+':
if( *psz_synchro ) return 0;
return VPAR_SYNCHRO_Iplus;
case 'p':
case 'P':
switch( *psz_synchro++ )
{
case '\0':
return VPAR_SYNCHRO_IP;
case '+':
if( *psz_synchro ) return 0;
return VPAR_SYNCHRO_IPplus;
case 'b':
case 'B':
if( *psz_synchro ) return 0;
return VPAR_SYNCHRO_IPB;
default:
return VPAR_SYNCHRO_DEFAULT;
}
default:
return VPAR_SYNCHRO_DEFAULT;
}
}
return VPAR_SYNCHRO_DEFAULT;
}
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment