diff --git a/include/config.h b/include/config.h index 75b5c8a65c..c756c5835c 100644 --- a/include/config.h +++ b/include/config.h @@ -301,7 +301,7 @@ * Video parser configuration *****************************************************************************/ -#define VPAR_IDLE_SLEEP 100000 +#define VPAR_IDLE_SLEEP 10000 /* Time to sleep when waiting for a buffer (from vout or the video fifo). * It should be approximately the time needed to perform a complete picture diff --git a/include/vpar_synchro.h b/include/vpar_synchro.h index bde125bfc7..27e08aa274 100644 --- a/include/vpar_synchro.h +++ b/include/vpar_synchro.h @@ -97,6 +97,8 @@ typedef struct video_synchro_s #ifdef POLUX_SYNCHRO +#define SYNC_AVERAGE_COUNT 10 + typedef struct video_synchro_s { /* Date Section */ @@ -109,6 +111,7 @@ typedef struct video_synchro_s /* Frame Trashing Section */ int i_b_nb, i_p_nb; /* number of decoded P and B between two I */ + float r_b_average, r_p_average; int i_b_count, i_p_count, i_i_count; int i_b_trasher; /* used for brensenham algorithm */ diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 0d5026926b..3dc7699fd1 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -942,6 +942,10 @@ static int InitThread( vout_thread_t *p_vout ) *****************************************************************************/ static void RunThread( vout_thread_t *p_vout) { + //?? welcome to gore land + static int i_trash_count = 0; + static mtime_t last_display_date = 0; + int i_index; /* index in heap */ mtime_t current_date; /* current date */ mtime_t display_date; /* display date */ @@ -993,8 +997,12 @@ static void RunThread( vout_thread_t *p_vout) /* Computes FPS rate */ p_vout->p_fps_sample[ p_vout->c_fps_samples++ % VOUT_FPS_SAMPLES ] = display_date; #endif -#if 0 - 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 will sleep and * go to next picture */ @@ -1012,12 +1020,13 @@ static void RunThread( vout_thread_t *p_vout) intf_DbgMsg( "warning: late picture %p skipped refcount=%d\n", p_pic, p_pic->i_refcount ); vlc_mutex_unlock( &p_vout->picture_lock ); - p_pic = NULL; - display_date = 0; - /* Update synchronization information as if display delay * was 0 */ - Synchronize( p_vout, 0 ); + Synchronize( p_vout, display_date - current_date ); + + p_pic = NULL; + display_date = 0; + i_trash_count = 0; } else #endif @@ -1034,9 +1043,8 @@ static void RunThread( vout_thread_t *p_vout) /* Picture will be displayed, update synchronization * information */ Synchronize( p_vout, display_date - current_date ); - } + } } - /* * Find the subpicture to display - this operation does not need lock, since * only READY_SUBPICTURES are handled. If no picture has been selected, @@ -1917,64 +1925,74 @@ static void Synchronize( vout_thread_t *p_vout, s64 i_delay ) { int i_synchro_inc = 0; //???? gore following - //static int i_panic_count = 0; + static int i_panic_count = 0; static int i_last_synchro_inc = 0; static float r_synchro_level = VOUT_SYNCHRO_LEVEL_START; - static int i_truc = 1; + static int i_truc = 10; - //?? heap size is p_vout->i_pictures - //?? if( i_delay < 0 ) { -// intf_Msg("PANIC %d\n", i_panic_count++); + 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_synchro_inc++; - } - else if( p_vout->i_pictures < VOUT_SYNCHRO_HEAP_IDEAL_SIZE ) - { - i_synchro_inc--; + i_truc = 40; + i_synchro_inc += p_vout->i_pictures - VOUT_SYNCHRO_HEAP_IDEAL_SIZE - 1; + } -*/ - if( i_delay < 10000 ) + else { - i_truc = 4; + 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_delay < 1000 ) + { + //i_truc = 4; + } } - - if( i_delay < 20000 ) + + if( i_truc > VOUT_SYNCHRO_LEVEL_MAX*2*2*2*2*2 || + i_synchro_inc*i_last_synchro_inc < 0 ) { - i_synchro_inc--; - } - else if( i_delay > 50000 ) - { - i_synchro_inc++; + i_truc = 32; } - if( i_synchro_inc*i_last_synchro_inc < 0 ) + if( i_delay < 6000 ) { - i_truc = 2; + i_truc = 16; + i_synchro_inc -= 2; } - else + else if( i_delay < 70000 ) { - i_truc *= 2; - } - if( i_truc > VOUT_SYNCHRO_LEVEL_MAX || i_delay == 0 ) + 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_truc = 2; + r_synchro_level += 1; + if( i_delay > 130000 ) + r_synchro_level += 1; } - + r_synchro_level += (float)i_synchro_inc / i_truc; - p_vout->i_synchro_level = (int) r_synchro_level; + p_vout->i_synchro_level = (int)(r_synchro_level+0.5); if( r_synchro_level > VOUT_SYNCHRO_LEVEL_MAX ) { r_synchro_level = VOUT_SYNCHRO_LEVEL_MAX; } -// printf( "synchro level : %d, (%d, %d) (%d, %f) - %Ld\n", p_vout->i_synchro_level, -// i_last_synchro_inc, i_synchro_inc, i_truc, r_synchro_level, i_delay ); + 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; } diff --git a/src/video_parser/video_parser.c b/src/video_parser/video_parser.c index 898de5c832..87f78d6bf7 100644 --- a/src/video_parser/video_parser.c +++ b/src/video_parser/video_parser.c @@ -306,8 +306,8 @@ static int InitThread( vpar_thread_t *p_vpar ) p_vpar->synchro.i_current_frame_date = 0; p_vpar->synchro.i_backward_frame_date = 0; - p_vpar->synchro.i_p_nb = 5; - p_vpar->synchro.i_b_nb = 6; + 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; diff --git a/src/video_parser/vpar_synchro.c b/src/video_parser/vpar_synchro.c index 05c6758e36..6f9d71b564 100644 --- a/src/video_parser/vpar_synchro.c +++ b/src/video_parser/vpar_synchro.c @@ -542,7 +542,7 @@ void vpar_SynchroSetCurrentDate( vpar_thread_t * p_vpar, int i_coding_type ) } else { - p_vpar->synchro.i_current_frame_date += 1000000/(1+p_vpar->sequence.r_frame_rate); + p_vpar->synchro.i_current_frame_date += 1000000/(p_vpar->sequence.r_frame_rate); } break; @@ -550,7 +550,7 @@ void vpar_SynchroSetCurrentDate( vpar_thread_t * p_vpar, int i_coding_type ) if( p_vpar->synchro.i_backward_frame_date == 0 ) { - p_vpar->synchro.i_current_frame_date += 1000000/(1+p_vpar->sequence.r_frame_rate); + p_vpar->synchro.i_current_frame_date += 1000000/(p_vpar->sequence.r_frame_rate); } else { @@ -588,15 +588,22 @@ boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type, switch( i_coding_type ) { case I_CODING_TYPE: - if( p_vpar->synchro.i_i_count != 0 ) - { - p_vpar->synchro.i_p_nb = p_vpar->synchro.i_p_count; - p_vpar->synchro.i_b_nb = p_vpar->synchro.i_b_count; - } + +//fprintf( stderr, "p : %d (%d), b : %d (%d)\n", p_vpar->synchro.i_p_count, p_vpar->synchro.i_p_nb, +// p_vpar->synchro.i_b_count, p_vpar->synchro.i_b_nb ); + + p_vpar->synchro.r_p_average = + (p_vpar->synchro.r_p_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_p_count)/SYNC_AVERAGE_COUNT; + p_vpar->synchro.r_b_average = + (p_vpar->synchro.r_b_average*(SYNC_AVERAGE_COUNT-1)+p_vpar->synchro.i_b_count)/SYNC_AVERAGE_COUNT; + + p_vpar->synchro.i_p_nb = (int)(p_vpar->synchro.r_p_average+0.5); + p_vpar->synchro.i_b_nb = (int)(p_vpar->synchro.r_b_average+0.5); + p_vpar->synchro.i_p_count = p_vpar->synchro.i_b_count = 0; p_vpar->synchro.i_b_trasher = p_vpar->synchro.i_b_nb / 2; p_vpar->synchro.i_i_count++; - break; + break; case P_CODING_TYPE: p_vpar->synchro.i_p_count++;