Tune quality again, remove vbr

This commit is contained in:
dec05eba 2022-10-11 02:47:17 +02:00
parent 1a4e0aff72
commit 1ca4dcfbdb
4 changed files with 51 additions and 64 deletions

View File

@ -1,8 +1,8 @@
#!/bin/sh -e #!/bin/sh -e
dependencies="libavcodec libavformat libavutil x11 xcomposite libpulse libswresample" dependencies="libavcodec libavformat libavutil x11 xcomposite libpulse libswresample"
includes="$(pkg-config --cflags $dependencies) -Iexternal" includes="$(pkg-config --cflags $dependencies)"
libs="$(pkg-config --libs $dependencies) -ldl -pthread -lm" libs="$(pkg-config --libs $dependencies) -ldl -pthread -lm"
g++ -c src/sound.cpp -O2 $includes g++ -c src/sound.cpp -O2 -g0 -DNDEBUG $includes
g++ -c src/main.cpp -O2 $includes g++ -c src/main.cpp -O2 -g0 -DNDEBUG $includes
g++ -o gpu-screen-recorder -O2 sound.o main.o -s $libs g++ -o gpu-screen-recorder -O2 sound.o main.o -s $libs

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <NvFBC.h> #include "../external/NvFBC.h"
#include <dlfcn.h> #include <dlfcn.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>

View File

@ -11,13 +11,4 @@ apt-get -y install build-essential\
libgl-dev libx11-dev libxcomposite-dev\ libgl-dev libx11-dev libxcomposite-dev\
libpulse-dev libpulse-dev
dependencies="libavcodec libavformat libavutil x11 xcomposite libpulse libswresample" ./install.sh
includes="$(pkg-config --cflags $dependencies) -Iexternal"
libs="$(pkg-config --libs $dependencies) -ldl -pthread -lm"
g++ -c src/sound.cpp -O2 $includes
g++ -c src/main.cpp -O2 $includes
g++ -o gpu-screen-recorder -O2 sound.o main.o -s $libs
install -Dm755 "gpu-screen-recorder" "/usr/local/bin/gpu-screen-recorder"
install -Dm755 "gpu-screen-recorder" "/usr/bin/gpu-screen-recorder"
echo "Successfully installed gpu-screen-recorder"

View File

@ -349,6 +349,7 @@ static bool recreate_window_pixmap(Display *dpy, Window window_id,
fprintf(stderr, "Warning: failed to get texture size. You are probably trying to record a window with client-side decorations (using GNOME?). Trying to fallback to recording the compositor proxy window\n"); fprintf(stderr, "Warning: failed to get texture size. You are probably trying to record a window with client-side decorations (using GNOME?). Trying to fallback to recording the compositor proxy window\n");
XCompositeRedirectWindow(dpy, compositor_window, CompositeRedirectAutomatic); XCompositeRedirectWindow(dpy, compositor_window, CompositeRedirectAutomatic);
// TODO: Target texture should be the same size as the target window, not the size of the composite window
if(recreate_window_pixmap(dpy, compositor_window, pixmap, false)) { if(recreate_window_pixmap(dpy, compositor_window, pixmap, false)) {
pixmap.composite_window = compositor_window; pixmap.composite_window = compositor_window;
pixmap.texture_width = attr.width; pixmap.texture_width = attr.width;
@ -645,29 +646,24 @@ static AVCodecContext *create_video_codec_context(AVFormatContext *av_format_con
codec_context->codec_tag = MKTAG('h', 'v', 'c', '1'); codec_context->codec_tag = MKTAG('h', 'v', 'c', '1');
switch(video_quality) { switch(video_quality) {
case VideoQuality::MEDIUM: case VideoQuality::MEDIUM:
codec_context->bit_rate = 6500000 + (codec_context->width * codec_context->height)*0.75; //codec_context->qmin = 35;
/* //codec_context->qmax = 35;
if(use_hevc) { codec_context->bit_rate = 100000;//4500000 + (codec_context->width * codec_context->height)*0.75;
codec_context->qmin = 20;
codec_context->qmax = 35;
} else {
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; break;
case VideoQuality::HIGH: case VideoQuality::HIGH:
codec_context->bit_rate = 10000000-5000000 + (codec_context->width * codec_context->height)*0.75; //codec_context->qmin = 34;
//codec_context->qmax = 34;
codec_context->bit_rate = 100000;//10000000-9000000 + (codec_context->width * codec_context->height)*0.75;
break; break;
case VideoQuality::VERY_HIGH: case VideoQuality::VERY_HIGH:
codec_context->bit_rate = 10000000-5000000 + (codec_context->width * codec_context->height)*0.75; //codec_context->qmin = 28;
//codec_context->qmax = 28;
codec_context->bit_rate = 100000;//10000000-9000000 + (codec_context->width * codec_context->height)*0.75;
break; break;
case VideoQuality::ULTRA: case VideoQuality::ULTRA:
codec_context->bit_rate = 10000000-5000000 + (codec_context->width * codec_context->height)*0.75; //codec_context->qmin = 22;
//codec_context->qmax = 22;
codec_context->bit_rate = 100000;//10000000-9000000 + (codec_context->width * codec_context->height)*0.75;
break; break;
} }
//codec_context->profile = FF_PROFILE_H264_MAIN; //codec_context->profile = FF_PROFILE_H264_MAIN;
@ -693,9 +689,9 @@ static AVCodecContext *create_video_codec_context(AVFormatContext *av_format_con
codec_context->bit_rate = 0; codec_context->bit_rate = 0;
#endif #endif
codec_context->rc_max_rate = codec_context->bit_rate; //codec_context->rc_max_rate = codec_context->bit_rate;
codec_context->rc_min_rate = codec_context->bit_rate; //codec_context->rc_min_rate = codec_context->bit_rate;
codec_context->rc_buffer_size = codec_context->bit_rate / 10; //codec_context->rc_buffer_size = codec_context->bit_rate / 10;
av_format_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; av_format_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
@ -796,28 +792,27 @@ static void open_video(AVCodecContext *codec_context,
AVDictionary *options = nullptr; AVDictionary *options = nullptr;
switch(video_quality) { switch(video_quality) {
case VideoQuality::MEDIUM: case VideoQuality::MEDIUM:
av_dict_set_int(&options, "qp", 35, 0); av_dict_set_int(&options, "qp", 40, 0);
av_dict_set(&options, "rc", "vbr", 0);
//av_dict_set(&options, "preset", "hq", 0);
break; break;
case VideoQuality::HIGH: case VideoQuality::HIGH:
av_dict_set_int(&options, "qp", 34, 0); av_dict_set_int(&options, "qp", 35, 0);
//av_dict_set(&options, "preset", "hq", 0);
break; break;
case VideoQuality::VERY_HIGH: case VideoQuality::VERY_HIGH:
av_dict_set_int(&options, "qp", 28, 0); av_dict_set_int(&options, "qp", 30, 0);
//av_dict_set(&options, "preset", "hq", 0);
break; break;
case VideoQuality::ULTRA: case VideoQuality::ULTRA:
av_dict_set_int(&options, "qp", 22, 0); av_dict_set_int(&options, "qp", 24, 0);
//av_dict_set(&options, "preset", "slow", 0);
break; break;
} }
if(is_livestream) { //if(is_livestream) {
av_dict_set_int(&options, "zerolatency", 1, 0); // av_dict_set_int(&options, "zerolatency", 1, 0);
//av_dict_set(&options, "preset", "llhq", 0); // //av_dict_set(&options, "preset", "llhq", 0);
} //}
av_dict_set(&options, "preset", "p7", 0);
av_dict_set(&options, "tune", "hq", 0);
av_dict_set(&options, "rc", "constqp", 0);
ret = avcodec_open2(codec_context, codec_context->codec, &options); ret = avcodec_open2(codec_context, codec_context->codec, &options);
if (ret < 0) { if (ret < 0) {
@ -866,7 +861,7 @@ static void usage() {
fprintf(stderr, " -r Replay buffer size in seconds. If this is set, then only the last seconds as set by this option will be stored" fprintf(stderr, " -r Replay buffer size in seconds. If this is set, then only the last seconds as set by this option will be stored"
" and the video will only be saved when the gpu-screen-recorder is closed. This feature is similar to Nvidia's instant replay feature." " and the video will only be saved when the gpu-screen-recorder is closed. This feature is similar to Nvidia's instant replay feature."
" This option has be between 5 and 1200. Note that the replay buffer size will not always be precise, because of keyframes. Optional, disabled by default.\n"); " This option has be between 5 and 1200. Note that the replay buffer size will not always be precise, because of keyframes. Optional, disabled by default.\n");
fprintf(stderr, " -k Codec to use. Should be either 'h264' or 'h265'. Defaults to 'h264' unless recording at a higher resolution than 3840x2160. Forcefully set to 'h264' if -c is 'flv.\n"); fprintf(stderr, " -k Codec to use. Should be either 'auto', 'h264' or 'h265'. Defaults to 'auto' which defaults to 'h265' unless recording at a higher resolution than 60. Forcefully set to 'h264' if -c is 'flv'.\n");
fprintf(stderr, " -o The output file path. If omitted then the encoded data is sent to stdout. Required in replay mode (when using -r). In replay mode this has to be an existing directory instead of a file.\n"); fprintf(stderr, " -o The output file path. If omitted then the encoded data is sent to stdout. Required in replay mode (when using -r). In replay mode this has to be an existing directory instead of a file.\n");
fprintf(stderr, "NOTES:\n"); fprintf(stderr, "NOTES:\n");
fprintf(stderr, " Send signal SIGINT (Ctrl+C) to gpu-screen-recorder to stop and save the recording (when not using replay mode).\n"); fprintf(stderr, " Send signal SIGINT (Ctrl+C) to gpu-screen-recorder to stop and save the recording (when not using replay mode).\n");
@ -1139,16 +1134,17 @@ int main(int argc, char **argv) {
VideoCodec video_codec; VideoCodec video_codec;
const char *codec_to_use = args["-k"].value(); const char *codec_to_use = args["-k"].value();
if(codec_to_use) { if(!codec_to_use)
codec_to_use = "auto";
if(strcmp(codec_to_use, "h264") == 0) { if(strcmp(codec_to_use, "h264") == 0) {
video_codec = VideoCodec::H264; video_codec = VideoCodec::H264;
} else if(strcmp(codec_to_use, "h265") == 0) { } else if(strcmp(codec_to_use, "h265") == 0) {
video_codec = VideoCodec::H265; video_codec = VideoCodec::H265;
} else { } else if(strcmp(codec_to_use, "auto") != 0) {
fprintf(stderr, "Error: -k should either be either 'h264' or 'h265', got: '%s'\n", codec_to_use); fprintf(stderr, "Error: -k should either be either 'auto', 'h264' or 'h265', got: '%s'\n", codec_to_use);
usage(); usage();
} }
}
const Arg &audio_input_arg = args["-a"]; const Arg &audio_input_arg = args["-a"];
const std::vector<AudioInput> audio_inputs = get_pulseaudio_inputs(); const std::vector<AudioInput> audio_inputs = get_pulseaudio_inputs();
@ -1405,18 +1401,18 @@ int main(int argc, char **argv) {
window_pixmap.texture_height = window_height; window_pixmap.texture_height = window_height;
} }
if(!codec_to_use) { if(strcmp(codec_to_use, "auto") == 0) {
// h265 generally allows recording at a higher resolution than h264 on nvidia cards. On a gtx 1080 4k is the max resolution for h264 but for h265 it's 8k. // h265 generally allows recording at a higher resolution than h264 on nvidia cards. On a gtx 1080 4k is the max resolution for h264 but for h265 it's 8k.
// Another important info is that when recording at a higher fps than.. 60? h265 has very bad performance. For example when recording at 144 fps the fps drops to 1 // Another important info is that when recording at a higher fps than.. 60? h265 has very bad performance. For example when recording at 144 fps the fps drops to 1
// while with h264 the fps doesn't drop. // while with h264 the fps doesn't drop.
if(window_width > 3840 || window_height > 2160) { if(fps > 60) {
fprintf(stderr, "Info: using h265 encoder because a codec was not specified and resolution width is more than 3840 or height is more than 2160\n"); fprintf(stderr, "Info: using h264 encoder because a codec was not specified and fps is more than 60\n");
codec_to_use = "h265";
video_codec = VideoCodec::H265;
} else {
fprintf(stderr, "Info: using h264 encoder because a codec was not specified\n");
codec_to_use = "h264"; codec_to_use = "h264";
video_codec = VideoCodec::H264; video_codec = VideoCodec::H264;
} else {
fprintf(stderr, "Info: using h265 encoder because a codec was not specified\n");
codec_to_use = "h265";
video_codec = VideoCodec::H265;
} }
} }