Add configurable variable QP for video
This commit is contained in:
+13
-7
@@ -20,7 +20,7 @@ ping_timeout = 2000
|
|||||||
# How much error correcting packets must be send for every video max_b_frames
|
# How much error correcting packets must be send for every video max_b_frames
|
||||||
# This is just some random number, don't know the optimal value
|
# This is just some random number, don't know the optimal value
|
||||||
# The higher fec_percentage, the lower space for the actual data to send per frame there is
|
# The higher fec_percentage, the lower space for the actual data to send per frame there is
|
||||||
fec_percentage = 25
|
fec_percentage = 1
|
||||||
|
|
||||||
###############################################
|
###############################################
|
||||||
# FFmpeg software encoding parameters
|
# FFmpeg software encoding parameters
|
||||||
@@ -29,15 +29,21 @@ fec_percentage = 25
|
|||||||
max_b_frames = 16
|
max_b_frames = 16
|
||||||
gop_size = 24
|
gop_size = 24
|
||||||
|
|
||||||
# Constant Rate Factor. Between 1 and 52.
|
# Constant Rate Factor. Between 1 and 52. It allows QP to go up during motion and down with still image, resulting in constant perceived quality
|
||||||
# Higher value means more compression, but less quality
|
# Higher value means more compression, but less quality
|
||||||
crf = 28
|
# If crf == 0, then use QP directly instead
|
||||||
|
crf = 0
|
||||||
|
|
||||||
|
# Quantitization Parameter
|
||||||
|
# Higher value means more compression, but less quality
|
||||||
|
# If crf != 0, then this parameter is ignored
|
||||||
|
qp = 28
|
||||||
|
|
||||||
# Number of threads used by ffmpeg to encode the video
|
# Number of threads used by ffmpeg to encode the video
|
||||||
# threads = 4
|
threads = 8
|
||||||
|
|
||||||
|
|
||||||
# See x264 --fullhelp for the different presets
|
# See x264 --fullhelp for the different presets
|
||||||
# profile = baseline
|
profile = baseline
|
||||||
# preset = superfast
|
preset = superfast
|
||||||
# tune = zerolatency
|
tune = zerolatency
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ video_t video {
|
|||||||
16, // max_b_frames
|
16, // max_b_frames
|
||||||
24, // gop_size
|
24, // gop_size
|
||||||
35, // crf
|
35, // crf
|
||||||
|
35, // qp
|
||||||
|
|
||||||
4, // threads
|
4, // threads
|
||||||
|
|
||||||
@@ -121,6 +122,7 @@ void parse_file(const char *file) {
|
|||||||
int_f(vars, "max_b_frames", video.max_b_frames);
|
int_f(vars, "max_b_frames", video.max_b_frames);
|
||||||
int_f(vars, "gop_size", video.gop_size);
|
int_f(vars, "gop_size", video.gop_size);
|
||||||
int_f(vars, "crf", video.crf);
|
int_f(vars, "crf", video.crf);
|
||||||
|
int_f(vars, "qp", video.qp);
|
||||||
int_f(vars, "threads", video.threads);
|
int_f(vars, "threads", video.threads);
|
||||||
string_f(vars, "profile", video.profile);
|
string_f(vars, "profile", video.profile);
|
||||||
string_f(vars, "preset", video.preset);
|
string_f(vars, "preset", video.preset);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ struct video_t {
|
|||||||
int max_b_frames;
|
int max_b_frames;
|
||||||
int gop_size;
|
int gop_size;
|
||||||
int crf; // higher == more compression and less quality
|
int crf; // higher == more compression and less quality
|
||||||
|
int qp; // higher == more compression and less quality, ignored if crf != 0
|
||||||
|
|
||||||
int threads; // Number threads used by ffmpeg
|
int threads; // Number threads used by ffmpeg
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -876,7 +876,7 @@ void cmd_announce(host_t &host, peer_t peer, msg_t &&req) {
|
|||||||
config.monitor.height = util::from_view(args.at("x-nv-video[0].clientViewportHt"sv));
|
config.monitor.height = util::from_view(args.at("x-nv-video[0].clientViewportHt"sv));
|
||||||
config.monitor.width = util::from_view(args.at("x-nv-video[0].clientViewportWd"sv));
|
config.monitor.width = util::from_view(args.at("x-nv-video[0].clientViewportWd"sv));
|
||||||
config.monitor.framerate = util::from_view(args.at("x-nv-video[0].maxFPS"sv));
|
config.monitor.framerate = util::from_view(args.at("x-nv-video[0].maxFPS"sv));
|
||||||
config.monitor.bitrate = util::from_view(args.at("x-nv-video[0].initialBitrateKbps"sv));
|
config.monitor.bitrate = util::from_view(args.at("x-nv-vqos[0].bw.maximumBitrateKbps"sv));
|
||||||
config.monitor.slicesPerFrame = util::from_view(args.at("x-nv-video[0].videoEncoderSlicesPerFrame"sv));
|
config.monitor.slicesPerFrame = util::from_view(args.at("x-nv-video[0].videoEncoderSlicesPerFrame"sv));
|
||||||
|
|
||||||
} catch(std::out_of_range &) {
|
} catch(std::out_of_range &) {
|
||||||
|
|||||||
+6
-3
@@ -103,6 +103,7 @@ void encodeThread(
|
|||||||
ctx->pix_fmt = AV_PIX_FMT_YUV420P;
|
ctx->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||||
ctx->max_b_frames = config::video.max_b_frames;
|
ctx->max_b_frames = config::video.max_b_frames;
|
||||||
ctx->gop_size = config::video.gop_size;
|
ctx->gop_size = config::video.gop_size;
|
||||||
|
ctx->has_b_frames = 1;
|
||||||
|
|
||||||
ctx->slices = config.slicesPerFrame;
|
ctx->slices = config.slicesPerFrame;
|
||||||
ctx->thread_type = FF_THREAD_SLICE;
|
ctx->thread_type = FF_THREAD_SLICE;
|
||||||
@@ -114,7 +115,12 @@ void encodeThread(
|
|||||||
av_dict_set(&options, "preset", config::video.preset.c_str(), 0);
|
av_dict_set(&options, "preset", config::video.preset.c_str(), 0);
|
||||||
av_dict_set(&options, "tune", config::video.tune.c_str(), 0);
|
av_dict_set(&options, "tune", config::video.tune.c_str(), 0);
|
||||||
|
|
||||||
|
if(config::video.crf != 0) {
|
||||||
av_dict_set_int(&options, "crf", config::video.crf, 0);
|
av_dict_set_int(&options, "crf", config::video.crf, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
av_dict_set_int(&options, "qp", config::video.qp, 0);
|
||||||
|
}
|
||||||
|
|
||||||
ctx->flags |= (AV_CODEC_FLAG_CLOSED_GOP | AV_CODEC_FLAG_LOW_DELAY);
|
ctx->flags |= (AV_CODEC_FLAG_CLOSED_GOP | AV_CODEC_FLAG_LOW_DELAY);
|
||||||
ctx->flags2 |= AV_CODEC_FLAG2_FAST;
|
ctx->flags2 |= AV_CODEC_FLAG2_FAST;
|
||||||
@@ -126,7 +132,6 @@ void encodeThread(
|
|||||||
yuv_frame->width = ctx->width;
|
yuv_frame->width = ctx->width;
|
||||||
yuv_frame->height = ctx->height;
|
yuv_frame->height = ctx->height;
|
||||||
|
|
||||||
// yuv_frame->opaque = 0;
|
|
||||||
av_frame_get_buffer(yuv_frame.get(), 0);
|
av_frame_get_buffer(yuv_frame.get(), 0);
|
||||||
|
|
||||||
int64_t frame = 1;
|
int64_t frame = 1;
|
||||||
@@ -146,8 +151,6 @@ void encodeThread(
|
|||||||
if(idr_events->peek()) {
|
if(idr_events->peek()) {
|
||||||
yuv_frame->pict_type = AV_PICTURE_TYPE_I;
|
yuv_frame->pict_type = AV_PICTURE_TYPE_I;
|
||||||
frame = idr_events->pop()->first;
|
frame = idr_events->pop()->first;
|
||||||
|
|
||||||
// ++yuv_frame->opaque;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
encode(frame++, ctx, sws, yuv_frame, img, packets);
|
encode(frame++, ctx, sws, yuv_frame, img, packets);
|
||||||
|
|||||||
Reference in New Issue
Block a user