diff -uNrp c/common/common.c b/common/common.c --- c/common/common.c 2008-09-18 14:03:12 +0300 +++ b/common/common.c 2008-09-18 14:08:13 +0300 @@ -111,6 +111,7 @@ void x264_param_default( x264_param_t param->pf_log = x264_log_default; param->p_log_private = NULL; param->i_log_level = X264_LOG_INFO; + param->i_log_file_level = X264_LOG_INFO; /* */ param->analyse.intra = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8; @@ -443,6 +444,10 @@ int x264_param_parse( x264_param_t *p, c } OPT("log") p->i_log_level = atoi(value); + OPT("log-file") + p->psz_log_file = strdup(value); + OPT("log-file-level") + p->i_log_file_level = x264_clip3( atoi(value), -1, 3 ); #ifdef VISUALIZE OPT("visualize") p->b_visualize = atobool(value); @@ -603,6 +608,31 @@ int x264_param_parse( x264_param_t *p, c return b_error ? X264_PARAM_BAD_VALUE : 0; } +static void x264_log_file( FILE *p_file, int i_level, const char *psz_fmt, va_list arg ) +{ + char *psz_prefix; + switch( i_level ) + { + case X264_LOG_ERROR: + psz_prefix = "error"; + break; + case X264_LOG_WARNING: + psz_prefix = "warning"; + break; + case X264_LOG_INFO: + psz_prefix = "info"; + break; + case X264_LOG_DEBUG: + psz_prefix = "debug"; + break; + default: + psz_prefix = "unknown"; + break; + } + fprintf( p_file, "x264 [%s]: ", psz_prefix ); + vfprintf( p_file, psz_fmt, arg ); +} + /**************************************************************************** * x264_log: ****************************************************************************/ @@ -615,6 +645,14 @@ void x264_log( x264_t *h, int i_level, c h->param.pf_log( h->param.p_log_private, i_level, psz_fmt, arg ); va_end( arg ); } + if( i_level <= h->param.i_log_file_level ) + { + va_list arg; + va_start( arg, psz_fmt ); + if( h->p_log_file ) + x264_log_file( h->p_log_file, i_level, psz_fmt, arg ); + va_end( arg ); + } } static void x264_log_default( void *p_unused, int i_level, const char *psz_fmt, va_list arg ) diff -uNrp c/common/common.h b/common/common.h --- c/common/common.h 2008-09-18 14:03:02 +0300 +++ b/common/common.h 2008-09-18 14:09:37 +0300 @@ -353,7 +353,8 @@ struct x264_t x264_frame_t *fref1[16+3]; /* ref list 1 */ int b_ref_reorder[2]; - + /* log */ + FILE *p_log_file; /* Current MB DCT coeffs */ struct diff -uNrp c/encoder/encoder.c b/encoder/encoder.c --- c/encoder/encoder.c 2008-09-18 14:03:17 +0300 +++ b/encoder/encoder.c 2008-09-18 14:15:43 +0300 @@ -661,12 +661,36 @@ x264_t *x264_encoder_open ( x264_param /* Create a copy of param */ memcpy( &h->param, param, sizeof( x264_param_t ) ); + if( h->param.psz_log_file ) + { + h->p_log_file = fopen( h->param.psz_log_file, "wb" ); + if( !h->p_log_file ) + { + x264_log( h, X264_LOG_ERROR, "can't write log to \"%s\"\n", h->param.psz_log_file ); + goto fail1; + } + } + if( x264_validate_parameters( h ) < 0 ) + { + if( h->p_log_file ) + { + fclose( h->p_log_file ); + h->p_log_file = NULL; + } goto fail1; + } if( h->param.psz_cqm_file ) if( x264_cqm_parse_file( h, h->param.psz_cqm_file ) < 0 ) + { + if( h->p_log_file ) + { + fclose( h->p_log_file ); + h->p_log_file = NULL; + } goto fail1; + } if( h->param.rc.psz_stat_out ) h->param.rc.psz_stat_out = strdup( h->param.rc.psz_stat_out ); @@ -717,7 +741,14 @@ x264_t *x264_encoder_open ( x264_param x264_validate_levels( h, 1 ); if( x264_cqm_init( h ) < 0 ) + { + if( h->p_log_file ) + { + fclose( h->p_log_file ); + h->p_log_file = NULL; + } goto fail2; + } h->mb.i_mb_count = h->sps->i_mb_width * h->sps->i_mb_height; @@ -837,6 +868,11 @@ x264_t *x264_encoder_open ( x264_param else { x264_log( h, X264_LOG_ERROR, "can't write to fdec.yuv\n" ); + if( h->p_log_file ) + { + fclose( h->p_log_file ); + h->p_log_file = NULL; + } goto fail3; } } @@ -2204,7 +2240,11 @@ void x264_encoder_close ( x264_t *h free( h->param.rc.psz_stat_in ); x264_cqm_delete( h ); - + if( h->p_log_file ) + { + fclose( h->p_log_file ); + h->p_log_file = NULL; + } if( h->param.i_threads > 1) h = h->thread[ h->i_thread_phase % h->param.i_thread_queue ]; diff -uNrp c/x264.c b/x264.c --- c/x264.c 2008-09-18 14:03:12 +0300 +++ b/x264.c 2008-09-18 14:16:35 +0300 @@ -335,6 +335,9 @@ static void Help( x264_param_t *defaults H0( " --quiet Quiet Mode\n" ); H0( " --no-psnr Disable PSNR computation\n" ); H0( " --no-ssim Disable SSIM computation\n" ); + H0( " --log-file Save log to file\n" ); + H0( " --log-file-level Log-file level information (-1=NONE,0=ERROR,1=WARNING,2=INFO,3=DEBUG) [%d]\n", + defaults->i_log_file_level); H0( " --threads Parallel encoding\n" ); H1( " --thread-queue Number of delay frames for thread sync\n" ); H0( " --thread-input Run Avisynth in its own thread\n" ); @@ -474,6 +477,8 @@ static int Parse( int argc, char **argv { "quiet", no_argument, NULL, OPT_QUIET }, { "verbose", no_argument, NULL, 'v' }, { "progress",no_argument, NULL, OPT_PROGRESS }, + { "log-file",required_argument, NULL, 0 }, + { "log-file-level",required_argument, NULL, 0 }, { "visualize",no_argument, NULL, OPT_VISUALIZE }, { "dump-yuv",required_argument, NULL, 0 }, { "sps-id", required_argument, NULL, 0 }, diff -uNrp c/x264.h b/x264.h --- c/x264.h 2008-09-18 14:03:06 +0300 +++ b/x264.h 2008-09-18 14:17:06 +0300 @@ -219,6 +219,8 @@ typedef struct x264_param_t void (*pf_log)( void *, int i_level, const char *psz, va_list ); void *p_log_private; int i_log_level; + int i_log_file_level; + char *psz_log_file; int b_visualize; char *psz_dump_yuv; /* filename for reconstructed frames */