mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
libobs,libobs-opengl: enable GPU encoding for OpenGL
Enable all of the previously Windows only paths for OpenGL backends that support encode_texture2 Co-authored-by: Torge Matthies <openglfreak@googlemail.com>
This commit is contained in:
parent
f81ed52ec7
commit
02c90207fc
@ -1519,6 +1519,18 @@ void gs_swapchain_destroy(gs_swapchain_t *swapchain)
|
|||||||
bfree(swapchain);
|
bfree(swapchain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool device_nv12_available(gs_device_t *device)
|
||||||
|
{
|
||||||
|
UNUSED_PARAMETER(device);
|
||||||
|
return true; // always a split R8,R8G8 texture.
|
||||||
|
}
|
||||||
|
|
||||||
|
bool device_p010_available(gs_device_t *device)
|
||||||
|
{
|
||||||
|
UNUSED_PARAMETER(device);
|
||||||
|
return true; // always a split R16,R16G16 texture.
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t gs_voltexture_get_width(const gs_texture_t *voltex)
|
uint32_t gs_voltexture_get_width(const gs_texture_t *voltex)
|
||||||
{
|
{
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
@ -195,6 +195,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
|||||||
|
|
||||||
GRAPHICS_IMPORT_OPTIONAL(device_nv12_available);
|
GRAPHICS_IMPORT_OPTIONAL(device_nv12_available);
|
||||||
GRAPHICS_IMPORT_OPTIONAL(device_p010_available);
|
GRAPHICS_IMPORT_OPTIONAL(device_p010_available);
|
||||||
|
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_nv12);
|
||||||
|
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_p010);
|
||||||
|
|
||||||
GRAPHICS_IMPORT(device_is_monitor_hdr);
|
GRAPHICS_IMPORT(device_is_monitor_hdr);
|
||||||
|
|
||||||
@ -231,8 +233,6 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
|||||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_wrap_obj);
|
GRAPHICS_IMPORT_OPTIONAL(device_texture_wrap_obj);
|
||||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_acquire_sync);
|
GRAPHICS_IMPORT_OPTIONAL(device_texture_acquire_sync);
|
||||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_release_sync);
|
GRAPHICS_IMPORT_OPTIONAL(device_texture_release_sync);
|
||||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_nv12);
|
|
||||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_p010);
|
|
||||||
GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_nv12);
|
GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_nv12);
|
||||||
GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_p010);
|
GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_p010);
|
||||||
GRAPHICS_IMPORT_OPTIONAL(device_register_loss_callbacks);
|
GRAPHICS_IMPORT_OPTIONAL(device_register_loss_callbacks);
|
||||||
|
@ -273,6 +273,16 @@ struct gs_exports {
|
|||||||
|
|
||||||
bool (*device_nv12_available)(gs_device_t *device);
|
bool (*device_nv12_available)(gs_device_t *device);
|
||||||
bool (*device_p010_available)(gs_device_t *device);
|
bool (*device_p010_available)(gs_device_t *device);
|
||||||
|
bool (*device_texture_create_nv12)(gs_device_t *device,
|
||||||
|
gs_texture_t **tex_y,
|
||||||
|
gs_texture_t **tex_uv,
|
||||||
|
uint32_t width, uint32_t height,
|
||||||
|
uint32_t flags);
|
||||||
|
bool (*device_texture_create_p010)(gs_device_t *device,
|
||||||
|
gs_texture_t **tex_y,
|
||||||
|
gs_texture_t **tex_uv,
|
||||||
|
uint32_t width, uint32_t height,
|
||||||
|
uint32_t flags);
|
||||||
|
|
||||||
bool (*device_is_monitor_hdr)(gs_device_t *device, void *monitor);
|
bool (*device_is_monitor_hdr)(gs_device_t *device, void *monitor);
|
||||||
|
|
||||||
@ -331,16 +341,6 @@ struct gs_exports {
|
|||||||
int (*device_texture_acquire_sync)(gs_texture_t *tex, uint64_t key,
|
int (*device_texture_acquire_sync)(gs_texture_t *tex, uint64_t key,
|
||||||
uint32_t ms);
|
uint32_t ms);
|
||||||
int (*device_texture_release_sync)(gs_texture_t *tex, uint64_t key);
|
int (*device_texture_release_sync)(gs_texture_t *tex, uint64_t key);
|
||||||
bool (*device_texture_create_nv12)(gs_device_t *device,
|
|
||||||
gs_texture_t **tex_y,
|
|
||||||
gs_texture_t **tex_uv,
|
|
||||||
uint32_t width, uint32_t height,
|
|
||||||
uint32_t flags);
|
|
||||||
bool (*device_texture_create_p010)(gs_device_t *device,
|
|
||||||
gs_texture_t **tex_y,
|
|
||||||
gs_texture_t **tex_uv,
|
|
||||||
uint32_t width, uint32_t height,
|
|
||||||
uint32_t flags);
|
|
||||||
|
|
||||||
gs_stagesurf_t *(*device_stagesurface_create_nv12)(gs_device_t *device,
|
gs_stagesurf_t *(*device_stagesurface_create_nv12)(gs_device_t *device,
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
|
@ -2908,6 +2908,84 @@ void gs_debug_marker_end(void)
|
|||||||
thread_graphics->device);
|
thread_graphics->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
||||||
|
uint32_t width, uint32_t height, uint32_t flags)
|
||||||
|
{
|
||||||
|
graphics_t *graphics = thread_graphics;
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if (!gs_valid("gs_texture_create_nv12"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((width & 1) == 1 || (height & 1) == 1) {
|
||||||
|
blog(LOG_ERROR, "NV12 textures must have dimensions "
|
||||||
|
"divisible by 2.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (graphics->exports.device_texture_create_nv12) {
|
||||||
|
success = graphics->exports.device_texture_create_nv12(
|
||||||
|
graphics->device, tex_y, tex_uv, width, height, flags);
|
||||||
|
if (success)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
*tex_y = gs_texture_create(width, height, GS_R8, 1, NULL, flags);
|
||||||
|
*tex_uv = gs_texture_create(width / 2, height / 2, GS_R8G8, 1, NULL,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
if (!*tex_y || !*tex_uv) {
|
||||||
|
if (*tex_y)
|
||||||
|
gs_texture_destroy(*tex_y);
|
||||||
|
if (*tex_uv)
|
||||||
|
gs_texture_destroy(*tex_uv);
|
||||||
|
*tex_y = NULL;
|
||||||
|
*tex_uv = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gs_texture_create_p010(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
||||||
|
uint32_t width, uint32_t height, uint32_t flags)
|
||||||
|
{
|
||||||
|
graphics_t *graphics = thread_graphics;
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if (!gs_valid("gs_texture_create_p010"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((width & 1) == 1 || (height & 1) == 1) {
|
||||||
|
blog(LOG_ERROR, "P010 textures must have dimensions "
|
||||||
|
"divisible by 2.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (graphics->exports.device_texture_create_p010) {
|
||||||
|
success = graphics->exports.device_texture_create_p010(
|
||||||
|
graphics->device, tex_y, tex_uv, width, height, flags);
|
||||||
|
if (success)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
*tex_y = gs_texture_create(width, height, GS_R16, 1, NULL, flags);
|
||||||
|
*tex_uv = gs_texture_create(width / 2, height / 2, GS_RG16, 1, NULL,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
if (!*tex_y || !*tex_uv) {
|
||||||
|
if (*tex_y)
|
||||||
|
gs_texture_destroy(*tex_y);
|
||||||
|
if (*tex_uv)
|
||||||
|
gs_texture_destroy(*tex_uv);
|
||||||
|
*tex_y = NULL;
|
||||||
|
*tex_uv = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
||||||
/** Platform specific functions */
|
/** Platform specific functions */
|
||||||
@ -3186,84 +3264,6 @@ int gs_texture_release_sync(gs_texture_t *tex, uint64_t key)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
|
||||||
uint32_t width, uint32_t height, uint32_t flags)
|
|
||||||
{
|
|
||||||
graphics_t *graphics = thread_graphics;
|
|
||||||
bool success = false;
|
|
||||||
|
|
||||||
if (!gs_valid("gs_texture_create_nv12"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if ((width & 1) == 1 || (height & 1) == 1) {
|
|
||||||
blog(LOG_ERROR, "NV12 textures must have dimensions "
|
|
||||||
"divisible by 2.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (graphics->exports.device_texture_create_nv12) {
|
|
||||||
success = graphics->exports.device_texture_create_nv12(
|
|
||||||
graphics->device, tex_y, tex_uv, width, height, flags);
|
|
||||||
if (success)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
*tex_y = gs_texture_create(width, height, GS_R8, 1, NULL, flags);
|
|
||||||
*tex_uv = gs_texture_create(width / 2, height / 2, GS_R8G8, 1, NULL,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
if (!*tex_y || !*tex_uv) {
|
|
||||||
if (*tex_y)
|
|
||||||
gs_texture_destroy(*tex_y);
|
|
||||||
if (*tex_uv)
|
|
||||||
gs_texture_destroy(*tex_uv);
|
|
||||||
*tex_y = NULL;
|
|
||||||
*tex_uv = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gs_texture_create_p010(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
|
||||||
uint32_t width, uint32_t height, uint32_t flags)
|
|
||||||
{
|
|
||||||
graphics_t *graphics = thread_graphics;
|
|
||||||
bool success = false;
|
|
||||||
|
|
||||||
if (!gs_valid("gs_texture_create_p010"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if ((width & 1) == 1 || (height & 1) == 1) {
|
|
||||||
blog(LOG_ERROR, "P010 textures must have dimensions "
|
|
||||||
"divisible by 2.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (graphics->exports.device_texture_create_p010) {
|
|
||||||
success = graphics->exports.device_texture_create_p010(
|
|
||||||
graphics->device, tex_y, tex_uv, width, height, flags);
|
|
||||||
if (success)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
*tex_y = gs_texture_create(width, height, GS_R16, 1, NULL, flags);
|
|
||||||
*tex_uv = gs_texture_create(width / 2, height / 2, GS_RG16, 1, NULL,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
if (!*tex_y || !*tex_uv) {
|
|
||||||
if (*tex_y)
|
|
||||||
gs_texture_destroy(*tex_y);
|
|
||||||
if (*tex_uv)
|
|
||||||
gs_texture_destroy(*tex_uv);
|
|
||||||
*tex_y = NULL;
|
|
||||||
*tex_uv = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width, uint32_t height)
|
gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
graphics_t *graphics = thread_graphics;
|
graphics_t *graphics = thread_graphics;
|
||||||
|
@ -857,6 +857,12 @@ EXPORT bool gs_timer_range_get_data(gs_timer_range_t *range, bool *disjoint,
|
|||||||
|
|
||||||
EXPORT bool gs_nv12_available(void);
|
EXPORT bool gs_nv12_available(void);
|
||||||
EXPORT bool gs_p010_available(void);
|
EXPORT bool gs_p010_available(void);
|
||||||
|
EXPORT bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
||||||
|
uint32_t width, uint32_t height,
|
||||||
|
uint32_t flags);
|
||||||
|
EXPORT bool gs_texture_create_p010(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
||||||
|
uint32_t width, uint32_t height,
|
||||||
|
uint32_t flags);
|
||||||
|
|
||||||
EXPORT bool gs_is_monitor_hdr(void *monitor);
|
EXPORT bool gs_is_monitor_hdr(void *monitor);
|
||||||
|
|
||||||
@ -956,13 +962,6 @@ EXPORT int gs_texture_acquire_sync(gs_texture_t *tex, uint64_t key,
|
|||||||
*/
|
*/
|
||||||
EXPORT int gs_texture_release_sync(gs_texture_t *tex, uint64_t key);
|
EXPORT int gs_texture_release_sync(gs_texture_t *tex, uint64_t key);
|
||||||
|
|
||||||
EXPORT bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
|
||||||
uint32_t width, uint32_t height,
|
|
||||||
uint32_t flags);
|
|
||||||
EXPORT bool gs_texture_create_p010(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
|
||||||
uint32_t width, uint32_t height,
|
|
||||||
uint32_t flags);
|
|
||||||
|
|
||||||
EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width,
|
EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width,
|
||||||
uint32_t height);
|
uint32_t height);
|
||||||
EXPORT gs_stagesurf_t *gs_stagesurface_create_p010(uint32_t width,
|
EXPORT gs_stagesurf_t *gs_stagesurface_create_p010(uint32_t width,
|
||||||
|
@ -29,6 +29,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct obs_encoder;
|
||||||
|
typedef struct obs_encoder obs_encoder_t;
|
||||||
|
|
||||||
#define OBS_ENCODER_CAP_DEPRECATED (1 << 0)
|
#define OBS_ENCODER_CAP_DEPRECATED (1 << 0)
|
||||||
#define OBS_ENCODER_CAP_PASS_TEXTURE (1 << 1)
|
#define OBS_ENCODER_CAP_PASS_TEXTURE (1 << 1)
|
||||||
#define OBS_ENCODER_CAP_DYN_BITRATE (1 << 2)
|
#define OBS_ENCODER_CAP_DYN_BITRATE (1 << 2)
|
||||||
|
@ -269,9 +269,9 @@ struct obs_core_video_mix {
|
|||||||
gs_stagesurf_t *active_copy_surfaces[NUM_TEXTURES][NUM_CHANNELS];
|
gs_stagesurf_t *active_copy_surfaces[NUM_TEXTURES][NUM_CHANNELS];
|
||||||
gs_stagesurf_t *copy_surfaces[NUM_TEXTURES][NUM_CHANNELS];
|
gs_stagesurf_t *copy_surfaces[NUM_TEXTURES][NUM_CHANNELS];
|
||||||
gs_texture_t *convert_textures[NUM_CHANNELS];
|
gs_texture_t *convert_textures[NUM_CHANNELS];
|
||||||
|
gs_texture_t *convert_textures_encode[NUM_CHANNELS];
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
gs_stagesurf_t *copy_surfaces_encode[NUM_TEXTURES];
|
gs_stagesurf_t *copy_surfaces_encode[NUM_TEXTURES];
|
||||||
gs_texture_t *convert_textures_encode[NUM_CHANNELS];
|
|
||||||
#endif
|
#endif
|
||||||
gs_texture_t *render_texture;
|
gs_texture_t *render_texture;
|
||||||
gs_texture_t *output_texture;
|
gs_texture_t *output_texture;
|
||||||
|
@ -17,8 +17,11 @@
|
|||||||
|
|
||||||
#include "obs-internal.h"
|
#include "obs-internal.h"
|
||||||
|
|
||||||
static void *gpu_encode_thread(struct obs_core_video_mix *video)
|
#define NBSP "\xC2\xA0"
|
||||||
|
static const char *gpu_encode_frame_name = "gpu_encode_frame";
|
||||||
|
static void *gpu_encode_thread(void *data)
|
||||||
{
|
{
|
||||||
|
struct obs_core_video_mix *video = data;
|
||||||
uint64_t interval = video_output_get_frame_time(video->video);
|
uint64_t interval = video_output_get_frame_time(video->video);
|
||||||
DARRAY(obs_encoder_t *) encoders;
|
DARRAY(obs_encoder_t *) encoders;
|
||||||
int wait_frames = NUM_ENCODE_TEXTURE_FRAMES_TO_WAIT;
|
int wait_frames = NUM_ENCODE_TEXTURE_FRAMES_TO_WAIT;
|
||||||
@ -26,6 +29,10 @@ static void *gpu_encode_thread(struct obs_core_video_mix *video)
|
|||||||
da_init(encoders);
|
da_init(encoders);
|
||||||
|
|
||||||
os_set_thread_name("obs gpu encode thread");
|
os_set_thread_name("obs gpu encode thread");
|
||||||
|
const char *gpu_encode_thread_name = profile_store_name(
|
||||||
|
obs_get_profiler_name_store(),
|
||||||
|
"obs_gpu_encode_thread(%g" NBSP "ms)", interval / 1000000.);
|
||||||
|
profile_register_root(gpu_encode_thread_name, interval);
|
||||||
|
|
||||||
while (os_sem_wait(video->gpu_encode_semaphore) == 0) {
|
while (os_sem_wait(video->gpu_encode_semaphore) == 0) {
|
||||||
struct obs_tex_frame tf;
|
struct obs_tex_frame tf;
|
||||||
@ -42,6 +49,8 @@ static void *gpu_encode_thread(struct obs_core_video_mix *video)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
profile_start(gpu_encode_thread_name);
|
||||||
|
|
||||||
os_event_reset(video->gpu_encode_inactive);
|
os_event_reset(video->gpu_encode_inactive);
|
||||||
|
|
||||||
/* -------------- */
|
/* -------------- */
|
||||||
@ -125,6 +134,7 @@ static void *gpu_encode_thread(struct obs_core_video_mix *video)
|
|||||||
else
|
else
|
||||||
next_key++;
|
next_key++;
|
||||||
|
|
||||||
|
profile_start(gpu_encode_frame_name);
|
||||||
if (encoder->info.encode_texture2) {
|
if (encoder->info.encode_texture2) {
|
||||||
struct encoder_texture tex = {0};
|
struct encoder_texture tex = {0};
|
||||||
|
|
||||||
@ -142,6 +152,8 @@ static void *gpu_encode_thread(struct obs_core_video_mix *video)
|
|||||||
encoder->cur_pts, lock_key, &next_key,
|
encoder->cur_pts, lock_key, &next_key,
|
||||||
&pkt, &received);
|
&pkt, &received);
|
||||||
}
|
}
|
||||||
|
profile_end(gpu_encode_frame_name);
|
||||||
|
|
||||||
send_off_encoder_packet(encoder, success, received,
|
send_off_encoder_packet(encoder, success, received,
|
||||||
&pkt);
|
&pkt);
|
||||||
|
|
||||||
@ -178,6 +190,9 @@ static void *gpu_encode_thread(struct obs_core_video_mix *video)
|
|||||||
obs_encoder_release(encoders.array[i]);
|
obs_encoder_release(encoders.array[i]);
|
||||||
|
|
||||||
da_resize(encoders, 0);
|
da_resize(encoders, 0);
|
||||||
|
|
||||||
|
profile_end(gpu_encode_thread_name);
|
||||||
|
profile_reenable_thread();
|
||||||
}
|
}
|
||||||
|
|
||||||
da_free(encoders);
|
da_free(encoders);
|
||||||
@ -186,7 +201,6 @@ static void *gpu_encode_thread(struct obs_core_video_mix *video)
|
|||||||
|
|
||||||
bool init_gpu_encoding(struct obs_core_video_mix *video)
|
bool init_gpu_encoding(struct obs_core_video_mix *video)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
const struct video_output_info *info =
|
const struct video_output_info *info =
|
||||||
video_output_get_info(video->video);
|
video_output_get_info(video->video);
|
||||||
|
|
||||||
@ -210,7 +224,11 @@ bool init_gpu_encoding(struct obs_core_video_mix *video)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
uint32_t handle = gs_texture_get_shared_handle(tex);
|
uint32_t handle = gs_texture_get_shared_handle(tex);
|
||||||
|
#else
|
||||||
|
uint32_t handle = (uint32_t)-1;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct obs_tex_frame frame = {.tex = tex,
|
struct obs_tex_frame frame = {.tex = tex,
|
||||||
.tex_uv = tex_uv,
|
.tex_uv = tex_uv,
|
||||||
@ -233,10 +251,6 @@ bool init_gpu_encoding(struct obs_core_video_mix *video)
|
|||||||
|
|
||||||
video->gpu_encode_thread_initialized = true;
|
video->gpu_encode_thread_initialized = true;
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
UNUSED_PARAMETER(video);
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_gpu_encoding_thread(struct obs_core_video_mix *video)
|
void stop_gpu_encoding_thread(struct obs_core_video_mix *video)
|
||||||
|
@ -477,7 +477,6 @@ stage_output_texture(struct obs_core_video_mix *video, int cur_texture,
|
|||||||
profile_end(stage_output_texture_name);
|
profile_end(stage_output_texture_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
static inline bool queue_frame(struct obs_core_video_mix *video,
|
static inline bool queue_frame(struct obs_core_video_mix *video,
|
||||||
bool raw_active,
|
bool raw_active,
|
||||||
struct obs_vframe_info *vframe_info)
|
struct obs_vframe_info *vframe_info)
|
||||||
@ -505,7 +504,9 @@ static inline bool queue_frame(struct obs_core_video_mix *video,
|
|||||||
deque_pop_front(&video->gpu_encoder_avail_queue, &tf, sizeof(tf));
|
deque_pop_front(&video->gpu_encoder_avail_queue, &tf, sizeof(tf));
|
||||||
|
|
||||||
if (tf.released) {
|
if (tf.released) {
|
||||||
|
#ifdef _WIN32
|
||||||
gs_texture_acquire_sync(tf.tex, tf.lock_key, GS_WAIT_INFINITE);
|
gs_texture_acquire_sync(tf.tex, tf.lock_key, GS_WAIT_INFINITE);
|
||||||
|
#endif
|
||||||
tf.released = false;
|
tf.released = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,8 +530,10 @@ static inline bool queue_frame(struct obs_core_video_mix *video,
|
|||||||
tf.count = 1;
|
tf.count = 1;
|
||||||
tf.timestamp = vframe_info->timestamp;
|
tf.timestamp = vframe_info->timestamp;
|
||||||
tf.released = true;
|
tf.released = true;
|
||||||
|
#ifdef _WIN32
|
||||||
tf.handle = gs_texture_get_shared_handle(tf.tex);
|
tf.handle = gs_texture_get_shared_handle(tf.tex);
|
||||||
gs_texture_release_sync(tf.tex, ++tf.lock_key);
|
gs_texture_release_sync(tf.tex, ++tf.lock_key);
|
||||||
|
#endif
|
||||||
deque_push_back(&video->gpu_encoder_queue, &tf, sizeof(tf));
|
deque_push_back(&video->gpu_encoder_queue, &tf, sizeof(tf));
|
||||||
|
|
||||||
os_sem_post(video->gpu_encode_semaphore);
|
os_sem_post(video->gpu_encode_semaphore);
|
||||||
@ -570,7 +573,6 @@ static void output_gpu_encoders(struct obs_core_video_mix *video,
|
|||||||
end:
|
end:
|
||||||
profile_end(output_gpu_encoders_name);
|
profile_end(output_gpu_encoders_name);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void render_video(struct obs_core_video_mix *video,
|
static inline void render_video(struct obs_core_video_mix *video,
|
||||||
bool raw_active, const bool gpu_active,
|
bool raw_active, const bool gpu_active,
|
||||||
@ -590,26 +592,24 @@ static inline void render_video(struct obs_core_video_mix *video,
|
|||||||
size_t channel_count = NUM_CHANNELS;
|
size_t channel_count = NUM_CHANNELS;
|
||||||
gs_texture_t *output_texture = render_output_texture(video);
|
gs_texture_t *output_texture = render_output_texture(video);
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (gpu_active) {
|
if (gpu_active) {
|
||||||
convert_textures = video->convert_textures_encode;
|
convert_textures = video->convert_textures_encode;
|
||||||
|
#ifdef _WIN32
|
||||||
copy_surfaces = video->copy_surfaces_encode;
|
copy_surfaces = video->copy_surfaces_encode;
|
||||||
channel_count = 1;
|
channel_count = 1;
|
||||||
|
#endif
|
||||||
gs_flush();
|
gs_flush();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (video->gpu_conversion) {
|
if (video->gpu_conversion) {
|
||||||
render_convert_texture(video, convert_textures,
|
render_convert_texture(video, convert_textures,
|
||||||
output_texture);
|
output_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (gpu_active) {
|
if (gpu_active) {
|
||||||
gs_flush();
|
gs_flush();
|
||||||
output_gpu_encoders(video, raw_active);
|
output_gpu_encoders(video, raw_active);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (raw_active) {
|
if (raw_active) {
|
||||||
stage_output_texture(video, cur_texture,
|
stage_output_texture(video, cur_texture,
|
||||||
@ -1014,12 +1014,10 @@ static void clear_raw_frame_data(struct obs_core_video_mix *video)
|
|||||||
deque_free(&video->vframe_info_buffer);
|
deque_free(&video->vframe_info_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
static void clear_gpu_frame_data(struct obs_core_video_mix *video)
|
static void clear_gpu_frame_data(struct obs_core_video_mix *video)
|
||||||
{
|
{
|
||||||
deque_free(&video->vframe_info_buffer_gpu);
|
deque_free(&video->vframe_info_buffer_gpu);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
extern THREAD_LOCAL bool is_graphics_thread;
|
extern THREAD_LOCAL bool is_graphics_thread;
|
||||||
|
|
||||||
@ -1127,30 +1125,22 @@ static const char *output_frame_name = "output_frame";
|
|||||||
static inline void update_active_state(struct obs_core_video_mix *video)
|
static inline void update_active_state(struct obs_core_video_mix *video)
|
||||||
{
|
{
|
||||||
const bool raw_was_active = video->raw_was_active;
|
const bool raw_was_active = video->raw_was_active;
|
||||||
#ifdef _WIN32
|
|
||||||
const bool gpu_was_active = video->gpu_was_active;
|
const bool gpu_was_active = video->gpu_was_active;
|
||||||
#endif
|
|
||||||
const bool was_active = video->was_active;
|
const bool was_active = video->was_active;
|
||||||
|
|
||||||
bool raw_active = os_atomic_load_long(&video->raw_active) > 0;
|
bool raw_active = os_atomic_load_long(&video->raw_active) > 0;
|
||||||
#ifdef _WIN32
|
|
||||||
const bool gpu_active =
|
const bool gpu_active =
|
||||||
os_atomic_load_long(&video->gpu_encoder_active) > 0;
|
os_atomic_load_long(&video->gpu_encoder_active) > 0;
|
||||||
const bool active = raw_active || gpu_active;
|
const bool active = raw_active || gpu_active;
|
||||||
#else
|
|
||||||
const bool active = raw_active;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!was_active && active)
|
if (!was_active && active)
|
||||||
clear_base_frame_data(video);
|
clear_base_frame_data(video);
|
||||||
if (!raw_was_active && raw_active)
|
if (!raw_was_active && raw_active)
|
||||||
clear_raw_frame_data(video);
|
clear_raw_frame_data(video);
|
||||||
#ifdef _WIN32
|
|
||||||
if (!gpu_was_active && gpu_active)
|
if (!gpu_was_active && gpu_active)
|
||||||
clear_gpu_frame_data(video);
|
clear_gpu_frame_data(video);
|
||||||
|
|
||||||
video->gpu_was_active = gpu_active;
|
video->gpu_was_active = gpu_active;
|
||||||
#endif
|
|
||||||
video->raw_was_active = raw_active;
|
video->raw_was_active = raw_active;
|
||||||
video->was_active = active;
|
video->was_active = active;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,6 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
|
|||||||
video->convert_textures[0] = NULL;
|
video->convert_textures[0] = NULL;
|
||||||
video->convert_textures[1] = NULL;
|
video->convert_textures[1] = NULL;
|
||||||
video->convert_textures[2] = NULL;
|
video->convert_textures[2] = NULL;
|
||||||
#ifdef _WIN32
|
|
||||||
video->convert_textures_encode[0] = NULL;
|
video->convert_textures_encode[0] = NULL;
|
||||||
video->convert_textures_encode[1] = NULL;
|
video->convert_textures_encode[1] = NULL;
|
||||||
video->convert_textures_encode[2] = NULL;
|
video->convert_textures_encode[2] = NULL;
|
||||||
@ -200,7 +199,6 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
@ -297,13 +295,11 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
|
|||||||
gs_texture_destroy(video->convert_textures[c]);
|
gs_texture_destroy(video->convert_textures[c]);
|
||||||
video->convert_textures[c] = NULL;
|
video->convert_textures[c] = NULL;
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
|
||||||
if (video->convert_textures_encode[c]) {
|
if (video->convert_textures_encode[c]) {
|
||||||
gs_texture_destroy(
|
gs_texture_destroy(
|
||||||
video->convert_textures_encode[c]);
|
video->convert_textures_encode[c]);
|
||||||
video->convert_textures_encode[c] = NULL;
|
video->convert_textures_encode[c] = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,12 +826,10 @@ static void obs_free_render_textures(struct obs_core_video_mix *video)
|
|||||||
gs_texture_destroy(video->convert_textures[c]);
|
gs_texture_destroy(video->convert_textures[c]);
|
||||||
video->convert_textures[c] = NULL;
|
video->convert_textures[c] = NULL;
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
|
||||||
if (video->convert_textures_encode[c]) {
|
if (video->convert_textures_encode[c]) {
|
||||||
gs_texture_destroy(video->convert_textures_encode[c]);
|
gs_texture_destroy(video->convert_textures_encode[c]);
|
||||||
video->convert_textures_encode[c] = NULL;
|
video->convert_textures_encode[c] = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_texture_destroy(video->output_texture);
|
gs_texture_destroy(video->output_texture);
|
||||||
|
Loading…
Reference in New Issue
Block a user