From: Steven Walters Date: Sat, 26 Jun 2010 20:28:49 +0000 (-0400) Subject: Centralize logging within x264cli X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=43a4334670ae60d0f8a30d3e4bd530d3b90a1ce1;p=x264 Centralize logging within x264cli x264cli messages will now respect the log level they pertain to. Slightly reduces binary size. --- diff --git a/input/avs.c b/input/avs.c index 07add40e..b83f7159 100644 --- a/input/avs.c +++ b/input/avs.c @@ -20,8 +20,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "input.h" #include +#define FAIL_IF_ERROR( cond, ... ) FAIL_IF_ERR( cond, "avs", __VA_ARGS__ ) /* the AVS interface currently uses __declspec to link function declarations to their definitions in the dll. this has a side effect of preventing program execution if the avisynth dll is not found, @@ -131,27 +132,15 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c FILE *fh = fopen( psz_filename, "r" ); if( !fh ) 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 ); - return -1; - } + FAIL_IF_ERROR( !x264_is_regular_file( fh ), "AVS input is incompatible with non-regular file `%s'\n", psz_filename ); fclose( fh ); avs_hnd_t *h = malloc( sizeof(avs_hnd_t) ); if( !h ) return -1; - if( avs_load_library( h ) ) - { - fprintf( stderr, "avs [error]: failed to load avisynth\n" ); - return -1; - } + FAIL_IF_ERROR( avs_load_library( h ), "failed to load avisynth\n" ) h->env = h->func.avs_create_script_environment( AVS_INTERFACE_YV12 ); - if( !h->env ) - { - fprintf( stderr, "avs [error]: failed to initiate avisynth\n" ); - return -1; - } + FAIL_IF_ERROR( !h->env, "failed to initiate avisynth\n" ) AVS_Value arg = avs_new_value_string( psz_filename ); AVS_Value res; char *filename_ext = get_filename_extension( psz_filename ); @@ -159,11 +148,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c if( !strcasecmp( filename_ext, "avs" ) ) { 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 ) ); - return -1; - } + FAIL_IF_ERROR( avs_is_error( res ), "%s\n", avs_as_string( res ) ) /* check if the user is using a multi-threaded script and apply distributor if necessary. adapted from avisynth's vfw interface */ AVS_Value mt_test = h->func.avs_invoke( h->env, "GetMTMode", avs_new_value_bool( 0 ), NULL ); @@ -184,78 +169,55 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c int i; for( i = 0; filter[i]; i++ ) { - fprintf( stderr, "avs [info]: trying %s... ", filter[i] ); + x264_cli_log( "avs", X264_LOG_INFO, "trying %s... ", filter[i] ); if( !h->func.avs_function_exists( h->env, filter[i] ) ) { - fprintf( stderr, "not found\n" ); + x264_cli_printf( X264_LOG_INFO, "not found\n" ); continue; } if( !strncasecmp( filter[i], "FFmpegSource", 12 ) ) { - fprintf( stderr, "indexing... " ); + x264_cli_printf( X264_LOG_INFO, "indexing... " ); fflush( stderr ); } res = h->func.avs_invoke( h->env, filter[i], arg, NULL ); if( !avs_is_error( res ) ) { - fprintf( stderr, "succeeded\n" ); + x264_cli_printf( X264_LOG_INFO, "succeeded\n" ); break; } - fprintf( stderr, "failed\n" ); - } - if( !filter[i] ) - { - fprintf( stderr, "avs [error]: unable to find source filter to open `%s'\n", psz_filename ); - return -1; + x264_cli_printf( X264_LOG_INFO, "failed\n" ); } + FAIL_IF_ERROR( !filter[i], "unable to find source filter to open `%s'\n", psz_filename ) } - if( !avs_is_clip( res ) ) - { - fprintf( stderr, "avs [error]: `%s' didn't return a video clip\n", psz_filename ); - return -1; - } + FAIL_IF_ERROR( !avs_is_clip( res ), "`%s' didn't return a video clip\n", psz_filename ) h->clip = h->func.avs_take_clip( res, h->env ); int avs_version = h->func.avs_get_version( h->clip ); 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 ); - return -1; - } + FAIL_IF_ERROR( !avs_has_video( vi ), "`%s' has no video data\n", psz_filename ) /* if the clip is made of fields instead of frames, call weave to make them frames */ if( avs_is_field_based( vi ) ) { - fprintf( stderr, "avs [warning]: detected fieldbased (separated) input, weaving to frames\n" ); + x264_cli_log( "avs", X264_LOG_WARNING, "detected fieldbased (separated) input, weaving to frames\n" ); AVS_Value tmp = h->func.avs_invoke( h->env, "Weave", res, NULL ); - if( avs_is_error( tmp ) ) - { - fprintf( stderr, "avs [error]: couldn't weave fields into frames\n" ); - return -1; - } + FAIL_IF_ERROR( avs_is_error( tmp ), "couldn't weave fields into frames\n" ) res = update_clip( h, &vi, tmp, res ); info->interlaced = 1; info->tff = avs_is_tff( vi ); } - if( vi->width&1 || vi->height&1 ) - { - fprintf( stderr, "avs [error]: input clip width or height not divisible by 2 (%dx%d)\n", - vi->width, vi->height ); - return -1; - } + FAIL_IF_ERROR( vi->width&1 || vi->height&1, "input clip width or height not divisible by 2 (%dx%d)\n", vi->width, vi->height ) /* always call ConvertToYV12 to convert non YV12 planar colorspaces to YV12 when user's AVS supports them, as all planar colorspaces are flagged as YV12. If it is already YV12 in this case, the call does nothing */ if( !avs_is_yv12( vi ) || avs_version >= AVS_INTERFACE_OTHER_PLANAR ) { - fprintf( stderr, "avs %s\n", !avs_is_yv12( vi ) ? "[warning]: converting input clip to YV12" - : "[info]: avisynth 2.6+ detected, forcing conversion to YV12" ); + if( !avs_is_yv12( vi ) ) + x264_cli_log( "avs", X264_LOG_WARNING, "converting input clip to YV12" ); + else + x264_cli_log( "avs", X264_LOG_INFO, "avisynth 2.6+ detected, forcing conversion to YV12" ); const char *arg_name[2] = { NULL, "interlaced" }; AVS_Value arg_arr[2] = { res, avs_new_value_bool( info->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" ); - return -1; - } + FAIL_IF_ERROR( avs_is_error( res2 ), "couldn't convert input clip to YV12\n" ) res = update_clip( h, &vi, res2, res ); } h->func.avs_release_value( res ); @@ -294,11 +256,7 @@ static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame ) return -1; AVS_VideoFrame *frm = p_pic->opaque = h->func.avs_get_frame( h->clip, i_frame ); const char *err = h->func.avs_clip_get_error( h->clip ); - if( err ) - { - fprintf( stderr, "avs [error]: %s occurred while reading frame %d\n", err, i_frame ); - return -1; - } + FAIL_IF_ERROR( err, "%s occurred while reading frame %d\n", err, i_frame ) for( int i = 0; i < 3; i++ ) { /* explicitly cast away the const attribute to avoid a warning */ diff --git a/input/ffms.c b/input/ffms.c index b2a253e7..fe8bf7e9 100644 --- a/input/ffms.c +++ b/input/ffms.c @@ -21,8 +21,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "input.h" #include +#define FAIL_IF_ERROR( cond, ... ) FAIL_IF_ERR( cond, "ffms", __VA_ARGS__ ) + #undef DECLARE_ALIGNED #include #include @@ -86,28 +88,16 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c { idx = FFMS_MakeIndex( psz_filename, 0, 0, NULL, NULL, 0, update_progress, NULL, &e ); fprintf( stderr, " \r" ); - if( !idx ) - { - fprintf( stderr, "ffms [error]: could not create index\n" ); - return -1; - } + FAIL_IF_ERROR( !idx, "could not create index\n" ) if( opt->index_file && FFMS_WriteIndex( opt->index_file, idx, &e ) ) - fprintf( stderr, "ffms [warning]: could not write index file\n" ); + x264_cli_log( "ffms", X264_LOG_WARNING, "could not write index file\n" ); } int trackno = FFMS_GetFirstTrackOfType( idx, FFMS_TYPE_VIDEO, &e ); - if( trackno < 0 ) - { - fprintf( stderr, "ffms [error]: could not find video track\n" ); - return -1; - } + FAIL_IF_ERROR( trackno < 0, "could not find video track\n" ) h->video_source = FFMS_CreateVideoSource( psz_filename, trackno, idx, 1, seekmode, &e ); - if( !h->video_source ) - { - fprintf( stderr, "ffms [error]: could not create video source\n" ); - return -1; - } + FAIL_IF_ERROR( !h->video_source, "could not create video source\n" ) h->track = FFMS_GetTrackFromVideo( h->video_source ); @@ -121,11 +111,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c h->vfr_input = info->vfr; const FFMS_Frame *frame = FFMS_GetFrame( h->video_source, 0, &e ); - if( !frame ) - { - fprintf( stderr, "ffms [error]: could not read frame 0\n" ); - return -1; - } + FAIL_IF_ERROR( !frame, "could not read frame 0\n" ) h->init_width = h->cur_width = info->width = frame->EncodedWidth; h->init_height = h->cur_height = info->height = frame->EncodedHeight; @@ -134,8 +120,8 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c info->tff = frame->TopFieldFirst; if( h->cur_pix_fmt != PIX_FMT_YUV420P ) - fprintf( stderr, "ffms [warning]: converting from %s to YV12\n", - avcodec_get_pix_fmt_name( h->cur_pix_fmt ) ); + x264_cli_log( "ffms", X264_LOG_WARNING, "converting from %s to YV12\n", + avcodec_get_pix_fmt_name( h->cur_pix_fmt ) ); /* ffms timestamps are in milliseconds. ffms also uses int64_ts for timebase, * so we need to reduce large timebases to prevent overflow */ @@ -173,19 +159,15 @@ static int check_swscale( ffms_hnd_t *h, const FFMS_Frame *frame, int i_frame ) if( h->scaler ) { sws_freeContext( h->scaler ); - fprintf( stderr, "ffms [warning]: stream properties changed to %dx%d, %s at frame %d \n", frame->EncodedWidth, - frame->EncodedHeight, avcodec_get_pix_fmt_name( frame->EncodedPixelFormat ), i_frame ); + x264_cli_log( "ffms", X264_LOG_WARNING, "stream properties changed to %dx%d, %s at frame %d \n", frame->EncodedWidth, + frame->EncodedHeight, avcodec_get_pix_fmt_name( frame->EncodedPixelFormat ), i_frame ); h->cur_width = frame->EncodedWidth; h->cur_height = frame->EncodedHeight; h->cur_pix_fmt = frame->EncodedPixelFormat; } h->scaler = sws_getContext( h->cur_width, h->cur_height, h->cur_pix_fmt, h->init_width, h->init_height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL ); - if( !h->scaler ) - { - fprintf( stderr, "ffms [error]: could not open swscale context\n" ); - return -1; - } + FAIL_IF_ERROR( !h->scaler, "could not open swscale context\n" ) return 0; } @@ -195,11 +177,7 @@ static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame ) FFMS_ErrorInfo e; e.BufferSize = 0; const FFMS_Frame *frame = FFMS_GetFrame( h->video_source, i_frame, &e ); - if( !frame ) - { - fprintf( stderr, "ffms [error]: could not read frame %d\n", i_frame ); - return -1; - } + FAIL_IF_ERROR( !frame, "could not read frame %d\n", i_frame ) if( check_swscale( h, frame, i_frame ) ) return -1; @@ -214,12 +192,8 @@ static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame ) if( h->vfr_input ) { - if( info->PTS == AV_NOPTS_VALUE ) - { - fprintf( stderr, "ffms [error]: invalid timestamp. " - "Use --force-cfr and specify a framerate with --fps\n" ); - return -1; - } + FAIL_IF_ERROR( info->PTS == AV_NOPTS_VALUE, "invalid timestamp. " + "Use --force-cfr and specify a framerate with --fps\n" ) if( !h->pts_offset_flag ) { diff --git a/input/input.h b/input/input.h index f89b13b1..f588f3cb 100644 --- a/input/input.h +++ b/input/input.h @@ -25,6 +25,8 @@ #ifndef X264_INPUT_H #define X264_INPUT_H +#include "x264cli.h" + /* options that are used by only some demuxers */ typedef struct { diff --git a/input/lavf.c b/input/lavf.c index 4b0375fa..54a275fe 100644 --- a/input/lavf.c +++ b/input/lavf.c @@ -21,7 +21,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "input.h" +#define FAIL_IF_ERROR( cond, ... ) FAIL_IF_ERR( cond, "lavf", __VA_ARGS__ ) #undef DECLARE_ALIGNED #include #include @@ -59,19 +60,15 @@ static int check_swscale( lavf_hnd_t *h, AVCodecContext *c, int i_frame ) if( h->scaler ) { sws_freeContext( h->scaler ); - fprintf( stderr, "lavf [warning]: stream properties changed to %dx%d, %s at frame %d \n", - c->width, c->height, avcodec_get_pix_fmt_name( c->pix_fmt ), i_frame ); + x264_cli_log( "lavf", X264_LOG_WARNING, "stream properties changed to %dx%d, %s at frame %d \n", + c->width, c->height, avcodec_get_pix_fmt_name( c->pix_fmt ), i_frame ); h->cur_width = c->width; h->cur_height = c->height; h->cur_pix_fmt = c->pix_fmt; } h->scaler = sws_getContext( h->cur_width, h->cur_height, h->cur_pix_fmt, h->init_width, h->init_height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL ); - if( !h->scaler ) - { - fprintf( stderr, "lavf [error]: could not open swscale context\n" ); - return -1; - } + FAIL_IF_ERROR( !h->scaler, "could not open swscale context\n" ) return 0; } @@ -106,12 +103,12 @@ static int read_frame_internal( x264_picture_t *p_pic, lavf_hnd_t *h, int i_fram { c->reordered_opaque = pkt->pts; if( avcodec_decode_video2( c, frame, &finished, pkt ) < 0 ) - fprintf( stderr, "lavf [warning]: video decoding failed on frame %d\n", h->next_frame ); + x264_cli_log( "lavf", X264_LOG_WARNING, "video decoding failed on frame %d\n", h->next_frame ); } if( !finished ) { if( avcodec_decode_video2( c, frame, &finished, pkt ) < 0 ) - fprintf( stderr, "lavf [warning]: video decoding failed on frame %d\n", h->next_frame ); + x264_cli_log( "lavf", X264_LOG_WARNING, "video decoding failed on frame %d\n", h->next_frame ); if( !finished ) return -1; } @@ -166,26 +163,13 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c if( !strcmp( psz_filename, "-" ) ) psz_filename = "pipe:"; - if( av_open_input_file( &h->lavf, psz_filename, NULL, 0, NULL ) ) - { - fprintf( stderr, "lavf [error]: could not open input file\n" ); - return -1; - } - - if( av_find_stream_info( h->lavf ) < 0 ) - { - fprintf( stderr, "lavf [error]: could not find input stream info\n" ); - return -1; - } + FAIL_IF_ERROR( av_open_input_file( &h->lavf, psz_filename, NULL, 0, NULL ), "could not open input file\n" ) + FAIL_IF_ERROR( av_find_stream_info( h->lavf ) < 0, "could not find input stream info\n" ) int i = 0; while( i < h->lavf->nb_streams && h->lavf->streams[i]->codec->codec_type != CODEC_TYPE_VIDEO ) i++; - if( i == h->lavf->nb_streams ) - { - fprintf( stderr, "lavf [error]: could not find video stream\n" ); - return -1; - } + FAIL_IF_ERROR( i == h->lavf->nb_streams, "could not find video stream\n" ) h->stream_id = i; h->next_frame = 0; h->pts_offset_flag = 0; @@ -207,22 +191,15 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c info->csp |= X264_CSP_VFLIP; if( h->cur_pix_fmt != PIX_FMT_YUV420P ) - fprintf( stderr, "lavf [warning]: converting from %s to YV12\n", - avcodec_get_pix_fmt_name( h->cur_pix_fmt ) ); - - if( avcodec_open( c, avcodec_find_decoder( c->codec_id ) ) ) - { - fprintf( stderr, "lavf [error]: could not find decoder for video stream\n" ); - return -1; - } + x264_cli_log( "lavf", X264_LOG_WARNING, "converting from %s to YV12\n", + avcodec_get_pix_fmt_name( h->cur_pix_fmt ) ); + FAIL_IF_ERROR( avcodec_open( c, avcodec_find_decoder( c->codec_id ) ), + "could not find decoder for video stream\n" ) /* prefetch the first frame and set/confirm flags */ h->first_pic = malloc( sizeof(x264_picture_t) ); - if( !h->first_pic || lavf_input.picture_alloc( h->first_pic, info->csp, info->width, info->height ) ) - { - fprintf( stderr, "lavf [error]: malloc failed\n" ); - return -1; - } + FAIL_IF_ERROR( !h->first_pic || lavf_input.picture_alloc( h->first_pic, info->csp, info->width, info->height ), + "malloc failed\n" ) else if( read_frame_internal( h->first_pic, h, 0, info ) ) return -1; diff --git a/input/thread.c b/input/thread.c index c4b07fa0..98af22b9 100644 --- a/input/thread.c +++ b/input/thread.c @@ -21,7 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "input.h" extern cli_input_t input; @@ -47,11 +47,8 @@ typedef struct thread_input_arg_t static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt ) { thread_hnd_t *h = malloc( sizeof(thread_hnd_t) ); - if( !h || input.picture_alloc( &h->pic, info->csp, info->width, info->height ) ) - { - fprintf( stderr, "x264 [error]: malloc failed\n" ); - return -1; - } + FAIL_IF_ERR( !h || input.picture_alloc( &h->pic, info->csp, info->width, info->height ), + "x264", "malloc failed\n" ) h->input = input; h->p_handle = *p_handle; h->next_frame = -1; diff --git a/input/timecode.c b/input/timecode.c index a3073278..7821e760 100644 --- a/input/timecode.c +++ b/input/timecode.c @@ -20,7 +20,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "input.h" +#define FAIL_IF_ERROR( cond, ... ) FAIL_IF_ERR( cond, "timecode", __VA_ARGS__ ) #include extern cli_input_t input; @@ -61,12 +62,8 @@ static double correct_fps( double fps, timecode_hnd_t *h ) { fps_den = i * h->timebase_num; fps_num = round( fps_den * fps_sig ) * exponent; - if( fps_num > UINT32_MAX ) - { - fprintf( stderr, "timecode [error]: tcfile fps correction failed.\n" - " Specify an appropriate timebase manually or remake tcfile.\n" ); - return -1; - } + FAIL_IF_ERROR( fps_num > UINT32_MAX, "tcfile fps correction failed.\n" + " Specify an appropriate timebase manually or remake tcfile.\n" ) if( fabs( ((double)fps_num / fps_den) / exponent - fps_sig ) < DOUBLE_EPSILON ) break; ++i; @@ -91,12 +88,8 @@ static int try_mkv_timebase_den( double *fpss, timecode_hnd_t *h, int loop_num ) double fps_sig = sigexp10( fpss[num], &exponent ); fps_den = round( MKV_TIMEBASE_DEN / fps_sig ) / exponent; h->timebase_num = fps_den && h->timebase_num ? gcd( h->timebase_num, fps_den ) : fps_den; - if( h->timebase_num > UINT32_MAX || !h->timebase_num ) - { - fprintf( stderr, "timecode [error]: automatic timebase generation failed.\n" - " Specify timebase manually.\n" ); - return -1; - } + FAIL_IF_ERROR( h->timebase_num > UINT32_MAX || !h->timebase_num, "automatic timebase generation failed.\n" + " Specify timebase manually.\n" ) } return 0; } @@ -110,11 +103,7 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info double *fpss = NULL; ret = fscanf( tcfile_in, "# timecode format v%d", &tcfv ); - if( ret != 1 || (tcfv != 1 && tcfv != 2) ) - { - fprintf( stderr, "timecode [error]: unsupported timecode format\n" ); - return -1; - } + FAIL_IF_ERROR( ret != 1 || (tcfv != 1 && tcfv != 2), "unsupported timecode format\n" ) if( tcfv == 1 ) { @@ -128,18 +117,11 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info { if( buff[0] == '#' || buff[0] == '\n' || buff[0] == '\r' ) continue; - if( sscanf( buff, "assume %lf", &h->assume_fps ) != 1 && sscanf( buff, "Assume %lf", &h->assume_fps ) != 1 ) - { - fprintf( stderr, "timecode [error]: tcfile parsing error: assumed fps not found\n" ); - return -1; - } + FAIL_IF_ERROR( sscanf( buff, "assume %lf", &h->assume_fps ) != 1 && sscanf( buff, "Assume %lf", &h->assume_fps ) != 1, + "tcfile parsing error: assumed fps not found\n" ) break; } - if( h->assume_fps <= 0 ) - { - fprintf( stderr, "timecode [error]: invalid assumed fps %.6f\n", h->assume_fps ); - return -1; - } + FAIL_IF_ERROR( h->assume_fps <= 0, "invalid assumed fps %.6f\n", h->assume_fps ) file_pos = ftell( tcfile_in ); h->stored_pts_num = 0; @@ -152,16 +134,9 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info continue; } ret = sscanf( buff, "%d,%d,%lf", &start, &end, &seq_fps ); - if( ret != 3 && ret != EOF ) - { - fprintf( stderr, "timecode [error]: invalid input tcfile\n" ); - return -1; - } - if( start > end || start <= prev_start || end <= prev_end || seq_fps <= 0 ) - { - fprintf( stderr, "timecode [error]: invalid input tcfile at line %d: %s\n", num, buff ); - return -1; - } + FAIL_IF_ERROR( ret != 3 && ret != EOF, "invalid input tcfile\n" ) + FAIL_IF_ERROR( start > end || start <= prev_start || end <= prev_end || seq_fps <= 0, + "invalid input tcfile at line %d: %s\n", num, buff ) prev_start = start; prev_end = end; if( h->auto_timebase_den || h->auto_timebase_num ) @@ -259,11 +234,7 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info ++num; } timecodes_num = h->stored_pts_num + h->seek; - if( !timecodes_num ) - { - fprintf( stderr, "timecode [error]: input tcfile doesn't have any timecodes!\n" ); - return -1; - } + FAIL_IF_ERROR( !timecodes_num, "input tcfile doesn't have any timecodes!\n" ) fseek( tcfile_in, file_pos, SEEK_SET ); timecodes = malloc( timecodes_num * sizeof(double) ); @@ -272,11 +243,7 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info fgets( buff, sizeof(buff), tcfile_in ); ret = sscanf( buff, "%lf", &timecodes[0] ); - if( ret != 1 ) - { - fprintf( stderr, "timecode [error]: invalid input tcfile for frame 0\n" ); - goto fail; - } + FAIL_IF_ERROR( ret != 1, "invalid input tcfile for frame 0\n" ) for( num = 1; num < timecodes_num; ) { fgets( buff, sizeof(buff), tcfile_in ); @@ -284,11 +251,8 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info continue; ret = sscanf( buff, "%lf", &timecodes[num] ); timecodes[num] *= 1e-3; /* Timecode format v2 is expressed in milliseconds. */ - if( ret != 1 || timecodes[num] <= timecodes[num - 1] ) - { - fprintf( stderr, "timecode [error]: invalid input tcfile for frame %d\n", num ); - goto fail; - } + FAIL_IF_ERROR( ret != 1 || timecodes[num] <= timecodes[num - 1], + "invalid input tcfile for frame %d\n", num ) ++num; } @@ -342,14 +306,10 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info uint64_t i = gcd( h->timebase_num, h->timebase_den ); h->timebase_num /= i; h->timebase_den /= i; - fprintf( stderr, "timecode [info]: automatic timebase generation %"PRIu64"/%"PRIu64"\n", h->timebase_num, h->timebase_den ); - } - else if( h->timebase_den > UINT32_MAX || !h->timebase_den ) - { - fprintf( stderr, "timecode [error]: automatic timebase generation failed.\n" - " Specify an appropriate timebase manually.\n" ); - goto fail; + x264_cli_log( "timecode", X264_LOG_INFO, "automatic timebase generation %"PRIu64"/%"PRIu64"\n", h->timebase_num, h->timebase_den ); } + else FAIL_IF_ERROR( h->timebase_den > UINT32_MAX || !h->timebase_den, "automatic timebase generation failed.\n" + " Specify an appropriate timebase manually.\n" ) h->pts = malloc( h->stored_pts_num * sizeof(int64_t) ); if( !h->pts ) @@ -360,11 +320,7 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info { h->pts[num] = (int64_t)( timecodes[h->seek + num] * ((double)h->timebase_den / h->timebase_num) + 0.5 ); h->pts[num] -= pts_seek_offset; - if( h->pts[num] <= h->pts[num - 1] ) - { - fprintf( stderr, "timecode [error]: invalid timebase or timecode for frame %d\n", num ); - goto fail; - } + FAIL_IF_ERROR( h->pts[num] <= h->pts[num - 1], "invalid timebase or timecode for frame %d\n", num ) } free( timecodes ); @@ -386,11 +342,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c int ret = 0; FILE *tcfile_in; timecode_hnd_t *h = malloc( sizeof(timecode_hnd_t) ); - if( !h ) - { - fprintf( stderr, "timecode [error]: malloc failed\n" ); - return -1; - } + FAIL_IF_ERROR( !h, "malloc failed\n" ) h->input = input; h->p_handle = *p_handle; h->frame_total = input.get_frame_total( h->p_handle ); @@ -400,11 +352,8 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c ret = sscanf( opt->timebase, "%"SCNu64"/%"SCNu64, &h->timebase_num, &h->timebase_den ); if( ret == 1 ) h->timebase_num = strtoul( opt->timebase, NULL, 10 ); - if( h->timebase_num > UINT32_MAX || h->timebase_den > UINT32_MAX ) - { - fprintf( stderr, "timecode [error]: timebase you specified exceeds H.264 maximum\n" ); - return -1; - } + FAIL_IF_ERROR( h->timebase_num > UINT32_MAX || h->timebase_den > UINT32_MAX, + "timebase you specified exceeds H.264 maximum\n" ) } h->auto_timebase_num = !ret; h->auto_timebase_den = ret < 2; @@ -418,14 +367,10 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c *p_handle = h; tcfile_in = fopen( psz_filename, "rb" ); - if( !tcfile_in ) - { - fprintf( stderr, "timecode [error]: can't open `%s'\n", psz_filename ); - return -1; - } + FAIL_IF_ERROR( !tcfile_in, "can't open `%s'\n", psz_filename ) else if( !x264_is_regular_file( tcfile_in ) ) { - fprintf( stderr, "timecode [error]: tcfile input incompatible with non-regular file `%s'\n", psz_filename ); + x264_cli_log( "timecode", X264_LOG_ERROR, "tcfile input incompatible with non-regular file `%s'\n", psz_filename ); fclose( tcfile_in ); return -1; } @@ -466,8 +411,8 @@ static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame ) { if( h->pts ) { - fprintf( stderr, "timecode [info]: input timecode file missing data for frame %d and later\n" - " assuming constant fps %.6f\n", i_frame, h->assume_fps ); + x264_cli_log( "timecode", X264_LOG_INFO, "input timecode file missing data for frame %d and later\n" + " assuming constant fps %.6f\n", i_frame, h->assume_fps ); free( h->pts ); h->pts = NULL; } diff --git a/input/y4m.c b/input/y4m.c index fd421402..9b39d2f7 100644 --- a/input/y4m.c +++ b/input/y4m.c @@ -21,7 +21,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "input.h" +#define FAIL_IF_ERROR( cond, ... ) FAIL_IF_ERR( cond, "y4m", __VA_ARGS__ ) typedef struct { @@ -162,11 +163,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c if( colorspace == X264_CSP_NONE ) colorspace = X264_CSP_I420; - if( colorspace != X264_CSP_I420 ) - { - fprintf( stderr, "y4m [error]: colorspace unhandled\n" ); - return -1; - } + FAIL_IF_ERROR( colorspace != X264_CSP_I420, "colorspace unhandled\n" ) *p_handle = h; return 0; @@ -202,21 +199,13 @@ static int read_frame_internal( x264_picture_t *p_pic, y4m_hnd_t *h ) return -1; header[slen] = 0; - if( strncmp( header, Y4M_FRAME_MAGIC, slen ) ) - { - fprintf( stderr, "y4m [error]: bad header magic (%"PRIx32" <=> %s)\n", - M32(header), header ); - return -1; - } + FAIL_IF_ERROR( strncmp( header, Y4M_FRAME_MAGIC, slen ), "bad header magic (%"PRIx32" <=> %s)\n", + M32(header), header ) /* Skip most of it */ while( i < MAX_FRAME_HEADER && fgetc( h->fh ) != '\n' ) i++; - if( i == MAX_FRAME_HEADER ) - { - fprintf( stderr, "y4m [error]: bad frame header!\n" ); - return -1; - } + FAIL_IF_ERROR( i == MAX_FRAME_HEADER, "bad frame header!\n" ) h->frame_header_len = i+slen+1; if( fread( p_pic->img.plane[0], h->width * h->height, 1, h->fh ) <= 0 diff --git a/input/yuv.c b/input/yuv.c index cbed7fc0..613662c7 100644 --- a/input/yuv.c +++ b/input/yuv.c @@ -21,7 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "input.h" typedef struct { @@ -45,11 +45,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c } else sscanf( opt->resolution, "%ux%u", &info->width, &info->height ); - if( !info->width || !info->height ) - { - fprintf( stderr, "yuv [error]: rawyuv input requires a resolution.\n" ); - return -1; - } + FAIL_IF_ERR( !info->width || !info->height, "yuv", "rawyuv input requires a resolution.\n" ) h->next_frame = 0; info->vfr = 0; diff --git a/output/flv.c b/output/flv.c index e441b6d4..9831a5b4 100644 --- a/output/flv.c +++ b/output/flv.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "output.h" #include "flv_bytestream.h" #define CHECK(x)\ @@ -223,14 +223,14 @@ static int write_frame( hnd_t handle, uint8_t *p_nalu, int i_size, x264_picture_ if( prev_dts == dts ) { double fps = ((double)p_flv->i_timebase_den / p_flv->i_timebase_num) / (p_picture->i_dts - p_flv->i_prev_dts); - fprintf( stderr, "flv [warning]: duplicate DTS %"PRId64" generated by rounding\n" - " current internal decoding framerate: %.6f fps\n", dts, fps ); + x264_cli_log( "flv", X264_LOG_WARNING, "duplicate DTS %"PRId64" generated by rounding\n" + " current internal decoding framerate: %.6f fps\n", dts, fps ); } if( prev_cts == cts ) { double fps = ((double)p_flv->i_timebase_den / p_flv->i_timebase_num) / (p_picture->i_pts - p_flv->i_prev_pts); - fprintf( stderr, "flv [warning]: duplicate CTS %"PRId64" generated by rounding\n" - " current internal composition framerate: %.6f fps\n", cts, fps ); + x264_cli_log( "flv", X264_LOG_WARNING, "duplicate CTS %"PRId64" generated by rounding\n" + " current internal composition framerate: %.6f fps\n", cts, fps ); } } p_flv->i_prev_dts = p_picture->i_dts; diff --git a/output/flv_bytestream.c b/output/flv_bytestream.c index 316114c8..e02476cd 100644 --- a/output/flv_bytestream.c +++ b/output/flv_bytestream.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "output.h" #include "flv_bytestream.h" uint64_t dbl2int( double value ) diff --git a/output/matroska.c b/output/matroska.c index 0304c847..a1219d07 100644 --- a/output/matroska.c +++ b/output/matroska.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "output.h" #include "matroska_ebml.h" typedef struct diff --git a/output/matroska_ebml.c b/output/matroska_ebml.c index 31b62f89..adfcaa85 100644 --- a/output/matroska_ebml.c +++ b/output/matroska_ebml.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "output.h" #include "matroska_ebml.h" #define CLSIZE 1048576 diff --git a/output/mp4.c b/output/mp4.c index 0e3c2fc1..f2ff5bed 100644 --- a/output/mp4.c +++ b/output/mp4.c @@ -21,7 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "output.h" #include #if HAVE_GF_MALLOC @@ -61,12 +61,12 @@ static void recompute_bitrate_mp4( GF_ISOFile *p_file, int i_track ) timescale = gf_isom_get_media_timescale( p_file, i_track ); count = gf_isom_get_sample_count( p_file, i_track ); - for( int i = 0; i < count; i++ ) + for( u32 i = 0; i < count; i++ ) { GF_ISOSample *samp = gf_isom_get_sample_info( p_file, i_track, i+1, &di, &offset ); if( !samp ) { - fprintf( stderr, "mp4 [error]: failure reading back frame %u\n", i ); + x264_cli_log( "mp4", X264_LOG_ERROR, "failure reading back frame %u\n", i ); break; } @@ -163,11 +163,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle ) FILE *fh = fopen( psz_filename, "w" ); if( !fh ) return -1; - else if( !x264_is_regular_file( fh ) ) - { - fprintf( stderr, "mp4 [error]: MP4 output is incompatible with non-regular file `%s'\n", psz_filename ); - return -1; - } + FAIL_IF_ERR( !x264_is_regular_file( fh ), "mp4", "MP4 output is incompatible with non-regular file `%s'\n", psz_filename ) fclose( fh ); if( !(p_mp4 = malloc( sizeof(mp4_hnd_t) )) ) diff --git a/output/output.h b/output/output.h index c79b48e4..094fefcf 100644 --- a/output/output.h +++ b/output/output.h @@ -24,6 +24,8 @@ #ifndef X264_OUTPUT_H #define X264_OUTPUT_H +#include "x264cli.h" + typedef struct { int (*open_file)( char *psz_filename, hnd_t *p_handle ); diff --git a/output/raw.c b/output/raw.c index 02e4c56a..fc418fb4 100644 --- a/output/raw.c +++ b/output/raw.c @@ -21,7 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#include "muxers.h" +#include "output.h" static int open_file( char *psz_filename, hnd_t *p_handle ) { diff --git a/x264.c b/x264.c index f08ab416..741570c7 100644 --- a/x264.c +++ b/x264.c @@ -31,9 +31,11 @@ #include #include "common/common.h" -#include "common/cpu.h" -#include "x264.h" -#include "muxers.h" +#include "x264cli.h" +#include "input/input.h" +#include "output/output.h" + +#define FAIL_IF_ERROR( cond, ... ) FAIL_IF_ERR( cond, "x264", __VA_ARGS__ ) #ifdef _WIN32 #include @@ -96,6 +98,7 @@ static const char * const muxer_names[] = }; static const char * const pulldown_names[] = { "none", "22", "32", "64", "double", "triple", "euro", 0 }; +static const char * const log_level_names[] = { "none", "error", "warning", "info", "debug", 0 }; typedef struct{ int mod; @@ -141,6 +144,48 @@ static void Help( x264_param_t *defaults, int longhelp ); static int Parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt ); static int Encode( x264_param_t *param, cli_opt_t *opt ); +/* logging and printing for within the cli system */ +static int cli_log_level; +void x264_cli_log( const char *name, int i_level, const char *fmt, ... ) +{ + if( i_level > cli_log_level ) + return; + char *s_level; + switch( i_level ) + { + case X264_LOG_ERROR: + s_level = "error"; + break; + case X264_LOG_WARNING: + s_level = "warning"; + break; + case X264_LOG_INFO: + s_level = "info"; + break; + case X264_LOG_DEBUG: + s_level = "debug"; + break; + default: + s_level = "unknown"; + break; + } + fprintf( stderr, "%s [%s]: ", name, s_level ); + va_list arg; + va_start( arg, fmt ); + vfprintf( stderr, fmt, arg ); + va_end( arg ); +} + +void x264_cli_printf( int i_level, const char *fmt, ... ) +{ + if( i_level > cli_log_level ) + return; + va_list arg; + va_start( arg, fmt ); + vfprintf( stderr, fmt, arg ); + va_end( arg ); +} + /**************************************************************************** * main: ****************************************************************************/ @@ -571,6 +616,9 @@ static void Help( x264_param_t *defaults, int longhelp ) H1( " -v, --verbose Print stats for each frame\n" ); 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 ) ); H1( " --psnr Enable PSNR computation\n" ); H1( " --ssim Enable SSIM computation\n" ); H1( " --threads Force a specific number of threads\n" ); @@ -616,6 +664,7 @@ enum { OPT_TCFILE_OUT, OPT_TIMEBASE, OPT_PULLDOWN, + OPT_LOG_LEVEL } OptionsOPT; static char short_options[] = "8A:B:b:f:hI:i:m:o:p:q:r:t:Vvw"; @@ -729,6 +778,7 @@ static struct option long_options[] = { "ssim", no_argument, NULL, 0 }, { "quiet", no_argument, NULL, OPT_QUIET }, { "verbose", no_argument, NULL, 'v' }, + { "log-level", required_argument, NULL, OPT_LOG_LEVEL }, { "no-progress", no_argument, NULL, OPT_NOPROGRESS }, { "visualize", no_argument, NULL, OPT_VISUALIZE }, { "dump-yuv", required_argument, NULL, 0 }, @@ -780,11 +830,11 @@ static int select_output( const char *muxer, char *filename, x264_param_t *param param->b_repeat_headers = 0; if( param->i_nal_hrd == X264_NAL_HRD_CBR ) { - fprintf( stderr, "x264 [warning]: cbr nal-hrd is not compatible with mp4\n" ); + x264_cli_log( "x264", X264_LOG_WARNING, "cbr nal-hrd is not compatible with mp4\n" ); param->i_nal_hrd = X264_NAL_HRD_VBR; } #else - fprintf( stderr, "x264 [error]: not compiled with MP4 output support\n" ); + x264_cli_log( "x264", X264_LOG_ERROR, "not compiled with MP4 output support\n" ); return -1; #endif } @@ -833,7 +883,7 @@ static int select_input( const char *demuxer, char *used_demuxer, char *filename input = avs_input; module = "avs"; #else - fprintf( stderr, "x264 [error]: not compiled with AVS input support\n" ); + x264_cli_log( "x264", X264_LOG_ERROR, "not compiled with AVS input support\n" ); return -1; #endif } @@ -877,11 +927,7 @@ static int select_input( const char *demuxer, char *used_demuxer, char *filename input = yuv_input; } - if( !(*p_handle) ) - { - fprintf( stderr, "x264 [error]: could not open input file `%s' via any method!\n", filename ); - return -1; - } + FAIL_IF_ERROR( !(*p_handle), "could not open input file `%s' via any method!\n", filename ) } strcpy( used_demuxer, module ); @@ -932,6 +978,7 @@ static int Parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt ) char *tune = NULL; x264_param_default( &defaults ); + cli_log_level = defaults.i_log_level; memset( opt, 0, sizeof(cli_opt_t) ); memset( &input_opt, 0, sizeof(cli_input_opt_t) ); @@ -1004,32 +1051,20 @@ static int Parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt ) output_filename = optarg; break; case OPT_MUXER: - if( parse_enum_name( optarg, muxer_names, &muxer ) < 0 ) - { - fprintf( stderr, "x264 [error]: Unknown muxer `%s'\n", optarg ); - return -1; - } + FAIL_IF_ERROR( parse_enum_name( optarg, muxer_names, &muxer ), "Unknown muxer `%s'\n", optarg ) break; case OPT_DEMUXER: - if( parse_enum_name( optarg, demuxer_names, &demuxer ) < 0 ) - { - fprintf( stderr, "x264 [error]: Unknown demuxer `%s'\n", optarg ); - return -1; - } + FAIL_IF_ERROR( parse_enum_name( optarg, demuxer_names, &demuxer ), "Unknown demuxer `%s'\n", optarg ) break; case OPT_INDEX: input_opt.index_file = optarg; break; case OPT_QPFILE: opt->qpfile = fopen( optarg, "rb" ); - if( !opt->qpfile ) - { - fprintf( stderr, "x264 [error]: can't open qpfile `%s'\n", optarg ); - return -1; - } - else if( !x264_is_regular_file( opt->qpfile ) ) + FAIL_IF_ERROR( !opt->qpfile, "can't open qpfile `%s'\n", optarg ) + if( !x264_is_regular_file( opt->qpfile ) ) { - fprintf( stderr, "x264 [error]: qpfile incompatible with non-regular file `%s'\n", optarg ); + x264_cli_log( "x264", X264_LOG_ERROR, "qpfile incompatible with non-regular file `%s'\n", optarg ); fclose( opt->qpfile ); return -1; } @@ -1038,11 +1073,17 @@ static int Parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt ) b_thread_input = 1; break; case OPT_QUIET: - param->i_log_level = X264_LOG_NONE; + cli_log_level = param->i_log_level = X264_LOG_NONE; break; case 'v': - param->i_log_level = X264_LOG_DEBUG; + 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 ) ) + cli_log_level += X264_LOG_NONE; + else + cli_log_level = atoi( optarg ); + param->i_log_level = cli_log_level; case OPT_NOPROGRESS: opt->b_progress = 0; break; @@ -1051,7 +1092,7 @@ static int Parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt ) param->b_visualize = 1; b_exit_on_ctrl_c = 1; #else - fprintf( stderr, "x264 [warning]: not compiled with visualization support\n" ); + x264_cli_log( "x264", X264_LOG_WARNING, "not compiled with visualization support\n" ); #endif break; case OPT_TUNE: @@ -1078,18 +1119,13 @@ static int Parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt ) break; case OPT_TCFILE_OUT: opt->tcfile_out = fopen( optarg, "wb" ); - if( !opt->tcfile_out ) - { - fprintf( stderr, "x264 [error]: can't open `%s'\n", optarg ); - return -1; - } + FAIL_IF_ERROR( !opt->tcfile_out, "can't open `%s'\n", optarg ) break; case OPT_TIMEBASE: input_opt.timebase = optarg; break; case OPT_PULLDOWN: - if( parse_enum_value( optarg, pulldown_names, &opt->i_pulldown ) < 0 ) - return -1; + FAIL_IF_ERROR( parse_enum_value( optarg, pulldown_names, &opt->i_pulldown ), "Unknown pulldown `%s'\n", optarg ) break; default: generic_option: @@ -1116,7 +1152,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 ); + x264_cli_log( "x264", X264_LOG_ERROR, "invalid argument: %s = %s\n", name, optarg ); return -1; } } @@ -1130,20 +1166,12 @@ generic_option: return -1; /* 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", - optind > argc - 1 ? "input" : "output" ); - return -1; - } + FAIL_IF_ERROR( optind > argc - 1 || !output_filename, "No %s file. Run x264 --help for a list of options.\n", + optind > argc - 1 ? "input" : "output" ) if( select_output( muxer, output_filename, param ) ) return -1; - if( output.open_file( output_filename, &opt->hout ) ) - { - fprintf( stderr, "x264 [error]: could not open output file `%s'\n", output_filename ); - return -1; - } + FAIL_IF_ERROR( output.open_file( output_filename, &opt->hout ), "could not open output file `%s'\n", output_filename ) input_filename = argv[optind++]; input_opt.resolution = optind < argc ? argv[optind++] : NULL; @@ -1163,39 +1191,22 @@ generic_option: if( select_input( demuxer, demuxername, input_filename, &opt->hin, &info, &input_opt ) ) return -1; - if( !opt->hin && input.open_file( input_filename, &opt->hin, &info, &input_opt ) ) - { - fprintf( stderr, "x264 [error]: could not open input file `%s'\n", input_filename ); - return -1; - } + FAIL_IF_ERROR( !opt->hin && input.open_file( input_filename, &opt->hin, &info, &input_opt ), + "could not open input file `%s'\n", input_filename ) x264_reduce_fraction( &info.sar_width, &info.sar_height ); x264_reduce_fraction( &info.fps_num, &info.fps_den ); - if( param->i_log_level >= X264_LOG_INFO ) - fprintf( stderr, "%s [info]: %dx%d%c %d:%d @ %d/%d fps (%cfr)\n", demuxername, info.width, - info.height, info.interlaced ? 'i' : 'p', info.sar_width, info.sar_height, - info.fps_num, info.fps_den, info.vfr ? 'v' : 'c' ); + x264_cli_log( demuxername, X264_LOG_INFO, "%dx%d%c %d:%d @ %d/%d fps (%cfr)\n", info.width, + info.height, info.interlaced ? 'i' : 'p', info.sar_width, info.sar_height, + info.fps_num, info.fps_den, info.vfr ? 'v' : 'c' ); if( tcfile_name ) { - if( b_user_fps ) - { - fprintf( stderr, "x264 [error]: --fps + --tcfile-in is incompatible.\n" ); - return -1; - } - if( timecode_input.open_file( tcfile_name, &opt->hin, &info, &input_opt ) ) - { - fprintf( stderr, "x264 [error]: timecode input failed\n" ); - return -1; - } - else - input = timecode_input; - } - else if( !info.vfr && input_opt.timebase ) - { - fprintf( stderr, "x264 [error]: --timebase is incompatible with cfr input\n" ); - return -1; + FAIL_IF_ERROR( b_user_fps, "--fps + --tcfile-in is incompatible.\n" ) + FAIL_IF_ERROR( timecode_input.open_file( tcfile_name, &opt->hin, &info, &input_opt ), "timecode input failed\n" ) + input = timecode_input; } + else FAIL_IF_ERROR( !info.vfr && input_opt.timebase, "--timebase is incompatible with cfr input\n" ) /* set param flags from the info flags as necessary */ param->i_csp = info.csp; @@ -1204,9 +1215,9 @@ generic_option: param->i_width = info.width; if( !b_user_interlaced && info.interlaced ) { - fprintf( stderr, "x264 [warning]: input appears to be interlaced, enabling %cff interlaced mode.\n" - " If you want otherwise, use --no-interlaced or --%cff\n", - info.tff ? 't' : 'b', info.tff ? 'b' : 't' ); + x264_cli_log( "x264", X264_LOG_WARNING, "input appears to be interlaced, enabling %cff interlaced mode.\n" + " If you want otherwise, use --no-interlaced or --%cff\n", + info.tff ? 't' : 'b', info.tff ? 'b' : 't' ); param->b_interlaced = 1; param->b_tff = !!info.tff; } @@ -1230,21 +1241,14 @@ generic_option: uint64_t i_user_timebase_num; uint64_t i_user_timebase_den; int ret = sscanf( input_opt.timebase, "%"SCNu64"/%"SCNu64, &i_user_timebase_num, &i_user_timebase_den ); - if( !ret ) - { - fprintf( stderr, "x264 [error]: invalid argument: timebase = %s\n", input_opt.timebase ); - return -1; - } + FAIL_IF_ERROR( !ret, "invalid argument: timebase = %s\n", input_opt.timebase ) else if( ret == 1 ) { i_user_timebase_num = param->i_timebase_num; i_user_timebase_den = strtoul( input_opt.timebase, NULL, 10 ); } - if( i_user_timebase_num > UINT32_MAX || i_user_timebase_den > UINT32_MAX ) - { - fprintf( stderr, "x264 [error]: timebase you specified exceeds H.264 maximum\n" ); - return -1; - } + FAIL_IF_ERROR( i_user_timebase_num > UINT32_MAX || i_user_timebase_den > UINT32_MAX, + "timebase you specified exceeds H.264 maximum\n" ) opt->timebase_convert_multiplier = ((double)i_user_timebase_den / param->i_timebase_den) * ((double)param->i_timebase_num / i_user_timebase_num); param->i_timebase_num = i_user_timebase_num; @@ -1261,13 +1265,8 @@ generic_option: if( b_thread_input || param->i_threads > 1 || (param->i_threads == X264_THREADS_AUTO && x264_cpu_num_processors() > 1) ) { - if( thread_input.open_file( NULL, &opt->hin, &info, NULL ) ) - { - fprintf( stderr, "x264 [error]: threaded input failed\n" ); - return -1; - } - else - input = thread_input; + FAIL_IF_ERROR( thread_input.open_file( NULL, &opt->hin, &info, NULL ), "threaded input failed\n" ) + input = thread_input; } #endif @@ -1321,7 +1320,7 @@ static void parse_qpfile( cli_opt_t *opt, x264_picture_t *pic, int i_frame ) else ret = 0; if( ret != 3 || qp < -1 || qp > 51 ) { - fprintf( stderr, "x264 [error]: can't parse qpfile for frame %d\n", i_frame ); + x264_cli_log( "x264", X264_LOG_ERROR, "can't parse qpfile for frame %d\n", i_frame ); fclose( opt->qpfile ); opt->qpfile = NULL; pic->i_type = X264_TYPE_AUTO; @@ -1344,11 +1343,7 @@ static int Encode_frame( x264_t *h, hnd_t hout, x264_picture_t *pic, int64_t *l i_frame_size = x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out ); - if( i_frame_size < 0 ) - { - fprintf( stderr, "x264 [error]: x264_encoder_encode failed\n" ); - return -1; - } + FAIL_IF_ERROR( i_frame_size < 0, "x264_encoder_encode failed\n" ); if( i_frame_size ) { @@ -1424,17 +1419,14 @@ static int Encode( x264_param_t *param, cli_opt_t *opt ) param->b_pic_struct = 1; pulldown = &pulldown_values[opt->i_pulldown]; param->i_timebase_num = param->i_fps_den; - if( fmod( param->i_fps_num * pulldown->fps_factor, 1 ) ) - { - fprintf( stderr, "x264 [error]: unsupported framerate for chosen pulldown\n" ); - return -1; - } + FAIL_IF_ERROR( fmod( param->i_fps_num * pulldown->fps_factor, 1 ), + "unsupported framerate for chosen pulldown\n" ) param->i_timebase_den = param->i_fps_num * pulldown->fps_factor; } if( ( h = x264_encoder_open( param ) ) == NULL ) { - fprintf( stderr, "x264 [error]: x264_encoder_open failed\n" ); + x264_cli_log( "x264", X264_LOG_ERROR, "x264_encoder_open failed\n" ); input.close_file( opt->hin ); return -1; } @@ -1445,27 +1437,19 @@ static int Encode( x264_param_t *param, cli_opt_t *opt ) if( output.set_param( opt->hout, param ) ) { - fprintf( stderr, "x264 [error]: can't set outfile param\n" ); + x264_cli_log( "x264", X264_LOG_ERROR, "can't set outfile param\n" ); input.close_file( opt->hin ); output.close_file( opt->hout, largest_pts, second_largest_pts ); 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" ); - return -1; - } + FAIL_IF_ERROR( input.picture_alloc( &pic, param->i_csp, param->i_width, param->i_height ), "malloc failed\n" ) i_start = x264_mdate(); /* ticks/frame = ticks/second / frames/second */ ticks_per_frame = (int64_t)param->i_timebase_den * param->i_fps_den / param->i_timebase_num / param->i_fps_num; - if( ticks_per_frame < 1 ) - { - fprintf( stderr, "x264 [error]: ticks_per_frame invalid: %"PRId64"\n", ticks_per_frame ); - return -1; - } + FAIL_IF_ERROR( ticks_per_frame < 1, "ticks_per_frame invalid: %"PRId64"\n", ticks_per_frame ) if( !param->b_repeat_headers ) { @@ -1473,12 +1457,7 @@ static int Encode( x264_param_t *param, cli_opt_t *opt ) x264_nal_t *headers; int i_nal; - if( x264_encoder_headers( h, &headers, &i_nal ) < 0 ) - { - fprintf( stderr, "x264 [error]: x264_encoder_headers failed\n" ); - return -1; - } - + FAIL_IF_ERROR( x264_encoder_headers( h, &headers, &i_nal ) < 0, "x264_encoder_headers failed\n" ) if( (i_file = output.write_headers( opt->hout, headers )) < 0 ) return -1; } @@ -1508,15 +1487,12 @@ static int Encode( x264_param_t *param, cli_opt_t *opt ) if( pic.i_pts <= largest_pts ) { - if( param->i_log_level >= X264_LOG_WARNING ) - { - if( param->i_log_level >= X264_LOG_DEBUG || pts_warning_cnt < MAX_PTS_WARNING ) - fprintf( stderr, "x264 [warning]: non-strictly-monotonic pts at frame %d (%"PRId64" <= %"PRId64")\n", + if( cli_log_level >= X264_LOG_DEBUG || pts_warning_cnt < MAX_PTS_WARNING ) + x264_cli_log( "x264", X264_LOG_WARNING, "non-strictly-monotonic pts at frame %d (%"PRId64" <= %"PRId64")\n", i_frame, output_pts, largest_pts * dts_compress_multiplier ); - else if( pts_warning_cnt == MAX_PTS_WARNING ) - fprintf( stderr, "x264 [warning]: too many nonmonotonic pts warnings, suppressing further ones\n" ); - pts_warning_cnt++; - } + else if( pts_warning_cnt == MAX_PTS_WARNING ) + x264_cli_log( "x264", X264_LOG_WARNING, "too many nonmonotonic pts warnings, suppressing further ones\n" ); + pts_warning_cnt++; pic.i_pts = largest_pts + ticks_per_frame; output_pts = pic.i_pts * dts_compress_multiplier; } @@ -1573,8 +1549,8 @@ static int Encode( x264_param_t *param, cli_opt_t *opt ) if( opt->b_progress && i_frame_output % i_update_interval == 0 && i_frame_output ) Print_status( i_start, i_frame_output, i_frame_total, i_file, param, 2 * last_dts - prev_dts - first_dts ); } - if( pts_warning_cnt >= MAX_PTS_WARNING && param->i_log_level < X264_LOG_DEBUG ) - fprintf( stderr, "x264 [warning]: %d suppressed nonmonotonic pts warnings\n", pts_warning_cnt-MAX_PTS_WARNING ); + if( pts_warning_cnt >= MAX_PTS_WARNING && cli_log_level < X264_LOG_DEBUG ) + x264_cli_log( "x264", X264_LOG_WARNING, "%d suppressed nonmonotonic pts warnings\n", pts_warning_cnt-MAX_PTS_WARNING ); /* duration algorithm fails when only 1 frame is output */ if( i_frame_output == 1 ) diff --git a/muxers.h b/x264cli.h similarity index 81% rename from muxers.h rename to x264cli.h index b3093202..1acca561 100644 --- a/muxers.h +++ b/x264cli.h @@ -1,7 +1,7 @@ /***************************************************************************** - * muxers.h: h264 file i/o modules + * x264cli.h: x264cli common ***************************************************************************** - * Copyright (C) 2003-2009 x264 project + * Copyright (C) 2003-2010 x264 project * * Authors: Laurent Aimar * Loren Merritt @@ -21,11 +21,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. *****************************************************************************/ -#ifndef X264_MUXERS_H -#define X264_MUXERS_H +#ifndef X264_CLI_H +#define X264_CLI_H #include "common/common.h" -#include "x264.h" typedef void *hnd_t; @@ -55,7 +54,14 @@ static inline char *get_filename_extension( char *filename ) return ext; } -#include "input/input.h" -#include "output/output.h" +void x264_cli_log( const char *name, int i_level, const char *fmt, ... ); +void x264_cli_printf( int i_level, const char *fmt, ... ); + +#define FAIL_IF_ERR( cond, name, ... )\ +if( cond )\ +{\ + x264_cli_log( name, X264_LOG_ERROR, __VA_ARGS__ );\ + return -1;\ +} #endif