aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-05-21 22:02:59 +0200
committerdec05eba <dec05eba@protonmail.com>2024-05-21 22:02:59 +0200
commitfee6441bc504c37817b883dcc2812b90a641a49e (patch)
treeebc6a53e08541e72b4cef6df729d6d78f4800386 /src
parent42d9ebd3c775ae60b80a99ef8bd33a444de0fb21 (diff)
Allow setting gop multiplication to reduce file size
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp32
1 files changed, 26 insertions, 6 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 1381c3d..ae2b95d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -328,7 +328,7 @@ static AVCodecContext* create_audio_codec_context(int fps, AudioCodec audio_code
static AVCodecContext *create_video_codec_context(AVPixelFormat pix_fmt,
VideoQuality video_quality,
int fps, const AVCodec *codec, bool is_livestream, gsr_gpu_vendor vendor, FramerateMode framerate_mode,
- bool hdr, gsr_color_range color_range) {
+ bool hdr, gsr_color_range color_range, int gopm) {
AVCodecContext *codec_context = avcodec_alloc_context3(codec);
@@ -352,9 +352,9 @@ static AVCodecContext *create_video_codec_context(AVPixelFormat pix_fmt,
codec_context->flags2 |= AV_CODEC_FLAG2_FAST;
//codec_context->gop_size = std::numeric_limits<int>::max();
//codec_context->keyint_min = std::numeric_limits<int>::max();
- codec_context->gop_size = fps * 2;
+ codec_context->gop_size = fps * gopm;
} else {
- codec_context->gop_size = fps * 2;
+ codec_context->gop_size = fps * gopm;
}
codec_context->max_b_frames = 0;
codec_context->pix_fmt = pix_fmt;
@@ -505,7 +505,7 @@ static bool vaapi_create_codec_context(AVCodecContext *video_codec_context, cons
static bool check_if_codec_valid_for_hardware(const AVCodec *codec, gsr_gpu_vendor vendor, const char *card_path) {
// Do not use AV_PIX_FMT_CUDA because we dont want to do full check with hardware context
- AVCodecContext *codec_context = create_video_codec_context(vendor == GSR_GPU_VENDOR_NVIDIA ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_VAAPI, VideoQuality::VERY_HIGH, 60, codec, false, vendor, FramerateMode::CONSTANT, false, GSR_COLOR_RANGE_LIMITED);
+ AVCodecContext *codec_context = create_video_codec_context(vendor == GSR_GPU_VENDOR_NVIDIA ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_VAAPI, VideoQuality::VERY_HIGH, 60, codec, false, vendor, FramerateMode::CONSTANT, false, GSR_COLOR_RANGE_LIMITED, 2);
if(!codec_context)
return false;
@@ -822,7 +822,7 @@ static void open_video(AVCodecContext *codec_context, VideoQuality video_quality
static void usage_header() {
const bool inside_flatpak = getenv("FLATPAK_ID") != NULL;
const char *program_name = inside_flatpak ? "flatpak run --command=gpu-screen-recorder com.dec05eba.gpu_screen_recorder" : "gpu-screen-recorder";
- fprintf(stderr, "usage: %s -w <window_id|monitor|focused> [-c <container_format>] [-s WxH] -f <fps> [-a <audio_input>] [-q <quality>] [-r <replay_buffer_size_sec>] [-k h264|hevc|hevc_hdr|av1|av1_hdr] [-ac aac|opus|flac] [-ab <bitrate>] [-oc yes|no] [-fm cfr|vfr] [-cr limited|full] [-v yes|no] [-h|--help] [-o <output_file>] [-mf yes|no] [-sc <script_path>] [-cursor yes|no]\n", program_name);
+ fprintf(stderr, "usage: %s -w <window_id|monitor|focused> [-c <container_format>] [-s WxH] -f <fps> [-a <audio_input>] [-q <quality>] [-r <replay_buffer_size_sec>] [-k h264|hevc|hevc_hdr|av1|av1_hdr] [-ac aac|opus|flac] [-ab <bitrate>] [-oc yes|no] [-fm cfr|vfr] [-cr limited|full] [-v yes|no] [-h|--help] [-o <output_file>] [-mf yes|no] [-sc <script_path>] [-cursor yes|no] [-gopm <value>]\n", program_name);
}
static void usage_full() {
@@ -892,6 +892,11 @@ static void usage_full() {
fprintf(stderr, "\n");
fprintf(stderr, " -cursor\n");
fprintf(stderr, " Record cursor. Defaults to 'yes'.\n");
+ fprintf(stderr, " -gopm\n");
+ fprintf(stderr, " Set GOP multiplication. This specifies in seconds how often an I-frame (complete image) should be generated. For the final GOP this value is multiplied by the fps.\n");
+ fprintf(stderr, " This also affects seeking in the video and how the replay video is cut. If this is set to 10 for example then you can only seek in 10-second chunks in the video.\n");
+ fprintf(stderr, " Setting this to a higher value reduces the video file size if you are ok with the previously described downside. This option is expected to be an integer value.\n");
+ fprintf(stderr, " By default this value is set to 2.\n");
fprintf(stderr, "\n");
fprintf(stderr, " --list-supported-video-codecs\n");
fprintf(stderr, " List supported video codecs and exits. Prints h264, hevc, hevc_hdr, av1 and av1_hdr (if supported).\n");
@@ -1688,6 +1693,7 @@ int main(int argc, char **argv) {
{ "-sc", Arg { {}, true, false } },
{ "-cr", Arg { {}, true, false } },
{ "-cursor", Arg { {}, true, false } },
+ { "-gopm", Arg { {}, true, false } },
};
for(int i = 1; i < argc; i += 2) {
@@ -1768,6 +1774,20 @@ int main(int argc, char **argv) {
}
}
+ int gopm = 2;
+ const char *gopm_str = args["-gopm"].value();
+ if(gopm_str) {
+ if(sscanf(gopm_str, "%d", &gopm) != 1) {
+ fprintf(stderr, "Error: -gopm argument \"%s\" is not an integer\n", gopm_str);
+ usage();
+ }
+
+ if(gopm < 0) {
+ fprintf(stderr, "Error: -gopm is expected to be 0 or larger\n");
+ usage();
+ }
+ }
+
bool overclock = false;
const char *overclock_str = args["-oc"].value();
if(!overclock_str)
@@ -2276,7 +2296,7 @@ int main(int argc, char **argv) {
std::vector<AudioTrack> audio_tracks;
const bool hdr = video_codec_is_hdr(video_codec);
- AVCodecContext *video_codec_context = create_video_codec_context(egl.gpu_info.vendor == GSR_GPU_VENDOR_NVIDIA ? AV_PIX_FMT_CUDA : AV_PIX_FMT_VAAPI, quality, fps, video_codec_f, is_livestream, egl.gpu_info.vendor, framerate_mode, hdr, color_range);
+ AVCodecContext *video_codec_context = create_video_codec_context(egl.gpu_info.vendor == GSR_GPU_VENDOR_NVIDIA ? AV_PIX_FMT_CUDA : AV_PIX_FMT_VAAPI, quality, fps, video_codec_f, is_livestream, egl.gpu_info.vendor, framerate_mode, hdr, color_range, gopm);
if(replay_buffer_size_secs == -1)
video_stream = create_stream(av_format_context, video_codec_context);