aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-10-02 22:19:54 +0200
committerdec05eba <dec05eba@protonmail.com>2022-10-02 22:19:54 +0200
commit6885d1a30e41cbb86355820ecc4005706937cb23 (patch)
treeb795d25da98fb169ae5c4df78dc0798fe0295086
parent5d92b53f1c352b2629fc0b7dbd300b7a7609087b (diff)
Sacrifice seek speed for reduced file size
-rw-r--r--README.md4
-rw-r--r--src/main.cpp33
2 files changed, 29 insertions, 8 deletions
diff --git a/README.md b/README.md
index 878b193..0d2c49c 100644
--- a/README.md
+++ b/README.md
@@ -7,17 +7,19 @@ where only the last few seconds are saved.
## Note
For NvFBC to work with PRIME, you must set the primary GPU to your dedicated Nvidia graphics card. On Pop OS, you can select the 'NVIDIA Graphics' option in the power menu, or on Arch Linux you can use Optimus Manager.\
-If you are using a variable refresh rate monitor, then choose to record "screen-direct". This will allow variable refresh rate to work when recording fullscreen applications. Note that some applications such as mpv will not work in fullscreen mode. A fix is being developed for this.\
+If you are using a variable refresh rate monitor, then choose to record "screen-direct". This will allow variable refresh rate to work when recording fullscreen applications. Note that some applications such as mpv will not work in fullscreen mode. A fix is being developed for this.
# Performance
When recording Legend of Zelda Breath of the Wild at 4k, fps drops from 30 to 7 when using OBS Studio + nvenc, however when using this screen recorder the fps remains at 30.\
When recording GTA V at 4k on highest settings, fps drops from 60 to 23 when using obs-nvfbc + nvenc, however when using this screen recorder the fps only drops to 55. The quality is also much better when using gpu-screen-recorder.\
It is recommended to save the video to a SSD because of the large file size, which a slow HDD might not be fast enough to handle.\
Using NvFBC (recording the monitor/screen) is not faster than not using NvFBC (recording a single window) with gpu screen recorder, in fact it might be a tiny bit slower.
+
# Installation
If you are running an Arch Linux based distro, then you can find gpu screen recorder on aur under the name gpu-screen-recorder-git (`yay -S gpu-screen-recorder-git`).\
If you are running an Ubuntu based distro then run `install_ubuntu.sh` as root: `sudo ./install_ubuntu.sh`.\
If you are running another distro then you can run `install.sh` as root: `sudo ./install.sh`, but you need to manually install the dependencies, as described below.
+
# Dependencies
`libgl (libglvnd), ffmpeg, libx11, libxcomposite, libpulse`. You need to additionally have `cuda` installed when you run `gpu-screen-recorder`.\
Recording monitors requires a gpu with NvFBC support (note: this is not required when recording a single window!). Normally only tesla and quadro gpus support this, but by using [nvidia-patch](https://github.com/keylase/nvidia-patch) or [nvlax](https://github.com/illnyang/nvlax) you can do this on all gpus that support nvenc as well (gpus as old as the nvidia 600 series), provided you are not using outdated gpu drivers.
diff --git a/src/main.cpp b/src/main.cpp
index 45a53d1..61cd07c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -623,15 +623,18 @@ static AVCodecContext *create_video_codec_context(AVFormatContext *av_format_con
codec_context->framerate.den = 1;
codec_context->sample_aspect_ratio.num = 0;
codec_context->sample_aspect_ratio.den = 0;
- codec_context->gop_size = fps * 2;
+ // High values reeduce file size but increases time it takes to seek
+ codec_context->gop_size = fps * 10;
+ codec_context->keyint_min = fps * 10;
codec_context->max_b_frames = 0;
codec_context->pix_fmt = AV_PIX_FMT_CUDA;
codec_context->color_range = AVCOL_RANGE_JPEG;
- //if(use_hevc)
- // codec_context->codec_tag = MKTAG('h', 'v', 'c', '1');
+ if(use_hevc)
+ codec_context->codec_tag = MKTAG('h', 'v', 'c', '1');
switch(video_quality) {
case VideoQuality::VERY_HIGH:
- codec_context->bit_rate = 10000000 + (codec_context->width * codec_context->height) / 2;
+ codec_context->bit_rate = 10000000 + (codec_context->width * codec_context->height) / 2;
+ /*
if(use_hevc) {
codec_context->qmin = 20;
codec_context->qmax = 35;
@@ -639,12 +642,14 @@ static AVCodecContext *create_video_codec_context(AVFormatContext *av_format_con
codec_context->qmin = 5;
codec_context->qmax = 20;
}
+ */
//av_opt_set(codec_context->priv_data, "preset", "slow", 0);
//av_opt_set(codec_context->priv_data, "profile", "high", 0);
//codec_context->profile = FF_PROFILE_H264_HIGH;
//av_opt_set(codec_context->priv_data, "preset", "p4", 0);
break;
case VideoQuality::ULTRA:
+ /*
if(use_hevc) {
codec_context->qmin = 17;
codec_context->qmax = 30;
@@ -652,12 +657,14 @@ static AVCodecContext *create_video_codec_context(AVFormatContext *av_format_con
codec_context->qmin = 5;
codec_context->qmax = 15;
}
+ */
//av_opt_set(codec_context->priv_data, "preset", "slow", 0);
//av_opt_set(codec_context->priv_data, "profile", "high", 0);
//codec_context->profile = FF_PROFILE_H264_HIGH;
//av_opt_set(codec_context->priv_data, "preset", "p5", 0);
break;
}
+ //codec_context->profile = FF_PROFILE_H264_MAIN;
if (codec_context->codec_id == AV_CODEC_ID_MPEG1VIDEO)
codec_context->mb_decision = 2;
@@ -731,7 +738,7 @@ static AVBufferRef* dummy_hw_frame_init(size_t size) {
static void open_video(AVCodecContext *codec_context,
WindowPixmap &window_pixmap, AVBufferRef **device_ctx,
- CUgraphicsResource *cuda_graphics_resource, CUcontext cuda_context, bool use_nvfbc) {
+ CUgraphicsResource *cuda_graphics_resource, CUcontext cuda_context, bool use_nvfbc, VideoQuality video_quality) {
int ret;
*device_ctx = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_CUDA);
@@ -777,7 +784,19 @@ static void open_video(AVCodecContext *codec_context,
codec_context->hw_device_ctx = *device_ctx;
codec_context->hw_frames_ctx = frame_context;
- ret = avcodec_open2(codec_context, codec_context->codec, nullptr);
+ AVDictionary *options = nullptr;
+ switch(video_quality) {
+ case VideoQuality::VERY_HIGH:
+ av_dict_set_int(&options, "qp", 28, 0);
+ //av_dict_set(&options, "preset", "hq", 0);
+ break;
+ case VideoQuality::ULTRA:
+ av_dict_set_int(&options, "qp", 18, 0);
+ //av_dict_set(&options, "preset", "slow", 0);
+ break;
+ }
+
+ ret = avcodec_open2(codec_context, codec_context->codec, &options);
if (ret < 0) {
fprintf(stderr, "Error: Could not open video codec: %s\n",
"blabla"); // av_err2str(ret));
@@ -1361,7 +1380,7 @@ int main(int argc, char **argv) {
AVBufferRef *device_ctx;
CUgraphicsResource cuda_graphics_resource;
- open_video(video_codec_context, window_pixmap, &device_ctx, &cuda_graphics_resource, cu_ctx, !src_window_id);
+ open_video(video_codec_context, window_pixmap, &device_ctx, &cuda_graphics_resource, cu_ctx, !src_window_id, quality);
if(video_stream)
avcodec_parameters_from_context(video_stream->codecpar, video_codec_context);