1
mirror of https://code.videolan.org/videolan/x264 synced 2024-11-15 03:32:13 +01:00

Centralize logging within x264cli

x264cli messages will now respect the log level they pertain to.
Slightly reduces binary size.
This commit is contained in:
Steven Walters 2010-06-26 16:28:49 -04:00 committed by Fiona Glaser
parent 899bf0fdb9
commit 43a4334670
17 changed files with 235 additions and 417 deletions

View File

@ -20,8 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
*****************************************************************************/
#include "muxers.h"
#include "input.h"
#include <windows.h>
#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 */

View File

@ -21,8 +21,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
*****************************************************************************/
#include "muxers.h"
#include "input.h"
#include <ffms.h>
#define FAIL_IF_ERROR( cond, ... ) FAIL_IF_ERR( cond, "ffms", __VA_ARGS__ )
#undef DECLARE_ALIGNED
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
@ -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 )
{

View File

@ -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
{

View File

@ -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 <libavformat/avformat.h>
#include <libswscale/swscale.h>
@ -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;

View File

@ -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;

View File

@ -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 <math.h>
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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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 )

View File

@ -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

View File

@ -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

View File

@ -21,7 +21,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
*****************************************************************************/
#include "muxers.h"
#include "output.h"
#include <gpac/isomedia.h>
#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) )) )

View File

@ -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 );

View File

@ -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 )
{

246
x264.c
View File

@ -31,9 +31,11 @@
#include <getopt.h>
#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 <windows.h>
@ -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 <string> 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 <integer> 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 )
FAIL_IF_ERROR( !opt->qpfile, "can't open qpfile `%s'\n", optarg )
if( !x264_is_regular_file( opt->qpfile ) )
{
fprintf( stderr, "x264 [error]: can't open qpfile `%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 );
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 )

View File

@ -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 <fenrir@via.ecp.fr>
* Loren Merritt <lorenm@u.washington.edu>
@ -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