mirror of
https://repo.dec05eba.com/gpu-screen-recorder
synced 2026-03-31 09:07:13 +09:00
Add support for camera (yuyv, mjpeg) and multiple capture sources
This commit is contained in:
@@ -10,6 +10,15 @@ typedef struct gsr_egl gsr_egl;
|
||||
|
||||
#define NUM_ARGS 32
|
||||
|
||||
typedef enum {
|
||||
GSR_CAPTURE_SOURCE_TYPE_WINDOW,
|
||||
GSR_CAPTURE_SOURCE_TYPE_FOCUSED_WINDOW,
|
||||
GSR_CAPTURE_SOURCE_TYPE_MONITOR,
|
||||
GSR_CAPTURE_SOURCE_TYPE_REGION,
|
||||
GSR_CAPTURE_SOURCE_TYPE_PORTAL,
|
||||
GSR_CAPTURE_SOURCE_TYPE_V4L2
|
||||
} CaptureSourceType;
|
||||
|
||||
typedef enum {
|
||||
ARG_TYPE_STRING,
|
||||
ARG_TYPE_BOOLEAN,
|
||||
@@ -52,6 +61,7 @@ typedef struct {
|
||||
void (*info)(void *userdata);
|
||||
void (*list_audio_devices)(void *userdata);
|
||||
void (*list_application_audio)(void *userdata);
|
||||
void (*list_v4l2_devices)(void *userdata);
|
||||
void (*list_capture_options)(const char *card_path, void *userdata);
|
||||
} args_handlers;
|
||||
|
||||
@@ -68,7 +78,8 @@ typedef struct {
|
||||
gsr_bitrate_mode bitrate_mode;
|
||||
gsr_video_quality video_quality;
|
||||
gsr_replay_storage replay_storage;
|
||||
char window[64];
|
||||
|
||||
const char *capture_source;
|
||||
const char *container_format;
|
||||
const char *filename;
|
||||
const char *replay_recording_directory;
|
||||
|
||||
@@ -12,24 +12,34 @@ typedef struct AVFrame AVFrame;
|
||||
typedef struct AVMasteringDisplayMetadata AVMasteringDisplayMetadata;
|
||||
typedef struct AVContentLightMetadata AVContentLightMetadata;
|
||||
typedef struct gsr_capture gsr_capture;
|
||||
typedef struct gsr_capture_metadata gsr_capture_metadata;
|
||||
|
||||
typedef struct {
|
||||
// Width and height of the video
|
||||
int video_width;
|
||||
int video_height;
|
||||
// Width and height of the frame at the start of capture, the target size
|
||||
int recording_width;
|
||||
int recording_height;
|
||||
typedef enum {
|
||||
GSR_CAPTURE_ALIGN_START,
|
||||
GSR_CAPTURE_ALIGN_CENTER,
|
||||
GSR_CAPTURE_ALIGN_END
|
||||
} gsr_capture_alignment;
|
||||
|
||||
struct gsr_capture_metadata {
|
||||
// Size of the video
|
||||
vec2i video_size;
|
||||
// The captured output gets scaled to this size. By default this will be the same size as the captured target
|
||||
vec2i recording_size;
|
||||
vec2i position;
|
||||
int fps;
|
||||
} gsr_capture_metadata;
|
||||
gsr_capture_alignment halign;
|
||||
gsr_capture_alignment valign;
|
||||
gsr_flip flip;
|
||||
};
|
||||
|
||||
struct gsr_capture {
|
||||
/* These methods should not be called manually. Call gsr_capture_* instead. |capture_metadata->video_width| and |capture_metadata->video_height| should be set by this function */
|
||||
/* These methods should not be called manually. Call gsr_capture_* instead. |capture_metadata->video_size| should be set by this function */
|
||||
int (*start)(gsr_capture *cap, gsr_capture_metadata *capture_metadata);
|
||||
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 */
|
||||
bool (*capture_has_synchronous_task)(gsr_capture *cap); /* can be NULL. If this returns true then the time spent in |capture| is ignored for video/audio (capture is paused while the synchronous task happens) */
|
||||
void (*pre_capture)(gsr_capture *cap, gsr_capture_metadata *capture_metadata, gsr_color_conversion *color_conversion); /* can be NULL */
|
||||
int (*capture)(gsr_capture *cap, gsr_capture_metadata *capture_metadata, gsr_color_conversion *color_conversion); /* Return 0 if the frame was captured */
|
||||
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 */
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
#define GSR_CAPTURE_KMS_H
|
||||
|
||||
#include "capture.h"
|
||||
#include "../cursor.h"
|
||||
#include "../../kms/kms_shared.h"
|
||||
|
||||
typedef struct {
|
||||
gsr_egl *egl;
|
||||
gsr_cursor *x11_cursor;
|
||||
gsr_kms_response *kms_response;
|
||||
const char *display_to_capture; /* A copy is made of this */
|
||||
bool hdr;
|
||||
bool record_cursor;
|
||||
|
||||
30
include/capture/v4l2.h
Normal file
30
include/capture/v4l2.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef GSR_CAPTURE_V4L2_H
|
||||
#define GSR_CAPTURE_V4L2_H
|
||||
|
||||
#include "capture.h"
|
||||
|
||||
typedef enum {
|
||||
GSR_CAPTURE_V4L2_PIXFMT_AUTO,
|
||||
GSR_CAPTURE_V4L2_PIXFMT_YUYV,
|
||||
GSR_CAPTURE_V4L2_PIXFMT_MJPEG
|
||||
} gsr_capture_v4l2_pixfmt;
|
||||
|
||||
typedef struct {
|
||||
bool yuyv;
|
||||
bool mjpeg;
|
||||
} gsr_capture_v4l2_supported_pixfmts;
|
||||
|
||||
typedef struct {
|
||||
gsr_egl *egl;
|
||||
vec2i output_resolution;
|
||||
const char *device_path;
|
||||
gsr_capture_v4l2_pixfmt pixfmt;
|
||||
int fps;
|
||||
} gsr_capture_v4l2_params;
|
||||
|
||||
gsr_capture* gsr_capture_v4l2_create(const gsr_capture_v4l2_params *params);
|
||||
|
||||
typedef void (*v4l2_devices_query_callback)(const char *path, gsr_capture_v4l2_supported_pixfmts supported_pixfmts, vec2i size, void *userdata);
|
||||
void gsr_capture_v4l2_list_devices(v4l2_devices_query_callback callback, void *userdata);
|
||||
|
||||
#endif /* GSR_CAPTURE_V4L2_H */
|
||||
@@ -3,9 +3,11 @@
|
||||
|
||||
#include "capture.h"
|
||||
#include "../vec2.h"
|
||||
#include "../cursor.h"
|
||||
|
||||
typedef struct {
|
||||
gsr_egl *egl;
|
||||
gsr_cursor *cursor;
|
||||
unsigned long window;
|
||||
bool follow_focused; /* If this is set then |window| is ignored */
|
||||
bool record_cursor;
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
|
||||
#include "capture.h"
|
||||
#include "../vec2.h"
|
||||
#include "../cursor.h"
|
||||
|
||||
typedef struct {
|
||||
gsr_egl *egl;
|
||||
gsr_cursor *cursor;
|
||||
const char *display_to_capture; /* A copy is made of this */
|
||||
bool record_cursor;
|
||||
vec2i output_resolution;
|
||||
|
||||
@@ -27,6 +27,12 @@ typedef enum {
|
||||
GSR_ROT_270
|
||||
} gsr_rotation;
|
||||
|
||||
typedef enum {
|
||||
GSR_FLIP_NONE = 0,
|
||||
GSR_FLIP_HORIZONTAL = (1 << 0),
|
||||
GSR_FLIP_VERTICAL = (1 << 1)
|
||||
} gsr_flip;
|
||||
|
||||
typedef struct {
|
||||
int rotation_matrix;
|
||||
int offset;
|
||||
@@ -55,12 +61,14 @@ typedef struct {
|
||||
|
||||
unsigned int vertex_array_object_id;
|
||||
unsigned int vertex_buffer_object_id;
|
||||
|
||||
bool schedule_clear;
|
||||
} gsr_color_conversion;
|
||||
|
||||
int gsr_color_conversion_init(gsr_color_conversion *self, const gsr_color_conversion_params *params);
|
||||
void gsr_color_conversion_deinit(gsr_color_conversion *self);
|
||||
|
||||
void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i source_pos, vec2i source_size, vec2i texture_size, gsr_rotation rotation, gsr_source_color source_color, bool external_texture);
|
||||
void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i source_pos, vec2i source_size, vec2i texture_size, gsr_rotation rotation, gsr_flip flip, gsr_source_color source_color, bool external_texture);
|
||||
void gsr_color_conversion_clear(gsr_color_conversion *self);
|
||||
void gsr_color_conversion_read_destination_texture(gsr_color_conversion *self, int destination_texture_index, int x, int y, int width, int height, unsigned int color_format, unsigned int data_format, void *pixels);
|
||||
|
||||
|
||||
@@ -9,40 +9,62 @@
|
||||
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;
|
||||
#define GSR_DAMAGE_MAX_MONITORS 32
|
||||
#define GSR_DAMAGE_MAX_TRACKED_TARGETS 12
|
||||
|
||||
typedef struct {
|
||||
int64_t window_id;
|
||||
vec2i window_pos;
|
||||
vec2i window_size;
|
||||
uint64_t damage;
|
||||
int refcount;
|
||||
} gsr_damage_window;
|
||||
|
||||
typedef struct {
|
||||
char *monitor_name;
|
||||
gsr_monitor *monitor;
|
||||
int refcount;
|
||||
} gsr_damage_monitor;
|
||||
|
||||
typedef struct {
|
||||
gsr_egl *egl;
|
||||
Display *display;
|
||||
bool track_cursor;
|
||||
gsr_damage_track_type track_type;
|
||||
|
||||
int damage_event;
|
||||
int damage_error;
|
||||
uint64_t damage;
|
||||
bool damaged;
|
||||
|
||||
uint64_t monitor_damage;
|
||||
|
||||
int randr_event;
|
||||
int randr_error;
|
||||
|
||||
uint64_t window;
|
||||
//vec2i window_pos;
|
||||
vec2i window_size;
|
||||
gsr_cursor *cursor;
|
||||
gsr_monitor monitors[GSR_DAMAGE_MAX_MONITORS];
|
||||
int num_monitors;
|
||||
|
||||
gsr_cursor cursor; /* Relative to |window| */
|
||||
gsr_monitor monitor;
|
||||
char monitor_name[32];
|
||||
gsr_damage_window windows_tracked[GSR_DAMAGE_MAX_TRACKED_TARGETS];
|
||||
int num_windows_tracked;
|
||||
|
||||
gsr_damage_monitor monitors_tracked[GSR_DAMAGE_MAX_TRACKED_TARGETS];
|
||||
int num_monitors_tracked;
|
||||
|
||||
int all_monitors_tracked_refcount;
|
||||
vec2i cursor_pos;
|
||||
} gsr_damage;
|
||||
|
||||
bool gsr_damage_init(gsr_damage *self, gsr_egl *egl, bool track_cursor);
|
||||
bool gsr_damage_init(gsr_damage *self, gsr_egl *egl, gsr_cursor *cursor, 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);
|
||||
/* This is reference counted */
|
||||
bool gsr_damage_start_tracking_window(gsr_damage *self, int64_t window);
|
||||
void gsr_damage_stop_tracking_window(gsr_damage *self, int64_t window);
|
||||
|
||||
/* This is reference counted. If |monitor_name| is NULL then all monitors are tracked */
|
||||
bool gsr_damage_start_tracking_monitor(gsr_damage *self, const char *monitor_name);
|
||||
void gsr_damage_stop_tracking_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 */
|
||||
|
||||
@@ -140,6 +140,7 @@ typedef void(*__GLXextFuncPtr)(void);
|
||||
#define GL_TEXTURE1 0x84C1
|
||||
#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
|
||||
#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
|
||||
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
|
||||
|
||||
#define GL_VENDOR 0x1F00
|
||||
#define GL_RENDERER 0x1F01
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
typedef struct AVCodecContext AVCodecContext;
|
||||
typedef struct AVFrame AVFrame;
|
||||
typedef struct gsr_capture_metadata gsr_capture_metadata;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
@@ -55,6 +56,7 @@ int create_directory_recursive(char *path);
|
||||
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);
|
||||
|
||||
vec2i scale_keep_aspect_ratio(vec2i from, vec2i to);
|
||||
vec2i gsr_capture_get_target_position(vec2i output_size, gsr_capture_metadata *capture_metadata);
|
||||
|
||||
unsigned int gl_create_texture(gsr_egl *egl, int width, int height, int internal_format, unsigned int format, int filter);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user