Compare commits

...

6 Commits
4.2.0 ... 4.2.2

Author SHA1 Message Date
dec05eba
eb602b9b53 4.2.2: AMD IS SHIT 2024-10-16 01:07:58 +02:00
dec05eba
19d77b8a96 Enable low latency encoding mode on amd (only available on amd since mesa version mesa 24.1.4) 2024-10-16 00:35:18 +02:00
dec05eba
601219febb README kdenlive 2024-10-14 14:22:37 +02:00
dec05eba
3e199f241a 4.2.1 2024-10-12 12:20:23 +02:00
dec05eba
a5895b775d appendum 2024-10-12 11:58:56 +02:00
dec05eba
2c4b077f43 Better frametimes when recording is too slow 2024-10-12 11:49:31 +02:00
5 changed files with 40 additions and 18 deletions

View File

@@ -168,4 +168,6 @@ Try recording to an SSD and make sure it's not using NTFS file system. Also reco
## The colors look washed out when recording a monitor with HDR enabled
You have to either record in hdr mode (-k `hevc_hdr` or -k `av1_hdr` option) to record a HDR video or record with desktop portal option (`-w portal`) to turn the HDR recording into SDR.
## GPU Screen Recorder records night light when recording in HDR mode
You can record with desktop portal option (`-w portal`) instead which ignores night light, if you are ok with recording without HDR.
You can record with desktop portal option (`-w portal`) instead which ignores night light, if you are ok with recording without HDR.
## Kdenlive says that the video is not usable for editing because it has variable frame rate
To fix this you can either record the video in .mkv format or constant frame rate (-fm cfr).

11
TODO
View File

@@ -156,9 +156,6 @@ Restart replay/update video resolution if monitor resolution changes.
Fix pure vaapi copy on intel.
ffmpeg supports vulkan encoding now (h264!). Doesn't work on amd yet because mesa is missing VK_KHR_video_maintenance1, see https://gitlab.freedesktop.org/mesa/mesa/-/issues/11857. Test on nvidia!
Test vaapi low latency mode (setenv("AMD_DEBUG", "lowlatencyenc", true);), added in mesa 24.1.4, released on july 17, 2024. Note that this forces gpu power usage to max at all times, even when recording at 2 fps.
Use nvidia low latency options for better encoding times.
Test ideal async_depth value. Increasing async_depth also increased gpu memory usage a lot (from 100mb to 500mb when moving from async_depth 2 to 16) at 4k resolution. Setting it to 8 increases it by 200mb which might be ok.
@@ -175,4 +172,10 @@ Support recording while in replay mode. This will be needed when enabling replay
Dynamically change bitrate/resolution to match desired fps. This would be helpful when streaming for example, where the encode output speed also depends on upload speed to the streaming service.
Implement opengl injection to capture texture. This fixes VRR without having to use NvFBC direct capture and also allows perfect frame timing.
Always use direct capture with NvFBC once the capture issue in mpv fullscreen has been resolved (maybe detect if direct capture fails in nvfbc and switch to non-direct recording. NvFBC says if direct capture fails).
Always use direct capture with NvFBC once the capture issue in mpv fullscreen has been resolved (maybe detect if direct capture fails in nvfbc and switch to non-direct recording. NvFBC says if direct capture fails).
Support ROI (AV_FRAME_DATA_REGIONS_OF_INTEREST).
Default to hevc if capture size is larger than 4096 in width or height.
Set low latency mode on vulkan encoding.

View File

@@ -1,4 +1,4 @@
project('gpu-screen-recorder', ['c', 'cpp'], version : '4.2.0', default_options : ['warning_level=2'])
project('gpu-screen-recorder', ['c', 'cpp'], version : '4.2.2', default_options : ['warning_level=2'])
add_project_arguments('-Wshadow', language : ['c', 'cpp'])
if get_option('buildtype') == 'debug'

View File

@@ -1,7 +1,7 @@
[package]
name = "gpu-screen-recorder"
type = "executable"
version = "4.2.0"
version = "4.2.2"
platforms = ["posix"]
[config]

View File

@@ -810,10 +810,9 @@ static void open_video_software(AVCodecContext *codec_context, VideoQuality vide
if(bitrate_mode == BitrateMode::QP)
video_software_set_qp(codec_context, video_quality, hdr, &options);
av_dict_set(&options, "preset", "medium", 0);
av_dict_set(&options, "preset", "fast", 0);
dict_set_profile(codec_context, GSR_GPU_VENDOR_INTEL, color_depth, &options);
// TODO: If streaming or piping output set this to zerolatency
av_dict_set(&options, "tune", "fastdecode", 0);
av_dict_set(&options, "tune", "zerolatency", 0);
if(codec_context->codec_id == AV_CODEC_ID_H264) {
av_dict_set(&options, "coder", "cabac", 0); // TODO: cavlc is faster than cabac but worse compression. Which to use?
@@ -990,6 +989,14 @@ static void open_video_hardware(AVCodecContext *codec_context, VideoQuality vide
// TODO: Enable multipass
if(vendor == GSR_GPU_VENDOR_NVIDIA) {
// TODO: Test these, if they are needed, if they should be used
// av_dict_set_int(&options, "zerolatency", 1, 0);
// if(codec_context->codec_id == AV_CODEC_ID_AV1) {
// av_dict_set(&options, "tune", "ll", 0);
// } else if(codec_context->codec_id == AV_CODEC_ID_H264 || codec_context->codec_id == AV_CODEC_ID_HEVC) {
// av_dict_set(&options, "preset", "llhq", 0);
// av_dict_set(&options, "tune", "ll", 0);
// }
av_dict_set(&options, "tune", "hq", 0);
dict_set_profile(codec_context, vendor, color_depth, &options);
@@ -2600,6 +2607,13 @@ int main(int argc, char **argv) {
// If this is set to 1 then cuGraphicsGLRegisterImage will fail for egl context with error: invalid OpenGL or DirectX context,
// so we overwrite it
setenv("__GL_THREADED_OPTIMIZATIONS", "0", true);
// Forces low latency encoding mode. Use this environment variable until vaapi supports setting this as a parameter.
// The downside of this is that it always uses maximum power, which is not ideal for replay mode that runs on system startup.
// This option was added in mesa 24.1.4, released on july 17, 2024.
// TODO: Add an option to enable/disable this?
// Seems like the performance issue is not in encoding, but rendering the frame.
// Some frames end up taking 10 times longer. Seems to be an issue with amd gpu power management when letting the application sleep on the cpu side?
setenv("AMD_DEBUG", "lowlatencyenc", true);
// Some people set this to nvidia (for nvdec) or vdpau (for nvidia vdpau), which breaks gpu screen recorder since
// nvidia doesn't support vaapi and nvidia-vaapi-driver doesn't support encoding yet.
// Let vaapi find the match vaapi driver instead of forcing a specific one.
@@ -3400,7 +3414,7 @@ int main(int argc, char **argv) {
}
double fps_start_time = clock_get_monotonic_seconds();
double frame_timer_start = fps_start_time;
//double frame_timer_start = fps_start_time;
int fps_counter = 0;
int damage_fps_counter = 0;
@@ -3638,7 +3652,7 @@ int main(int argc, char **argv) {
bool wait_until_frame_time_elapsed = false;
while(running) {
//const double frame_start = clock_get_monotonic_seconds();
const double frame_start = clock_get_monotonic_seconds();
while(gsr_egl_process_event(&egl)) {
gsr_damage_on_event(&damage, gsr_egl_get_event_data(&egl));
@@ -3780,7 +3794,8 @@ int main(int argc, char **argv) {
save_replay_async(video_codec_context, VIDEO_STREAM_INDEX, audio_tracks, frame_data_queue, frames_erased, filename, container_format, file_extension, write_output_mutex, date_folders, hdr, capture);
}
const double time_at_frame_end = clock_get_monotonic_seconds() - paused_time_offset;
const double frame_end = clock_get_monotonic_seconds();
const double time_at_frame_end = frame_end - paused_time_offset;
const double time_elapsed_total = time_at_frame_end - record_start_time;
const int64_t frames_elapsed = (int64_t)(time_elapsed_total / target_fps);
const double time_at_next_frame = (frames_elapsed + 1) * target_fps;
@@ -3788,16 +3803,18 @@ int main(int argc, char **argv) {
if(time_to_next_frame > target_fps*1.1)
time_to_next_frame = target_fps;
//const double frame_end = clock_get_monotonic_seconds();
//const double frame_time = frame_end - frame_start;
if(time_to_next_frame > 0.0)
const double frame_time = frame_end - frame_start;
const bool frame_deadline_missed = frame_time > target_fps;
if(time_to_next_frame > 0.0 && !frame_deadline_missed && frame_captured)
av_usleep(time_to_next_frame * 1000.0 * 1000.0);
else {
if(paused)
av_usleep(20.0 * 1000.0); // 10 milliseconds
av_usleep(20.0 * 1000.0); // 20 milliseconds
else if(frame_deadline_missed)
{}
else if(framerate_mode == FramerateMode::CONTENT || !frame_captured)
av_usleep(2.8 * 1000.0); // 2.8 milliseconds
else if(!damaged)
else if(!frame_captured)
av_usleep(1.0 * 1000.0); // 1 milliseconds
wait_until_frame_time_elapsed = true;
}