Sacrifice seek speed for reduced file size

This commit is contained in:
dec05eba 2022-10-02 22:19:54 +02:00
parent 5d92b53f1c
commit 6885d1a30e
2 changed files with 29 additions and 8 deletions

View File

@ -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.

View File

@ -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);