From a8bca7260e635856b5748c1f3bc829176369d36e Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Wed, 27 Dec 2000 18:09:02 +0000 Subject: [PATCH] New synchro statistics and warnings. --- src/video_decoder/vpar_synchro.h | 5 +- src/video_parser/vpar_headers.c | 10 +- src/video_parser/vpar_synchro.c | 201 ++++++++++++++++--------------- 3 files changed, 116 insertions(+), 100 deletions(-) diff --git a/src/video_decoder/vpar_synchro.h b/src/video_decoder/vpar_synchro.h index 06ce9a006f..5be78d4928 100644 --- a/src/video_decoder/vpar_synchro.h +++ b/src/video_decoder/vpar_synchro.h @@ -2,7 +2,7 @@ * vpar_synchro.h : video parser blocks management ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vpar_synchro.h,v 1.2 2000/12/26 19:14:47 massiot Exp $ + * $Id: vpar_synchro.h,v 1.3 2000/12/27 18:09:02 massiot Exp $ * * Author: Christophe Massiot * @@ -66,7 +66,7 @@ typedef struct video_synchro_s mtime_t backward_pts, current_pts; #ifdef STATS - unsigned int i_trashed_pic, i_pic; + unsigned int i_trashed_pic, i_not_chosen_pic, i_pic; #endif } video_synchro_t; @@ -94,3 +94,4 @@ void vpar_SynchroDecode ( struct vpar_thread_s * p_vpar, int i_coding_type, int i_structure ); void vpar_SynchroEnd ( struct vpar_thread_s * p_vpar, int i_garbage ); mtime_t vpar_SynchroDate ( struct vpar_thread_s * p_vpar ); +void vpar_SynchroNewPicture( struct vpar_thread_s * p_vpar, int i_coding_type ); diff --git a/src/video_parser/vpar_headers.c b/src/video_parser/vpar_headers.c index 1a3831db2a..bee81a12a3 100644 --- a/src/video_parser/vpar_headers.c +++ b/src/video_parser/vpar_headers.c @@ -2,7 +2,7 @@ * vpar_headers.c : headers parsing ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vpar_headers.c,v 1.62 2000/12/22 13:04:45 sam Exp $ + * $Id: vpar_headers.c,v 1.63 2000/12/27 18:09:02 massiot Exp $ * * Authors: Christophe Massiot * Stéphane Borel @@ -573,7 +573,7 @@ static void PictureHeader( vpar_thread_t * p_vpar ) } #ifdef STATS - p_vpar->pc_pictures[p_vpar->picture.i_coding_type]++; + p_vpar->pc_pictures[p_vpar->picture.i_coding_type]++; #endif if( p_vpar->picture.i_current_structure && @@ -620,6 +620,9 @@ static void PictureHeader( vpar_thread_t * p_vpar ) } else { + /* Warn synchro we have a new picture (updates pictures index). */ + vpar_SynchroNewPicture( p_vpar, p_vpar->picture.i_coding_type ); + /* Does synchro say we have enough time to decode it ? */ b_parsable = vpar_SynchroChoose( p_vpar, p_vpar->picture.i_coding_type, i_structure ); @@ -643,12 +646,15 @@ static void PictureHeader( vpar_thread_t * p_vpar ) { /* The frame is complete. */ p_vpar->picture.i_current_structure = i_structure; + + vpar_SynchroNewPicture( p_vpar, p_vpar->picture.i_coding_type ); vpar_SynchroTrash( p_vpar, p_vpar->picture.i_coding_type, i_structure ); } } else { /* Warn Synchro we have trashed a picture. */ + vpar_SynchroNewPicture( p_vpar, p_vpar->picture.i_coding_type ); vpar_SynchroTrash( p_vpar, p_vpar->picture.i_coding_type, i_structure ); } p_vpar->picture.p_picture = NULL; diff --git a/src/video_parser/vpar_synchro.c b/src/video_parser/vpar_synchro.c index 1f8e373f3a..e10129f839 100644 --- a/src/video_parser/vpar_synchro.c +++ b/src/video_parser/vpar_synchro.c @@ -2,7 +2,7 @@ * vpar_synchro.c : frame dropping routines ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vpar_synchro.c,v 1.64 2000/12/26 19:14:47 massiot Exp $ + * $Id: vpar_synchro.c,v 1.65 2000/12/27 18:09:02 massiot Exp $ * * Authors: Christophe Massiot * Samuel Hocevar @@ -126,7 +126,6 @@ * Local prototypes */ static int SynchroType( void ); -static void SynchroNewPicture( vpar_thread_t * p_vpar, int i_coding_type ); /* Error margins */ #define DELTA (int)(0.040*CLOCK_FREQ) @@ -235,10 +234,6 @@ boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type, switch( i_coding_type ) { case I_CODING_TYPE: - /* Stream structure changes */ - if( S.i_eta_p ) - S.i_n_p = S.i_eta_p; - if( S.backward_pts ) { pts = S.backward_pts; @@ -267,19 +262,13 @@ boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type, break; case P_CODING_TYPE: - /* Stream structure changes */ - if( S.i_eta_b ) - S.i_n_b = S.i_eta_b; - if( S.i_eta_p + 1 > S.i_n_p ) - S.i_n_p = S.i_eta_p + 1; - if( S.backward_pts ) { pts = S.backward_pts; } else { - pts = S.current_pts + period * (S.i_n_b + 2); + pts = S.current_pts + period * (S.i_n_b + 1); } if( (1 + S.i_n_p * (S.i_n_b + 1)) * period > @@ -296,7 +285,7 @@ boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type, /* next I */ b_decode &= (pts - now + period - * ( (S.i_n_p - S.i_eta_p - 1) * (1 + S.i_n_b) - 1 )) + * ( (S.i_n_p - S.i_eta_p) * (1 + S.i_n_b) - 1 )) > (TAU_PRIME(P_CODING_TYPE) + TAU_PRIME(I_CODING_TYPE) + DELTA); } @@ -308,22 +297,26 @@ boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type, break; case B_CODING_TYPE: - /* Stream structure changes */ - if( S.i_eta_b + 1 > S.i_n_b ) - S.i_n_b = S.i_eta_b + 1; - - pts = S.current_pts + period; + pts = S.current_pts; if( (S.i_n_b + 1) * period > S.p_tau[P_CODING_TYPE] ) { - b_decode = (pts - now) > (TAU_PRIME(B_CODING_TYPE) + DELTA); - - /* Remember that S.i_eta_b is for the moment only eta_b - 1. */ - b_decode &= (pts - now - + period - * ( 2 * S.i_n_b - S.i_eta_b + 2)) - > (TAU_PRIME(B_CODING_TYPE) - + TAU_PRIME(P_CODING_TYPE) + DELTA); + if( period > S.p_tau[B_CODING_TYPE] ) + { + /* Security in case we're _really_ late */ + b_decode = (pts - now > 0); + } + else + { + b_decode = (pts - now) > (TAU_PRIME(B_CODING_TYPE) + DELTA); + + /* next P or I */ + b_decode &= (pts - now + + period + * ( 2 * S.i_n_b - S.i_eta_b + 3)) + > (TAU_PRIME(B_CODING_TYPE) + + TAU_PRIME(P_CODING_TYPE) + DELTA); + } } else { @@ -338,6 +331,12 @@ boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type, (i_coding_type == P_CODING_TYPE ? "P" : "I"), mstrtime(p_date, pts), b_decode ? "decoding" : "trashed", S.p_tau[i_coding_type]); +#endif +#ifdef STATS + if( !b_decode ) + { + S.i_not_chosen_pic++; + } #endif return( b_decode ); #undef S @@ -346,12 +345,11 @@ boolean_t vpar_SynchroChoose( vpar_thread_t * p_vpar, int i_coding_type, } /***************************************************************************** - * vpar_SynchroTrash : Update timers when we trash a picture + * vpar_SynchroTrash : Update counters when we trash a picture *****************************************************************************/ void vpar_SynchroTrash( vpar_thread_t * p_vpar, int i_coding_type, int i_structure ) { - SynchroNewPicture( p_vpar, i_coding_type ); #ifdef STATS p_vpar->synchro.i_trashed_pic++; #endif @@ -379,8 +377,6 @@ void vpar_SynchroDecode( vpar_thread_t * p_vpar, int i_coding_type, intf_ErrMsg("vpar error: synchro fifo full, estimations will be biased"); } vlc_mutex_unlock( &p_vpar->synchro.fifo_lock ); - - SynchroNewPicture( p_vpar, i_coding_type ); } /***************************************************************************** @@ -429,96 +425,52 @@ mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar ) } /***************************************************************************** - * SynchroType: Get the user's synchro type - ***************************************************************************** - * This function is called at initialization. + * vpar_SynchroNewPicture: Update stream structure and PTS *****************************************************************************/ -static int SynchroType( void ) -{ - 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; -} - -/***************************************************************************** - * SynchroNewPicture: Update stream structure and PTS - *****************************************************************************/ -static void SynchroNewPicture( vpar_thread_t * p_vpar, int i_coding_type ) +void vpar_SynchroNewPicture( vpar_thread_t * p_vpar, int i_coding_type ) { + /* FIXME: use decoder_fifo callback */ pes_packet_t * p_pes; switch( i_coding_type ) { case I_CODING_TYPE: p_vpar->synchro.i_eta_p = p_vpar->synchro.i_eta_b = 0; - if( p_vpar->synchro.i_eta_p ) + 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; + } #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) : %d/%d", + 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_pic - - p_vpar->synchro.i_trashed_pic, + 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 = 0; - p_vpar->synchro.i_pic = 0; + 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 ) + 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: @@ -576,3 +528,60 @@ static void SynchroNewPicture( vpar_thread_t * p_vpar, int i_coding_type ) p_vpar->synchro.i_pic++; #endif } + +/***************************************************************************** + * SynchroType: Get the user's synchro type + ***************************************************************************** + * This function is called at initialization. + *****************************************************************************/ +static int SynchroType( void ) +{ + 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; +} + -- 2.39.5