mirror of https://code.videolan.org/videolan/x264
409 lines
10 KiB
C
409 lines
10 KiB
C
/*****************************************************************************
|
|
* autocomplete: x264cli shell autocomplete
|
|
*****************************************************************************
|
|
* Copyright (C) 2018-2024 x264 project
|
|
*
|
|
* Authors: Henrik Gramner <henrik@gramner.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
|
*
|
|
* This program is also available under a commercial proprietary license.
|
|
* For more information, contact us at licensing@x264.com.
|
|
*****************************************************************************/
|
|
|
|
#include "x264cli.h"
|
|
#include "input/input.h"
|
|
|
|
#if HAVE_LAVF
|
|
#undef DECLARE_ALIGNED
|
|
#include <libavformat/avformat.h>
|
|
#include <libavutil/pixdesc.h>
|
|
#endif
|
|
|
|
static const char * const level_names[] =
|
|
{
|
|
"1", "1.1", "1.2", "1.3", "1b",
|
|
"2", "2.1", "2.2",
|
|
"3", "3.1", "3.2",
|
|
"4", "4.1", "4.2",
|
|
"5", "5.1", "5.2",
|
|
"6", "6.1", "6.2",
|
|
NULL
|
|
};
|
|
|
|
/* Options requiring a value for which we provide suggestions. */
|
|
static const char * const opts_suggest[] =
|
|
{
|
|
"--alternative-transfer",
|
|
"--aq-mode",
|
|
"--asm",
|
|
"--avcintra-class",
|
|
"--avcintra-flavor",
|
|
"--b-adapt",
|
|
"--b-pyramid",
|
|
"--colormatrix",
|
|
"--colorprim",
|
|
"--cqm",
|
|
"--demuxer",
|
|
"--direct",
|
|
"--frame-packing",
|
|
"--input-csp",
|
|
"--input-fmt",
|
|
"--input-range",
|
|
"--level",
|
|
"--log-level",
|
|
"--me",
|
|
"--muxer",
|
|
"--nal-hrd",
|
|
"--output-csp",
|
|
"--overscan",
|
|
"--pass", "-p",
|
|
"--preset",
|
|
"--profile",
|
|
"--pulldown",
|
|
"--range",
|
|
"--subme", "-m",
|
|
"--transfer",
|
|
"--trellis", "-t",
|
|
"--tune",
|
|
"--videoformat",
|
|
"--weightp",
|
|
NULL
|
|
};
|
|
|
|
/* Options requiring a value for which we don't provide suggestions. */
|
|
static const char * const opts_nosuggest[] =
|
|
{
|
|
"--b-bias",
|
|
"--bframes", "-b",
|
|
"--deblock", "-f",
|
|
"--bitrate", "-B",
|
|
"--chroma-qp-offset",
|
|
"--chromaloc",
|
|
"--cplxblur",
|
|
"--cqm4",
|
|
"--cqm4i",
|
|
"--cqm4ic",
|
|
"--cqm4iy",
|
|
"--cqm4p",
|
|
"--cqm4pc",
|
|
"--cqm4py",
|
|
"--cqm8",
|
|
"--cqm8i",
|
|
"--cqm8p",
|
|
"--crf",
|
|
"--crf-max",
|
|
"--crop-rect",
|
|
"--deadzone-inter",
|
|
"--deadzone-intra",
|
|
"--fps",
|
|
"--frames",
|
|
"--input-depth",
|
|
"--input-res",
|
|
"--ipratio",
|
|
"--keyint", "-I",
|
|
"--lookahead-threads",
|
|
"--mastering-display",
|
|
"--cll",
|
|
"--merange",
|
|
"--min-keyint", "-i",
|
|
"--mvrange",
|
|
"--mvrange-thread",
|
|
"--nr",
|
|
"--opencl-device",
|
|
"--output-depth",
|
|
"--partitions", "-A",
|
|
"--pbratio",
|
|
"--psy-rd",
|
|
"--qblur",
|
|
"--qcomp",
|
|
"--qp", "-q",
|
|
"--qpmax",
|
|
"--qpmin",
|
|
"--qpstep",
|
|
"--ratetol",
|
|
"--ref", "-r",
|
|
"--rc-lookahead",
|
|
"--sar",
|
|
"--scenecut",
|
|
"--seek",
|
|
"--slices",
|
|
"--slices-max",
|
|
"--slice-max-size",
|
|
"--slice-max-mbs",
|
|
"--slice-min-mbs",
|
|
"--sps-id",
|
|
"--sync-lookahead",
|
|
"--threads",
|
|
"--timebase",
|
|
"--vbv-bufsize",
|
|
"--vbv-init",
|
|
"--vbv-maxrate",
|
|
"--video-filter", "--vf",
|
|
"--zones",
|
|
NULL
|
|
};
|
|
|
|
/* Options requiring a filename. */
|
|
static const char * const opts_filename[] =
|
|
{
|
|
"--cqmfile",
|
|
"--dump-yuv",
|
|
"--index",
|
|
"--opencl-clbin",
|
|
"--output", "-o",
|
|
"--qpfile",
|
|
"--stats",
|
|
"--tcfile-in",
|
|
"--tcfile-out",
|
|
NULL
|
|
};
|
|
|
|
/* Options without an associated value. */
|
|
static const char * const opts_standalone[] =
|
|
{
|
|
"--8x8dct",
|
|
"--aud",
|
|
"--bff",
|
|
"--bluray-compat",
|
|
"--cabac",
|
|
"--constrained-intra",
|
|
"--cpu-independent",
|
|
"--dts-compress",
|
|
"--fake-interlaced",
|
|
"--fast-pskip",
|
|
"--filler",
|
|
"--force-cfr",
|
|
"--mbtree",
|
|
"--mixed-refs",
|
|
"--no-8x8dct",
|
|
"--no-asm",
|
|
"--no-cabac",
|
|
"--no-chroma-me",
|
|
"--no-dct-decimate",
|
|
"--no-deblock",
|
|
"--no-fast-pskip",
|
|
"--no-mbtree",
|
|
"--no-mixed-refs",
|
|
"--no-progress",
|
|
"--no-psy",
|
|
"--no-scenecut",
|
|
"--no-weightb",
|
|
"--non-deterministic",
|
|
"--open-gop",
|
|
"--opencl",
|
|
"--pic-struct",
|
|
"--psnr",
|
|
"--quiet",
|
|
"--sliced-threads",
|
|
"--slow-firstpass",
|
|
"--ssim",
|
|
"--stitchable",
|
|
"--tff",
|
|
"--thread-input",
|
|
"--verbose", "-v",
|
|
"--weightb",
|
|
NULL
|
|
};
|
|
|
|
/* Options which shouldn't be suggested in combination with other options. */
|
|
static const char * const opts_special[] =
|
|
{
|
|
"--fullhelp",
|
|
"--help", "-h",
|
|
"--longhelp",
|
|
"--version",
|
|
NULL
|
|
};
|
|
|
|
static int list_contains( const char * const *list, const char *s )
|
|
{
|
|
if( *s )
|
|
for( ; *list; list++ )
|
|
if( !strcmp( *list, s ) )
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
static void suggest( const char *s, const char *cur, int cur_len )
|
|
{
|
|
if( s && *s && !strncmp( s, cur, cur_len ) )
|
|
printf( "%s ", s );
|
|
}
|
|
|
|
static void suggest_lower( const char *s, const char *cur, int cur_len )
|
|
{
|
|
if( s && *s && !strncasecmp( s, cur, cur_len ) )
|
|
{
|
|
for( ; *s; s++ )
|
|
putchar( *s < 'A' || *s > 'Z' ? *s : *s | 0x20 );
|
|
putchar( ' ' );
|
|
}
|
|
}
|
|
|
|
static void suggest_num_range( int start, int end, const char *cur, int cur_len )
|
|
{
|
|
char buf[16];
|
|
for( int i = start; i <= end; i++ )
|
|
{
|
|
snprintf( buf, sizeof( buf ), "%d", i );
|
|
suggest( buf, cur, cur_len );
|
|
}
|
|
}
|
|
|
|
#if HAVE_LAVF
|
|
/* Suggest each token in a string separated by delimiters. */
|
|
static void suggest_token( const char *s, int delim, const char *cur, int cur_len )
|
|
{
|
|
if( s && *s )
|
|
{
|
|
for( const char *tok_end; (tok_end = strchr( s, delim )); s = tok_end + 1 )
|
|
{
|
|
int tok_len = tok_end - s;
|
|
if( tok_len && tok_len >= cur_len && !strncmp( s, cur, cur_len ) )
|
|
printf( "%.*s ", tok_len, s );
|
|
}
|
|
suggest( s, cur, cur_len );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#define OPT( opt ) else if( !strcmp( prev, opt ) )
|
|
#define OPT2( opt1, opt2 ) else if( !strcmp( prev, opt1 ) || !strcmp( prev, opt2 ) )
|
|
#define OPT_TYPE( type ) list_contains( opts_##type, prev )
|
|
|
|
#define suggest( s ) suggest( s, cur, cur_len )
|
|
#define suggest_lower( s ) suggest_lower( s, cur, cur_len )
|
|
#define suggest_list( list ) for( const char * const *s = list; *s; s++ ) suggest( *s )
|
|
#define suggest_num_range( start, end ) suggest_num_range( start, end, cur, cur_len )
|
|
#define suggest_token( s, delim ) suggest_token( s, delim, cur, cur_len )
|
|
|
|
int x264_cli_autocomplete( const char *prev, const char *cur )
|
|
{
|
|
int cur_len = strlen( cur );
|
|
if( 0 );
|
|
OPT( "--alternative-transfer" )
|
|
suggest_list( x264_transfer_names );
|
|
OPT( "--aq-mode" )
|
|
suggest_num_range( 0, 3 );
|
|
OPT( "--asm" )
|
|
for( const x264_cpu_name_t *cpu = x264_cpu_names; cpu->flags; cpu++ )
|
|
suggest_lower( cpu->name );
|
|
OPT( "--avcintra-class" )
|
|
suggest_list( x264_avcintra_class_names );
|
|
OPT( "--avcintra-flavor" )
|
|
suggest_list( x264_avcintra_flavor_names );
|
|
OPT( "--b-adapt" )
|
|
suggest_num_range( 0, 2 );
|
|
OPT( "--b-pyramid" )
|
|
suggest_list( x264_b_pyramid_names );
|
|
OPT( "--colormatrix" )
|
|
suggest_list( x264_colmatrix_names );
|
|
OPT( "--colorprim" )
|
|
suggest_list( x264_colorprim_names );
|
|
OPT( "--cqm" )
|
|
suggest_list( x264_cqm_names );
|
|
OPT( "--demuxer" )
|
|
suggest_list( x264_demuxer_names );
|
|
OPT( "--direct" )
|
|
suggest_list( x264_direct_pred_names );
|
|
OPT( "--frame-packing" )
|
|
suggest_num_range( 0, 7 );
|
|
OPT( "--input-csp" )
|
|
{
|
|
for( int i = X264_CSP_NONE+1; i < X264_CSP_CLI_MAX; i++ )
|
|
suggest( x264_cli_csps[i].name );
|
|
#if HAVE_LAVF
|
|
for( const AVPixFmtDescriptor *d = NULL; (d = av_pix_fmt_desc_next( d )); )
|
|
suggest( d->name );
|
|
#endif
|
|
}
|
|
OPT( "--input-fmt" )
|
|
{
|
|
#if HAVE_LAVF
|
|
void *i = NULL;
|
|
for( const AVInputFormat *f; (f = av_demuxer_iterate( &i )); )
|
|
suggest_token( f->name, ',' );
|
|
#endif
|
|
}
|
|
OPT( "--input-range" )
|
|
suggest_list( x264_range_names );
|
|
OPT( "--level" )
|
|
suggest_list( level_names );
|
|
OPT( "--log-level" )
|
|
suggest_list( x264_log_level_names );
|
|
OPT( "--me" )
|
|
suggest_list( x264_motion_est_names );
|
|
OPT( "--muxer" )
|
|
suggest_list( x264_muxer_names );
|
|
OPT( "--nal-hrd" )
|
|
suggest_list( x264_nal_hrd_names );
|
|
OPT( "--output-csp" )
|
|
suggest_list( x264_output_csp_names );
|
|
OPT( "--output-depth" )
|
|
{
|
|
#if HAVE_BITDEPTH8
|
|
suggest( "8" );
|
|
#endif
|
|
#if HAVE_BITDEPTH10
|
|
suggest( "10" );
|
|
#endif
|
|
}
|
|
OPT( "--overscan" )
|
|
suggest_list( x264_overscan_names );
|
|
OPT2( "--partitions", "-A" )
|
|
suggest_list( x264_partition_names );
|
|
OPT2( "--pass", "-p" )
|
|
suggest_num_range( 1, 3 );
|
|
OPT( "--preset" )
|
|
suggest_list( x264_preset_names );
|
|
OPT( "--profile" )
|
|
suggest_list( x264_valid_profile_names );
|
|
OPT( "--pulldown" )
|
|
suggest_list( x264_pulldown_names );
|
|
OPT( "--range" )
|
|
suggest_list( x264_range_names );
|
|
OPT2( "--subme", "-m" )
|
|
suggest_num_range( 0, 11 );
|
|
OPT( "--transfer" )
|
|
suggest_list( x264_transfer_names );
|
|
OPT2( "--trellis", "-t" )
|
|
suggest_num_range( 0, 2 );
|
|
OPT( "--tune" )
|
|
suggest_list( x264_tune_names );
|
|
OPT( "--videoformat" )
|
|
suggest_list( x264_vidformat_names );
|
|
OPT( "--weightp" )
|
|
suggest_num_range( 0, 2 );
|
|
else if( !OPT_TYPE( nosuggest ) && !OPT_TYPE( special ) )
|
|
{
|
|
if( OPT_TYPE( filename ) || strncmp( cur, "--", 2 ) )
|
|
return 1; /* Fall back to default shell filename autocomplete. */
|
|
|
|
/* Suggest options. */
|
|
suggest_list( opts_suggest );
|
|
suggest_list( opts_nosuggest );
|
|
suggest_list( opts_filename );
|
|
suggest_list( opts_standalone );
|
|
|
|
/* Only suggest special options if no other options have been specified. */
|
|
if( !*prev )
|
|
suggest_list( opts_special );
|
|
}
|
|
|
|
putchar( '\n' );
|
|
return 0;
|
|
}
|