mirror of
https://repo.dec05eba.com/gpu-screen-recorder
synced 2026-04-18 16:05:49 +09:00
Prepare for video codec query, cleanup readme, add libva-drm as dependency
This commit is contained in:
@@ -122,6 +122,24 @@ static bool gsr_video_encoder_cuda_setup_textures(gsr_video_encoder_cuda *self,
|
||||
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 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 = (gsr_video_encoder) {
|
||||
.get_supported_codecs = gsr_video_encoder_cuda_get_supported_codecs,
|
||||
.start = gsr_video_encoder_cuda_start,
|
||||
.copy_textures_to_frame = gsr_video_encoder_cuda_copy_textures_to_frame,
|
||||
.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;
|
||||
}
|
||||
|
||||
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 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 = (gsr_video_encoder) {
|
||||
.get_supported_codecs = gsr_video_encoder_software_get_supported_codecs,
|
||||
.start = gsr_video_encoder_software_start,
|
||||
.copy_textures_to_frame = gsr_video_encoder_software_copy_textures_to_frame,
|
||||
.get_textures = gsr_video_encoder_software_get_textures,
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
#include <libavutil/hwcontext_vaapi.h>
|
||||
|
||||
#include <va/va_drmcommon.h>
|
||||
#include <va/va_drm.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
typedef struct {
|
||||
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 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 = (gsr_video_encoder) {
|
||||
.get_supported_codecs = gsr_video_encoder_vaapi_get_supported_codecs,
|
||||
.start = gsr_video_encoder_vaapi_start,
|
||||
.copy_textures_to_frame = NULL,
|
||||
.get_textures = gsr_video_encoder_vaapi_get_textures,
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#include "../../../include/encoder/video/video.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) {
|
||||
assert(!encoder->started);
|
||||
bool res = encoder->start(encoder, video_codec_context, frame);
|
||||
|
||||
Reference in New Issue
Block a user