diff -uNrp a/cli_common.h b/cli_common.h --- a/cli_common.h 1970-01-01 02:00:00 +0200 +++ b/cli_common.h 2009-12-05 22:19:47 +0200 @@ -0,0 +1,29 @@ +#ifndef X264_CLI_H +#define X264_CLI_H + +/** + * Contains necessities common to CLI elements but not the library. + */ + +/* log macros */ +FILE *f_log_file; +#define OPEN_LOG(prm,mode) \ +{\ + if( prm->psz_log_file )\ + f_log_file = fopen( prm->psz_log_file, mode );\ +} +#define CLOSE_LOG \ +{\ + if( f_log_file )\ + fclose( f_log_file );\ + f_log_file = NULL;\ +} +#define LOG(prm,lvl1,lvl2,...) \ +{\ + if( prm->i_log_level>=X264_LOG_##lvl1 )\ + fprintf( stderr, __VA_ARGS__ );\ + if( f_log_file && prm->i_log_file_level>=X264_LOG_##lvl2 )\ + fprintf( f_log_file, __VA_ARGS__ );\ +} + +#endif diff -uNrp a/common/common.c b/common/common.c --- a/common/common.c 2009-12-05 21:34:24 +0200 +++ b/common/common.c 2009-12-05 22:21:25 +0200 @@ -117,6 +117,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; @@ -468,6 +469,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); @@ -628,6 +633,32 @@ 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 ); + fflush( p_file ); +} + /**************************************************************************** * x264_log: ****************************************************************************/ @@ -643,6 +674,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 a/common/common.h b/common/common.h --- a/common/common.h 2009-12-05 21:34:24 +0200 +++ b/common/common.h 2009-12-05 22:21:45 +0200 @@ -446,7 +446,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 a/encoder/encoder.c b/encoder/encoder.c --- a/encoder/encoder.c 2009-12-05 21:34:24 +0200 +++ b/encoder/encoder.c 2009-12-05 22:23:18 +0200 @@ -795,6 +795,16 @@ x264_t *x264_encoder_open( x264_param_t if( param->param_free ) param->param_free( param ); + if( h->param.psz_log_file ) + { + h->p_log_file = fopen( h->param.psz_log_file, "ab" ); + if( !h->p_log_file ) + { + x264_log( h, X264_LOG_ERROR, "can't write log to \"%s\"\n", h->param.psz_log_file ); + goto fail; + } + } + if( x264_validate_parameters( h ) < 0 ) goto fail; @@ -978,6 +988,11 @@ x264_t *x264_encoder_open( x264_param_t return h; fail: + if( h && h->p_log_file ) + { + fclose( h->p_log_file ); + h->p_log_file = NULL; + } x264_free( h ); return NULL; } @@ -2632,6 +2647,13 @@ void x264_encoder_close ( x264_t *h x264_free( h->nal_buffer ); x264_analyse_free_costs( h ); + if( h->p_log_file ) + { + fflush( 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]; diff -uNrp a/input/avs.c b/input/avs.c --- a/input/avs.c 2009-12-05 21:34:24 +0200 +++ b/input/avs.c 2009-12-05 22:33:24 +0200 @@ -21,6 +21,7 @@ *****************************************************************************/ #include "muxers.h" +#include "cli_common.h" #include /* the AVS interface currently uses __declspec to link function declarations to their definitions in the dll. @@ -123,7 +124,7 @@ static int open_file( char *psz_filename return -1; else if( !x264_is_regular_file( fh ) ) { - fprintf( stderr, "avs [error]: AVS input is incompatible with non-regular file `%s'\n", psz_filename ); + LOG( p_param, NONE, ERROR, "avs [error]: AVS input is incompatible with non-regular file `%s'\n", psz_filename ); return -1; } fclose( fh ); @@ -133,13 +134,13 @@ static int open_file( char *psz_filename return -1; if( avs_load_library( h ) ) { - fprintf( stderr, "avs [error]: failed to load avisynth\n" ); + LOG( p_param, NONE, ERROR, "avs [error]: failed to load avisynth\n" ); return -1; } h->env = h->func.avs_create_script_environment( AVS_INTERFACE_YV12 ); if( !h->env ) { - fprintf( stderr, "avs [error]: failed to initiate avisynth\n" ); + LOG( p_param, NONE, ERROR, "avs [error]: failed to initiate avisynth\n" ); return -1; } AVS_Value arg = avs_new_value_string( psz_filename ); @@ -151,7 +152,7 @@ static int open_file( char *psz_filename res = h->func.avs_invoke( h->env, "Import", arg, NULL ); if( avs_is_error( res ) ) { - fprintf( stderr, "avs [error]: %s\n", avs_as_string( res ) ); + LOG( p_param, NONE, ERROR, "avs [error]: %s\n", avs_as_string( res ) ); return -1; } } @@ -163,34 +164,34 @@ static int open_file( char *psz_filename int i; for( i = 0; filter[i]; i++ ) { - fprintf( stderr, "avs [info]: Trying %s... ", filter[i] ); + LOG( p_param, NONE, INFO, "avs [info]: Trying %s... ", filter[i] ); if( !h->func.avs_function_exists( h->env, filter[i] ) ) { - fprintf( stderr, "not found\n" ); + LOG( p_param, NONE, INFO, "not found\n" ); continue; } if( !strncasecmp( filter[i], "FFmpegSource", 12 ) ) { - fprintf( stderr, "Indexing... " ); + LOG( p_param, NONE, INFO, "Indexing... " ); fflush( stderr ); } res = h->func.avs_invoke( h->env, filter[i], arg, NULL ); if( !avs_is_error( res ) ) { - fprintf( stderr, "succeeded\n" ); + LOG( p_param, NONE, INFO, "succeeded\n" ); break; } - fprintf( stderr, "failed\n" ); + LOG( p_param, NONE, INFO, "failed\n" ); } if( !filter[i] ) { - fprintf( stderr, "avs [error]: unable to find source filter to open `%s'\n", psz_filename ); + LOG( p_param, NONE, ERROR, "avs [error]: unable to find source filter to open `%s'\n", psz_filename ); return -1; } } if( !avs_is_clip( res ) ) { - fprintf( stderr, "avs [error]: `%s' didn't return a video clip\n", psz_filename ); + LOG( p_param, NONE, ERROR, "avs [error]: `%s' didn't return a video clip\n", psz_filename ); return -1; } h->clip = h->func.avs_take_clip( res, h->env ); @@ -198,12 +199,12 @@ static int open_file( char *psz_filename const AVS_VideoInfo *vi = h->func.avs_get_video_info( h->clip ); if( !avs_has_video( vi ) ) { - fprintf( stderr, "avs [error]: `%s' has no video data\n", psz_filename ); + LOG( p_param, NONE, ERROR, "avs [error]: `%s' has no video data\n", psz_filename ); return -1; } if( vi->width&1 || vi->height&1 ) { - fprintf( stderr, "avs [error]: input clip width or height not divisible by 2 (%dx%d)\n", + LOG( p_param, NONE, ERROR, "avs [error]: input clip width or height not divisible by 2 (%dx%d)\n", vi->width, vi->height ); return -1; } @@ -212,13 +213,13 @@ static int open_file( char *psz_filename if( !avs_is_yv12( vi ) || avs_version >= AVS_INTERFACE_OTHER_PLANAR ) { h->func.avs_release_clip( h->clip ); - fprintf( stderr, "avs [warning]: converting input clip to YV12\n" ); + LOG( p_param, NONE, WARNING, "avs [warning]: converting input clip to YV12\n" ); const char *arg_name[2] = { NULL, "interlaced" }; AVS_Value arg_arr[2] = { res, avs_new_value_bool( p_param->b_interlaced ) }; AVS_Value res2 = h->func.avs_invoke( h->env, "ConvertToYV12", avs_new_value_array( arg_arr, 2 ), arg_name ); if( avs_is_error( res2 ) ) { - fprintf( stderr, "avs [error]: Couldn't convert input clip to YV12\n" ); + LOG( p_param, NONE, ERROR, "avs [error]: Couldn't convert input clip to YV12\n" ); return -1; } h->clip = h->func.avs_take_clip( res2, h->env ); @@ -233,12 +234,13 @@ static int open_file( char *psz_filename p_param->i_fps_den = vi->fps_denominator; p_param->i_csp = X264_CSP_YV12; - fprintf( stderr, "avs [info]: %dx%d @ %.2f fps (%d frames)\n", + LOG( p_param, NONE, INFO, "avs [info]: %dx%d @ %.2f fps (%d frames)\n", p_param->i_width, p_param->i_height, (double)p_param->i_fps_num / p_param->i_fps_den, vi->num_frames ); *p_handle = h; + CLOSE_LOG; return 0; } diff -uNrp a/input/thread.c b/input/thread.c --- a/input/thread.c 2009-12-05 21:34:24 +0200 +++ b/input/thread.c 2009-12-05 22:33:36 +0200 @@ -22,6 +22,7 @@ *****************************************************************************/ #include "muxers.h" +#include "cli_common.h" extern cli_input_t input; @@ -50,7 +51,7 @@ static int open_file( char *psz_filename thread_hnd_t *h = malloc( sizeof(thread_hnd_t) ); if( !h || input.picture_alloc( &h->pic, p_param->i_csp, p_param->i_width, p_param->i_height ) ) { - fprintf( stderr, "x264 [error]: malloc failed\n" ); + LOG( p_param, NONE, ERROR, "x264 [error]: malloc failed\n" ); return -1; } h->input = input; @@ -67,6 +68,7 @@ static int open_file( char *psz_filename thread_input.picture_clean = h->input.picture_clean; *p_handle = h; + CLOSE_LOG; return 0; } diff -uNrp a/input/vfw.c b/input/vfw.c --- a/input/vfw.c 2009-12-05 21:34:24 +0200 +++ b/input/vfw.c 2009-12-05 22:33:46 +0200 @@ -22,6 +22,7 @@ *****************************************************************************/ #include "muxers.h" +#include "cli_common.h" #include #include @@ -39,7 +40,7 @@ static int open_file( char *psz_filename return -1; else if( !x264_is_regular_file( fh ) ) { - fprintf( stderr, "vfw [error]: VFW input is incompatible with non-regular file `%s'\n", psz_filename ); + LOG( p_param, NONE, ERROR, "vfw [error]: VFW input is incompatible with non-regular file `%s'\n", psz_filename ); return -1; } fclose( fh ); @@ -69,7 +70,7 @@ static int open_file( char *psz_filename // check input format if( info.fccHandler != MAKEFOURCC('Y', 'V', '1', '2') ) { - fprintf( stderr, "vfw [error]: unsupported input format (%c%c%c%c)\n", + LOG( p_param, NONE, ERROR, "vfw [error]: unsupported input format (%c%c%c%c)\n", (char)(info.fccHandler & 0xff), (char)((info.fccHandler >> 8) & 0xff), (char)((info.fccHandler >> 16) & 0xff), (char)((info.fccHandler >> 24)) ); @@ -88,11 +89,12 @@ static int open_file( char *psz_filename p_param->i_fps_num = info.dwRate / i; p_param->i_csp = X264_CSP_YV12; - fprintf( stderr, "vfw [info]: %dx%d @ %.2f fps (%d frames)\n", + LOG( p_param, NONE, INFO, "vfw [info]: %dx%d @ %.2f fps (%d frames)\n", p_param->i_width, p_param->i_height, (double)p_param->i_fps_num / (double)p_param->i_fps_den, (int)info.dwLength ); + CLOSE_LOG; return 0; } diff -uNrp a/input/y4m.c b/input/y4m.c --- a/input/y4m.c 2009-12-05 21:34:24 +0200 +++ b/input/y4m.c 2009-12-05 22:33:54 +0200 @@ -22,6 +22,7 @@ *****************************************************************************/ #include "muxers.h" +#include "cli_common.h" typedef struct { @@ -93,7 +94,7 @@ static int open_file( char *psz_filename case 'C': /* Color space */ if( strncmp( "420", tokstart, 3 ) ) { - fprintf( stderr, "Colorspace unhandled\n" ); + LOG( p_param, NONE, ERROR, "Colorspace unhandled\n" ); return -1; } tokstart = strchr( tokstart, 0x20 ); @@ -107,7 +108,7 @@ static int open_file( char *psz_filename case 'b': case 'm': default: - fprintf( stderr, "Warning, this sequence might be interlaced\n" ); + LOG( p_param, NONE, WARNING, "Warning, this sequence might be interlaced\n" ); } break; case 'F': /* Frame rate - 0:0 if unknown */ @@ -138,7 +139,7 @@ static int open_file( char *psz_filename strncmp( "420MPEG2",tokstart, 8 ) && strncmp( "420PALDV",tokstart, 8 ) ) { - fprintf( stderr, "Unsupported extended colorspace\n" ); + LOG( p_param, NONE, ERROR, "Unsupported extended colorspace\n" ); return -1; } } @@ -147,11 +148,12 @@ static int open_file( char *psz_filename } } - fprintf( stderr, "yuv4mpeg: %ix%i@%i/%ifps, %i:%i\n", + LOG( p_param, NONE, INFO, "yuv4mpeg: %ix%i@%i/%ifps, %i:%i\n", h->width, h->height, p_param->i_fps_num, p_param->i_fps_den, p_param->vui.i_sar_width, p_param->vui.i_sar_height ); *p_handle = h; + CLOSE_LOG; return 0; } diff -uNrp a/output/flv.c b/output/flv.c --- a/output/flv.c 2009-12-05 21:34:24 +0200 +++ b/output/flv.c 2009-12-05 22:36:20 +0200 @@ -19,6 +19,7 @@ *****************************************************************************/ #include "muxers.h" +#include "cli_common.h" #include "flv_bytestream.h" #define CHECK(x)\ do {\ @@ -134,9 +135,10 @@ static int set_param( hnd_t handle, x264 p_flv->i_init_delay = p_param->i_bframe ? (p_param->i_bframe_pyramid ? 2 : 1) : 0; p_flv->d_mspf = 1000 * (double)p_flv->i_fps_den / p_flv->i_fps_num; - fprintf( stderr, "flv [info]: initial delay %i frames\n", + LOG( p_param, INFO, INFO, "flv [info]: initial delay %i frames\n", (int)p_flv->i_init_delay ); + CLOSE_LOG; return 0; } diff -uNrp a/output/mp4.c b/output/mp4.c --- a/output/mp4.c 2009-12-05 21:34:24 +0200 +++ b/output/mp4.c 2009-12-05 22:37:27 +0200 @@ -22,6 +22,7 @@ *****************************************************************************/ #include "muxers.h" +#include "cli_common.h" #include typedef struct @@ -191,9 +192,10 @@ static int set_param( hnd_t handle, x264 p_mp4->i_time_inc = p_param->i_fps_den; p_mp4->i_init_delay = p_param->i_bframe ? (p_param->i_bframe_pyramid ? 2 : 1) : 0; p_mp4->i_init_delay *= p_mp4->i_time_inc; - fprintf( stderr, "mp4 [info]: initial delay %d (scale %d)\n", + LOG( p_param, INFO, INFO, "mp4 [info]: initial delay %d (scale %d)\n", p_mp4->i_init_delay, p_mp4->i_time_res ); + CLOSE_LOG; return 0; } diff -uNrp a/x264.c b/x264.c --- a/x264.c 2009-12-05 21:34:24 +0200 +++ b/x264.c 2009-12-05 22:46:15 +0200 @@ -32,6 +32,7 @@ #include "common/cpu.h" #include "x264.h" #include "muxers.h" +#include "cli_common.h" #ifdef _WIN32 #include @@ -75,6 +76,7 @@ static int Encode( x264_param_t *param, ****************************************************************************/ int main( int argc, char **argv ) { + f_log_file = NULL; x264_param_t param; cli_opt_t opt; int ret; @@ -378,6 +380,9 @@ static void Help( x264_param_t *defaults H0( " --quiet Quiet Mode\n" ); H1( " --psnr Enable PSNR computation\n" ); H1( " --ssim Enable SSIM computation\n" ); + H0( " --log-file Save log to file\n" ); + H1( " --log-file-level Log-file level information [%d]\n", + defaults->i_log_file_level ); H1( " --threads Force a specific number of threads\n" ); H2( " --thread-input Run Avisynth in its own thread\n" ); H2( " --sync-lookahead Number of buffer frames for threaded lookahead\n" ); @@ -508,6 +513,8 @@ static struct option long_options[] = { "ssim", no_argument, NULL, 0 }, { "quiet", no_argument, NULL, OPT_QUIET }, { "verbose", no_argument, NULL, 'v' }, + { "log-file" ,required_argument, NULL, 0 }, + { "log-file-level",required_argument, NULL, 0 }, { "no-progress", no_argument, NULL, OPT_NOPROGRESS }, { "visualize", no_argument, NULL, OPT_VISUALIZE }, { "dump-yuv", required_argument, NULL, 0 }, @@ -547,7 +554,7 @@ static int select_output( char *filename #ifdef MP4_OUTPUT output = mp4_output; // FIXME use b_annexb=0 #else - fprintf( stderr, "x264 [error]: not compiled with MP4 output support\n" ); + LOG( param, ERROR, ERROR, "x264 [error]: not compiled with MP4 output support\n" ); return -1; #endif } @@ -574,7 +581,7 @@ static int select_input( char *filename, #if defined(AVS_INPUT) || defined(VFW_INPUT) input = avs_input; #else - fprintf( stderr, "x264 [error]: not compiled with AVS input support\n" ); + LOG( param, ERROR, ERROR, "x264 [error]: not compiled with AVS input support\n" ); return -1; #endif } @@ -591,7 +598,7 @@ static int select_input( char *filename, sscanf( p, "%ux%u", ¶m->i_width, ¶m->i_height ) == 2 ) { if( param->i_log_level >= X264_LOG_INFO ) - fprintf( stderr, "x264 [info]: %dx%d (given by file name) @ %.2f fps\n", param->i_width, + LOG( param, INFO, INFO, "x264 [info]: %dx%d (given by file name) @ %.2f fps\n", param->i_width, param->i_height, (double)param->i_fps_num / param->i_fps_den ); break; } @@ -600,12 +607,12 @@ static int select_input( char *filename, { sscanf( resolution, "%ux%u", ¶m->i_width, ¶m->i_height ); if( param->i_log_level >= X264_LOG_INFO ) - fprintf( stderr, "x264 [info]: %dx%d @ %.2f fps\n", param->i_width, param->i_height, + LOG( param, INFO, INFO, "x264 [info]: %dx%d @ %.2f fps\n", param->i_width, param->i_height, (double)param->i_fps_num / param->i_fps_den ); } if( !param->i_width || !param->i_height ) { - fprintf( stderr, "x264 [error]: Rawyuv input requires a resolution.\n" ); + LOG( param, ERROR, ERROR, "x264 [error]: Rawyuv input requires a resolution.\n" ); return -1; } input = yuv_input; @@ -751,7 +758,7 @@ static int Parse( int argc, char **argv } else { - fprintf( stderr, "x264 [error]: invalid preset: %s\n", optarg ); + LOG( param, ERROR, ERROR, "x264 [error]: invalid preset: %s\n", optarg ); return -1; } } @@ -825,7 +832,7 @@ static int Parse( int argc, char **argv } else { - fprintf( stderr, "x264 [error]: invalid tune: %s\n", optarg ); + LOG( param, ERROR, ERROR, "x264 [error]: invalid tune: %s\n", optarg ); return -1; } } @@ -884,7 +891,7 @@ static int Parse( int argc, char **argv i++; if( !stdout_format_names[i] ) { - fprintf( stderr, "x264 [error]: invalid stdout format `%s'\n", optarg ); + LOG( param, ERROR, ERROR, "x264 [error]: invalid stdout format `%s'\n", optarg ); return -1; } stdout_format = optarg; @@ -894,7 +901,7 @@ static int Parse( int argc, char **argv i++; if( !stdin_format_names[i] ) { - fprintf( stderr, "x264 [error]: invalid stdin format `%s'\n", optarg ); + LOG( param, ERROR, ERROR, "x264 [error]: invalid stdin format `%s'\n", optarg ); return -1; } stdin_format = optarg; @@ -903,12 +910,12 @@ static int Parse( int argc, char **argv opt->qpfile = fopen( optarg, "rb" ); if( !opt->qpfile ) { - fprintf( stderr, "x264 [error]: can't open `%s'\n", optarg ); + LOG( param, ERROR, ERROR, "x264 [error]: can't open `%s'\n", optarg ); return -1; } else if( !x264_is_regular_file( opt->qpfile ) ) { - fprintf( stderr, "x264 [error]: qpfile incompatible with non-regular file `%s'\n", optarg ); + LOG( param, ERROR, ERROR, "x264 [error]: qpfile incompatible with non-regular file `%s'\n", optarg ); fclose( opt->qpfile ); return -1; } @@ -930,7 +937,7 @@ static int Parse( int argc, char **argv param->b_visualize = 1; b_exit_on_ctrl_c = 1; #else - fprintf( stderr, "x264 [warning]: not compiled with visualization support\n" ); + LOG( param, WARNING, WARNING, "x264 [warning]: not compiled with visualization support\n" ); #endif break; case OPT_TUNE: @@ -977,7 +984,7 @@ generic_option: if( b_error ) { const char *name = long_options_index > 0 ? long_options[long_options_index].name : argv[optind-2]; - fprintf( stderr, "x264 [error]: invalid argument: %s = %s\n", name, optarg ); + LOG( param, ERROR, ERROR, "x264 [error]: invalid argument: %s = %s\n", name, optarg ); return -1; } } @@ -1005,7 +1012,7 @@ generic_option: param->analyse.i_weighted_pred = X264_WEIGHTP_NONE; if( param->b_interlaced ) { - fprintf( stderr, "x264 [error]: baseline profile doesn't support interlacing\n" ); + LOG( param, ERROR, ERROR, "x264 [error]: baseline profile doesn't support interlacing\n" ); return -1; } } @@ -1020,13 +1027,13 @@ generic_option: } else { - fprintf( stderr, "x264 [error]: invalid profile: %s\n", profile ); + LOG( param, ERROR, ERROR, "x264 [error]: invalid profile: %s\n", profile ); return -1; } if( (param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0) || (param->rc.i_rc_method == X264_RC_CRF && param->rc.f_rf_constant == 0) ) { - fprintf( stderr, "x264 [error]: %s profile doesn't support lossless\n", profile ); + LOG( param, ERROR, ERROR, "x264 [error]: %s profile doesn't support lossless\n", profile ); return -1; } } @@ -1034,7 +1041,7 @@ generic_option: /* Get the file name */ if( optind > argc - 1 || !output_filename ) { - fprintf( stderr, "x264 [error]: No %s file. Run x264 --help for a list of options.\n", + LOG( param, ERROR, ERROR, "x264 [error]: No %s file. Run x264 --help for a list of options.\n", optind > argc - 1 ? "input" : "output" ); return -1; } @@ -1044,7 +1051,7 @@ generic_option: return -1; if( output.open_file( output_filename, &opt->hout ) ) { - fprintf( stderr, "x264 [error]: could not open output file `%s'\n", output_filename ); + LOG( param, ERROR, ERROR, "x264 [error]: could not open output file `%s'\n", output_filename ); return -1; } @@ -1057,7 +1064,7 @@ generic_option: if( input.open_file( input_filename, &opt->hin, param ) ) { - fprintf( stderr, "x264 [error]: could not open input file `%s'\n", input_filename ); + LOG( param, ERROR, ERROR, "x264 [error]: could not open input file `%s'\n", input_filename ); return -1; } /* Restore the user's frame rate if fps has been explicitly set on the commandline. */ @@ -1074,7 +1081,7 @@ generic_option: { if( thread_input.open_file( NULL, &opt->hin, param ) ) { - fprintf( stderr, "x264 [error]: threaded input failed\n" ); + LOG( param, ERROR, ERROR, "x264 [error]: threaded input failed\n" ); return -1; } else @@ -1155,7 +1162,7 @@ static int Encode_frame( x264_t *h, hnd if( x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out ) < 0 ) { - fprintf( stderr, "x264 [error]: x264_encoder_encode failed\n" ); + LOG( (&h->param), ERROR, ERROR, "x264 [error]: x264_encoder_encode failed\n" ); return -1; } @@ -1214,27 +1221,32 @@ static int Encode( x264_param_t *param, param->i_frame_total = i_frame_total; i_update_interval = i_frame_total ? x264_clip3( i_frame_total / 1000, 1, 10 ) : 10; + OPEN_LOG( param, "ab" ); if( ( h = x264_encoder_open( param ) ) == NULL ) { - fprintf( stderr, "x264 [error]: x264_encoder_open failed\n" ); + LOG( param, NONE, ERROR, "x264 [error]: x264_encoder_open failed\n" ); input.close_file( opt->hin ); + CLOSE_LOG; return -1; } if( output.set_param( opt->hout, param ) ) { - fprintf( stderr, "x264 [error]: can't set outfile param\n" ); + LOG( param, NONE, ERROR, "x264 [error]: can't set outfile param\n" ); input.close_file( opt->hin ); output.close_file( opt->hout ); + CLOSE_LOG; return -1; } /* Create a new pic */ if( input.picture_alloc( &pic, param->i_csp, param->i_width, param->i_height ) ) { - fprintf( stderr, "x264 [error]: malloc failed\n" ); + LOG( param, NONE, ERROR, "x264 [error]: malloc failed\n" ); + CLOSE_LOG; return -1; } + CLOSE_LOG; i_start = x264_mdate(); @@ -1292,8 +1304,9 @@ static int Encode( x264_param_t *param, x264_encoder_close( h ); fprintf( stderr, "\n" ); + OPEN_LOG( param, "ab" ); if( b_ctrl_c ) - fprintf( stderr, "aborted at input frame %d, output frame %d\n", opt->i_seek + i_frame, i_frame_output ); + LOG( param, NONE, INFO, "aborted at input frame %d, output frame %d\n", opt->i_seek + i_frame, i_frame_output ); input.close_file( opt->hin ); output.close_file( opt->hout ); @@ -1303,10 +1316,11 @@ static int Encode( x264_param_t *param, 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, + LOG( param, NONE, INFO, "encoded %d frames, %.2f fps, %.2f kb/s\n", i_frame_output, fps, (double) i_file * 8 * param->i_fps_num / ( (double) param->i_fps_den * i_frame_output * 1000 ) ); } + CLOSE_LOG; return 0; } diff -uNrp a/x264.h b/x264.h --- a/x264.h 2009-12-05 21:34:24 +0200 +++ b/x264.h 2009-12-05 22:46:32 +0200 @@ -228,6 +228,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 */