mirror of
https://github.com/LizardByte/Sunshine.git
synced 2025-01-30 12:32:43 +00:00
Merge pull request #1 from cgutman/optimize_video_params
Optimize encoding parameters for low-latency
This commit is contained in:
commit
a104862830
@ -46,7 +46,7 @@ ping_timeout = 2000
|
|||||||
# The file where configuration for the different applications that Sunshine can run during a stream
|
# The file where configuration for the different applications that Sunshine can run during a stream
|
||||||
# file_apps = apps.json
|
# file_apps = apps.json
|
||||||
|
|
||||||
# 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
|
||||||
# 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 = 10
|
fec_percentage = 10
|
||||||
@ -70,8 +70,6 @@ fec_percentage = 10
|
|||||||
# FFmpeg software encoding parameters
|
# FFmpeg software encoding parameters
|
||||||
# Honestly, I have no idea what the optimal values would be.
|
# Honestly, I have no idea what the optimal values would be.
|
||||||
# Play around with this :)
|
# Play around with this :)
|
||||||
max_b_frames = 4
|
|
||||||
gop_size = 24
|
|
||||||
|
|
||||||
# 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
|
# 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
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
namespace config {
|
namespace config {
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
video_t video {
|
video_t video {
|
||||||
16, // max_b_frames
|
|
||||||
24, // gop_size
|
|
||||||
35, // crf
|
35, // crf
|
||||||
35, // qp
|
35, // qp
|
||||||
|
|
||||||
@ -160,8 +158,6 @@ void parse_file(const char *file) {
|
|||||||
std::cout << "["sv << name << "] -- ["sv << val << ']' << std::endl;
|
std::cout << "["sv << name << "] -- ["sv << val << ']' << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int_f(vars, "max_b_frames", video.max_b_frames);
|
|
||||||
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, "qp", video.qp);
|
||||||
int_f(vars, "threads", video.threads);
|
int_f(vars, "threads", video.threads);
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
namespace config {
|
namespace config {
|
||||||
struct video_t {
|
struct video_t {
|
||||||
// ffmpeg params
|
// ffmpeg params
|
||||||
int max_b_frames;
|
|
||||||
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 qp; // higher == more compression and less quality, ignored if crf != 0
|
||||||
|
|
||||||
|
@ -970,6 +970,7 @@ void cmd_announce(host_t &host, peer_t peer, msg_t &&req) {
|
|||||||
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-vqos[0].bw.maximumBitrateKbps"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));
|
||||||
|
config.monitor.numRefFrames = util::from_view(args.at("x-nv-video[0].maxNumReferenceFrames"sv));
|
||||||
|
|
||||||
} catch(std::out_of_range &) {
|
} catch(std::out_of_range &) {
|
||||||
|
|
||||||
|
@ -98,12 +98,20 @@ void encodeThread(
|
|||||||
ctx->time_base = AVRational{1, framerate};
|
ctx->time_base = AVRational{1, framerate};
|
||||||
ctx->framerate = AVRational{framerate, 1};
|
ctx->framerate = AVRational{framerate, 1};
|
||||||
ctx->pix_fmt = AV_PIX_FMT_YUV420P;
|
ctx->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||||
ctx->max_b_frames = config::video.max_b_frames;
|
|
||||||
ctx->has_b_frames = 1;
|
// B-frames delay decoder output, so never use them
|
||||||
|
ctx->max_b_frames = 0;
|
||||||
|
|
||||||
|
// Use an infinite GOP length since I-frames are generated on demand
|
||||||
|
ctx->gop_size = std::numeric_limits<int>::max();
|
||||||
|
ctx->keyint_min = ctx->gop_size;
|
||||||
|
|
||||||
|
// Some client decoders have limits on the number of reference frames
|
||||||
|
ctx->refs = config.numRefFrames;
|
||||||
|
|
||||||
ctx->slices = config.slicesPerFrame;
|
ctx->slices = config.slicesPerFrame;
|
||||||
ctx->thread_type = FF_THREAD_SLICE;
|
ctx->thread_type = FF_THREAD_SLICE;
|
||||||
ctx->thread_count = config::video.threads;
|
ctx->thread_count = std::min(ctx->slices, config::video.threads);
|
||||||
|
|
||||||
|
|
||||||
AVDictionary *options {nullptr};
|
AVDictionary *options {nullptr};
|
||||||
@ -119,11 +127,9 @@ void encodeThread(
|
|||||||
ctx->rc_min_rate = config.bitrate;
|
ctx->rc_min_rate = config.bitrate;
|
||||||
}
|
}
|
||||||
else if(config::video.crf != 0) {
|
else if(config::video.crf != 0) {
|
||||||
ctx->gop_size = config::video.gop_size;
|
|
||||||
av_dict_set_int(&options, "crf", config::video.crf, 0);
|
av_dict_set_int(&options, "crf", config::video.crf, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ctx->gop_size = config::video.gop_size;
|
|
||||||
av_dict_set_int(&options, "qp", config::video.qp, 0);
|
av_dict_set_int(&options, "qp", config::video.qp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ struct config_t {
|
|||||||
int framerate;
|
int framerate;
|
||||||
int bitrate;
|
int bitrate;
|
||||||
int slicesPerFrame;
|
int slicesPerFrame;
|
||||||
|
int numRefFrames;
|
||||||
};
|
};
|
||||||
|
|
||||||
void capture_display(packet_queue_t packets, idr_event_t idr_events, config_t config);
|
void capture_display(packet_queue_t packets, idr_event_t idr_events, config_t config);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user