diff -uNrp src/common/common.c src.new/common/common.c --- src/common/common.c 2011-05-13 11:43:22 +0300 +++ src.new/common/common.c 2011-05-13 11:44:37 +0300 @@ -36,6 +36,7 @@ const int x264_bit_depth = BIT_DEPTH; static void x264_log_default( void *, int, const char *, va_list ); +static void x264_log_file( char *, int, const char *, va_list ); /**************************************************************************** * x264_param_default: @@ -121,6 +122,7 @@ void x264_param_default( x264_param_t *p 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; @@ -815,6 +817,13 @@ 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") + if( !parse_enum( value, x264_log_level_names, &p->i_log_file_level ) ) + p->i_log_file_level += X264_LOG_NONE; + else + p->i_log_file_level = atoi(value); #if HAVE_VISUALIZE OPT("visualize") p->b_visualize = atobool(value); @@ -1006,6 +1015,44 @@ 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( h && h->param.psz_log_file && i_level <= h->param.i_log_file_level ) + { + va_list arg; + va_start( arg, psz_fmt ); + x264_log_file( h->param.psz_log_file, i_level, psz_fmt, arg ); + va_end( arg ); + } +} + +static void x264_log_file( char *p_file_name, 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; + } + FILE *p_log_file = fopen( p_file_name, "ab" ); + if( p_log_file ) + { + fprintf( p_log_file, "x264 [%s]: ", psz_prefix ); + vfprintf( p_log_file, psz_fmt, arg ); + fclose( p_log_file ); + } } static void x264_log_default( void *p_unused, int i_level, const char *psz_fmt, va_list arg ) diff -uNrp src/encoder/encoder.c src.new/encoder/encoder.c --- src/encoder/encoder.c 2011-05-13 11:43:23 +0300 +++ src.new/encoder/encoder.c 2011-05-13 11:45:19 +0300 @@ -726,7 +726,7 @@ static int x264_validate_parameters( x26 if( h->param.rc.f_aq_strength == 0 ) h->param.rc.i_aq_mode = 0; - if( h->param.i_log_level < X264_LOG_INFO ) + if( h->param.i_log_level < X264_LOG_INFO && (!h->param.psz_log_file || h->param.i_log_file_level < X264_LOG_INFO) ) { h->param.analyse.b_psnr = 0; h->param.analyse.b_ssim = 0; @@ -2202,7 +2202,7 @@ reencode: int b_intra = IS_INTRA( h->mb.i_type ); int b_skip = IS_SKIP( h->mb.i_type ); - if( h->param.i_log_level >= X264_LOG_INFO || h->param.rc.b_stat_write ) + if( h->param.i_log_level >= X264_LOG_INFO || (h->param.psz_log_file && h->param.i_log_file_level >= X264_LOG_INFO) || h->param.rc.b_stat_write ) { if( !b_intra && !b_skip && !IS_DIRECT( h->mb.i_type ) ) { @@ -2222,7 +2222,7 @@ reencode: } } - if( h->param.i_log_level >= X264_LOG_INFO ) + if( h->param.i_log_level >= X264_LOG_INFO || (h->param.psz_log_file && h->param.i_log_file_level >= X264_LOG_INFO) ) { if( h->mb.i_cbp_luma | h->mb.i_cbp_chroma ) { diff -uNrp src/x264.c src.new/x264.c --- src/x264.c 2011-05-13 11:43:23 +0300 +++ src.new/x264.c 2011-05-13 11:51:34 +0300 @@ -169,9 +169,32 @@ static int parse( int argc, char **argv static int encode( x264_param_t *param, cli_opt_t *opt ); /* logging and printing for within the cli system */ +static char *psz_log_file = NULL; +static int cli_log_file_level = -1; + +static inline void x264_log_done() +{ + if( psz_log_file ) free( psz_log_file ); + psz_log_file = NULL; +} + +static inline void x264_log_init( const char *file_name ) +{ + x264_log_done(); + psz_log_file = strdup( file_name ); +} + static int cli_log_level; void x264_cli_log( const char *name, int i_level, const char *fmt, ... ) { + if( psz_log_file && *psz_log_file && i_level <= cli_log_file_level ) + { + va_list arg; + va_start( arg, fmt ); + x264_cli_log_file( psz_log_file, i_level, fmt, arg ); + va_end( arg ); + } + if( i_level > cli_log_level ) return; char *s_level; @@ -200,8 +223,46 @@ void x264_cli_log( const char *name, int va_end( arg ); } +void x264_cli_log_file( char *p_file_name, 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; + } + FILE *p_log_file = fopen( p_file_name, "ab" ); + if( p_log_file ) + { + fprintf( p_log_file, "x264 [%s]: ", psz_prefix ); + vfprintf( p_log_file, psz_fmt, arg ); + fclose( p_log_file ); + } + } + void x264_cli_printf( int i_level, const char *fmt, ... ) { + if( psz_log_file && *psz_log_file ) + { + va_list arg; + va_start( arg, fmt ); + x264_cli_log_file( psz_log_file, X264_LOG_INFO, fmt, arg ); + va_end( arg ); + } + if( i_level > cli_log_level ) return; va_list arg; @@ -293,6 +354,7 @@ int main( int argc, char **argv ) SetConsoleTitle( originalCTitle ); + x264_log_done(); return ret; } @@ -748,8 +810,12 @@ static void help( x264_param_t *defaults H1( " --no-progress Don't show the progress indicator while encoding\n" ); H0( " --quiet Quiet Mode\n" ); H1( " --log-level Specify the maximum level of logging [\"%s\"]\n" - " - %s\n", strtable_lookup( log_level_names, cli_log_level - X264_LOG_NONE ), - stringify_names( buf, log_level_names ) ); + " - %s\n", strtable_lookup( x264_log_level_names, cli_log_level - X264_LOG_NONE ), + stringify_names( buf, x264_log_level_names ) ); + H1( " --log-file Save log to file\n" ); + H1( " --log-file-level Log-file level information [\"%s\"]\n" + " - %s\n", strtable_lookup( x264_log_level_names, defaults->i_log_file_level - X264_LOG_NONE ), + stringify_names( buf, x264_log_level_names ) ); H1( " --psnr Enable PSNR computation\n" ); H1( " --ssim Enable SSIM computation\n" ); H1( " --threads Force a specific number of threads\n" ); @@ -809,6 +875,8 @@ enum OPT_TIMEBASE, OPT_PULLDOWN, OPT_LOG_LEVEL, + OPT_LOG_FILE, + OPT_LOG_FILE_LEVEL, OPT_DEMUXER_THREADS, OPT_VIDEO_FILTER, OPT_INPUT_FMT, @@ -932,6 +1000,8 @@ static struct option long_options[] = { "quiet", no_argument, NULL, OPT_QUIET }, { "verbose", no_argument, NULL, 'v' }, { "log-level", required_argument, NULL, OPT_LOG_LEVEL }, + { "log-file", required_argument, NULL, OPT_LOG_FILE }, + { "log-file-level", required_argument, NULL, OPT_LOG_FILE_LEVEL }, { "no-progress", no_argument, NULL, OPT_NOPROGRESS }, { "visualize", no_argument, NULL, OPT_VISUALIZE }, { "dump-yuv", required_argument, NULL, 0 }, @@ -1202,6 +1272,7 @@ static int parse( int argc, char **argv, x264_param_default( &defaults ); cli_log_level = defaults.i_log_level; + cli_log_file_level = defaults.i_log_file_level; memset( &input_opt, 0, sizeof(cli_input_opt_t) ); memset( &output_opt, 0, sizeof(cli_output_opt_t) ); @@ -1296,12 +1367,21 @@ static int parse( int argc, char **argv, cli_log_level = param->i_log_level = X264_LOG_DEBUG; break; case OPT_LOG_LEVEL: - if( !parse_enum_value( optarg, log_level_names, &cli_log_level ) ) + if( !parse_enum_value( optarg, x264_log_level_names, &cli_log_level ) ) cli_log_level += X264_LOG_NONE; else cli_log_level = atoi( optarg ); param->i_log_level = cli_log_level; break; + case OPT_LOG_FILE: + x264_log_init( optarg ); + goto generic_option; + case OPT_LOG_FILE_LEVEL: + if( !parse_enum_value( optarg, x264_log_level_names, &cli_log_file_level ) ) + cli_log_file_level += X264_LOG_NONE; + else + cli_log_file_level = atoi( optarg ); + goto generic_option; case OPT_NOPROGRESS: opt->b_progress = 0; break; @@ -1452,7 +1532,7 @@ generic_option: { if( thread_input.open_file( NULL, &opt->hin, &info, NULL ) ) { - fprintf( stderr, "x264 [error]: threaded input failed\n" ); + x264_cli_log( "x264", X264_LOG_ERROR, "threaded input failed\n" ); return -1; } input = thread_input; @@ -1824,7 +1904,7 @@ fail: fprintf( stderr, "\n" ); if( b_ctrl_c ) - fprintf( stderr, "aborted at input frame %d, output frame %d\n", opt->i_seek + i_frame, i_frame_output ); + x264_cli_printf( X264_LOG_INFO, "aborted at input frame %d, output frame %d\n", opt->i_seek + i_frame, i_frame_output ); output.close_file( opt->hout, largest_pts, second_largest_pts ); opt->hout = NULL; @@ -1834,7 +1914,7 @@ fail: double fps = (double)i_frame_output * (double)1000000 / (double)( i_end - i_start ); - fprintf( stderr, "encoded %d frames, %.2f fps, %.2f kb/s\n", i_frame_output, fps, + x264_cli_printf( X264_LOG_INFO, "encoded %d frames, %.2f fps, %.2f kb/s\n", i_frame_output, fps, (double) i_file * 8 / ( 1000 * duration ) ); } diff -uNrp src/x264.h src.new/x264.h --- src/x264.h 2011-04-13 14:46:31 +0300 +++ src.new/x264.h 2011-05-13 11:52:01 +0300 @@ -173,6 +173,7 @@ static const char * const x264_colorprim static const char * const x264_transfer_names[] = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m", "smpte240m", "linear", "log100", "log316", 0 }; static const char * const x264_colmatrix_names[] = { "GBR", "bt709", "undef", "", "fcc", "bt470bg", "smpte170m", "smpte240m", "YCgCo", 0 }; static const char * const x264_nal_hrd_names[] = { "none", "vbr", "cbr", 0 }; +static const char * const x264_log_level_names[] = { "none", "error", "warning", "info", "debug", 0 }; /* Colorspace type */ #define X264_CSP_MASK 0x00ff /* */ @@ -303,6 +304,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 */ diff -uNrp src/x264cli.h src.new/x264cli.h --- src/x264cli.h 2011-04-13 14:46:31 +0300 +++ src.new/x264cli.h 2011-05-13 11:52:13 +0300 @@ -61,6 +61,7 @@ static inline char *get_filename_extensi } void x264_cli_log( const char *name, int i_level, const char *fmt, ... ); +void x264_cli_log_file( char *p_file_name, int i_level, const char *psz_fmt, va_list arg ); void x264_cli_printf( int i_level, const char *fmt, ... ); #define RETURN_IF_ERR( cond, name, ret, ... )\