mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
libobs: Format changes for multiple video mixes
This commit is contained in:
parent
7e39ee291c
commit
0a87797a21
@ -150,7 +150,8 @@ 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
|
#ifdef _WIN32
|
||||||
const struct video_output_info *info = video_output_get_info(video->video);
|
const struct video_output_info *info =
|
||||||
|
video_output_get_info(video->video);
|
||||||
|
|
||||||
video->gpu_encode_stop = false;
|
video->gpu_encode_stop = false;
|
||||||
|
|
||||||
@ -160,15 +161,13 @@ bool init_gpu_encoding(struct obs_core_video_mix *video)
|
|||||||
gs_texture_t *tex_uv;
|
gs_texture_t *tex_uv;
|
||||||
|
|
||||||
if (info->format == VIDEO_FORMAT_P010) {
|
if (info->format == VIDEO_FORMAT_P010) {
|
||||||
gs_texture_create_p010(&tex, &tex_uv, info->width,
|
gs_texture_create_p010(
|
||||||
info->height,
|
&tex, &tex_uv, info->width, info->height,
|
||||||
GS_RENDER_TARGET |
|
GS_RENDER_TARGET | GS_SHARED_KM_TEX);
|
||||||
GS_SHARED_KM_TEX);
|
|
||||||
} else {
|
} else {
|
||||||
gs_texture_create_nv12(&tex, &tex_uv, info->width,
|
gs_texture_create_nv12(
|
||||||
info->height,
|
&tex, &tex_uv, info->width, info->height,
|
||||||
GS_RENDER_TARGET |
|
GS_RENDER_TARGET | GS_SHARED_KM_TEX);
|
||||||
GS_SHARED_KM_TEX);
|
|
||||||
}
|
}
|
||||||
if (!tex) {
|
if (!tex) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -37,8 +37,7 @@ static uint64_t tick_sources(uint64_t cur_time, uint64_t last_time)
|
|||||||
float seconds;
|
float seconds;
|
||||||
|
|
||||||
if (!last_time)
|
if (!last_time)
|
||||||
last_time = cur_time -
|
last_time = cur_time - obs->video.video_frame_interval_ns;
|
||||||
obs->video.video_frame_interval_ns;
|
|
||||||
|
|
||||||
delta_time = cur_time - last_time;
|
delta_time = cur_time - last_time;
|
||||||
seconds = (float)((double)delta_time / 1000000000.0);
|
seconds = (float)((double)delta_time / 1000000000.0);
|
||||||
@ -148,8 +147,7 @@ static inline void render_main_texture(struct obs_core_video_mix *video)
|
|||||||
struct draw_callback *callback;
|
struct draw_callback *callback;
|
||||||
callback = obs->data.draw_callbacks.array + (i - 1);
|
callback = obs->data.draw_callbacks.array + (i - 1);
|
||||||
|
|
||||||
callback->draw(callback->param, base_width,
|
callback->draw(callback->param, base_width, base_height);
|
||||||
base_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&obs->data.draw_callbacks_mutex);
|
pthread_mutex_unlock(&obs->data.draw_callbacks_mutex);
|
||||||
@ -166,7 +164,8 @@ static inline gs_effect_t *
|
|||||||
get_scale_effect_internal(struct obs_core_video_mix *mix)
|
get_scale_effect_internal(struct obs_core_video_mix *mix)
|
||||||
{
|
{
|
||||||
struct obs_core_video *video = &obs->video;
|
struct obs_core_video *video = &obs->video;
|
||||||
const struct video_output_info *info = video_output_get_info(mix->video);
|
const struct video_output_info *info =
|
||||||
|
video_output_get_info(mix->video);
|
||||||
|
|
||||||
/* if the dimension is under half the size of the original image,
|
/* if the dimension is under half the size of the original image,
|
||||||
* bicubic/lanczos can't sample enough pixels to create an accurate
|
* bicubic/lanczos can't sample enough pixels to create an accurate
|
||||||
@ -219,7 +218,8 @@ static inline gs_effect_t *get_scale_effect(struct obs_core_video_mix *mix,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char *render_output_texture_name = "render_output_texture";
|
static const char *render_output_texture_name = "render_output_texture";
|
||||||
static inline gs_texture_t *render_output_texture(struct obs_core_video_mix *mix)
|
static inline gs_texture_t *
|
||||||
|
render_output_texture(struct obs_core_video_mix *mix)
|
||||||
{
|
{
|
||||||
struct obs_core_video *video = &obs->video;
|
struct obs_core_video *video = &obs->video;
|
||||||
gs_texture_t *texture = mix->render_texture;
|
gs_texture_t *texture = mix->render_texture;
|
||||||
@ -427,7 +427,8 @@ stage_output_texture(struct obs_core_video_mix *video, int cur_texture,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static inline bool queue_frame(struct obs_core_video_mix *video, bool raw_active,
|
static inline bool queue_frame(struct obs_core_video_mix *video,
|
||||||
|
bool raw_active,
|
||||||
struct obs_vframe_info *vframe_info)
|
struct obs_vframe_info *vframe_info)
|
||||||
{
|
{
|
||||||
bool duplicate =
|
bool duplicate =
|
||||||
@ -497,7 +498,8 @@ static inline void encode_gpu(struct obs_core_video_mix *video, bool raw_active,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char *output_gpu_encoders_name = "output_gpu_encoders";
|
static const char *output_gpu_encoders_name = "output_gpu_encoders";
|
||||||
static void output_gpu_encoders(struct obs_core_video_mix *video, bool raw_active)
|
static void output_gpu_encoders(struct obs_core_video_mix *video,
|
||||||
|
bool raw_active)
|
||||||
{
|
{
|
||||||
profile_start(output_gpu_encoders_name);
|
profile_start(output_gpu_encoders_name);
|
||||||
|
|
||||||
@ -519,8 +521,9 @@ end:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void render_video(struct obs_core_video_mix *video, bool raw_active,
|
static inline void render_video(struct obs_core_video_mix *video,
|
||||||
const bool gpu_active, int cur_texture)
|
bool raw_active, const bool gpu_active,
|
||||||
|
int cur_texture)
|
||||||
{
|
{
|
||||||
gs_begin_scene();
|
gs_begin_scene();
|
||||||
|
|
||||||
@ -795,8 +798,7 @@ static inline void output_video_data(struct obs_core_video_mix *video,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void video_sleep(struct obs_core_video *video,
|
static inline void video_sleep(struct obs_core_video *video, uint64_t *p_time,
|
||||||
uint64_t *p_time,
|
|
||||||
uint64_t interval_ns)
|
uint64_t interval_ns)
|
||||||
{
|
{
|
||||||
struct obs_vframe_info vframe_info;
|
struct obs_vframe_info vframe_info;
|
||||||
@ -830,12 +832,12 @@ static inline void video_sleep(struct obs_core_video *video,
|
|||||||
bool raw_active = video->raw_was_active;
|
bool raw_active = video->raw_was_active;
|
||||||
bool gpu_active = video->gpu_was_active;
|
bool gpu_active = video->gpu_was_active;
|
||||||
|
|
||||||
if (raw_active)
|
if (raw_active)
|
||||||
circlebuf_push_back(&video->vframe_info_buffer, &vframe_info,
|
circlebuf_push_back(&video->vframe_info_buffer,
|
||||||
sizeof(vframe_info));
|
&vframe_info, sizeof(vframe_info));
|
||||||
if (gpu_active)
|
if (gpu_active)
|
||||||
circlebuf_push_back(&video->vframe_info_buffer_gpu,
|
circlebuf_push_back(&video->vframe_info_buffer_gpu,
|
||||||
&vframe_info, sizeof(vframe_info));
|
&vframe_info, sizeof(vframe_info));
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&obs->video.mixes_mutex);
|
pthread_mutex_unlock(&obs->video.mixes_mutex);
|
||||||
}
|
}
|
||||||
@ -1132,8 +1134,7 @@ bool obs_graphics_thread_loop(struct obs_graphics_context *context)
|
|||||||
|
|
||||||
profile_reenable_thread();
|
profile_reenable_thread();
|
||||||
|
|
||||||
video_sleep(&obs->video, &obs->video.video_time,
|
video_sleep(&obs->video, &obs->video.video_time, context->interval);
|
||||||
context->interval);
|
|
||||||
|
|
||||||
context->frame_time_total_ns += frame_time_ns;
|
context->frame_time_total_ns += frame_time_ns;
|
||||||
context->fps_total_ns += (obs->video.video_time - context->last_time);
|
context->fps_total_ns += (obs->video.video_time - context->last_time);
|
||||||
|
205
libobs/obs.c
205
libobs/obs.c
@ -46,7 +46,8 @@ static inline void make_video_info(struct video_output_info *vi,
|
|||||||
|
|
||||||
static inline void calc_gpu_conversion_sizes(struct obs_core_video_mix *video)
|
static inline void calc_gpu_conversion_sizes(struct obs_core_video_mix *video)
|
||||||
{
|
{
|
||||||
const struct video_output_info *info = video_output_get_info(video->video);
|
const struct video_output_info *info =
|
||||||
|
video_output_get_info(video->video);
|
||||||
|
|
||||||
video->conversion_needed = false;
|
video->conversion_needed = false;
|
||||||
video->conversion_techs[0] = NULL;
|
video->conversion_techs[0] = NULL;
|
||||||
@ -117,12 +118,10 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
|
|||||||
|
|
||||||
calc_gpu_conversion_sizes(video);
|
calc_gpu_conversion_sizes(video);
|
||||||
|
|
||||||
video->using_nv12_tex = info->format == VIDEO_FORMAT_NV12
|
video->using_nv12_tex =
|
||||||
? gs_nv12_available()
|
info->format == VIDEO_FORMAT_NV12 ? gs_nv12_available() : false;
|
||||||
: false;
|
video->using_p010_tex =
|
||||||
video->using_p010_tex = info->format == VIDEO_FORMAT_P010
|
info->format == VIDEO_FORMAT_P010 ? gs_p010_available() : false;
|
||||||
? gs_p010_available()
|
|
||||||
: false;
|
|
||||||
|
|
||||||
if (!video->conversion_needed) {
|
if (!video->conversion_needed) {
|
||||||
blog(LOG_INFO, "GPU conversion not available for format: %u",
|
blog(LOG_INFO, "GPU conversion not available for format: %u",
|
||||||
@ -152,19 +151,19 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
|
|||||||
video->convert_textures_encode[1] = NULL;
|
video->convert_textures_encode[1] = NULL;
|
||||||
video->convert_textures_encode[2] = NULL;
|
video->convert_textures_encode[2] = NULL;
|
||||||
if (video->using_nv12_tex) {
|
if (video->using_nv12_tex) {
|
||||||
if (!gs_texture_create_nv12(
|
if (!gs_texture_create_nv12(&video->convert_textures_encode[0],
|
||||||
&video->convert_textures_encode[0],
|
&video->convert_textures_encode[1],
|
||||||
&video->convert_textures_encode[1],
|
info->width, info->height,
|
||||||
info->width, info->height,
|
GS_RENDER_TARGET |
|
||||||
GS_RENDER_TARGET | GS_SHARED_KM_TEX)) {
|
GS_SHARED_KM_TEX)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (video->using_p010_tex) {
|
} else if (video->using_p010_tex) {
|
||||||
if (!gs_texture_create_p010(
|
if (!gs_texture_create_p010(&video->convert_textures_encode[0],
|
||||||
&video->convert_textures_encode[0],
|
&video->convert_textures_encode[1],
|
||||||
&video->convert_textures_encode[1],
|
info->width, info->height,
|
||||||
info->width, info->height,
|
GS_RENDER_TARGET |
|
||||||
GS_RENDER_TARGET | GS_SHARED_KM_TEX)) {
|
GS_SHARED_KM_TEX)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,63 +174,63 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
|
|||||||
switch (info->format) {
|
switch (info->format) {
|
||||||
case VIDEO_FORMAT_I420:
|
case VIDEO_FORMAT_I420:
|
||||||
video->convert_textures[0] =
|
video->convert_textures[0] =
|
||||||
gs_texture_create(info->width, info->height,
|
gs_texture_create(info->width, info->height, GS_R8, 1,
|
||||||
|
NULL, GS_RENDER_TARGET);
|
||||||
|
video->convert_textures[1] =
|
||||||
|
gs_texture_create(info->width / 2, info->height / 2,
|
||||||
|
GS_R8, 1, NULL, GS_RENDER_TARGET);
|
||||||
|
video->convert_textures[2] =
|
||||||
|
gs_texture_create(info->width / 2, info->height / 2,
|
||||||
GS_R8, 1, NULL, GS_RENDER_TARGET);
|
GS_R8, 1, NULL, GS_RENDER_TARGET);
|
||||||
video->convert_textures[1] = gs_texture_create(
|
|
||||||
info->width / 2, info->height / 2, GS_R8, 1,
|
|
||||||
NULL, GS_RENDER_TARGET);
|
|
||||||
video->convert_textures[2] = gs_texture_create(
|
|
||||||
info->width / 2, info->height / 2, GS_R8, 1,
|
|
||||||
NULL, GS_RENDER_TARGET);
|
|
||||||
if (!video->convert_textures[0] ||
|
if (!video->convert_textures[0] ||
|
||||||
!video->convert_textures[1] || !video->convert_textures[2])
|
!video->convert_textures[1] || !video->convert_textures[2])
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
case VIDEO_FORMAT_NV12:
|
case VIDEO_FORMAT_NV12:
|
||||||
video->convert_textures[0] =
|
video->convert_textures[0] =
|
||||||
gs_texture_create(info->width, info->height,
|
gs_texture_create(info->width, info->height, GS_R8, 1,
|
||||||
GS_R8, 1, NULL, GS_RENDER_TARGET);
|
NULL, GS_RENDER_TARGET);
|
||||||
video->convert_textures[1] = gs_texture_create(
|
video->convert_textures[1] =
|
||||||
info->width / 2, info->height / 2, GS_R8G8,
|
gs_texture_create(info->width / 2, info->height / 2,
|
||||||
1, NULL, GS_RENDER_TARGET);
|
GS_R8G8, 1, NULL, GS_RENDER_TARGET);
|
||||||
if (!video->convert_textures[0] || !video->convert_textures[1])
|
if (!video->convert_textures[0] || !video->convert_textures[1])
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
case VIDEO_FORMAT_I444:
|
case VIDEO_FORMAT_I444:
|
||||||
video->convert_textures[0] =
|
video->convert_textures[0] =
|
||||||
gs_texture_create(info->width, info->height,
|
gs_texture_create(info->width, info->height, GS_R8, 1,
|
||||||
GS_R8, 1, NULL, GS_RENDER_TARGET);
|
NULL, GS_RENDER_TARGET);
|
||||||
video->convert_textures[1] =
|
video->convert_textures[1] =
|
||||||
gs_texture_create(info->width, info->height,
|
gs_texture_create(info->width, info->height, GS_R8, 1,
|
||||||
GS_R8, 1, NULL, GS_RENDER_TARGET);
|
NULL, GS_RENDER_TARGET);
|
||||||
video->convert_textures[2] =
|
video->convert_textures[2] =
|
||||||
gs_texture_create(info->width, info->height,
|
gs_texture_create(info->width, info->height, GS_R8, 1,
|
||||||
GS_R8, 1, NULL, GS_RENDER_TARGET);
|
NULL, GS_RENDER_TARGET);
|
||||||
if (!video->convert_textures[0] ||
|
if (!video->convert_textures[0] ||
|
||||||
!video->convert_textures[1] || !video->convert_textures[2])
|
!video->convert_textures[1] || !video->convert_textures[2])
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
case VIDEO_FORMAT_I010:
|
case VIDEO_FORMAT_I010:
|
||||||
video->convert_textures[0] =
|
video->convert_textures[0] =
|
||||||
gs_texture_create(info->width, info->height,
|
gs_texture_create(info->width, info->height, GS_R16, 1,
|
||||||
|
NULL, GS_RENDER_TARGET);
|
||||||
|
video->convert_textures[1] =
|
||||||
|
gs_texture_create(info->width / 2, info->height / 2,
|
||||||
|
GS_R16, 1, NULL, GS_RENDER_TARGET);
|
||||||
|
video->convert_textures[2] =
|
||||||
|
gs_texture_create(info->width / 2, info->height / 2,
|
||||||
GS_R16, 1, NULL, GS_RENDER_TARGET);
|
GS_R16, 1, NULL, GS_RENDER_TARGET);
|
||||||
video->convert_textures[1] = gs_texture_create(
|
|
||||||
info->width / 2, info->height / 2, GS_R16,
|
|
||||||
1, NULL, GS_RENDER_TARGET);
|
|
||||||
video->convert_textures[2] = gs_texture_create(
|
|
||||||
info->width / 2, info->height / 2, GS_R16,
|
|
||||||
1, NULL, GS_RENDER_TARGET);
|
|
||||||
if (!video->convert_textures[0] ||
|
if (!video->convert_textures[0] ||
|
||||||
!video->convert_textures[1] || !video->convert_textures[2])
|
!video->convert_textures[1] || !video->convert_textures[2])
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
case VIDEO_FORMAT_P010:
|
case VIDEO_FORMAT_P010:
|
||||||
video->convert_textures[0] =
|
video->convert_textures[0] =
|
||||||
gs_texture_create(info->width, info->height,
|
gs_texture_create(info->width, info->height, GS_R16, 1,
|
||||||
GS_R16, 1, NULL, GS_RENDER_TARGET);
|
NULL, GS_RENDER_TARGET);
|
||||||
video->convert_textures[1] = gs_texture_create(
|
video->convert_textures[1] =
|
||||||
info->width / 2, info->height / 2, GS_RG16,
|
gs_texture_create(info->width / 2, info->height / 2,
|
||||||
1, NULL, GS_RENDER_TARGET);
|
GS_RG16, 1, NULL, GS_RENDER_TARGET);
|
||||||
if (!video->convert_textures[0] || !video->convert_textures[1])
|
if (!video->convert_textures[0] || !video->convert_textures[1])
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
@ -256,7 +255,8 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool obs_init_gpu_copy_surfaces(struct obs_core_video_mix *video, size_t i)
|
static bool obs_init_gpu_copy_surfaces(struct obs_core_video_mix *video,
|
||||||
|
size_t i)
|
||||||
{
|
{
|
||||||
const struct video_output_info *info =
|
const struct video_output_info *info =
|
||||||
video_output_get_info(video->video);
|
video_output_get_info(video->video);
|
||||||
@ -332,7 +332,8 @@ static bool obs_init_gpu_copy_surfaces(struct obs_core_video_mix *video, size_t
|
|||||||
|
|
||||||
static bool obs_init_textures(struct obs_core_video_mix *video)
|
static bool obs_init_textures(struct obs_core_video_mix *video)
|
||||||
{
|
{
|
||||||
const struct video_output_info *info = video_output_get_info(video->video);
|
const struct video_output_info *info =
|
||||||
|
video_output_get_info(video->video);
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
@ -396,15 +397,14 @@ static bool obs_init_textures(struct obs_core_video_mix *video)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
video->render_texture = gs_texture_create(obs->video.base_width,
|
video->render_texture =
|
||||||
obs->video.base_height, format, 1,
|
gs_texture_create(obs->video.base_width, obs->video.base_height,
|
||||||
NULL, GS_RENDER_TARGET);
|
format, 1, NULL, GS_RENDER_TARGET);
|
||||||
if (!video->render_texture)
|
if (!video->render_texture)
|
||||||
success = false;
|
success = false;
|
||||||
|
|
||||||
video->output_texture = gs_texture_create(info->width,
|
video->output_texture = gs_texture_create(
|
||||||
info->height, format, 1,
|
info->width, info->height, format, 1, NULL, GS_RENDER_TARGET);
|
||||||
NULL, GS_RENDER_TARGET);
|
|
||||||
if (!video->output_texture)
|
if (!video->output_texture)
|
||||||
success = false;
|
success = false;
|
||||||
|
|
||||||
@ -625,8 +625,10 @@ static int obs_init_video(struct obs_video_info *ovi)
|
|||||||
struct obs_core_video *video = &obs->video;
|
struct obs_core_video *video = &obs->video;
|
||||||
video->base_width = ovi->base_width;
|
video->base_width = ovi->base_width;
|
||||||
video->base_height = ovi->base_height;
|
video->base_height = ovi->base_height;
|
||||||
video->video_frame_interval_ns = util_mul_div64(1000000000ULL, ovi->fps_den, ovi->fps_num);
|
video->video_frame_interval_ns =
|
||||||
video->video_half_frame_interval_ns = util_mul_div64(500000000ULL, ovi->fps_den, ovi->fps_num);
|
util_mul_div64(1000000000ULL, ovi->fps_den, ovi->fps_num);
|
||||||
|
video->video_half_frame_interval_ns =
|
||||||
|
util_mul_div64(500000000ULL, ovi->fps_den, ovi->fps_num);
|
||||||
|
|
||||||
if (pthread_mutex_init(&video->task_mutex, NULL) < 0)
|
if (pthread_mutex_init(&video->task_mutex, NULL) < 0)
|
||||||
return OBS_VIDEO_FAIL;
|
return OBS_VIDEO_FAIL;
|
||||||
@ -663,67 +665,64 @@ static void stop_video(void)
|
|||||||
struct obs_core_video *video = &obs->video;
|
struct obs_core_video *video = &obs->video;
|
||||||
void *thread_retval;
|
void *thread_retval;
|
||||||
|
|
||||||
if (video->thread_initialized) {
|
if (video->thread_initialized) {
|
||||||
pthread_join(video->video_thread, &thread_retval);
|
pthread_join(video->video_thread, &thread_retval);
|
||||||
video->thread_initialized = false;
|
video->thread_initialized = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void obs_free_render_textures(struct obs_core_video_mix *video)
|
static void obs_free_render_textures(struct obs_core_video_mix *video)
|
||||||
{
|
{
|
||||||
if (!obs->video.graphics)
|
if (!obs->video.graphics)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gs_enter_context(obs->video.graphics);
|
gs_enter_context(obs->video.graphics);
|
||||||
|
|
||||||
for (size_t c = 0; c < NUM_CHANNELS; c++) {
|
for (size_t c = 0; c < NUM_CHANNELS; c++) {
|
||||||
if (video->mapped_surfaces[c]) {
|
if (video->mapped_surfaces[c]) {
|
||||||
gs_stagesurface_unmap(
|
gs_stagesurface_unmap(video->mapped_surfaces[c]);
|
||||||
video->mapped_surfaces[c]);
|
video->mapped_surfaces[c] = NULL;
|
||||||
video->mapped_surfaces[c] = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < NUM_TEXTURES; i++) {
|
for (size_t i = 0; i < NUM_TEXTURES; i++) {
|
||||||
for (size_t c = 0; c < NUM_CHANNELS; c++) {
|
for (size_t c = 0; c < NUM_CHANNELS; c++) {
|
||||||
if (video->copy_surfaces[i][c]) {
|
if (video->copy_surfaces[i][c]) {
|
||||||
gs_stagesurface_destroy(
|
|
||||||
video->copy_surfaces[i][c]);
|
|
||||||
video->copy_surfaces[i][c] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
video->active_copy_surfaces[i][c] = NULL;
|
|
||||||
}
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (video->copy_surfaces_encode[i]) {
|
|
||||||
gs_stagesurface_destroy(
|
gs_stagesurface_destroy(
|
||||||
video->copy_surfaces_encode[i]);
|
video->copy_surfaces[i][c]);
|
||||||
video->copy_surfaces_encode[i] = NULL;
|
video->copy_surfaces[i][c] = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
video->active_copy_surfaces[i][c] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_texture_destroy(video->render_texture);
|
|
||||||
|
|
||||||
for (size_t c = 0; c < NUM_CHANNELS; c++) {
|
|
||||||
if (video->convert_textures[c]) {
|
|
||||||
gs_texture_destroy(video->convert_textures[c]);
|
|
||||||
video->convert_textures[c] = NULL;
|
|
||||||
}
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (video->convert_textures_encode[c]) {
|
if (video->copy_surfaces_encode[i]) {
|
||||||
gs_texture_destroy(
|
gs_stagesurface_destroy(video->copy_surfaces_encode[i]);
|
||||||
video->convert_textures_encode[c]);
|
video->copy_surfaces_encode[i] = NULL;
|
||||||
video->convert_textures_encode[c] = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
gs_texture_destroy(video->output_texture);
|
gs_texture_destroy(video->render_texture);
|
||||||
video->render_texture = NULL;
|
|
||||||
video->output_texture = NULL;
|
|
||||||
|
|
||||||
gs_leave_context();
|
for (size_t c = 0; c < NUM_CHANNELS; c++) {
|
||||||
|
if (video->convert_textures[c]) {
|
||||||
|
gs_texture_destroy(video->convert_textures[c]);
|
||||||
|
video->convert_textures[c] = NULL;
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (video->convert_textures_encode[c]) {
|
||||||
|
gs_texture_destroy(video->convert_textures_encode[c]);
|
||||||
|
video->convert_textures_encode[c] = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
gs_texture_destroy(video->output_texture);
|
||||||
|
video->render_texture = NULL;
|
||||||
|
video->output_texture = NULL;
|
||||||
|
|
||||||
|
gs_leave_context();
|
||||||
}
|
}
|
||||||
|
|
||||||
void obs_free_video_mix(struct obs_core_video_mix *video)
|
void obs_free_video_mix(struct obs_core_video_mix *video)
|
||||||
|
Loading…
Reference in New Issue
Block a user