From e2efcadaaefd36c200accf5c72c6a9954a474602 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Tue, 26 Apr 2016 00:44:31 +0200 Subject: [PATCH] Support setting x264 bitrate parameters from the command line. --- defs.h | 1 + flags.cpp | 18 ++++++++++++++++++ flags.h | 3 +++ x264_encoder.cpp | 18 ++++++++++++------ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/defs.h b/defs.h index 7654f98..05a3899 100644 --- a/defs.h +++ b/defs.h @@ -12,6 +12,7 @@ #define AUDIO_OUTPUT_CODEC_NAME "pcm_s32le" #define DEFAULT_AUDIO_OUTPUT_BIT_RATE 0 +#define DEFAULT_X264_OUTPUT_BIT_RATE 4500 // 5 Mbit after making room for some audio and TCP overhead. #define LOCAL_DUMP_PREFIX "record-" #define LOCAL_DUMP_SUFFIX ".nut" diff --git a/flags.cpp b/flags.cpp index 01f563f..c2dd153 100644 --- a/flags.cpp +++ b/flags.cpp @@ -19,6 +19,12 @@ void usage() fprintf(stderr, " --http-x264-video send x264-compressed video to HTTP clients\n"); fprintf(stderr, " --x264-preset x264 quality preset (default " X264_DEFAULT_PRESET ")\n"); fprintf(stderr, " --x264-tune x264 tuning (default " X264_DEFAULT_TUNE ", can be blank)\n"); + fprintf(stderr, " --x264-bitrate x264 bitrate (in kilobit/sec, default %d)\n", + DEFAULT_X264_OUTPUT_BIT_RATE); + 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"); + fprintf(stderr, " 0 = no limit, default: same as --x264-bitrate, i.e., CBR)\n"); fprintf(stderr, " --http-mux=NAME mux to use for HTTP streams (default " DEFAULT_STREAM_MUX_NAME ")\n"); fprintf(stderr, " --http-audio-codec=NAME audio codec to use for HTTP streams\n"); fprintf(stderr, " (default is to use the same as for the recording)\n"); @@ -44,6 +50,9 @@ void parse_flags(int argc, char * const argv[]) { "http-x264-video", no_argument, 0, 1008 }, { "x264-preset", required_argument, 0, 1009 }, { "x264-tune", required_argument, 0, 1010 }, + { "x264-bitrate", required_argument, 0, 1011 }, + { "x264-vbv-bufsize", required_argument, 0, 1012 }, + { "x264-vbv-max-bitrate", required_argument, 0, 1013 }, { "http-mux", required_argument, 0, 1004 }, { "http-coarse-timebase", no_argument, 0, 1005 }, { "http-audio-codec", required_argument, 0, 1006 }, @@ -93,6 +102,15 @@ void parse_flags(int argc, char * const argv[]) case 1010: global_flags.x264_tune = optarg; break; + case 1011: + global_flags.x264_bitrate = atoi(optarg); + break; + case 1012: + global_flags.x264_vbv_buffer_size = atoi(optarg); + break; + case 1013: + global_flags.x264_vbv_max_bitrate = atoi(optarg); + break; case 1002: global_flags.flat_audio = true; break; diff --git a/flags.h b/flags.h index b157822..0f27cf2 100644 --- a/flags.h +++ b/flags.h @@ -19,6 +19,9 @@ struct Flags { int stream_audio_codec_bitrate = DEFAULT_AUDIO_OUTPUT_BIT_RATE; // Ignored if stream_audio_codec_name is blank. std::string x264_preset = X264_DEFAULT_PRESET; std::string x264_tune = X264_DEFAULT_TUNE; + int x264_bitrate = DEFAULT_X264_OUTPUT_BIT_RATE; // In kilobit/sec. + int x264_vbv_max_bitrate = -1; // In kilobits. 0 = no limit, -1 = same as (CBR). + int x264_vbv_buffer_size = -1; // In kilobits. 0 = one-frame VBV, -1 = same as (one-second VBV). }; extern Flags global_flags; diff --git a/x264_encoder.cpp b/x264_encoder.cpp index bbbb1ba..feec9da 100644 --- a/x264_encoder.cpp +++ b/x264_encoder.cpp @@ -76,13 +76,19 @@ void X264Encoder::init_x264() param.vui.i_transfer = 2; // Unspecified (since we use sRGB). param.vui.i_colmatrix = 6; // BT.601/SMPTE 170M. - // 4.5 Mbit/sec, CBR. - param.rc.i_rc_method = X264_RC_ABR; - param.rc.i_bitrate = 4500; - // One-second VBV. - param.rc.i_vbv_max_bitrate = 4500; - param.rc.i_vbv_buffer_size = 4500; + param.rc.i_rc_method = X264_RC_ABR; + param.rc.i_bitrate = global_flags.x264_vbv_max_bitrate; + if (global_flags.x264_vbv_buffer_size < 0) { + param.rc.i_vbv_buffer_size = param.rc.i_bitrate; // One-second VBV. + } else { + param.rc.i_vbv_buffer_size = global_flags.x264_vbv_buffer_size; + } + if (global_flags.x264_vbv_max_bitrate < 0) { + param.rc.i_vbv_max_bitrate = param.rc.i_bitrate; // CBR. + } else { + param.rc.i_vbv_max_bitrate = global_flags.x264_vbv_max_bitrate; + } // TODO: more flags here, via x264_param_parse(). -- 2.39.2