OPTION_X264_SPEEDCONTROL,
OPTION_X264_SPEEDCONTROL_VERBOSE,
OPTION_X264_BITRATE,
+ OPTION_X264_CRF,
OPTION_X264_VBV_BUFSIZE,
OPTION_X264_VBV_MAX_BITRATE,
OPTION_X264_PARAM,
fprintf(stderr, " --x264-speedcontrol-verbose output speedcontrol debugging statistics\n");
fprintf(stderr, " --x264-bitrate x264 bitrate (in kilobit/sec, default %d)\n",
DEFAULT_X264_OUTPUT_BIT_RATE);
+ fprintf(stderr, " --x264-crf=VALUE quality-based VBR (-12 to 51), incompatible with --x264-bitrate and VBV\n");
fprintf(stderr, " --x264-vbv-bufsize x264 VBV size (in kilobits, 0 = one-frame VBV,\n");
fprintf(stderr, " default: same as --x264-bitrate, that is, one-second VBV)\n");
fprintf(stderr, " --x264-vbv-max-bitrate x264 local max bitrate (in kilobit/sec per --vbv-bufsize,\n");
{ "x264-speedcontrol", no_argument, 0, OPTION_X264_SPEEDCONTROL },
{ "x264-speedcontrol-verbose", no_argument, 0, OPTION_X264_SPEEDCONTROL_VERBOSE },
{ "x264-bitrate", required_argument, 0, OPTION_X264_BITRATE },
+ { "x264-crf", required_argument, 0, OPTION_X264_CRF },
{ "x264-vbv-bufsize", required_argument, 0, OPTION_X264_VBV_BUFSIZE },
{ "x264-vbv-max-bitrate", required_argument, 0, OPTION_X264_VBV_MAX_BITRATE },
{ "x264-param", required_argument, 0, OPTION_X264_PARAM },
case OPTION_X264_BITRATE:
global_flags.x264_bitrate = atoi(optarg);
break;
+ case OPTION_X264_CRF:
+ global_flags.x264_crf = atof(optarg);
+ break;
case OPTION_X264_VBV_BUFSIZE:
global_flags.x264_vbv_buffer_size = atoi(optarg);
break;
if (global_flags.max_input_queue_frames > 10) {
fprintf(stderr, "WARNING: --max-input-queue-frames has little effect over 10.\n");
}
+
+ if (!isinf(global_flags.x264_crf)) { // CRF mode is selected.
+ if (global_flags.x264_bitrate != -1) {
+ fprintf(stderr, "ERROR: --x264-bitrate and --x264-crf are mutually incompatible.\n");
+ exit(1);
+ }
+ if (global_flags.x264_vbv_max_bitrate != -1 && global_flags.x264_vbv_buffer_size != -1) {
+ fprintf(stderr, "WARNING: VBV settings are ignored with --x264-crf.\n");
+ }
+ } else if (global_flags.x264_bitrate == -1) {
+ global_flags.x264_bitrate = DEFAULT_X264_OUTPUT_BIT_RATE;
+ }
}
#ifndef _FLAGS_H
#define _FLAGS_H
+#include <math.h>
+
#include <map>
#include <string>
#include <vector>
std::string x264_tune = X264_DEFAULT_TUNE;
bool x264_speedcontrol = false;
bool x264_speedcontrol_verbose = false;
- int x264_bitrate = DEFAULT_X264_OUTPUT_BIT_RATE; // In kilobit/sec.
+ int x264_bitrate = -1; // In kilobit/sec. -1 = not set = DEFAULT_X264_OUTPUT_BIT_RATE.
+ float x264_crf = HUGE_VAL; // From 51 - QP_MAX_SPEC to 51. HUGE_VAL = not set = use x264_bitrate instead.
int x264_vbv_max_bitrate = -1; // In kilobits. 0 = no limit, -1 = same as <x264_bitrate> (CBR).
int x264_vbv_buffer_size = -1; // In kilobits. 0 = one-frame VBV, -1 = same as <x264_bitrate> (one-second VBV).
std::vector<std::string> x264_extra_param; // In “key[,value]” format.
void update_vbv_settings(x264_param_t *param)
{
+ if (global_flags.x264_bitrate == -1) {
+ return;
+ }
if (global_flags.x264_vbv_buffer_size < 0) {
param->rc.i_vbv_buffer_size = param->rc.i_bitrate; // One-second VBV.
} else {
param.vui.i_colmatrix = 6; // BT.601/SMPTE 170M.
}
- param.rc.i_rc_method = X264_RC_ABR;
- param.rc.i_bitrate = global_flags.x264_bitrate;
+ if (!isinf(global_flags.x264_crf)) {
+ param.rc.i_rc_method = X264_RC_CRF;
+ param.rc.f_rf_constant = global_flags.x264_crf;
+ } else {
+ param.rc.i_rc_method = X264_RC_ABR;
+ param.rc.i_bitrate = global_flags.x264_bitrate;
+ }
update_vbv_settings(¶m);
if (param.rc.i_vbv_max_bitrate > 0) {
// If the user wants VBV control to cap the max rate, it is