mirror of
https://repo.dec05eba.com/gpu-screen-recorder
synced 2026-03-31 09:07:13 +09:00
Prepare for video codec query, cleanup readme, add libva-drm as dependency
This commit is contained in:
72
README.md
72
README.md
@@ -55,43 +55,41 @@ from one of the official sources before reporting it as an issue.
|
|||||||
If you install GPU Screen Recorder flatpak, which is the gtk gui version then you can still run GPU Screen Recorder command line by using the flatpak command option, for example `flatpak run --command=gpu-screen-recorder com.dec05eba.gpu_screen_recorder -w screen -f 60 -o video.mp4`. Note that if you want to record your monitor on AMD/Intel then you need to install the flatpak system-wide (like so: `flatpak install flathub --system com.dec05eba.gpu_screen_recorder`).
|
If you install GPU Screen Recorder flatpak, which is the gtk gui version then you can still run GPU Screen Recorder command line by using the flatpak command option, for example `flatpak run --command=gpu-screen-recorder com.dec05eba.gpu_screen_recorder -w screen -f 60 -o video.mp4`. Note that if you want to record your monitor on AMD/Intel then you need to install the flatpak system-wide (like so: `flatpak install flathub --system com.dec05eba.gpu_screen_recorder`).
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
GPU Screen Recorder uses meson build system so you need to install `meson`. There are additional dependencies depending on your graphics card:
|
GPU Screen Recorder uses meson build system so you need to install `meson` to build GPU Screen Recorder:
|
||||||
## AMD
|
|
||||||
libglvnd (which provides libgl and libegl)\
|
## Build dependencies
|
||||||
mesa\
|
These are the dependencies needed to build GPU Screen Recorder:
|
||||||
ffmpeg (libavcodec, libavformat, libavutil, libswresample, libavfilter)\
|
|
||||||
x11 (libx11, libxcomposite, libxrandr, libxfixes, libxdamage, libxi)\
|
* libglvnd (which provides libgl and libegl)
|
||||||
libpulse\
|
* ffmpeg (libavcodec, libavformat, libavutil, libswresample, libavfilter)
|
||||||
vaapi (libva, libva-mesa-driver)\
|
* x11 (libx11, libxcomposite, libxrandr, libxfixes, libxdamage, libxi)
|
||||||
libdrm\
|
* libpulse
|
||||||
libcap\
|
* libva (and libva-drm)
|
||||||
wayland-client
|
* libdrm
|
||||||
## Intel
|
* libcap
|
||||||
libglvnd (which provides libgl and libegl)\
|
* wayland-client
|
||||||
mesa\
|
|
||||||
ffmpeg (libavcodec, libavformat, libavutil, libswresample, libavfilter)\
|
## Runtime dependencies
|
||||||
x11 (libx11, libxcomposite, libxrandr, libxfixes, libxdamage, libxi)\
|
There are also additional dependencies needed at runtime depending on your GPU vendor:
|
||||||
libpulse\
|
|
||||||
vaapi (libva, intel-media-driver/libva-intel-driver)\
|
### AMD
|
||||||
libdrm\
|
* mesa
|
||||||
libcap\
|
* vaapi (libva-mesa-driver)
|
||||||
wayland-client
|
|
||||||
## NVIDIA
|
### Intel
|
||||||
libglvnd (which provides libgl and libegl)\
|
* mesa
|
||||||
ffmpeg (libavcodec, libavformat, libavutil, libswresample, libavfilter)\
|
* vaapi (intel-media-driver/libva-intel-driver/linux-firmware, depending on which intel iGPU you have)
|
||||||
x11 (libx11, libxcomposite, libxrandr, libxfixes, libxdamage, libxi)\
|
|
||||||
libpulse\
|
### NVIDIA
|
||||||
cuda runtime (libcuda.so.1) (libnvidia-compute)\
|
* cuda runtime (libcuda.so.1) (libnvidia-compute)
|
||||||
nvenc (libnvidia-encode)\
|
* nvenc (libnvidia-encode)
|
||||||
libva\
|
* nvfbc (libnvidia-fbc1, when recording the screen on x11)
|
||||||
libdrm\
|
* xnvctrl (libxnvctrl0, when using the `-oc` option)
|
||||||
libcap\
|
|
||||||
wayland-client\
|
## Optional dependencies
|
||||||
nvfbc (libnvidia-fbc1, when recording the screen on x11)\
|
When compiling GPU Screen Recorder with portal support (`-Dportal=true`, which is enabled by default) these dependencies are also needed:
|
||||||
xnvctrl (libxnvctrl0, when using the `-oc` option)
|
* libdbus
|
||||||
## Optional dependencies when compiling with portal support (default option)
|
* libpipewire (and libspa which is usually part of libpipewire)
|
||||||
dbus\
|
|
||||||
libpipewire (and libspa which is usually part of libpipewire)
|
|
||||||
|
|
||||||
# How to use
|
# How to use
|
||||||
Run `gpu-screen-recorder --help` to see all options and also examples.
|
Run `gpu-screen-recorder --help` to see all options and also examples.
|
||||||
|
|||||||
@@ -8,7 +8,20 @@ typedef struct gsr_video_encoder gsr_video_encoder;
|
|||||||
typedef struct AVCodecContext AVCodecContext;
|
typedef struct AVCodecContext AVCodecContext;
|
||||||
typedef struct AVFrame AVFrame;
|
typedef struct AVFrame AVFrame;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool h264;
|
||||||
|
bool hevc;
|
||||||
|
bool hevc_hdr;
|
||||||
|
bool hevc_10bit;
|
||||||
|
bool av1;
|
||||||
|
bool av1_hdr;
|
||||||
|
bool av1_10bit;
|
||||||
|
bool vp8;
|
||||||
|
bool vp9;
|
||||||
|
} gsr_supported_video_codecs;
|
||||||
|
|
||||||
struct gsr_video_encoder {
|
struct gsr_video_encoder {
|
||||||
|
gsr_supported_video_codecs (*get_supported_codecs)(gsr_video_encoder *encoder, bool cleanup);
|
||||||
bool (*start)(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame);
|
bool (*start)(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame);
|
||||||
void (*copy_textures_to_frame)(gsr_video_encoder *encoder, AVFrame *frame); /* Can be NULL */
|
void (*copy_textures_to_frame)(gsr_video_encoder *encoder, AVFrame *frame); /* Can be NULL */
|
||||||
/* |textures| should be able to fit 2 elements */
|
/* |textures| should be able to fit 2 elements */
|
||||||
@@ -19,6 +32,7 @@ struct gsr_video_encoder {
|
|||||||
bool started;
|
bool started;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gsr_supported_video_codecs gsr_video_encoder_get_supported_codecs(gsr_video_encoder *encoder, bool cleanup);
|
||||||
bool gsr_video_encoder_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame);
|
bool gsr_video_encoder_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame);
|
||||||
void gsr_video_encoder_copy_textures_to_frame(gsr_video_encoder *encoder, AVFrame *frame);
|
void gsr_video_encoder_copy_textures_to_frame(gsr_video_encoder *encoder, AVFrame *frame);
|
||||||
void gsr_video_encoder_get_textures(gsr_video_encoder *encoder, unsigned int *textures, int *num_textures, gsr_destination_color *destination_color);
|
void gsr_video_encoder_get_textures(gsr_video_encoder *encoder, unsigned int *textures, int *num_textures, gsr_destination_color *destination_color);
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ dep = [
|
|||||||
dependency('libswresample'),
|
dependency('libswresample'),
|
||||||
dependency('libavfilter'),
|
dependency('libavfilter'),
|
||||||
dependency('libva'),
|
dependency('libva'),
|
||||||
|
dependency('libva-drm'),
|
||||||
dependency('libcap'),
|
dependency('libcap'),
|
||||||
dependency('libdrm'),
|
dependency('libdrm'),
|
||||||
dependency('wayland-egl'),
|
dependency('wayland-egl'),
|
||||||
|
|||||||
@@ -25,10 +25,11 @@ libpulse = ">=13"
|
|||||||
libswresample = ">=3"
|
libswresample = ">=3"
|
||||||
libavfilter = ">=5"
|
libavfilter = ">=5"
|
||||||
libva = ">=1"
|
libva = ">=1"
|
||||||
|
libva-drm = ">=1"
|
||||||
libcap = ">=2"
|
libcap = ">=2"
|
||||||
libdrm = ">=2"
|
libdrm = ">=2"
|
||||||
wayland-egl = ">=15"
|
wayland-egl = ">=15"
|
||||||
wayland-client = ">=1"
|
wayland-client = ">=1"
|
||||||
dbus-1 = ">=1"
|
dbus-1 = ">=1"
|
||||||
libpipewire-0.3 = ">=1"
|
libpipewire-0.3 = ">=1"
|
||||||
libspa-0.2 = ">=0"
|
libspa-0.2 = ">=0"
|
||||||
@@ -122,6 +122,24 @@ static bool gsr_video_encoder_cuda_setup_textures(gsr_video_encoder_cuda *self,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gsr_supported_video_codecs gsr_video_encoder_cuda_get_supported_codecs(gsr_video_encoder *encoder, bool cleanup) {
|
||||||
|
(void)encoder;
|
||||||
|
(void)cleanup;
|
||||||
|
//gsr_video_encoder_cuda *encoder_cuda = encoder->priv;
|
||||||
|
// TODO: Query support
|
||||||
|
return (gsr_supported_video_codecs) {
|
||||||
|
.h264 = true,
|
||||||
|
.hevc = true,
|
||||||
|
.hevc_hdr = true,
|
||||||
|
.hevc_10bit = true,
|
||||||
|
.av1 = true,
|
||||||
|
.av1_hdr = true,
|
||||||
|
.av1_10bit = true,
|
||||||
|
.vp8 = false,
|
||||||
|
.vp9 = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static void gsr_video_encoder_cuda_stop(gsr_video_encoder_cuda *self, AVCodecContext *video_codec_context);
|
static void gsr_video_encoder_cuda_stop(gsr_video_encoder_cuda *self, AVCodecContext *video_codec_context);
|
||||||
|
|
||||||
static bool gsr_video_encoder_cuda_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame) {
|
static bool gsr_video_encoder_cuda_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame) {
|
||||||
@@ -225,6 +243,7 @@ gsr_video_encoder* gsr_video_encoder_cuda_create(const gsr_video_encoder_cuda_pa
|
|||||||
encoder_cuda->params = *params;
|
encoder_cuda->params = *params;
|
||||||
|
|
||||||
*encoder = (gsr_video_encoder) {
|
*encoder = (gsr_video_encoder) {
|
||||||
|
.get_supported_codecs = gsr_video_encoder_cuda_get_supported_codecs,
|
||||||
.start = gsr_video_encoder_cuda_start,
|
.start = gsr_video_encoder_cuda_start,
|
||||||
.copy_textures_to_frame = gsr_video_encoder_cuda_copy_textures_to_frame,
|
.copy_textures_to_frame = gsr_video_encoder_cuda_copy_textures_to_frame,
|
||||||
.get_textures = gsr_video_encoder_cuda_get_textures,
|
.get_textures = gsr_video_encoder_cuda_get_textures,
|
||||||
|
|||||||
@@ -58,6 +58,22 @@ static bool gsr_video_encoder_software_setup_textures(gsr_video_encoder_software
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gsr_supported_video_codecs gsr_video_encoder_software_get_supported_codecs(gsr_video_encoder *encoder, bool cleanup) {
|
||||||
|
(void)encoder;
|
||||||
|
(void)cleanup;
|
||||||
|
return (gsr_supported_video_codecs) {
|
||||||
|
.h264 = true,
|
||||||
|
.hevc = false,
|
||||||
|
.hevc_hdr = false,
|
||||||
|
.hevc_10bit = false,
|
||||||
|
.av1 = false,
|
||||||
|
.av1_hdr = false,
|
||||||
|
.av1_10bit = false,
|
||||||
|
.vp8 = false,
|
||||||
|
.vp9 = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static void gsr_video_encoder_software_stop(gsr_video_encoder_software *self, AVCodecContext *video_codec_context);
|
static void gsr_video_encoder_software_stop(gsr_video_encoder_software *self, AVCodecContext *video_codec_context);
|
||||||
|
|
||||||
static bool gsr_video_encoder_software_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame) {
|
static bool gsr_video_encoder_software_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame) {
|
||||||
@@ -126,6 +142,7 @@ gsr_video_encoder* gsr_video_encoder_software_create(const gsr_video_encoder_sof
|
|||||||
encoder_software->params = *params;
|
encoder_software->params = *params;
|
||||||
|
|
||||||
*encoder = (gsr_video_encoder) {
|
*encoder = (gsr_video_encoder) {
|
||||||
|
.get_supported_codecs = gsr_video_encoder_software_get_supported_codecs,
|
||||||
.start = gsr_video_encoder_software_start,
|
.start = gsr_video_encoder_software_start,
|
||||||
.copy_textures_to_frame = gsr_video_encoder_software_copy_textures_to_frame,
|
.copy_textures_to_frame = gsr_video_encoder_software_copy_textures_to_frame,
|
||||||
.get_textures = gsr_video_encoder_software_get_textures,
|
.get_textures = gsr_video_encoder_software_get_textures,
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
#include <libavutil/hwcontext_vaapi.h>
|
#include <libavutil/hwcontext_vaapi.h>
|
||||||
|
|
||||||
#include <va/va_drmcommon.h>
|
#include <va/va_drmcommon.h>
|
||||||
|
#include <va/va_drm.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gsr_video_encoder_vaapi_params params;
|
gsr_video_encoder_vaapi_params params;
|
||||||
@@ -147,6 +149,174 @@ static bool gsr_video_encoder_vaapi_setup_textures(gsr_video_encoder_vaapi *self
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool profile_is_h264(VAProfile profile) {
|
||||||
|
switch(profile) {
|
||||||
|
case 5: // VAProfileH264Baseline
|
||||||
|
case VAProfileH264Main:
|
||||||
|
case VAProfileH264High:
|
||||||
|
case VAProfileH264ConstrainedBaseline:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool profile_is_hevc_8bit(VAProfile profile) {
|
||||||
|
switch(profile) {
|
||||||
|
case VAProfileHEVCMain:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool profile_is_hevc_10bit(VAProfile profile) {
|
||||||
|
switch(profile) {
|
||||||
|
case VAProfileHEVCMain10:
|
||||||
|
//case VAProfileHEVCMain12:
|
||||||
|
//case VAProfileHEVCMain422_10:
|
||||||
|
//case VAProfileHEVCMain422_12:
|
||||||
|
//case VAProfileHEVCMain444:
|
||||||
|
//case VAProfileHEVCMain444_10:
|
||||||
|
//case VAProfileHEVCMain444_12:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool profile_is_av1(VAProfile profile) {
|
||||||
|
switch(profile) {
|
||||||
|
case VAProfileAV1Profile0:
|
||||||
|
case VAProfileAV1Profile1:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool profile_is_vp8(VAProfile profile) {
|
||||||
|
switch(profile) {
|
||||||
|
case VAProfileVP8Version0_3:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool profile_is_vp9(VAProfile profile) {
|
||||||
|
switch(profile) {
|
||||||
|
case VAProfileVP9Profile0:
|
||||||
|
case VAProfileVP9Profile1:
|
||||||
|
case VAProfileVP9Profile2:
|
||||||
|
case VAProfileVP9Profile3:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool profile_supports_video_encoding(VADisplay va_dpy, VAProfile profile) {
|
||||||
|
int num_entrypoints = vaMaxNumEntrypoints(va_dpy);
|
||||||
|
if(num_entrypoints <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
VAEntrypoint *entrypoint_list = calloc(num_entrypoints, sizeof(VAEntrypoint));
|
||||||
|
if(!entrypoint_list)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool supported = false;
|
||||||
|
if(vaQueryConfigEntrypoints(va_dpy, profile, entrypoint_list, &num_entrypoints) == VA_STATUS_SUCCESS) {
|
||||||
|
for(int i = 0; i < num_entrypoints; ++i) {
|
||||||
|
if(entrypoint_list[i] == VAEntrypointEncSlice) {
|
||||||
|
supported = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(entrypoint_list);
|
||||||
|
return supported;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool get_supported_video_codecs(VADisplay va_dpy, gsr_supported_video_codecs *video_codecs, bool cleanup) {
|
||||||
|
*video_codecs = (gsr_supported_video_codecs){0};
|
||||||
|
bool success = false;
|
||||||
|
VAProfile *profile_list = NULL;
|
||||||
|
|
||||||
|
int va_major = 0;
|
||||||
|
int va_minor = 0;
|
||||||
|
if(vaInitialize(va_dpy, &va_major, &va_minor) != VA_STATUS_SUCCESS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int num_profiles = vaMaxNumProfiles(va_dpy);
|
||||||
|
if(num_profiles <= 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
profile_list = calloc(num_profiles, sizeof(VAProfile));
|
||||||
|
if(!profile_list || vaQueryConfigProfiles(va_dpy, profile_list, &num_profiles) != VA_STATUS_SUCCESS)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
for(int i = 0; i < num_profiles; ++i) {
|
||||||
|
if(profile_is_h264(profile_list[i])) {
|
||||||
|
if(profile_supports_video_encoding(va_dpy, profile_list[i]))
|
||||||
|
video_codecs->h264 = true;
|
||||||
|
} else if(profile_is_hevc_8bit(profile_list[i])) {
|
||||||
|
if(profile_supports_video_encoding(va_dpy, profile_list[i]))
|
||||||
|
video_codecs->hevc = true;
|
||||||
|
} else if(profile_is_hevc_10bit(profile_list[i])) {
|
||||||
|
if(profile_supports_video_encoding(va_dpy, profile_list[i])) {
|
||||||
|
video_codecs->hevc_hdr = true;
|
||||||
|
video_codecs->hevc_10bit = true;
|
||||||
|
}
|
||||||
|
} else if(profile_is_av1(profile_list[i])) {
|
||||||
|
if(profile_supports_video_encoding(va_dpy, profile_list[i])) {
|
||||||
|
video_codecs->av1 = true;
|
||||||
|
video_codecs->av1_hdr = true;
|
||||||
|
video_codecs->av1_10bit = true;
|
||||||
|
}
|
||||||
|
} else if(profile_is_vp8(profile_list[i])) {
|
||||||
|
if(profile_supports_video_encoding(va_dpy, profile_list[i]))
|
||||||
|
video_codecs->vp8 = true;
|
||||||
|
} else if(profile_is_vp9(profile_list[i])) {
|
||||||
|
if(profile_supports_video_encoding(va_dpy, profile_list[i]))
|
||||||
|
video_codecs->vp9 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
done:
|
||||||
|
if(profile_list)
|
||||||
|
free(profile_list);
|
||||||
|
|
||||||
|
if(cleanup)
|
||||||
|
vaTerminate(va_dpy);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gsr_supported_video_codecs gsr_video_encoder_vaapi_get_supported_codecs(gsr_video_encoder *encoder, bool cleanup) {
|
||||||
|
gsr_video_encoder_vaapi *encoder_vaapi = encoder->priv;
|
||||||
|
gsr_supported_video_codecs supported_video_codecs = {0};
|
||||||
|
|
||||||
|
const int drm_fd = open(encoder_vaapi->params.egl->card_path, O_RDWR);
|
||||||
|
if(drm_fd == -1) {
|
||||||
|
fprintf(stderr, "gsr error: gsr_video_encoder_vaapi_get_supported_codecs: failed to open device %s\n", encoder_vaapi->params.egl->card_path);
|
||||||
|
return supported_video_codecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
VADisplay va_dpy = vaGetDisplayDRM(drm_fd);
|
||||||
|
if(va_dpy) {
|
||||||
|
if(!get_supported_video_codecs(va_dpy, &supported_video_codecs, cleanup))
|
||||||
|
fprintf(stderr, "gsr error: gsr_video_encoder_vaapi_get_supported_codecs: failed to query supported video codecs for device %s\n", encoder_vaapi->params.egl->card_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cleanup)
|
||||||
|
close(drm_fd);
|
||||||
|
|
||||||
|
return supported_video_codecs;
|
||||||
|
}
|
||||||
|
|
||||||
static void gsr_video_encoder_vaapi_stop(gsr_video_encoder_vaapi *self, AVCodecContext *video_codec_context);
|
static void gsr_video_encoder_vaapi_stop(gsr_video_encoder_vaapi *self, AVCodecContext *video_codec_context);
|
||||||
|
|
||||||
static bool gsr_video_encoder_vaapi_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame) {
|
static bool gsr_video_encoder_vaapi_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame) {
|
||||||
@@ -234,6 +404,7 @@ gsr_video_encoder* gsr_video_encoder_vaapi_create(const gsr_video_encoder_vaapi_
|
|||||||
encoder_vaapi->params = *params;
|
encoder_vaapi->params = *params;
|
||||||
|
|
||||||
*encoder = (gsr_video_encoder) {
|
*encoder = (gsr_video_encoder) {
|
||||||
|
.get_supported_codecs = gsr_video_encoder_vaapi_get_supported_codecs,
|
||||||
.start = gsr_video_encoder_vaapi_start,
|
.start = gsr_video_encoder_vaapi_start,
|
||||||
.copy_textures_to_frame = NULL,
|
.copy_textures_to_frame = NULL,
|
||||||
.get_textures = gsr_video_encoder_vaapi_get_textures,
|
.get_textures = gsr_video_encoder_vaapi_get_textures,
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
#include "../../../include/encoder/video/video.h"
|
#include "../../../include/encoder/video/video.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
gsr_supported_video_codecs gsr_video_encoder_get_supported_codecs(gsr_video_encoder *encoder, bool cleanup) {
|
||||||
|
return encoder->get_supported_codecs(encoder, cleanup);
|
||||||
|
}
|
||||||
|
|
||||||
bool gsr_video_encoder_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame) {
|
bool gsr_video_encoder_start(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame) {
|
||||||
assert(!encoder->started);
|
assert(!encoder->started);
|
||||||
bool res = encoder->start(encoder, video_codec_context, frame);
|
bool res = encoder->start(encoder, video_codec_context, frame);
|
||||||
|
|||||||
102
src/main.cpp
102
src/main.cpp
@@ -1686,6 +1686,39 @@ static int init_filter_graph(AVCodecContext *audio_codec_context, AVFilterGraph
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gsr_video_encoder* create_video_encoder(gsr_egl *egl, bool overclock, gsr_color_depth color_depth, bool use_software_video_encoder) {
|
||||||
|
gsr_video_encoder *video_encoder = nullptr;
|
||||||
|
|
||||||
|
if(use_software_video_encoder) {
|
||||||
|
gsr_video_encoder_software_params params;
|
||||||
|
params.egl = egl;
|
||||||
|
params.color_depth = color_depth;
|
||||||
|
video_encoder = gsr_video_encoder_software_create(¶ms);
|
||||||
|
return video_encoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(egl->gpu_info.vendor) {
|
||||||
|
case GSR_GPU_VENDOR_AMD:
|
||||||
|
case GSR_GPU_VENDOR_INTEL: {
|
||||||
|
gsr_video_encoder_vaapi_params params;
|
||||||
|
params.egl = egl;
|
||||||
|
params.color_depth = color_depth;
|
||||||
|
video_encoder = gsr_video_encoder_vaapi_create(¶ms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GSR_GPU_VENDOR_NVIDIA: {
|
||||||
|
gsr_video_encoder_cuda_params params;
|
||||||
|
params.egl = egl;
|
||||||
|
params.overclock = overclock;
|
||||||
|
params.color_depth = color_depth;
|
||||||
|
video_encoder = gsr_video_encoder_cuda_create(¶ms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return video_encoder;
|
||||||
|
}
|
||||||
|
|
||||||
static void xwayland_check_callback(const gsr_monitor *monitor, void *userdata) {
|
static void xwayland_check_callback(const gsr_monitor *monitor, void *userdata) {
|
||||||
bool *xwayland_found = (bool*)userdata;
|
bool *xwayland_found = (bool*)userdata;
|
||||||
if(monitor->name_len >= 8 && strncmp(monitor->name, "XWAYLAND", 8) == 0)
|
if(monitor->name_len >= 8 && strncmp(monitor->name, "XWAYLAND", 8) == 0)
|
||||||
@@ -1735,6 +1768,7 @@ static void list_gpu_info(gsr_egl *egl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void list_supported_video_codecs(gsr_egl *egl, bool wayland) {
|
static void list_supported_video_codecs(gsr_egl *egl, bool wayland) {
|
||||||
|
#if 1
|
||||||
if(find_h264_encoder(egl->gpu_info.vendor, egl->card_path))
|
if(find_h264_encoder(egl->gpu_info.vendor, egl->card_path))
|
||||||
puts("h264");
|
puts("h264");
|
||||||
if(find_h264_software_encoder())
|
if(find_h264_software_encoder())
|
||||||
@@ -1755,6 +1789,34 @@ static void list_supported_video_codecs(gsr_egl *egl, bool wayland) {
|
|||||||
puts("vp8");
|
puts("vp8");
|
||||||
if(find_vp9_encoder(egl->gpu_info.vendor, egl->card_path))
|
if(find_vp9_encoder(egl->gpu_info.vendor, egl->card_path))
|
||||||
puts("vp9");
|
puts("vp9");
|
||||||
|
#else
|
||||||
|
// Dont clean it up on purpose to increase shutdown speed
|
||||||
|
gsr_video_encoder *video_encoder = create_video_encoder(egl, false, GSR_COLOR_DEPTH_8_BITS, false);
|
||||||
|
if(!video_encoder)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const gsr_supported_video_codecs supported_video_codecs = gsr_video_encoder_get_supported_codecs(video_encoder, false);
|
||||||
|
if(supported_video_codecs.h264)
|
||||||
|
puts("h264");
|
||||||
|
if(find_h264_software_encoder())
|
||||||
|
puts("h264_software");
|
||||||
|
if(supported_video_codecs.hevc) {
|
||||||
|
puts("hevc");
|
||||||
|
if(wayland)
|
||||||
|
puts("hevc_hdr"); // TODO: Verify if it's actually supported
|
||||||
|
puts("hevc_10bit"); // TODO: Verify if it's actually supported
|
||||||
|
}
|
||||||
|
if(supported_video_codecs.av1) {
|
||||||
|
puts("av1");
|
||||||
|
if(wayland)
|
||||||
|
puts("av1_hdr"); // TODO: Verify if it's actually supported
|
||||||
|
puts("av1_10bit"); // TODO: Verify if it's actually supported
|
||||||
|
}
|
||||||
|
if(supported_video_codecs.vp8)
|
||||||
|
puts("vp8");
|
||||||
|
if(supported_video_codecs.vp9)
|
||||||
|
puts("vp9");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool monitor_capture_use_drm(gsr_egl *egl, bool wayland) {
|
static bool monitor_capture_use_drm(gsr_egl *egl, bool wayland) {
|
||||||
@@ -1870,9 +1932,10 @@ static void info_command() {
|
|||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
gsr_egl_unload(&egl);
|
// Not needed as this will just slow down shutdown
|
||||||
if(dpy)
|
//gsr_egl_unload(&egl);
|
||||||
XCloseDisplay(dpy);
|
//if(dpy)
|
||||||
|
// XCloseDisplay(dpy);
|
||||||
|
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
@@ -2066,39 +2129,6 @@ static gsr_capture* create_capture_impl(const char *window_str, const char *scre
|
|||||||
return capture;
|
return capture;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gsr_video_encoder* create_video_encoder(gsr_egl *egl, bool overclock, gsr_color_depth color_depth, bool use_software_video_encoder) {
|
|
||||||
gsr_video_encoder *video_encoder = nullptr;
|
|
||||||
|
|
||||||
if(use_software_video_encoder) {
|
|
||||||
gsr_video_encoder_software_params params;
|
|
||||||
params.egl = egl;
|
|
||||||
params.color_depth = color_depth;
|
|
||||||
video_encoder = gsr_video_encoder_software_create(¶ms);
|
|
||||||
return video_encoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(egl->gpu_info.vendor) {
|
|
||||||
case GSR_GPU_VENDOR_AMD:
|
|
||||||
case GSR_GPU_VENDOR_INTEL: {
|
|
||||||
gsr_video_encoder_vaapi_params params;
|
|
||||||
params.egl = egl;
|
|
||||||
params.color_depth = color_depth;
|
|
||||||
video_encoder = gsr_video_encoder_vaapi_create(¶ms);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GSR_GPU_VENDOR_NVIDIA: {
|
|
||||||
gsr_video_encoder_cuda_params params;
|
|
||||||
params.egl = egl;
|
|
||||||
params.overclock = overclock;
|
|
||||||
params.color_depth = color_depth;
|
|
||||||
video_encoder = gsr_video_encoder_cuda_create(¶ms);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return video_encoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
static AVPixelFormat get_pixel_format(gsr_gpu_vendor vendor, bool use_software_video_encoder) {
|
static AVPixelFormat get_pixel_format(gsr_gpu_vendor vendor, bool use_software_video_encoder) {
|
||||||
if(use_software_video_encoder) {
|
if(use_software_video_encoder) {
|
||||||
return AV_PIX_FMT_NV12;
|
return AV_PIX_FMT_NV12;
|
||||||
|
|||||||
Reference in New Issue
Block a user