aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/capture/capture.h65
-rw-r--r--include/capture/kms.h52
-rw-r--r--include/capture/kms_cuda.h19
-rw-r--r--include/capture/kms_vaapi.h19
-rw-r--r--include/capture/nvfbc.h4
-rw-r--r--include/capture/portal.h18
-rw-r--r--include/capture/xcomposite.h38
-rw-r--r--include/capture/xcomposite_cuda.h14
-rw-r--r--include/capture/xcomposite_vaapi.h13
-rw-r--r--include/codec_query/codec_query.h18
-rw-r--r--include/codec_query/cuda.h8
-rw-r--r--include/codec_query/vaapi.h8
-rw-r--r--include/codec_query/vulkan.h8
-rw-r--r--include/color_conversion.h5
-rw-r--r--include/cursor.h4
-rw-r--r--include/damage.h51
-rw-r--r--include/dbus.h45
-rw-r--r--include/defs.h3
-rw-r--r--include/egl.h61
-rw-r--r--include/encoder/video/cuda.h16
-rw-r--r--include/encoder/video/software.h15
-rw-r--r--include/encoder/video/vaapi.h15
-rw-r--r--include/encoder/video/video.h27
-rw-r--r--include/encoder/video/vulkan.h15
-rw-r--r--include/pipewire.h112
-rw-r--r--include/sound.hpp8
-rw-r--r--include/utils.h18
-rw-r--r--include/window_texture.h1
28 files changed, 479 insertions, 201 deletions
diff --git a/include/capture/capture.h b/include/capture/capture.h
index 2eb8e42..7c8887d 100644
--- a/include/capture/capture.h
+++ b/include/capture/capture.h
@@ -3,66 +3,43 @@
#include "../color_conversion.h"
#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
typedef struct AVCodecContext AVCodecContext;
+typedef struct AVStream AVStream;
typedef struct AVFrame AVFrame;
-typedef void* VADisplay;
-typedef struct _VADRMPRIMESurfaceDescriptor VADRMPRIMESurfaceDescriptor;
-typedef struct gsr_cuda gsr_cuda;
-typedef struct AVFrame AVFrame;
-typedef struct CUgraphicsResource_st *CUgraphicsResource;
-typedef struct CUarray_st *CUarray;
-typedef struct CUctx_st *CUcontext;
-typedef struct CUstream_st *CUstream;
-
typedef struct gsr_capture gsr_capture;
+typedef struct AVMasteringDisplayMetadata AVMasteringDisplayMetadata;
+typedef struct AVContentLightMetadata AVContentLightMetadata;
struct gsr_capture {
/* These methods should not be called manually. Call gsr_capture_* instead */
int (*start)(gsr_capture *cap, AVCodecContext *video_codec_context, AVFrame *frame);
- void (*tick)(gsr_capture *cap, AVCodecContext *video_codec_context); /* can be NULL */
- bool (*should_stop)(gsr_capture *cap, bool *err); /* can be NULL */
- int (*capture)(gsr_capture *cap, AVFrame *frame);
- void (*capture_end)(gsr_capture *cap, AVFrame *frame); /* can be NULL */
+ void (*on_event)(gsr_capture *cap, gsr_egl *egl); /* can be NULL */
+ void (*tick)(gsr_capture *cap); /* can be NULL. If there is an event then |on_event| is called before this */
+ bool (*should_stop)(gsr_capture *cap, bool *err); /* can be NULL. If NULL, return false */
+ int (*capture)(gsr_capture *cap, AVFrame *frame, gsr_color_conversion *color_conversion);
+ gsr_source_color (*get_source_color)(gsr_capture *cap);
+ bool (*uses_external_image)(gsr_capture *cap); /* can be NULL. If NULL, return false */
+ bool (*set_hdr_metadata)(gsr_capture *cap, AVMasteringDisplayMetadata *mastering_display_metadata, AVContentLightMetadata *light_metadata); /* can be NULL. If NULL, return false */
+ uint64_t (*get_window_id)(gsr_capture *cap); /* can be NULL. Returns 0 if unknown */
+ bool (*is_damaged)(gsr_capture *cap); /* can be NULL */
+ void (*clear_damage)(gsr_capture *cap); /* can be NULL */
void (*destroy)(gsr_capture *cap, AVCodecContext *video_codec_context);
void *priv; /* can be NULL */
bool started;
};
-typedef struct gsr_capture_base gsr_capture_base;
-
-struct gsr_capture_base {
- gsr_egl *egl;
-
- unsigned int input_texture;
- unsigned int target_textures[2];
- unsigned int cursor_texture;
-
- gsr_color_conversion color_conversion;
-
- AVCodecContext *video_codec_context;
-};
-
-typedef struct {
- gsr_cuda *cuda;
- CUgraphicsResource *cuda_graphics_resources;
- CUarray *mapped_arrays;
-} gsr_cuda_context;
-
int gsr_capture_start(gsr_capture *cap, AVCodecContext *video_codec_context, AVFrame *frame);
-void gsr_capture_tick(gsr_capture *cap, AVCodecContext *video_codec_context);
+void gsr_capture_on_event(gsr_capture *cap, gsr_egl *egl);
+void gsr_capture_tick(gsr_capture *cap);
bool gsr_capture_should_stop(gsr_capture *cap, bool *err);
-int gsr_capture_capture(gsr_capture *cap, AVFrame *frame);
-void gsr_capture_end(gsr_capture *cap, AVFrame *frame);
-/* Calls |gsr_capture_stop| as well */
+int gsr_capture_capture(gsr_capture *cap, AVFrame *frame, gsr_color_conversion *color_conversion);
+gsr_source_color gsr_capture_get_source_color(gsr_capture *cap);
+bool gsr_capture_uses_external_image(gsr_capture *cap);
+bool gsr_capture_set_hdr_metadata(gsr_capture *cap, AVMasteringDisplayMetadata *mastering_display_metadata, AVContentLightMetadata *light_metadata);
void gsr_capture_destroy(gsr_capture *cap, AVCodecContext *video_codec_context);
-bool gsr_capture_base_setup_vaapi_textures(gsr_capture_base *self, AVFrame *frame, VADisplay va_dpy, VADRMPRIMESurfaceDescriptor *prime, gsr_color_range color_range);
-bool gsr_capture_base_setup_cuda_textures(gsr_capture_base *self, AVFrame *frame, gsr_cuda_context *cuda_context, gsr_color_range color_range, gsr_source_color source_color, bool hdr);
-void gsr_capture_base_stop(gsr_capture_base *self);
-
-bool drm_create_codec_context(const char *card_path, AVCodecContext *video_codec_context, int width, int height, bool hdr, VADisplay *va_dpy);
-bool cuda_create_codec_context(CUcontext cu_ctx, AVCodecContext *video_codec_context, int width, int height, bool hdr, CUstream *cuda_stream);
-
#endif /* GSR_CAPTURE_CAPTURE_H */
diff --git a/include/capture/kms.h b/include/capture/kms.h
index 674813a..646928e 100644
--- a/include/capture/kms.h
+++ b/include/capture/kms.h
@@ -2,49 +2,17 @@
#define GSR_CAPTURE_KMS_H
#include "capture.h"
-#include "../../kms/client/kms_client.h"
-#include "../color_conversion.h"
-#include "../vec2.h"
-#include "../defs.h"
-#include <stdbool.h>
-
-typedef struct AVCodecContext AVCodecContext;
-typedef struct AVMasteringDisplayMetadata AVMasteringDisplayMetadata;
-typedef struct AVContentLightMetadata AVContentLightMetadata;
-typedef struct gsr_capture_kms gsr_capture_kms;
-typedef struct gsr_egl gsr_egl;
-typedef struct AVFrame AVFrame;
-
-#define MAX_CONNECTOR_IDS 32
typedef struct {
- uint32_t connector_ids[MAX_CONNECTOR_IDS];
- int num_connector_ids;
-} MonitorId;
-
-struct gsr_capture_kms {
- gsr_capture_base base;
-
- bool should_stop;
- bool stop_is_error;
-
- gsr_kms_client kms_client;
- gsr_kms_response kms_response;
-
- vec2i capture_pos;
- vec2i capture_size;
- MonitorId monitor_id;
-
- AVMasteringDisplayMetadata *mastering_display_metadata;
- AVContentLightMetadata *light_metadata;
-
- gsr_monitor_rotation monitor_rotation;
-};
-
-/* Returns 0 on success */
-int gsr_capture_kms_start(gsr_capture_kms *self, const char *display_to_capture, gsr_egl *egl, AVCodecContext *video_codec_context, AVFrame *frame);
-void gsr_capture_kms_stop(gsr_capture_kms *self);
-bool gsr_capture_kms_capture(gsr_capture_kms *self, AVFrame *frame, bool hdr, bool screen_plane_use_modifiers, bool cursor_texture_is_external, bool record_cursor);
-void gsr_capture_kms_cleanup_kms_fds(gsr_capture_kms *self);
+ gsr_egl *egl;
+ const char *display_to_capture; /* if this is "screen", then the first monitor is captured. A copy is made of this */
+ gsr_color_depth color_depth;
+ gsr_color_range color_range;
+ bool hdr;
+ bool record_cursor;
+ int fps;
+} gsr_capture_kms_params;
+
+gsr_capture* gsr_capture_kms_create(const gsr_capture_kms_params *params);
#endif /* GSR_CAPTURE_KMS_H */
diff --git a/include/capture/kms_cuda.h b/include/capture/kms_cuda.h
deleted file mode 100644
index 433e053..0000000
--- a/include/capture/kms_cuda.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef GSR_CAPTURE_KMS_CUDA_H
-#define GSR_CAPTURE_KMS_CUDA_H
-
-#include "../vec2.h"
-#include "../utils.h"
-#include "../color_conversion.h"
-#include "capture.h"
-
-typedef struct {
- gsr_egl *egl;
- const char *display_to_capture; /* if this is "screen", then the first monitor is captured. A copy is made of this */
- bool hdr;
- gsr_color_range color_range;
- bool record_cursor;
-} gsr_capture_kms_cuda_params;
-
-gsr_capture* gsr_capture_kms_cuda_create(const gsr_capture_kms_cuda_params *params);
-
-#endif /* GSR_CAPTURE_KMS_CUDA_H */
diff --git a/include/capture/kms_vaapi.h b/include/capture/kms_vaapi.h
deleted file mode 100644
index bf078b5..0000000
--- a/include/capture/kms_vaapi.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef GSR_CAPTURE_KMS_VAAPI_H
-#define GSR_CAPTURE_KMS_VAAPI_H
-
-#include "../vec2.h"
-#include "../utils.h"
-#include "../color_conversion.h"
-#include "capture.h"
-
-typedef struct {
- gsr_egl *egl;
- const char *display_to_capture; /* if this is "screen", then the first monitor is captured. A copy is made of this */
- bool hdr;
- gsr_color_range color_range;
- bool record_cursor;
-} gsr_capture_kms_vaapi_params;
-
-gsr_capture* gsr_capture_kms_vaapi_create(const gsr_capture_kms_vaapi_params *params);
-
-#endif /* GSR_CAPTURE_KMS_VAAPI_H */
diff --git a/include/capture/nvfbc.h b/include/capture/nvfbc.h
index 36bc2b6..95ca88d 100644
--- a/include/capture/nvfbc.h
+++ b/include/capture/nvfbc.h
@@ -11,10 +11,10 @@ typedef struct {
vec2i pos;
vec2i size;
bool direct_capture;
- bool overclock;
- bool hdr;
+ gsr_color_depth color_depth;
gsr_color_range color_range;
bool record_cursor;
+ bool use_software_video_encoder;
} gsr_capture_nvfbc_params;
gsr_capture* gsr_capture_nvfbc_create(const gsr_capture_nvfbc_params *params);
diff --git a/include/capture/portal.h b/include/capture/portal.h
new file mode 100644
index 0000000..2e2c6f2
--- /dev/null
+++ b/include/capture/portal.h
@@ -0,0 +1,18 @@
+#ifndef GSR_CAPTURE_PORTAL_H
+#define GSR_CAPTURE_PORTAL_H
+
+#include "capture.h"
+
+typedef struct {
+ gsr_egl *egl;
+ gsr_color_depth color_depth;
+ gsr_color_range color_range;
+ bool record_cursor;
+ bool restore_portal_session;
+ /* If this is set to NULL then this defaults to $XDG_CONFIG_HOME/gpu-screen-recorder/restore_token ($XDG_CONFIG_HOME defaults to $HOME/.config) */
+ const char *portal_session_token_filepath;
+} gsr_capture_portal_params;
+
+gsr_capture* gsr_capture_portal_create(const gsr_capture_portal_params *params);
+
+#endif /* GSR_CAPTURE_PORTAL_H */
diff --git a/include/capture/xcomposite.h b/include/capture/xcomposite.h
index ce0dbad..8c87404 100644
--- a/include/capture/xcomposite.h
+++ b/include/capture/xcomposite.h
@@ -2,50 +2,18 @@
#define GSR_CAPTURE_XCOMPOSITE_H
#include "capture.h"
-#include "../egl.h"
#include "../vec2.h"
-#include "../color_conversion.h"
-#include "../window_texture.h"
-#include "../cursor.h"
typedef struct {
gsr_egl *egl;
- Window window;
+ unsigned long window;
bool follow_focused; /* If this is set then |window| is ignored */
vec2i region_size; /* This is currently only used with |follow_focused| */
gsr_color_range color_range;
bool record_cursor;
+ gsr_color_depth color_depth;
} gsr_capture_xcomposite_params;
-typedef struct {
- gsr_capture_base base;
- gsr_capture_xcomposite_params params;
- XEvent xev;
-
- bool should_stop;
- bool stop_is_error;
- bool window_resized;
- bool follow_focused_initialized;
-
- Window window;
- vec2i window_size;
- vec2i texture_size;
- double window_resize_timer;
-
- WindowTexture window_texture;
-
- Atom net_active_window_atom;
-
- gsr_cursor cursor;
- bool clear_next_frame;
-} gsr_capture_xcomposite;
-
-void gsr_capture_xcomposite_init(gsr_capture_xcomposite *self, const gsr_capture_xcomposite_params *params);
-
-int gsr_capture_xcomposite_start(gsr_capture_xcomposite *self, AVCodecContext *video_codec_context, AVFrame *frame);
-void gsr_capture_xcomposite_stop(gsr_capture_xcomposite *self);
-void gsr_capture_xcomposite_tick(gsr_capture_xcomposite *self, AVCodecContext *video_codec_context);
-bool gsr_capture_xcomposite_should_stop(gsr_capture_xcomposite *self, bool *err);
-int gsr_capture_xcomposite_capture(gsr_capture_xcomposite *self, AVFrame *frame);
+gsr_capture* gsr_capture_xcomposite_create(const gsr_capture_xcomposite_params *params);
#endif /* GSR_CAPTURE_XCOMPOSITE_H */
diff --git a/include/capture/xcomposite_cuda.h b/include/capture/xcomposite_cuda.h
deleted file mode 100644
index b93c6de..0000000
--- a/include/capture/xcomposite_cuda.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef GSR_CAPTURE_XCOMPOSITE_CUDA_H
-#define GSR_CAPTURE_XCOMPOSITE_CUDA_H
-
-#include "capture.h"
-#include "xcomposite.h"
-
-typedef struct {
- gsr_capture_xcomposite_params base;
- bool overclock;
-} gsr_capture_xcomposite_cuda_params;
-
-gsr_capture* gsr_capture_xcomposite_cuda_create(const gsr_capture_xcomposite_cuda_params *params);
-
-#endif /* GSR_CAPTURE_XCOMPOSITE_CUDA_H */
diff --git a/include/capture/xcomposite_vaapi.h b/include/capture/xcomposite_vaapi.h
deleted file mode 100644
index 5d4b338..0000000
--- a/include/capture/xcomposite_vaapi.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef GSR_CAPTURE_XCOMPOSITE_VAAPI_H
-#define GSR_CAPTURE_XCOMPOSITE_VAAPI_H
-
-#include "capture.h"
-#include "xcomposite.h"
-
-typedef struct {
- gsr_capture_xcomposite_params base;
-} gsr_capture_xcomposite_vaapi_params;
-
-gsr_capture* gsr_capture_xcomposite_vaapi_create(const gsr_capture_xcomposite_vaapi_params *params);
-
-#endif /* GSR_CAPTURE_XCOMPOSITE_VAAPI_H */
diff --git a/include/codec_query/codec_query.h b/include/codec_query/codec_query.h
new file mode 100644
index 0000000..7d5a292
--- /dev/null
+++ b/include/codec_query/codec_query.h
@@ -0,0 +1,18 @@
+#ifndef GSR_CODEC_QUERY_H
+#define GSR_CODEC_QUERY_H
+
+#include <stdbool.h>
+
+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;
+
+#endif /* GSR_CODEC_QUERY_H */
diff --git a/include/codec_query/cuda.h b/include/codec_query/cuda.h
new file mode 100644
index 0000000..b57c4ee
--- /dev/null
+++ b/include/codec_query/cuda.h
@@ -0,0 +1,8 @@
+#ifndef GSR_CODEC_QUERY_CUDA_H
+#define GSR_CODEC_QUERY_CUDA_H
+
+#include "codec_query.h"
+
+bool gsr_get_supported_video_codecs_nvenc(gsr_supported_video_codecs *video_codecs, bool cleanup);
+
+#endif /* GSR_CODEC_QUERY_CUDA_H */
diff --git a/include/codec_query/vaapi.h b/include/codec_query/vaapi.h
new file mode 100644
index 0000000..60bdeca
--- /dev/null
+++ b/include/codec_query/vaapi.h
@@ -0,0 +1,8 @@
+#ifndef GSR_CODEC_QUERY_VAAPI_H
+#define GSR_CODEC_QUERY_VAAPI_H
+
+#include "codec_query.h"
+
+bool gsr_get_supported_video_codecs_vaapi(gsr_supported_video_codecs *video_codecs, const char *card_path, bool cleanup);
+
+#endif /* GSR_CODEC_QUERY_VAAPI_H */
diff --git a/include/codec_query/vulkan.h b/include/codec_query/vulkan.h
new file mode 100644
index 0000000..bb06c6b
--- /dev/null
+++ b/include/codec_query/vulkan.h
@@ -0,0 +1,8 @@
+#ifndef GSR_CODEC_QUERY_VULKAN_H
+#define GSR_CODEC_QUERY_VULKAN_H
+
+#include "codec_query.h"
+
+bool gsr_get_supported_video_codecs_vulkan(gsr_supported_video_codecs *video_codecs, const char *card_path, bool cleanup);
+
+#endif /* GSR_CODEC_QUERY_VULKAN_H */
diff --git a/include/color_conversion.h b/include/color_conversion.h
index d05df6a..236bfbd 100644
--- a/include/color_conversion.h
+++ b/include/color_conversion.h
@@ -11,6 +11,11 @@ typedef enum {
} gsr_color_range;
typedef enum {
+ GSR_COLOR_DEPTH_8_BITS,
+ GSR_COLOR_DEPTH_10_BITS
+} gsr_color_depth;
+
+typedef enum {
GSR_SOURCE_COLOR_RGB,
GSR_SOURCE_COLOR_BGR
} gsr_source_color;
diff --git a/include/cursor.h b/include/cursor.h
index b1ec6bd..1564714 100644
--- a/include/cursor.h
+++ b/include/cursor.h
@@ -15,12 +15,14 @@ typedef struct {
vec2i position;
bool cursor_image_set;
+ bool visible;
} gsr_cursor;
int gsr_cursor_init(gsr_cursor *self, gsr_egl *egl, Display *display);
void gsr_cursor_deinit(gsr_cursor *self);
-void gsr_cursor_update(gsr_cursor *self, XEvent *xev);
+/* Returns true if the cursor image has updated or if the cursor has moved */
+bool gsr_cursor_on_event(gsr_cursor *self, XEvent *xev);
void gsr_cursor_tick(gsr_cursor *self, Window relative_to);
#endif /* GSR_CURSOR_H */
diff --git a/include/damage.h b/include/damage.h
new file mode 100644
index 0000000..7229418
--- /dev/null
+++ b/include/damage.h
@@ -0,0 +1,51 @@
+#ifndef GSR_DAMAGE_H
+#define GSR_DAMAGE_H
+
+#include "cursor.h"
+#include "utils.h"
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef struct _XDisplay Display;
+typedef union _XEvent XEvent;
+
+typedef enum {
+ GSR_DAMAGE_TRACK_NONE,
+ GSR_DAMAGE_TRACK_WINDOW,
+ GSR_DAMAGE_TRACK_MONITOR
+} gsr_damage_track_type;
+
+typedef struct {
+ gsr_egl *egl;
+ bool track_cursor;
+ gsr_damage_track_type track_type;
+
+ int damage_event;
+ int damage_error;
+ uint64_t damage;
+ bool damaged;
+
+ int randr_event;
+ int randr_error;
+
+ uint64_t window;
+ //vec2i window_pos;
+ vec2i window_size;
+
+ gsr_cursor cursor; /* Relative to |window| */
+ gsr_monitor monitor;
+ char monitor_name[32];
+} gsr_damage;
+
+bool gsr_damage_init(gsr_damage *self, gsr_egl *egl, bool track_cursor);
+void gsr_damage_deinit(gsr_damage *self);
+
+bool gsr_damage_set_target_window(gsr_damage *self, uint64_t window);
+bool gsr_damage_set_target_monitor(gsr_damage *self, const char *monitor_name);
+void gsr_damage_on_event(gsr_damage *self, XEvent *xev);
+void gsr_damage_tick(gsr_damage *self);
+/* Also returns true if damage tracking is not available */
+bool gsr_damage_is_damaged(gsr_damage *self);
+void gsr_damage_clear(gsr_damage *self);
+
+#endif /* GSR_DAMAGE_H */
diff --git a/include/dbus.h b/include/dbus.h
new file mode 100644
index 0000000..6978634
--- /dev/null
+++ b/include/dbus.h
@@ -0,0 +1,45 @@
+#ifndef GSR_DBUS_H
+#define GSR_DBUS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <dbus/dbus.h>
+
+#define DBUS_RANDOM_STR_SIZE 16
+
+typedef struct {
+ DBusConnection *con;
+ DBusError err;
+ char random_str[DBUS_RANDOM_STR_SIZE + 1];
+ unsigned int handle_counter;
+ bool desktop_portal_rule_added;
+ uint32_t screencast_version;
+ char *screencast_restore_token;
+} gsr_dbus;
+
+typedef enum {
+ GSR_PORTAL_CAPTURE_TYPE_MONITOR = 1 << 0,
+ GSR_PORTAL_CAPTURE_TYPE_WINDOW = 1 << 1,
+ GSR_PORTAL_CAPTURE_TYPE_VIRTUAL = 1 << 2,
+ GSR_PORTAL_CAPTURE_TYPE_ALL = GSR_PORTAL_CAPTURE_TYPE_MONITOR | GSR_PORTAL_CAPTURE_TYPE_WINDOW | GSR_PORTAL_CAPTURE_TYPE_VIRTUAL
+} gsr_portal_capture_type;
+
+typedef enum {
+ GSR_PORTAL_CURSOR_MODE_HIDDEN = 1 << 0,
+ GSR_PORTAL_CURSOR_MODE_EMBEDDED = 1 << 1,
+ GSR_PORTAL_CURSOR_MODE_METADATA = 1 << 2
+} gsr_portal_cursor_mode;
+
+/* Blocking. TODO: Make non-blocking */
+bool gsr_dbus_init(gsr_dbus *self, const char *screencast_restore_token);
+void gsr_dbus_deinit(gsr_dbus *self);
+
+/* The follow functions should be called in order to setup ScreenCast properly */
+/* These functions that return an int return the response status code */
+int gsr_dbus_screencast_create_session(gsr_dbus *self, char **session_handle);
+int gsr_dbus_screencast_select_sources(gsr_dbus *self, const char *session_handle, gsr_portal_capture_type capture_type, gsr_portal_cursor_mode cursor_mode);
+int gsr_dbus_screencast_start(gsr_dbus *self, const char *session_handle, uint32_t *pipewire_node);
+bool gsr_dbus_screencast_open_pipewire_remote(gsr_dbus *self, const char *session_handle, int *pipewire_fd);
+const char* gsr_dbus_screencast_get_restore_token(gsr_dbus *self);
+
+#endif /* GSR_DBUS_H */
diff --git a/include/defs.h b/include/defs.h
index 473583c..8fd2ddc 100644
--- a/include/defs.h
+++ b/include/defs.h
@@ -1,6 +1,8 @@
#ifndef GSR_DEFS_H
#define GSR_DEFS_H
+#include <stdbool.h>
+
typedef enum {
GSR_GPU_VENDOR_AMD,
GSR_GPU_VENDOR_INTEL,
@@ -10,6 +12,7 @@ typedef enum {
typedef struct {
gsr_gpu_vendor vendor;
int gpu_version; /* 0 if unknown */
+ bool is_steam_deck;
} gsr_gpu_info;
typedef enum {
diff --git a/include/egl.h b/include/egl.h
index afdb5a9..82014b9 100644
--- a/include/egl.h
+++ b/include/egl.h
@@ -43,7 +43,9 @@ typedef void(*__GLXextFuncPtr)(void);
#define EGL_BUFFER_SIZE 0x3020
#define EGL_RENDERABLE_TYPE 0x3040
#define EGL_OPENGL_API 0x30A2
+#define EGL_OPENGL_ES_API 0x30A0
#define EGL_OPENGL_BIT 0x0008
+#define EGL_OPENGL_ES_BIT 0x0001
#define EGL_NONE 0x3038
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
#define EGL_BACK_BUFFER 0x3084
@@ -57,8 +59,23 @@ typedef void(*__GLXextFuncPtr)(void);
#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
+#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275
+#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276
+#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277
+#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278
+#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279
+#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A
+#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440
+#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441
+#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442
#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443
#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444
+#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445
+#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446
+#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447
+#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448
+#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449
+#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A
#define EGL_LINUX_DMA_BUF_EXT 0x3270
#define EGL_RED_SIZE 0x3024
#define EGL_ALPHA_SIZE 0x3021
@@ -78,9 +95,9 @@ typedef void(*__GLXextFuncPtr)(void);
#define GL_TEXTURE_2D 0x0DE1
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
#define GL_RED 0x1903
-#define GL_GREEN 0x1904
-#define GL_BLUE 0x1905
-#define GL_ALPHA 0x1906
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_ALPHA 0x1906
#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
#define GL_RG 0x8227
#define GL_RGB 0x1907
@@ -104,12 +121,13 @@ typedef void(*__GLXextFuncPtr)(void);
#define GL_FRAMEBUFFER 0x8D40
#define GL_COLOR_ATTACHMENT0 0x8CE0
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
-#define GL_STREAM_DRAW 0x88E0
+#define GL_DYNAMIC_DRAW 0x88E8
#define GL_ARRAY_BUFFER 0x8892
#define GL_BLEND 0x0BE2
#define GL_SRC_ALPHA 0x0302
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_SCISSOR_TEST 0x0C11
#define GL_VENDOR 0x1F00
#define GL_RENDERER 0x1F01
@@ -131,12 +149,25 @@ typedef int (*FUNC_glXSwapIntervalSGI)(int interval);
typedef void (*GLDEBUGPROC)(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, int length, const char *message, const void *userParam);
typedef int (*FUNC_eglQueryDisplayAttribEXT)(EGLDisplay dpy, int32_t attribute, intptr_t *value);
typedef const char* (*FUNC_eglQueryDeviceStringEXT)(void *device, int32_t name);
+typedef int (*FUNC_eglQueryDmaBufModifiersEXT)(EGLDisplay dpy, int32_t format, int32_t max_modifiers, uint64_t *modifiers, int *external_only, int32_t *num_modifiers);
#define GSR_MAX_OUTPUTS 32
typedef struct {
+ char *name;
+ vec2i pos;
+ vec2i size;
+ uint32_t connector_id;
+ gsr_monitor_rotation rotation;
+ uint32_t monitor_identifier; /* crtc id */
+} gsr_x11_output;
+
+typedef struct {
Display *dpy;
Window window;
+ gsr_x11_output outputs[GSR_MAX_OUTPUTS];
+ int num_outputs;
+ XEvent xev;
} gsr_x11;
typedef struct {
@@ -163,6 +194,11 @@ typedef enum {
GSR_GL_CONTEXT_TYPE_GLX
} gsr_gl_context_type;
+typedef enum {
+ GSR_DISPLAY_SERVER_X11,
+ GSR_DISPLAY_SERVER_WAYLAND
+} gsr_display_server;
+
typedef struct gsr_egl gsr_egl;
struct gsr_egl {
void *egl_library;
@@ -207,6 +243,7 @@ struct gsr_egl {
FUNC_glEGLImageTargetTexture2DOES glEGLImageTargetTexture2DOES;
FUNC_eglQueryDisplayAttribEXT eglQueryDisplayAttribEXT;
FUNC_eglQueryDeviceStringEXT eglQueryDeviceStringEXT;
+ FUNC_eglQueryDmaBufModifiersEXT eglQueryDmaBufModifiersEXT;
__GLXextFuncPtr (*glXGetProcAddress)(const unsigned char *procName);
GLXFBConfig* (*glXChooseFBConfig)(Display *dpy, int screen, const int *attribList, int *nitems);
@@ -235,8 +272,7 @@ struct gsr_egl {
void (*glTexParameteriv)(unsigned int target, unsigned int pname, const int *params);
void (*glGetTexLevelParameteriv)(unsigned int target, int level, unsigned int pname, int *params);
void (*glTexImage2D)(unsigned int target, int level, int internalFormat, int width, int height, int border, unsigned int format, unsigned int type, const void *pixels);
- void (*glCopyImageSubData)(unsigned int srcName, unsigned int srcTarget, int srcLevel, int srcX, int srcY, int srcZ, unsigned int dstName, unsigned int dstTarget, int dstLevel, int dstX, int dstY, int dstZ, int srcWidth, int srcHeight, int srcDepth);
- void (*glClearTexImage)(unsigned int texture, unsigned int level, unsigned int format, unsigned int type, const void *data);
+ void (*glGetTexImage)(unsigned int target, int level, unsigned int format, unsigned int type, void *pixels);
void (*glGenFramebuffers)(int n, unsigned int *framebuffers);
void (*glBindFramebuffer)(unsigned int target, unsigned int framebuffer);
void (*glDeleteFramebuffers)(int n, const unsigned int *framebuffers);
@@ -270,16 +306,27 @@ struct gsr_egl {
void (*glEnableVertexAttribArray)(unsigned int index);
void (*glDrawArrays)(unsigned int mode, int first, int count);
void (*glEnable)(unsigned int cap);
+ void (*glDisable)(unsigned int cap);
void (*glBlendFunc)(unsigned int sfactor, unsigned int dfactor);
int (*glGetUniformLocation)(unsigned int program, const char *name);
void (*glUniform1f)(int location, float v0);
void (*glUniform2f)(int location, float v0, float v1);
void (*glDebugMessageCallback)(GLDEBUGPROC callback, const void *userParam);
+ void (*glScissor)(int x, int y, int width, int height);
+ void (*glReadPixels)(int x, int y, int width, int height, unsigned int format, unsigned int type, void *pixels);
+ void* (*glMapBuffer)(unsigned int target, unsigned int access);
+ unsigned char (*glUnmapBuffer)(unsigned int target);
};
bool gsr_egl_load(gsr_egl *self, Display *dpy, bool wayland, bool is_monitor_capture);
void gsr_egl_unload(gsr_egl *self);
-void gsr_egl_update(gsr_egl *self);
+/* Returns true if an event is available */
+bool gsr_egl_process_event(gsr_egl *self);
+/* Does opengl swap with egl or glx, depending on which one is active */
+void gsr_egl_swap_buffers(gsr_egl *self);
+
+gsr_display_server gsr_egl_get_display_server(const gsr_egl *self);
+XEvent* gsr_egl_get_event_data(gsr_egl *self);
#endif /* GSR_EGL_H */
diff --git a/include/encoder/video/cuda.h b/include/encoder/video/cuda.h
new file mode 100644
index 0000000..6d32e09
--- /dev/null
+++ b/include/encoder/video/cuda.h
@@ -0,0 +1,16 @@
+#ifndef GSR_ENCODER_VIDEO_CUDA_H
+#define GSR_ENCODER_VIDEO_CUDA_H
+
+#include "video.h"
+
+typedef struct gsr_egl gsr_egl;
+
+typedef struct {
+ gsr_egl *egl;
+ bool overclock;
+ gsr_color_depth color_depth;
+} gsr_video_encoder_cuda_params;
+
+gsr_video_encoder* gsr_video_encoder_cuda_create(const gsr_video_encoder_cuda_params *params);
+
+#endif /* GSR_ENCODER_VIDEO_CUDA_H */
diff --git a/include/encoder/video/software.h b/include/encoder/video/software.h
new file mode 100644
index 0000000..fd2dc6b
--- /dev/null
+++ b/include/encoder/video/software.h
@@ -0,0 +1,15 @@
+#ifndef GSR_ENCODER_VIDEO_SOFTWARE_H
+#define GSR_ENCODER_VIDEO_SOFTWARE_H
+
+#include "video.h"
+
+typedef struct gsr_egl gsr_egl;
+
+typedef struct {
+ gsr_egl *egl;
+ gsr_color_depth color_depth;
+} gsr_video_encoder_software_params;
+
+gsr_video_encoder* gsr_video_encoder_software_create(const gsr_video_encoder_software_params *params);
+
+#endif /* GSR_ENCODER_VIDEO_SOFTWARE_H */
diff --git a/include/encoder/video/vaapi.h b/include/encoder/video/vaapi.h
new file mode 100644
index 0000000..b509f17
--- /dev/null
+++ b/include/encoder/video/vaapi.h
@@ -0,0 +1,15 @@
+#ifndef GSR_ENCODER_VIDEO_VAAPI_H
+#define GSR_ENCODER_VIDEO_VAAPI_H
+
+#include "video.h"
+
+typedef struct gsr_egl gsr_egl;
+
+typedef struct {
+ gsr_egl *egl;
+ gsr_color_depth color_depth;
+} gsr_video_encoder_vaapi_params;
+
+gsr_video_encoder* gsr_video_encoder_vaapi_create(const gsr_video_encoder_vaapi_params *params);
+
+#endif /* GSR_ENCODER_VIDEO_VAAPI_H */
diff --git a/include/encoder/video/video.h b/include/encoder/video/video.h
new file mode 100644
index 0000000..49f48bd
--- /dev/null
+++ b/include/encoder/video/video.h
@@ -0,0 +1,27 @@
+#ifndef GSR_ENCODER_VIDEO_H
+#define GSR_ENCODER_VIDEO_H
+
+#include "../../color_conversion.h"
+#include <stdbool.h>
+
+typedef struct gsr_video_encoder gsr_video_encoder;
+typedef struct AVCodecContext AVCodecContext;
+typedef struct AVFrame AVFrame;
+
+struct gsr_video_encoder {
+ bool (*start)(gsr_video_encoder *encoder, AVCodecContext *video_codec_context, AVFrame *frame);
+ void (*copy_textures_to_frame)(gsr_video_encoder *encoder, AVFrame *frame, gsr_color_conversion *color_conversion); /* Can be NULL */
+ /* |textures| should be able to fit 2 elements */
+ void (*get_textures)(gsr_video_encoder *encoder, unsigned int *textures, int *num_textures, gsr_destination_color *destination_color);
+ void (*destroy)(gsr_video_encoder *encoder, AVCodecContext *video_codec_context);
+
+ void *priv;
+ bool started;
+};
+
+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, gsr_color_conversion *color_conversion);
+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_destroy(gsr_video_encoder *encoder, AVCodecContext *video_codec_context);
+
+#endif /* GSR_ENCODER_VIDEO_H */
diff --git a/include/encoder/video/vulkan.h b/include/encoder/video/vulkan.h
new file mode 100644
index 0000000..383fc4f
--- /dev/null
+++ b/include/encoder/video/vulkan.h
@@ -0,0 +1,15 @@
+#ifndef GSR_ENCODER_VIDEO_VULKAN_H
+#define GSR_ENCODER_VIDEO_VULKAN_H
+
+#include "video.h"
+
+typedef struct gsr_egl gsr_egl;
+
+typedef struct {
+ gsr_egl *egl;
+ gsr_color_depth color_depth;
+} gsr_video_encoder_vulkan_params;
+
+gsr_video_encoder* gsr_video_encoder_vulkan_create(const gsr_video_encoder_vulkan_params *params);
+
+#endif /* GSR_ENCODER_VIDEO_VULKAN_H */
diff --git a/include/pipewire.h b/include/pipewire.h
new file mode 100644
index 0000000..1908e2d
--- /dev/null
+++ b/include/pipewire.h
@@ -0,0 +1,112 @@
+#ifndef GSR_PIPEWIRE_H
+#define GSR_PIPEWIRE_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <pthread.h>
+
+#include <spa/utils/hook.h>
+#include <spa/param/video/format.h>
+
+#define GSR_PIPEWIRE_MAX_MODIFIERS 1024
+#define GSR_PIPEWIRE_NUM_VIDEO_FORMATS 6
+#define GSR_PIPEWIRE_DMABUF_MAX_PLANES 4
+
+typedef struct gsr_egl gsr_egl;
+
+typedef struct {
+ int major;
+ int minor;
+ int micro;
+} gsr_pipewire_data_version;
+
+typedef struct {
+ uint32_t fps_num;
+ uint32_t fps_den;
+} gsr_pipewire_video_info;
+
+typedef struct {
+ int fd;
+ uint32_t offset;
+ int32_t stride;
+} gsr_pipewire_dmabuf_data;
+
+typedef struct {
+ int x, y;
+ int width, height;
+} gsr_pipewire_region;
+
+typedef struct {
+ enum spa_video_format format;
+ size_t modifiers_index;
+ size_t modifiers_size;
+} gsr_video_format;
+
+typedef struct {
+ unsigned int texture_id;
+ unsigned int external_texture_id;
+ unsigned int cursor_texture_id;
+} gsr_texture_map;
+
+typedef struct {
+ gsr_egl *egl;
+ int fd;
+ uint32_t node;
+ pthread_mutex_t mutex;
+ bool mutex_initialized;
+
+ struct pw_thread_loop *thread_loop;
+ struct pw_context *context;
+ struct pw_core *core;
+ struct spa_hook core_listener;
+ struct pw_stream *stream;
+ struct spa_hook stream_listener;
+ struct spa_source *reneg;
+ struct spa_video_info format;
+ int server_version_sync;
+ bool negotiated;
+ bool damaged;
+
+ struct {
+ bool visible;
+ bool valid;
+ uint8_t *data;
+ int x, y;
+ int hotspot_x, hotspot_y;
+ int width, height;
+ } cursor;
+
+ struct {
+ bool valid;
+ int x, y;
+ uint32_t width, height;
+ } crop;
+
+ gsr_video_format supported_video_formats[GSR_PIPEWIRE_NUM_VIDEO_FORMATS];
+
+ gsr_pipewire_data_version server_version;
+ gsr_pipewire_video_info video_info;
+ gsr_pipewire_dmabuf_data dmabuf_data[GSR_PIPEWIRE_DMABUF_MAX_PLANES];
+ size_t dmabuf_num_planes;
+
+ bool no_modifiers_fallback;
+ bool external_texture_fallback;
+
+ uint64_t modifiers[GSR_PIPEWIRE_MAX_MODIFIERS];
+ size_t num_modifiers;
+} gsr_pipewire;
+
+/*
+ |capture_cursor| only applies to when capturing a window or region.
+ In other cases |pipewire_node|'s setup will determine if the cursor is included.
+ Note that the cursor is not guaranteed to be shown even if set to true, it depends on the wayland compositor.
+*/
+bool gsr_pipewire_init(gsr_pipewire *self, int pipewire_fd, uint32_t pipewire_node, int fps, bool capture_cursor, gsr_egl *egl);
+void gsr_pipewire_deinit(gsr_pipewire *self);
+
+/* |dmabuf_data| should be at least GSR_PIPEWIRE_DMABUF_MAX_PLANES in size */
+bool gsr_pipewire_map_texture(gsr_pipewire *self, gsr_texture_map texture_map, gsr_pipewire_region *region, gsr_pipewire_region *cursor_region, gsr_pipewire_dmabuf_data *dmabuf_data, int *num_dmabuf_data, uint32_t *fourcc, uint64_t *modifiers, bool *using_external_image);
+bool gsr_pipewire_is_damaged(gsr_pipewire *self);
+void gsr_pipewire_clear_damage(gsr_pipewire *self);
+
+#endif /* GSR_PIPEWIRE_H */
diff --git a/include/sound.hpp b/include/sound.hpp
index 77bec99..7bcc120 100644
--- a/include/sound.hpp
+++ b/include/sound.hpp
@@ -31,6 +31,12 @@ struct AudioInput {
std::string description;
};
+struct AudioDevices {
+ std::string default_output;
+ std::string default_input;
+ std::vector<AudioInput> audio_inputs;
+};
+
struct MergedAudioInputs {
std::vector<AudioInput> audio_inputs;
};
@@ -57,6 +63,6 @@ void sound_device_close(SoundDevice *device);
*/
int sound_device_read_next_chunk(SoundDevice *device, void **buffer, double timeout_sec, double *latency_seconds);
-std::vector<AudioInput> get_pulseaudio_inputs();
+AudioDevices get_pulseaudio_inputs();
#endif /* GPU_SCREEN_RECORDER_H */
diff --git a/include/utils.h b/include/utils.h
index c5d659a..92eb851 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -6,17 +6,18 @@
#include "../include/defs.h"
#include <stdbool.h>
#include <stdint.h>
-#include <X11/extensions/Xrandr.h>
+
+typedef struct AVCodecContext AVCodecContext;
+typedef struct AVFrame AVFrame;
typedef struct {
const char *name;
int name_len;
vec2i pos;
vec2i size;
- XRRCrtcInfo *crt_info; /* Only on x11 */
uint32_t connector_id; /* Only on x11 and drm */
gsr_monitor_rotation rotation; /* Only on x11 and wayland */
- uint32_t monitor_identifier; /* Only on drm and wayland */
+ uint32_t monitor_identifier; /* On x11 this is the crtc id */
} gsr_monitor;
typedef struct {
@@ -29,7 +30,8 @@ typedef struct {
double clock_get_monotonic_seconds(void);
typedef void (*active_monitor_callback)(const gsr_monitor *monitor, void *userdata);
-void for_each_active_monitor_output_x11(Display *display, active_monitor_callback callback, void *userdata);
+void for_each_active_monitor_output_x11_not_cached(Display *display, active_monitor_callback callback, void *userdata);
+void for_each_active_monitor_output_x11(const gsr_egl *egl, active_monitor_callback callback, void *userdata);
void for_each_active_monitor_output(const gsr_egl *egl, gsr_connection_type connection_type, active_monitor_callback callback, void *userdata);
bool get_monitor_by_name(const gsr_egl *egl, gsr_connection_type connection_type, const char *name, gsr_monitor *monitor);
gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_egl *egl, const gsr_monitor *monitor);
@@ -41,4 +43,12 @@ bool gsr_get_valid_card_path(gsr_egl *egl, char *output, bool is_monitor_capture
/* |render_path| should be at least 128 bytes in size */
bool gsr_card_path_get_render_path(const char *card_path, char *render_path);
+int create_directory_recursive(char *path);
+
+/* |img_attr| needs to be at least 44 in size */
+void setup_dma_buf_attrs(intptr_t *img_attr, uint32_t format, uint32_t width, uint32_t height, const int *fds, const uint32_t *offsets, const uint32_t *pitches, const uint64_t *modifiers, int num_planes, bool use_modifier);
+bool video_codec_context_is_vaapi(AVCodecContext *video_codec_context);
+bool vaapi_copy_drm_planes_to_video_surface(AVCodecContext *video_codec_context, AVFrame *video_frame, vec2i source_pos, vec2i source_size, vec2i dest_pos, vec2i dest_size, uint32_t format, vec2i size, const int *fds, const uint32_t *offsets, const uint32_t *pitches, const uint64_t *modifiers, int num_planes);
+bool vaapi_copy_egl_image_to_video_surface(gsr_egl *egl, EGLImage image, vec2i source_pos, vec2i source_size, vec2i dest_pos, vec2i dest_size, AVCodecContext *video_codec_context, AVFrame *video_frame);
+
#endif /* GSR_UTILS_H */
diff --git a/include/window_texture.h b/include/window_texture.h
index 75bb2a7..6ee5df4 100644
--- a/include/window_texture.h
+++ b/include/window_texture.h
@@ -7,6 +7,7 @@ typedef struct {
Display *display;
Window window;
Pixmap pixmap;
+ EGLImage image;
unsigned int texture_id;
int redirected;
gsr_egl *egl;