change names, fix some bugs, minor GL/D3D fixes, update tests, fix effect files, output a little more debug information
parent
1493a325bb
commit
9570f0b8d7
|
@ -23,6 +23,8 @@ extern "C" {
|
|||
|
||||
EXPORT device_t device_create(struct gs_init_data *data);
|
||||
EXPORT void device_destroy(device_t device);
|
||||
EXPORT void device_entercontext(device_t device);
|
||||
EXPORT void device_leavecontext(device_t device);
|
||||
EXPORT swapchain_t device_create_swapchain(device_t device,
|
||||
struct gs_init_data *data);
|
||||
EXPORT void device_resize(device_t device, uint32_t x, uint32_t y);
|
||||
|
|
|
@ -426,6 +426,16 @@ void device_destroy(device_t device)
|
|||
delete device;
|
||||
}
|
||||
|
||||
void device_entercontext(device_t device)
|
||||
{
|
||||
/* does nothing */
|
||||
}
|
||||
|
||||
void device_leavecontext(device_t device)
|
||||
{
|
||||
/* does nothing */
|
||||
}
|
||||
|
||||
swapchain_t device_create_swapchain(device_t device, struct gs_init_data *data)
|
||||
{
|
||||
gs_swap_chain *swap = NULL;
|
||||
|
@ -591,7 +601,7 @@ shader_t device_create_vertexshader(device_t device,
|
|||
if (error_string)
|
||||
*error_string = bstrdup(buf);
|
||||
blog(LOG_ERROR, "device_create_vertexshader (D3D11): "
|
||||
"Compile errors for %s:\n%s",
|
||||
"Compile warnings/errors for %s:\n%s",
|
||||
file, buf);
|
||||
|
||||
} catch (const char *error) {
|
||||
|
@ -620,7 +630,7 @@ shader_t device_create_pixelshader(device_t device,
|
|||
if (error_string)
|
||||
*error_string = bstrdup(buf);
|
||||
blog(LOG_ERROR, "device_create_pixelshader (D3D11): "
|
||||
"Compiler errors for %s:\n%s",
|
||||
"Compiler warnings/errors for %s:\n%s",
|
||||
file, buf);
|
||||
|
||||
} catch (const char *error) {
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
EXPORT device_t device_create(struct gs_init_data *data);
|
||||
EXPORT void device_destroy(device_t device);
|
||||
EXPORT void device_entercontext(device_t device);
|
||||
EXPORT void device_leavecontext(device_t device);
|
||||
EXPORT swapchain_t device_create_swapchain(device_t device,
|
||||
struct gs_init_data *data);
|
||||
EXPORT void device_resize(device_t device, uint32_t x, uint32_t y);
|
||||
|
|
|
@ -22,7 +22,7 @@ bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels,
|
|||
uint32_t width, uint32_t height, uint32_t size, void ***p_data)
|
||||
{
|
||||
bool success = true;
|
||||
void **data = *p_data;
|
||||
void **data = p_data ? *p_data : NULL;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < num_levels; i++) {
|
||||
|
@ -50,7 +50,8 @@ bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels,
|
|||
if (height == 0) height = 1;
|
||||
}
|
||||
|
||||
*p_data = data;
|
||||
if (data)
|
||||
*p_data = data;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ static inline bool gl_success(const char *funcname)
|
|||
{
|
||||
GLenum errorcode = glGetError();
|
||||
if (errorcode != GL_NO_ERROR) {
|
||||
blog(LOG_ERROR, "%s failed, glGetError returned %u",
|
||||
blog(LOG_ERROR, "%s failed, glGetError returned 0x%X",
|
||||
funcname, errorcode);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,8 @@ static inline void shader_param_free(struct shader_param *param)
|
|||
da_free(param->def_value);
|
||||
}
|
||||
|
||||
static void gl_get_program_info(GLuint program, char **error_string)
|
||||
static void gl_get_program_info(GLuint program, const char *file,
|
||||
char **error_string)
|
||||
{
|
||||
char *errors;
|
||||
GLint info_len = 0;
|
||||
|
@ -51,7 +52,12 @@ static void gl_get_program_info(GLuint program, char **error_string)
|
|||
glGetProgramInfoLog(program, info_len, &chars_written, errors);
|
||||
gl_success("glGetProgramInfoLog");
|
||||
|
||||
*error_string = errors;
|
||||
blog(LOG_DEBUG, "Compiler warnings/errors for %s:\n%s", file, errors);
|
||||
|
||||
if (error_string)
|
||||
*error_string = errors;
|
||||
else
|
||||
bfree(errors);
|
||||
}
|
||||
|
||||
static bool gl_add_param(struct gs_shader *shader, struct shader_var *var,
|
||||
|
@ -195,6 +201,12 @@ static bool gl_shader_init(struct gs_shader *shader,
|
|||
if (!shader->program)
|
||||
return false;
|
||||
|
||||
blog(LOG_DEBUG, "+++++++++++++++++++++++++++++++++++");
|
||||
blog(LOG_DEBUG, " GL shader string for: %s", file);
|
||||
blog(LOG_DEBUG, "-----------------------------------");
|
||||
blog(LOG_DEBUG, "%s", glsp->gl_string.array);
|
||||
blog(LOG_DEBUG, "+++++++++++++++++++++++++++++++++++");
|
||||
|
||||
glGetProgramiv(shader->program, GL_VALIDATE_STATUS, &compiled);
|
||||
if (!gl_success("glGetProgramiv"))
|
||||
return false;
|
||||
|
@ -202,7 +214,7 @@ static bool gl_shader_init(struct gs_shader *shader,
|
|||
if (!compiled)
|
||||
success = false;
|
||||
|
||||
gl_get_program_info(shader->program, error_string);
|
||||
gl_get_program_info(shader->program, file, error_string);
|
||||
|
||||
if (success)
|
||||
success = gl_add_params(shader, glsp);
|
||||
|
|
|
@ -417,7 +417,7 @@ static void gl_write_function(struct gl_shader_parser *glsp,
|
|||
dstr_cat(&glsp->gl_string, " ");
|
||||
|
||||
if (strcmp(func->name, "main") == 0)
|
||||
dstr_cat(&glsp->gl_string, "__main__");
|
||||
dstr_cat(&glsp->gl_string, "obs_main_x");
|
||||
else
|
||||
dstr_cat(&glsp->gl_string, func->name);
|
||||
|
||||
|
@ -521,7 +521,7 @@ static void gl_write_main(struct gl_shader_parser *glsp,
|
|||
dstr_cat(&glsp->gl_string, main->params.array[i].type);
|
||||
dstr_cat(&glsp->gl_string, " ");
|
||||
dstr_cat(&glsp->gl_string, main->params.array[i].name);
|
||||
dstr_cat(&glsp->gl_string, "\n");
|
||||
dstr_cat(&glsp->gl_string, ";\n");
|
||||
}
|
||||
|
||||
if (!main->mapping) {
|
||||
|
@ -534,7 +534,7 @@ static void gl_write_main(struct gl_shader_parser *glsp,
|
|||
gl_write_main_storage_var(glsp, main->params.array, NULL,
|
||||
"inputval_", true);
|
||||
|
||||
dstr_cat(&glsp->gl_string, "\n\toutputval = __main__(");
|
||||
dstr_cat(&glsp->gl_string, "\n\toutputval = obs_main_x(");
|
||||
for (i = 0; i < main->params.num; i++) {
|
||||
if (i)
|
||||
dstr_cat(&glsp->gl_string, ", ");
|
||||
|
|
|
@ -28,7 +28,9 @@ static bool create_pixel_pack_buffer(struct gs_stage_surface *surf)
|
|||
if (!gl_bind_buffer(GL_PIXEL_PACK_BUFFER, surf->pack_buffer))
|
||||
return false;
|
||||
|
||||
size = surf->width * surf->height * surf->bytes_per_pixel;
|
||||
size = surf->width * surf->bytes_per_pixel;
|
||||
size = (size+3) & 0xFFFFFFFC; /* align width to 4-byte boundry */
|
||||
size *= surf->height;
|
||||
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, size, 0, GL_DYNAMIC_READ);
|
||||
if (!gl_success("glBufferData"))
|
||||
|
|
|
@ -64,6 +64,7 @@ device_t device_create(struct gs_init_data *info)
|
|||
blog(LOG_DEBUG, "OpenGL debug information not available");
|
||||
#endif
|
||||
|
||||
device_leavecontext(device);
|
||||
return device;
|
||||
|
||||
fail:
|
||||
|
|
|
@ -52,8 +52,15 @@ static bool create_pixel_unpack_buffer(struct gs_texture_2d *tex)
|
|||
if (!gl_bind_buffer(GL_PIXEL_UNPACK_BUFFER, tex->unpack_buffer))
|
||||
return false;
|
||||
|
||||
size = tex->width * tex->height * gs_get_format_bpp(tex->base.format);
|
||||
size /= 8;
|
||||
size = tex->width * gs_get_format_bpp(tex->base.format);
|
||||
if (!gs_is_compressed_format(tex->base.format)) {
|
||||
size /= 8;
|
||||
size = (size+3) & 0xFFFFFFFC;
|
||||
size *= tex->height;
|
||||
} else {
|
||||
size *= tex->height;
|
||||
size /= 8;
|
||||
}
|
||||
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, size, 0, GL_DYNAMIC_DRAW);
|
||||
if (!gl_success("glBufferData"))
|
||||
|
@ -75,6 +82,7 @@ texture_t device_create_texture(device_t device, uint32_t width,
|
|||
tex->base.device = device;
|
||||
tex->base.type = GS_TEXTURE_2D;
|
||||
tex->base.format = color_format;
|
||||
tex->base.levels = levels;
|
||||
tex->base.gl_format = convert_gs_format(color_format);
|
||||
tex->base.gl_internal_format = convert_gs_internal_format(color_format);
|
||||
tex->base.gl_type = get_gl_format_type(color_format);
|
||||
|
|
|
@ -63,6 +63,7 @@ texture_t device_create_cubetexture(device_t device, uint32_t size,
|
|||
tex->base.device = device;
|
||||
tex->base.type = GS_TEXTURE_CUBE;
|
||||
tex->base.format = color_format;
|
||||
tex->base.levels = levels;
|
||||
tex->base.gl_format = convert_gs_format(color_format);
|
||||
tex->base.gl_internal_format = convert_gs_internal_format(color_format);
|
||||
tex->base.gl_target = GL_TEXTURE_CUBE_MAP;
|
||||
|
|
|
@ -127,6 +127,16 @@ static inline HWND gl_create_dummy_window(void)
|
|||
return hwnd;
|
||||
}
|
||||
|
||||
static inline bool wgl_make_current(HDC hdc, HGLRC hglrc)
|
||||
{
|
||||
bool success = wglMakeCurrent(hdc, hglrc);
|
||||
if (!success)
|
||||
blog(LOG_ERROR, "wglMakeCurrent failed, GetLastError "
|
||||
"returned %u", GetLastError());
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static inline HGLRC gl_init_context(HDC hdc)
|
||||
{
|
||||
HGLRC hglrc = wglCreateContext(hdc);
|
||||
|
@ -135,8 +145,7 @@ static inline HGLRC gl_init_context(HDC hdc)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!wglMakeCurrent(hdc, hglrc)) {
|
||||
blog(LOG_ERROR, "wglMakeCurrent failed, %u", GetLastError());
|
||||
if (!wgl_make_current(hdc, hglrc)) {
|
||||
wglDeleteContext(hglrc);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -428,6 +437,21 @@ void gl_windowinfo_destroy(struct gl_windowinfo *wi)
|
|||
}
|
||||
}
|
||||
|
||||
void device_entercontext(device_t device)
|
||||
{
|
||||
HDC hdc = device->plat->swap.wi->hdc;
|
||||
if (device->cur_swap)
|
||||
hdc = device->cur_swap->wi->hdc;
|
||||
|
||||
if (!wgl_make_current(hdc, device->plat->hrc))
|
||||
blog(LOG_ERROR, "device_load_swapchain (GL) failed");
|
||||
}
|
||||
|
||||
void device_leavecontext(device_t device)
|
||||
{
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
}
|
||||
|
||||
void device_load_swapchain(device_t device, swapchain_t swap)
|
||||
{
|
||||
HDC hdc = device->plat->swap.wi->hdc;
|
||||
|
@ -439,11 +463,8 @@ void device_load_swapchain(device_t device, swapchain_t swap)
|
|||
if (swap)
|
||||
hdc = swap->wi->hdc;
|
||||
|
||||
if (!wglMakeCurrent(hdc, device->plat->hrc)) {
|
||||
blog(LOG_ERROR, "wglMakeCurrent failed, GetLastError "
|
||||
"returned %u", GetLastError());
|
||||
if (!wgl_make_current(hdc, device->plat->hrc))
|
||||
blog(LOG_ERROR, "device_load_swapchain (GL) failed");
|
||||
}
|
||||
}
|
||||
|
||||
void device_present(device_t device)
|
||||
|
|
|
@ -37,6 +37,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
|||
|
||||
GRAPHICS_IMPORT(device_create);
|
||||
GRAPHICS_IMPORT(device_destroy);
|
||||
GRAPHICS_IMPORT(device_entercontext);
|
||||
GRAPHICS_IMPORT(device_leavecontext);
|
||||
GRAPHICS_IMPORT(device_create_swapchain);
|
||||
GRAPHICS_IMPORT(device_resize);
|
||||
GRAPHICS_IMPORT(device_getsize);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../util/threading.h"
|
||||
#include "../util/darray.h"
|
||||
#include "graphics.h"
|
||||
#include "matrix3.h"
|
||||
|
@ -25,6 +26,8 @@
|
|||
struct gs_exports {
|
||||
device_t (*device_create)(struct gs_init_data *data);
|
||||
void (*device_destroy)(device_t device);
|
||||
void (*device_entercontext)(device_t device);
|
||||
void (*device_leavecontext)(device_t device);
|
||||
swapchain_t (*device_create_swapchain)(device_t device,
|
||||
struct gs_init_data *data);
|
||||
void (*device_resize)(device_t device, uint32_t x, uint32_t y);
|
||||
|
@ -223,4 +226,7 @@ struct graphics_subsystem {
|
|||
DARRAY(struct vec3) norms;
|
||||
DARRAY(uint32_t) colors;
|
||||
DARRAY(struct vec2) texverts[16];
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
volatile int ref;
|
||||
};
|
||||
|
|
|
@ -28,31 +28,21 @@
|
|||
#include "effect-parser.h"
|
||||
#include "effect.h"
|
||||
|
||||
#if 0
|
||||
|
||||
#ifdef _MSC_VER
|
||||
static __declspec(thread) graphics_t thread_graphics = NULL;
|
||||
#else /* assume GCC or that other compiler we dare not mention */
|
||||
static __thread graphics_t thread_graphics = NULL;
|
||||
#endif
|
||||
|
||||
#else
|
||||
static graphics_t thread_graphics = NULL;
|
||||
#endif
|
||||
|
||||
#define IMMEDIATE_COUNT 512
|
||||
|
||||
bool load_graphics_imports(struct gs_exports *exports, void *module,
|
||||
const char *module_name);
|
||||
|
||||
static bool graphics_init(struct graphics_subsystem *graphics)
|
||||
static bool graphics_init_immediate_vb(struct graphics_subsystem *graphics)
|
||||
{
|
||||
struct matrix3 top_mat;
|
||||
struct vb_data *vbd;
|
||||
|
||||
matrix3_identity(&top_mat);
|
||||
da_push_back(graphics->matrix_stack, &top_mat);
|
||||
|
||||
vbd = vbdata_create();
|
||||
vbd->num = IMMEDIATE_COUNT;
|
||||
vbd->points = bmalloc(sizeof(struct vec3)*IMMEDIATE_COUNT);
|
||||
|
@ -69,6 +59,13 @@ static bool graphics_init(struct graphics_subsystem *graphics)
|
|||
if (!graphics->immediate_vertbuffer)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool graphics_init_sprite_vb(struct graphics_subsystem *graphics)
|
||||
{
|
||||
struct vb_data *vbd;
|
||||
|
||||
vbd = vbdata_create();
|
||||
vbd->num = 4;
|
||||
vbd->points = bmalloc(sizeof(struct vec3) * 4);
|
||||
|
@ -88,13 +85,36 @@ static bool graphics_init(struct graphics_subsystem *graphics)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool graphics_init(struct graphics_subsystem *graphics)
|
||||
{
|
||||
struct matrix3 top_mat;
|
||||
|
||||
matrix3_identity(&top_mat);
|
||||
da_push_back(graphics->matrix_stack, &top_mat);
|
||||
|
||||
graphics->exports.device_entercontext(graphics->device);
|
||||
|
||||
if (!graphics_init_immediate_vb(graphics))
|
||||
return false;
|
||||
if (!graphics_init_sprite_vb(graphics))
|
||||
return false;
|
||||
if (pthread_mutex_init(&graphics->mutex, NULL) != 0)
|
||||
return false;
|
||||
|
||||
graphics->exports.device_leavecontext(graphics->device);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int gs_create(graphics_t *pgraphics, const char *module,
|
||||
struct gs_init_data *data)
|
||||
{
|
||||
int errcode = GS_ERROR_FAIL;
|
||||
pthread_mutex_t mutex_init = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
graphics_t graphics = bmalloc(sizeof(struct graphics_subsystem));
|
||||
memset(graphics, 0, sizeof(struct graphics_subsystem));
|
||||
graphics->mutex = mutex_init;
|
||||
|
||||
graphics->module = os_dlopen(module);
|
||||
if (!graphics->module) {
|
||||
|
@ -126,6 +146,11 @@ void gs_destroy(graphics_t graphics)
|
|||
if (!graphics)
|
||||
return;
|
||||
|
||||
while (thread_graphics)
|
||||
gs_leavecontext();
|
||||
|
||||
graphics->exports.device_entercontext(graphics->device);
|
||||
|
||||
if (graphics->sprite_buffer)
|
||||
graphics->exports.vertexbuffer_destroy(graphics->sprite_buffer);
|
||||
|
||||
|
@ -136,18 +161,41 @@ void gs_destroy(graphics_t graphics)
|
|||
if (graphics->device)
|
||||
graphics->exports.device_destroy(graphics->device);
|
||||
|
||||
pthread_mutex_destroy(&graphics->mutex);
|
||||
da_free(graphics->matrix_stack);
|
||||
da_free(graphics->viewport_stack);
|
||||
os_dlclose(graphics->module);
|
||||
bfree(graphics);
|
||||
|
||||
if (thread_graphics == graphics)
|
||||
thread_graphics = NULL;
|
||||
}
|
||||
|
||||
void gs_setcontext(graphics_t graphics)
|
||||
void gs_entercontext(graphics_t graphics)
|
||||
{
|
||||
thread_graphics = graphics;
|
||||
bool is_current = thread_graphics == graphics;
|
||||
if (thread_graphics && !is_current) {
|
||||
while (thread_graphics)
|
||||
gs_leavecontext();
|
||||
}
|
||||
|
||||
if (!is_current) {
|
||||
pthread_mutex_lock(&graphics->mutex);
|
||||
graphics->exports.device_entercontext(graphics->device);
|
||||
thread_graphics = graphics;
|
||||
}
|
||||
|
||||
graphics->ref++;
|
||||
}
|
||||
|
||||
void gs_leavecontext(void)
|
||||
{
|
||||
if (thread_graphics) {
|
||||
if (!--thread_graphics->ref) {
|
||||
graphics_t graphics = thread_graphics;
|
||||
|
||||
graphics->exports.device_leavecontext(graphics->device);
|
||||
pthread_mutex_unlock(&graphics->mutex);
|
||||
thread_graphics = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
graphics_t gs_getcontext(void)
|
||||
|
|
|
@ -429,7 +429,8 @@ EXPORT int gs_create(graphics_t *graphics, const char *module,
|
|||
struct gs_init_data *data);
|
||||
EXPORT void gs_destroy(graphics_t graphics);
|
||||
|
||||
EXPORT void gs_setcontext(graphics_t graphics);
|
||||
EXPORT void gs_entercontext(graphics_t graphics);
|
||||
EXPORT void gs_leavecontext(void);
|
||||
EXPORT graphics_t gs_getcontext(void);
|
||||
|
||||
EXPORT void gs_matrix_push(void);
|
||||
|
|
|
@ -89,13 +89,10 @@ int audio_output_open(audio_t *audio, media_t media, struct audio_info *info)
|
|||
|
||||
if (pthread_mutex_init(&out->data_mutex, NULL) != 0)
|
||||
goto fail;
|
||||
|
||||
if (event_init(&out->stop_event, true) != 0)
|
||||
goto fail;
|
||||
|
||||
if (!ao_add_to_media(out))
|
||||
goto fail;
|
||||
|
||||
if (pthread_create(&out->thread, NULL, audio_thread, out) != 0)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -116,16 +116,12 @@ int video_output_open(video_t *video, media_t media, struct video_info *info)
|
|||
|
||||
if (pthread_mutex_init(&out->data_mutex, NULL) != 0)
|
||||
goto fail;
|
||||
|
||||
if (event_init(&out->stop_event, true) != 0)
|
||||
goto fail;
|
||||
|
||||
if (event_init(&out->update_event, false) != 0)
|
||||
goto fail;
|
||||
|
||||
if (!vo_add_to_media(out))
|
||||
goto fail;
|
||||
|
||||
if (pthread_create(&out->thread, NULL, video_thread, out) != 0)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
#define NUM_TEXTURES 2
|
||||
|
||||
struct obs_display {
|
||||
swapchain_t swap; /* can be NULL if just sound */
|
||||
source_t source;
|
||||
swapchain_t swap; /* can be NULL if just sound */
|
||||
obs_source_t source;
|
||||
/* TODO: sound output target */
|
||||
};
|
||||
|
||||
|
@ -74,7 +74,9 @@ struct obs_data {
|
|||
pthread_mutex_t source_mutex;
|
||||
bool thread_initialized;
|
||||
|
||||
source_t primary_source;
|
||||
obs_source_t primary_source;
|
||||
};
|
||||
|
||||
extern struct obs_data *obs;
|
||||
|
||||
extern void *obs_video_thread(void *param);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "obs.h"
|
||||
#include "obs-data.h"
|
||||
|
||||
display_t display_create(obs_t obs, struct gs_init_data *graphics_data)
|
||||
obs_display_t obs_display_create(struct gs_init_data *graphics_data)
|
||||
{
|
||||
struct obs_display *display = bmalloc(sizeof(struct obs_display));
|
||||
memset(display, 0, sizeof(struct obs_display));
|
||||
|
@ -26,7 +26,7 @@ display_t display_create(obs_t obs, struct gs_init_data *graphics_data)
|
|||
if (graphics_data) {
|
||||
display->swap = gs_create_swapchain(graphics_data);
|
||||
if (!display->swap) {
|
||||
display_destroy(display);
|
||||
obs_display_destroy(display);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ display_t display_create(obs_t obs, struct gs_init_data *graphics_data)
|
|||
return display;
|
||||
}
|
||||
|
||||
void display_destroy(display_t display)
|
||||
void obs_display_destroy(obs_display_t display)
|
||||
{
|
||||
if (display) {
|
||||
swapchain_destroy(display->swap);
|
||||
|
@ -42,12 +42,12 @@ void display_destroy(display_t display)
|
|||
}
|
||||
}
|
||||
|
||||
source_t display_getsource(display_t display)
|
||||
obs_source_t obs_display_getsource(obs_display_t display)
|
||||
{
|
||||
return display->source;
|
||||
}
|
||||
|
||||
void display_setsource(display_t display, source_t source)
|
||||
void obs_display_setsource(obs_display_t display, obs_source_t source)
|
||||
{
|
||||
display->source = source;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ complete:
|
|||
dstr_free(&enum_name);
|
||||
}
|
||||
|
||||
int obs_load_module(struct obs_data *obs, const char *path)
|
||||
int obs_load_module(const char *path)
|
||||
{
|
||||
struct obs_module mod;
|
||||
bool (*module_load)(void) = NULL;
|
||||
|
|
|
@ -42,7 +42,7 @@ bool get_output_info(void *module, const char *module_name,
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline const struct output_info *find_output(obs_t obs, const char *type)
|
||||
static inline const struct output_info *find_output(const char *type)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < obs->output_types.num; i++)
|
||||
|
@ -52,9 +52,9 @@ static inline const struct output_info *find_output(obs_t obs, const char *type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
output_t output_create(obs_t obs, const char *type, const char *settings)
|
||||
obs_output_t obs_output_create(const char *type, const char *settings)
|
||||
{
|
||||
const struct output_info *info = find_output(obs, type);
|
||||
const struct output_info *info = find_output(type);
|
||||
struct obs_output *output;
|
||||
|
||||
if (!info) {
|
||||
|
@ -74,7 +74,7 @@ output_t output_create(obs_t obs, const char *type, const char *settings)
|
|||
return output;
|
||||
}
|
||||
|
||||
void output_destroy(output_t output)
|
||||
void obs_output_destroy(obs_output_t output)
|
||||
{
|
||||
if (output) {
|
||||
output->callbacks.destroy(output->data);
|
||||
|
@ -83,39 +83,39 @@ void output_destroy(output_t output)
|
|||
}
|
||||
}
|
||||
|
||||
void output_start(output_t output)
|
||||
void obs_output_start(obs_output_t output)
|
||||
{
|
||||
output->callbacks.start(output->data);
|
||||
}
|
||||
|
||||
void output_stop(output_t output)
|
||||
void obs_output_stop(obs_output_t output)
|
||||
{
|
||||
output->callbacks.stop(output->data);
|
||||
}
|
||||
|
||||
bool output_canconfig(output_t output)
|
||||
bool obs_output_canconfig(obs_output_t output)
|
||||
{
|
||||
return output->callbacks.config != NULL;
|
||||
}
|
||||
|
||||
void output_config(output_t output, void *parent)
|
||||
void obs_output_config(obs_output_t output, void *parent)
|
||||
{
|
||||
if (output->callbacks.config)
|
||||
output->callbacks.config(output->data, parent);
|
||||
}
|
||||
|
||||
bool output_canpause(output_t output)
|
||||
bool obs_output_canpause(obs_output_t output)
|
||||
{
|
||||
return output->callbacks.pause != NULL;
|
||||
}
|
||||
|
||||
void output_pause(output_t output)
|
||||
void obs_output_pause(obs_output_t output)
|
||||
{
|
||||
if (output->callbacks.pause)
|
||||
output->callbacks.pause(output->data);
|
||||
}
|
||||
|
||||
void output_save_settings(output_t output, const char *settings)
|
||||
void obs_output_save_settings(obs_output_t output, const char *settings)
|
||||
{
|
||||
dstr_copy(&output->settings, settings);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "graphics/math-defs.h"
|
||||
#include "obs-scene.h"
|
||||
|
||||
static void *obs_scene_create(const char *settings, struct obs_source *source)
|
||||
static void *scene_create(const char *settings, struct obs_source *source)
|
||||
{
|
||||
struct obs_scene *scene = bmalloc(sizeof(struct obs_scene));
|
||||
scene->source = source;
|
||||
|
@ -27,7 +27,7 @@ static void *obs_scene_create(const char *settings, struct obs_source *source)
|
|||
return scene;
|
||||
}
|
||||
|
||||
static void obs_scene_destroy(void *data)
|
||||
static void scene_destroy(void *data)
|
||||
{
|
||||
struct obs_scene *scene = data;
|
||||
size_t i;
|
||||
|
@ -39,12 +39,12 @@ static void obs_scene_destroy(void *data)
|
|||
bfree(scene);
|
||||
}
|
||||
|
||||
static uint32_t obs_scene_get_output_flags(void *data)
|
||||
static uint32_t scene_get_output_flags(void *data)
|
||||
{
|
||||
return SOURCE_VIDEO | SOURCE_AUDIO;
|
||||
}
|
||||
|
||||
static void obs_scene_video_render(void *data)
|
||||
static void scene_video_render(void *data)
|
||||
{
|
||||
struct obs_scene *scene = data;
|
||||
size_t i;
|
||||
|
@ -58,18 +58,18 @@ static void obs_scene_video_render(void *data)
|
|||
gs_matrix_rotaa4f(0.0f, 0.0f, 1.0f, RAD(-item->rot));
|
||||
gs_matrix_translate3f(-item->pos.x, -item->pos.y, 0.0f);
|
||||
|
||||
source_video_render(item->source);
|
||||
obs_source_video_render(item->source);
|
||||
|
||||
gs_matrix_pop();
|
||||
}
|
||||
}
|
||||
|
||||
static int obs_scene_getsize(void *data)
|
||||
static int scene_getsize(void *data)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool obs_scene_enum_children(void *data, size_t idx, source_t *child)
|
||||
static bool scene_enum_children(void *data, size_t idx, obs_source_t *child)
|
||||
{
|
||||
struct obs_scene *scene = data;
|
||||
if (idx >= scene->items.num)
|
||||
|
@ -84,32 +84,32 @@ static bool obs_scene_enum_children(void *data, size_t idx, source_t *child)
|
|||
static const struct source_info scene_info =
|
||||
{
|
||||
"scene",
|
||||
obs_scene_create,
|
||||
obs_scene_destroy,
|
||||
obs_scene_get_output_flags, NULL, NULL, NULL, NULL,
|
||||
obs_scene_video_render,
|
||||
obs_scene_getsize,
|
||||
obs_scene_getsize, NULL, NULL,
|
||||
obs_scene_enum_children, NULL, NULL
|
||||
scene_create,
|
||||
scene_destroy,
|
||||
scene_get_output_flags, NULL, NULL, NULL, NULL,
|
||||
scene_video_render,
|
||||
scene_getsize,
|
||||
scene_getsize, NULL, NULL,
|
||||
scene_enum_children, NULL, NULL
|
||||
};
|
||||
#else
|
||||
static const struct source_info scene_info =
|
||||
{
|
||||
.name = "scene",
|
||||
.create = obs_scene_create,
|
||||
.destroy = obs_scene_destroy,
|
||||
.get_output_flags = obs_scene_get_output_flags,
|
||||
.video_render = obs_scene_video_render,
|
||||
.getwidth = obs_scene_getsize,
|
||||
.getheight = obs_scene_getsize,
|
||||
.enum_children = obs_scene_enum_children
|
||||
.create = scene_create,
|
||||
.destroy = scene_destroy,
|
||||
.get_output_flags = scene_get_output_flags,
|
||||
.video_render = scene_video_render,
|
||||
.getwidth = scene_getsize,
|
||||
.getheight = scene_getsize,
|
||||
.enum_children = scene_enum_children
|
||||
};
|
||||
#endif
|
||||
|
||||
scene_t scene_create(obs_t obs)
|
||||
obs_scene_t obs_scene_create(void)
|
||||
{
|
||||
struct obs_source *source = bmalloc(sizeof(struct obs_source));
|
||||
struct obs_scene *scene = obs_scene_create(NULL, source);
|
||||
struct obs_scene *scene = scene_create(NULL, source);
|
||||
|
||||
source->data = scene;
|
||||
if (!source->data) {
|
||||
|
@ -118,23 +118,23 @@ scene_t scene_create(obs_t obs)
|
|||
}
|
||||
|
||||
scene->source = source;
|
||||
source_init(obs, source);
|
||||
obs_source_init(source);
|
||||
memcpy(&source->callbacks, &scene_info, sizeof(struct source_info));
|
||||
return scene;
|
||||
}
|
||||
|
||||
void scene_destroy(scene_t scene)
|
||||
void obs_scene_destroy(obs_scene_t scene)
|
||||
{
|
||||
if (scene)
|
||||
source_destroy(scene->source);
|
||||
obs_source_destroy(scene->source);
|
||||
}
|
||||
|
||||
source_t scene_source(scene_t scene)
|
||||
obs_source_t obs_scene_getsource(obs_scene_t scene)
|
||||
{
|
||||
return scene->source;
|
||||
}
|
||||
|
||||
sceneitem_t scene_add(scene_t scene, source_t source)
|
||||
obs_sceneitem_t obs_scene_add(obs_scene_t scene, obs_source_t source)
|
||||
{
|
||||
struct obs_scene_item *item = bmalloc(sizeof(struct obs_scene_item));
|
||||
memset(item, 0, sizeof(struct obs_scene_item));
|
||||
|
@ -147,7 +147,7 @@ sceneitem_t scene_add(scene_t scene, source_t source)
|
|||
return item;
|
||||
}
|
||||
|
||||
void sceneitem_remove(sceneitem_t item)
|
||||
void obs_sceneitem_remove(obs_sceneitem_t item)
|
||||
{
|
||||
if (item) {
|
||||
da_erase_item(item->parent->items, item);
|
||||
|
@ -155,27 +155,27 @@ void sceneitem_remove(sceneitem_t item)
|
|||
}
|
||||
}
|
||||
|
||||
void sceneitem_setpos(sceneitem_t item, const struct vec2 *pos)
|
||||
void obs_sceneitem_setpos(obs_sceneitem_t item, const struct vec2 *pos)
|
||||
{
|
||||
vec2_copy(&item->pos, pos);
|
||||
}
|
||||
|
||||
void sceneitem_setrot(sceneitem_t item, float rot)
|
||||
void obs_sceneitem_setrot(obs_sceneitem_t item, float rot)
|
||||
{
|
||||
item->rot = rot;
|
||||
}
|
||||
|
||||
void sceneitem_setorigin(sceneitem_t item, const struct vec2 *origin)
|
||||
void obs_sceneitem_setorigin(obs_sceneitem_t item, const struct vec2 *origin)
|
||||
{
|
||||
vec2_copy(&item->origin, origin);
|
||||
}
|
||||
|
||||
void sceneitem_setscale(sceneitem_t item, const struct vec2 *scale)
|
||||
void obs_sceneitem_setscale(obs_sceneitem_t item, const struct vec2 *scale)
|
||||
{
|
||||
vec2_copy(&item->scale, scale);
|
||||
}
|
||||
|
||||
void sceneitem_setorder(sceneitem_t item, enum order_movement movement)
|
||||
void obs_sceneitem_setorder(obs_sceneitem_t item, enum order_movement movement)
|
||||
{
|
||||
struct obs_scene *scene = item->parent;
|
||||
|
||||
|
@ -201,22 +201,22 @@ void sceneitem_setorder(sceneitem_t item, enum order_movement movement)
|
|||
}
|
||||
}
|
||||
|
||||
void sceneitem_getpos(sceneitem_t item, struct vec2 *pos)
|
||||
void obs_sceneitem_getpos(obs_sceneitem_t item, struct vec2 *pos)
|
||||
{
|
||||
vec2_copy(pos, &item->pos);
|
||||
}
|
||||
|
||||
float sceneitem_getrot(sceneitem_t item)
|
||||
float obs_sceneitem_getrot(obs_sceneitem_t item)
|
||||
{
|
||||
return item->rot;
|
||||
}
|
||||
|
||||
void sceneitem_getorigin(sceneitem_t item, struct vec2 *origin)
|
||||
void obs_sceneitem_getorigin(obs_sceneitem_t item, struct vec2 *origin)
|
||||
{
|
||||
vec2_copy(origin, &item->origin);
|
||||
}
|
||||
|
||||
void sceneitem_getscale(sceneitem_t item, struct vec2 *scale)
|
||||
void obs_sceneitem_getscale(obs_sceneitem_t item, struct vec2 *scale)
|
||||
{
|
||||
vec2_copy(scale, &item->scale);
|
||||
}
|
||||
|
|
|
@ -23,17 +23,17 @@
|
|||
/* how obs scene! */
|
||||
|
||||
struct obs_scene_item {
|
||||
scene_t parent;
|
||||
source_t source;
|
||||
bool visible;
|
||||
obs_scene_t parent;
|
||||
obs_source_t source;
|
||||
bool visible;
|
||||
|
||||
struct vec2 origin;
|
||||
struct vec2 pos;
|
||||
struct vec2 scale;
|
||||
float rot;
|
||||
struct vec2 origin;
|
||||
struct vec2 pos;
|
||||
struct vec2 scale;
|
||||
float rot;
|
||||
};
|
||||
|
||||
struct obs_scene {
|
||||
source_t source;
|
||||
obs_source_t source;
|
||||
DARRAY(struct obs_scene_item*) items;
|
||||
};
|
||||
|
|
|
@ -62,8 +62,8 @@ bool get_source_info(void *module, const char *module_name,
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline const struct source_info *find_source(obs_t obs,
|
||||
struct darray *list, const char *name)
|
||||
static inline const struct source_info *find_source(struct darray *list,
|
||||
const char *name)
|
||||
{
|
||||
size_t i;
|
||||
struct source_info *array = list->array;
|
||||
|
@ -77,9 +77,8 @@ static inline const struct source_info *find_source(obs_t obs,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void source_init(obs_t obs, struct obs_source *source)
|
||||
void obs_source_init(struct obs_source *source)
|
||||
{
|
||||
source->obs = obs;
|
||||
source->filter_target = NULL;
|
||||
source->rendering_filter = false;
|
||||
|
||||
|
@ -88,7 +87,7 @@ void source_init(obs_t obs, struct obs_source *source)
|
|||
da_push_back(obs->sources, &source);
|
||||
}
|
||||
|
||||
source_t source_create(obs_t obs, enum source_type type, const char *name,
|
||||
obs_source_t obs_source_create(enum source_type type, const char *name,
|
||||
const char *settings)
|
||||
{
|
||||
const struct source_info *info = NULL;
|
||||
|
@ -103,7 +102,7 @@ source_t source_create(obs_t obs, enum source_type type, const char *name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
info = find_source(obs, list, name);
|
||||
info = find_source(list, name);
|
||||
if (!info) {
|
||||
blog(LOG_WARNING, "Source '%s' not found", type);
|
||||
return NULL;
|
||||
|
@ -116,17 +115,17 @@ source_t source_create(obs_t obs, enum source_type type, const char *name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
source_init(obs, source);
|
||||
obs_source_init(source);
|
||||
dstr_copy(&source->settings, settings);
|
||||
memcpy(&source->callbacks, info, sizeof(struct source_info));
|
||||
return source;
|
||||
}
|
||||
|
||||
void source_destroy(source_t source)
|
||||
void obs_source_destroy(obs_source_t source)
|
||||
{
|
||||
if (source) {
|
||||
da_free(source->filters);
|
||||
da_erase_item(source->obs->sources, &source);
|
||||
da_erase_item(obs->sources, &source);
|
||||
|
||||
source->callbacks.destroy(source->data);
|
||||
dstr_free(&source->settings);
|
||||
|
@ -134,46 +133,46 @@ void source_destroy(source_t source)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t source_get_output_flags(source_t source)
|
||||
uint32_t obs_source_get_output_flags(obs_source_t source)
|
||||
{
|
||||
return source->callbacks.get_output_flags(source->data);
|
||||
}
|
||||
|
||||
bool source_hasconfig(source_t source)
|
||||
bool obs_source_hasconfig(obs_source_t source)
|
||||
{
|
||||
return source->callbacks.config != NULL;
|
||||
}
|
||||
|
||||
void source_config(source_t source, void *parent)
|
||||
void obs_source_config(obs_source_t source, void *parent)
|
||||
{
|
||||
if (source->callbacks.config)
|
||||
source->callbacks.config(source->data, parent);
|
||||
}
|
||||
|
||||
void source_activate(source_t source)
|
||||
void obs_source_activate(obs_source_t source)
|
||||
{
|
||||
if (source->callbacks.activate)
|
||||
source->callbacks.activate(source->data);
|
||||
}
|
||||
|
||||
void source_deactivate(source_t source)
|
||||
void obs_source_deactivate(obs_source_t source)
|
||||
{
|
||||
if (source->callbacks.deactivate)
|
||||
source->callbacks.deactivate(source->data);
|
||||
}
|
||||
|
||||
void source_video_tick(source_t source, float seconds)
|
||||
void obs_source_video_tick(obs_source_t source, float seconds)
|
||||
{
|
||||
if (source->callbacks.video_tick)
|
||||
source->callbacks.video_tick(source->data, seconds);
|
||||
}
|
||||
|
||||
void source_video_render(source_t source)
|
||||
void obs_source_video_render(obs_source_t source)
|
||||
{
|
||||
if (source->callbacks.video_render) {
|
||||
if (source->filters.num && !source->rendering_filter) {
|
||||
source->rendering_filter = true;
|
||||
source_video_render(source->filters.array[0]);
|
||||
obs_source_video_render(source->filters.array[0]);
|
||||
source->rendering_filter = false;
|
||||
} else {
|
||||
source->callbacks.video_render(source->data);
|
||||
|
@ -181,21 +180,21 @@ void source_video_render(source_t source)
|
|||
}
|
||||
}
|
||||
|
||||
int source_getwidth(source_t source)
|
||||
int obs_source_getwidth(obs_source_t source)
|
||||
{
|
||||
if (source->callbacks.getwidth)
|
||||
return source->callbacks.getwidth(source->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int source_getheight(source_t source)
|
||||
int obs_source_getheight(obs_source_t source)
|
||||
{
|
||||
if (source->callbacks.getheight)
|
||||
return source->callbacks.getheight(source->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t source_getparam(source_t source, const char *param, void *buf,
|
||||
size_t obs_source_getparam(obs_source_t source, const char *param, void *buf,
|
||||
size_t buf_size)
|
||||
{
|
||||
if (source->callbacks.getparam)
|
||||
|
@ -204,26 +203,27 @@ size_t source_getparam(source_t source, const char *param, void *buf,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void source_setparam(source_t source, const char *param, const void *data,
|
||||
size_t size)
|
||||
void obs_source_setparam(obs_source_t source, const char *param,
|
||||
const void *data, size_t size)
|
||||
{
|
||||
if (source->callbacks.setparam)
|
||||
source->callbacks.setparam(source->data, param, data, size);
|
||||
}
|
||||
|
||||
bool source_enum_children(source_t source, size_t idx, source_t *child)
|
||||
bool obs_source_enum_children(obs_source_t source, size_t idx,
|
||||
obs_source_t *child)
|
||||
{
|
||||
if (source->callbacks.enum_children)
|
||||
return source->callbacks.enum_children(source, idx, child);
|
||||
return false;
|
||||
}
|
||||
|
||||
source_t filter_gettarget(source_t filter)
|
||||
obs_source_t obs_filter_gettarget(obs_source_t filter)
|
||||
{
|
||||
return filter->filter_target;
|
||||
}
|
||||
|
||||
void source_filter_add(source_t source, source_t filter)
|
||||
void obs_source_filter_add(obs_source_t source, obs_source_t filter)
|
||||
{
|
||||
if (da_find(source->filters, &filter, 0) != -1) {
|
||||
blog(LOG_WARNING, "Tried to add a filter that was already "
|
||||
|
@ -232,7 +232,7 @@ void source_filter_add(source_t source, source_t filter)
|
|||
}
|
||||
|
||||
if (source->filters.num) {
|
||||
source_t *back = da_end(source->filters);
|
||||
obs_source_t *back = da_end(source->filters);
|
||||
(*back)->filter_target = filter;
|
||||
}
|
||||
|
||||
|
@ -240,14 +240,14 @@ void source_filter_add(source_t source, source_t filter)
|
|||
filter->filter_target = source;
|
||||
}
|
||||
|
||||
void source_filter_remove(source_t source, source_t filter)
|
||||
void obs_source_filter_remove(obs_source_t source, obs_source_t filter)
|
||||
{
|
||||
size_t idx = da_find(source->filters, &filter, 0);
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
if (idx > 0) {
|
||||
source_t prev = source->filters.array[idx-1];
|
||||
obs_source_t prev = source->filters.array[idx-1];
|
||||
prev->filter_target = filter->filter_target;
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ void source_filter_remove(source_t source, source_t filter)
|
|||
filter->filter_target = NULL;
|
||||
}
|
||||
|
||||
void source_filter_setorder(source_t source, source_t filter,
|
||||
void obs_source_filter_setorder(obs_source_t source, obs_source_t filter,
|
||||
enum order_movement movement)
|
||||
{
|
||||
size_t idx = da_find(source->filters, &filter, 0);
|
||||
|
@ -286,28 +286,28 @@ void source_filter_setorder(source_t source, source_t filter,
|
|||
|
||||
/* reorder filter targets */
|
||||
for (i = 0; i < source->filters.num; i++) {
|
||||
source_t next_filter = (i == source->filters.num-1) ?
|
||||
obs_source_t next_filter = (i == source->filters.num-1) ?
|
||||
source : source->filters.array[idx+1];
|
||||
source->filters.array[i]->filter_target = next_filter;
|
||||
}
|
||||
}
|
||||
|
||||
const char *source_get_settings(source_t source)
|
||||
const char *obs_source_get_settings(obs_source_t source)
|
||||
{
|
||||
return source->settings.array;
|
||||
}
|
||||
|
||||
void source_save_settings(source_t source, const char *settings)
|
||||
void obs_source_save_settings(obs_source_t source, const char *settings)
|
||||
{
|
||||
dstr_copy(&source->settings, settings);
|
||||
}
|
||||
|
||||
void source_output_video(source_t source, struct video_frame *frame)
|
||||
void obs_source_output_video(obs_source_t source, struct video_frame *frame)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void source_output_audio(source_t source, struct audio_data *audio)
|
||||
void obs_source_output_audio(obs_source_t source, struct audio_data *audio)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
* ===========================================
|
||||
* Source Exports
|
||||
* ===========================================
|
||||
* void *[name]_create(const char *settings, source_t source);
|
||||
* void *[name]_create(const char *settings, obs_source_t source);
|
||||
* Creates a source.
|
||||
*
|
||||
* settings: Settings of the source.
|
||||
|
@ -127,7 +127,7 @@
|
|||
* val: Value of parameter to set.
|
||||
*
|
||||
* ---------------------------------------------------------
|
||||
* bool [name]_enum_children(void *data, size_t idx, source_t *child);
|
||||
* bool [name]_enum_children(void *data, size_t idx, obs_source_t *child);
|
||||
* Enumerates child sources, if any.
|
||||
*
|
||||
* idx: Child source index.
|
||||
|
@ -155,7 +155,7 @@ struct source_info {
|
|||
/* ----------------------------------------------------------------- */
|
||||
/* required implementations */
|
||||
|
||||
void *(*create)(const char *settings, struct obs_source *source);
|
||||
void *(*create)(const char *settings, obs_source_t source);
|
||||
void (*destroy)(void *data);
|
||||
|
||||
uint32_t (*get_output_flags)(void *data);
|
||||
|
@ -178,28 +178,27 @@ struct source_info {
|
|||
void (*setparam)(void *data, const char *param, const void *data_in,
|
||||
size_t size);
|
||||
|
||||
bool (*enum_children)(void *data, size_t idx, source_t *child);
|
||||
bool (*enum_children)(void *data, size_t idx, obs_source_t *child);
|
||||
|
||||
void (*filter_video)(void *data, struct video_frame *frame);
|
||||
void (*filter_audio)(void *data, struct audio_data *audio);
|
||||
};
|
||||
|
||||
struct obs_source {
|
||||
struct obs_data *obs;
|
||||
void *data;
|
||||
struct source_info callbacks;
|
||||
struct dstr settings;
|
||||
bool rendering_filter;
|
||||
void *data;
|
||||
struct source_info callbacks;
|
||||
struct dstr settings;
|
||||
bool rendering_filter;
|
||||
|
||||
struct obs_source *filter_target;
|
||||
struct obs_source *filter_target;
|
||||
DARRAY(struct obs_source*) filters;
|
||||
};
|
||||
|
||||
extern bool get_source_info(void *module, const char *module_name,
|
||||
const char *source_name, struct source_info *info);
|
||||
|
||||
extern void source_init(obs_t obs, struct obs_source *source);
|
||||
extern void obs_source_init(struct obs_source *source);
|
||||
|
||||
EXPORT void source_activate(source_t source);
|
||||
EXPORT void source_deactivate(source_t source);
|
||||
EXPORT void source_video_tick(source_t source, float seconds);
|
||||
extern void obs_source_activate(obs_source_t source);
|
||||
extern void obs_source_deactivate(obs_source_t source);
|
||||
extern void obs_source_video_tick(obs_source_t source, float seconds);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "obs-data.h"
|
||||
#include "graphics/vec4.h"
|
||||
|
||||
static void tick_sources(obs_t obs, uint64_t cur_time, uint64_t *last_time)
|
||||
static void tick_sources(uint64_t cur_time, uint64_t *last_time)
|
||||
{
|
||||
size_t i;
|
||||
uint64_t delta_time;
|
||||
|
@ -31,12 +31,12 @@ static void tick_sources(obs_t obs, uint64_t cur_time, uint64_t *last_time)
|
|||
seconds = (float)((double)delta_time / 1000000000.0);
|
||||
|
||||
for (i = 0; i < obs->sources.num; i++)
|
||||
source_video_tick(obs->sources.array[i], seconds);
|
||||
obs_source_video_tick(obs->sources.array[i], seconds);
|
||||
|
||||
*last_time = cur_time;
|
||||
}
|
||||
|
||||
static inline void render_displays(obs_t obs)
|
||||
static inline void render_displays(void)
|
||||
{
|
||||
size_t i;
|
||||
struct vec4 clear_color;
|
||||
|
@ -49,7 +49,7 @@ static inline void render_displays(obs_t obs)
|
|||
-100.0f, 100.0f);
|
||||
|
||||
for (i = 0; i < obs->displays.num; i++) {
|
||||
display_t display = obs->displays.array[i];
|
||||
obs_display_t display = obs->displays.array[i];
|
||||
|
||||
gs_load_swapchain(display->swap);
|
||||
|
||||
|
@ -57,7 +57,7 @@ static inline void render_displays(obs_t obs)
|
|||
gs_setviewport(0, 0, gs_getwidth(), gs_getheight());
|
||||
|
||||
if (display->source)
|
||||
source_video_render(display->source);
|
||||
obs_source_video_render(display->source);
|
||||
|
||||
gs_endscene();
|
||||
gs_present();
|
||||
|
@ -72,13 +72,13 @@ static inline void render_displays(obs_t obs)
|
|||
gs_setviewport(0, 0, gs_getwidth(), gs_getheight());
|
||||
|
||||
if (obs->primary_source)
|
||||
source_video_render(obs->primary_source);
|
||||
obs_source_video_render(obs->primary_source);
|
||||
|
||||
gs_endscene();
|
||||
gs_present();
|
||||
}
|
||||
|
||||
static bool swap_frame(obs_t obs, uint64_t timestamp)
|
||||
static bool swap_frame(uint64_t timestamp)
|
||||
{
|
||||
stagesurf_t last_surface = obs->copy_surfaces[obs->cur_texture];
|
||||
stagesurf_t surface;
|
||||
|
@ -117,9 +117,13 @@ void *obs_video_thread(void *param)
|
|||
while (video_output_wait(obs->video)) {
|
||||
uint64_t cur_time = video_gettime(obs->video);
|
||||
|
||||
tick_sources(obs, cur_time, &last_time);
|
||||
render_displays(obs);
|
||||
swap_frame(obs, cur_time);
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
tick_sources(cur_time, &last_time);
|
||||
render_displays();
|
||||
swap_frame(cur_time);
|
||||
|
||||
gs_leavecontext();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
102
libobs/obs.c
102
libobs/obs.c
|
@ -19,7 +19,9 @@
|
|||
#include "obs-data.h"
|
||||
#include "obs-module.h"
|
||||
|
||||
static bool obs_init_graphics(struct obs_data *obs, const char *graphics_module,
|
||||
struct obs_data *obs = NULL;
|
||||
|
||||
static bool obs_init_graphics(const char *graphics_module,
|
||||
struct gs_init_data *graphics_data, struct video_info *vi)
|
||||
{
|
||||
int errorcode;
|
||||
|
@ -33,7 +35,7 @@ static bool obs_init_graphics(struct obs_data *obs, const char *graphics_module,
|
|||
return false;
|
||||
}
|
||||
|
||||
gs_setcontext(obs->graphics);
|
||||
gs_entercontext(obs->graphics);
|
||||
|
||||
for (i = 0; i < NUM_TEXTURES; i++) {
|
||||
obs->copy_surfaces[i] = gs_create_stagesurface(vi->width,
|
||||
|
@ -42,25 +44,25 @@ static bool obs_init_graphics(struct obs_data *obs, const char *graphics_module,
|
|||
return false;
|
||||
}
|
||||
|
||||
gs_leavecontext();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool obs_init_media(struct obs_data *obs,
|
||||
struct video_info *vi, struct audio_info *ai)
|
||||
static bool obs_init_media(struct video_info *vi, struct audio_info *ai)
|
||||
{
|
||||
obs->media = media_open();
|
||||
if (!obs->media)
|
||||
return false;
|
||||
|
||||
if (!obs_reset_video(obs, vi))
|
||||
if (!obs_reset_video(vi))
|
||||
return false;
|
||||
if (!obs_reset_audio(obs, ai))
|
||||
if (!obs_reset_audio(ai))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool obs_init_threading(struct obs_data *obs)
|
||||
static bool obs_init_threading(void)
|
||||
{
|
||||
if (pthread_mutex_init(&obs->source_mutex, NULL) != 0)
|
||||
return false;
|
||||
|
@ -72,55 +74,54 @@ static bool obs_init_threading(struct obs_data *obs)
|
|||
return true;
|
||||
}
|
||||
|
||||
static pthread_mutex_t pthread_init_val = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
obs_t obs_create(const char *graphics_module,
|
||||
static bool obs_init(const char *graphics_module,
|
||||
struct gs_init_data *graphics_data,
|
||||
struct video_info *vi, struct audio_info *ai)
|
||||
{
|
||||
struct obs_data *obs = bmalloc(sizeof(struct obs_data));
|
||||
pthread_mutex_t pthread_init_val = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
obs = bmalloc(sizeof(struct obs_data));
|
||||
|
||||
memset(obs, 0, sizeof(struct obs_data));
|
||||
obs->source_mutex = pthread_init_val;
|
||||
|
||||
if (!obs_init_graphics(obs, graphics_module, graphics_data, vi))
|
||||
goto error;
|
||||
if (!obs_init_media(obs, vi, ai))
|
||||
goto error;
|
||||
if (!obs_init_threading(obs))
|
||||
goto error;
|
||||
if (!obs_init_graphics(graphics_module, graphics_data, vi))
|
||||
return false;
|
||||
if (!obs_init_media(vi, ai))
|
||||
return false;
|
||||
if (!obs_init_threading())
|
||||
return false;
|
||||
|
||||
return obs;
|
||||
|
||||
error:
|
||||
obs_destroy(obs);
|
||||
return NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void obs_free_graphics(obs_t obs)
|
||||
static inline void obs_free_graphics(void)
|
||||
{
|
||||
size_t i;
|
||||
if (!obs->graphics)
|
||||
return;
|
||||
|
||||
gs_entercontext(obs->graphics);
|
||||
|
||||
if (obs->copy_mapped)
|
||||
stagesurface_unmap(obs->copy_surfaces[obs->cur_texture]);
|
||||
|
||||
for (i = 0; i < NUM_TEXTURES; i++)
|
||||
stagesurface_destroy(obs->copy_surfaces[i]);
|
||||
|
||||
gs_setcontext(NULL);
|
||||
gs_leavecontext();
|
||||
|
||||
gs_destroy(obs->graphics);
|
||||
}
|
||||
|
||||
static inline void obs_free_media(obs_t obs)
|
||||
static inline void obs_free_media(void)
|
||||
{
|
||||
video_output_close(obs->video);
|
||||
audio_output_close(obs->audio);
|
||||
media_close(obs->media);
|
||||
}
|
||||
|
||||
static inline void obs_free_threading(obs_t obs)
|
||||
static inline void obs_free_threading(void)
|
||||
{
|
||||
void *thread_ret;
|
||||
video_output_stop(obs->video);
|
||||
|
@ -129,7 +130,7 @@ static inline void obs_free_threading(obs_t obs)
|
|||
pthread_mutex_destroy(&obs->source_mutex);
|
||||
}
|
||||
|
||||
void obs_destroy(obs_t obs)
|
||||
static void obs_destroy(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
|
@ -137,7 +138,7 @@ void obs_destroy(obs_t obs)
|
|||
return;
|
||||
|
||||
for (i = 0; i < obs->displays.num; i++)
|
||||
display_destroy(obs->displays.array[i]);
|
||||
obs_display_destroy(obs->displays.array[i]);
|
||||
|
||||
da_free(obs->input_types);
|
||||
da_free(obs->filter_types);
|
||||
|
@ -148,18 +149,36 @@ void obs_destroy(obs_t obs)
|
|||
da_free(obs->displays);
|
||||
da_free(obs->sources);
|
||||
|
||||
obs_free_threading(obs);
|
||||
obs_free_media(obs);
|
||||
obs_free_graphics(obs);
|
||||
obs_free_threading();
|
||||
obs_free_media();
|
||||
obs_free_graphics();
|
||||
|
||||
for (i = 0; i < obs->modules.num; i++)
|
||||
free_module(obs->modules.array+i);
|
||||
da_free(obs->modules);
|
||||
|
||||
bfree(obs);
|
||||
obs = NULL;
|
||||
}
|
||||
|
||||
bool obs_reset_video(obs_t obs, struct video_info *vi)
|
||||
bool obs_startup(const char *graphics_module,
|
||||
struct gs_init_data *graphics_data,
|
||||
struct video_info *vi, struct audio_info *ai)
|
||||
{
|
||||
if (!obs_init(graphics_module, graphics_data, vi, ai)) {
|
||||
obs_destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void obs_shutdown(void)
|
||||
{
|
||||
obs_destroy();
|
||||
}
|
||||
|
||||
bool obs_reset_video(struct video_info *vi)
|
||||
{
|
||||
int errorcode;
|
||||
|
||||
|
@ -182,13 +201,14 @@ bool obs_reset_video(obs_t obs, struct video_info *vi)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool obs_reset_audio(obs_t obs, struct audio_info *ai)
|
||||
bool obs_reset_audio(struct audio_info *ai)
|
||||
{
|
||||
/* TODO */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool obs_enum_inputs(obs_t obs, size_t idx, const char **name)
|
||||
bool obs_enum_inputs(size_t idx, const char **name)
|
||||
{
|
||||
if (idx >= obs->input_types.num)
|
||||
return false;
|
||||
|
@ -196,7 +216,7 @@ bool obs_enum_inputs(obs_t obs, size_t idx, const char **name)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool obs_enum_filters(obs_t obs, size_t idx, const char **name)
|
||||
bool obs_enum_filters(size_t idx, const char **name)
|
||||
{
|
||||
if (idx >= obs->filter_types.num)
|
||||
return false;
|
||||
|
@ -204,7 +224,7 @@ bool obs_enum_filters(obs_t obs, size_t idx, const char **name)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool obs_enum_transitions(obs_t obs, size_t idx, const char **name)
|
||||
bool obs_enum_transitions(size_t idx, const char **name)
|
||||
{
|
||||
if (idx >= obs->transition_types.num)
|
||||
return false;
|
||||
|
@ -212,7 +232,7 @@ bool obs_enum_transitions(obs_t obs, size_t idx, const char **name)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool obs_enum_outputs(obs_t obs, size_t idx, const char **name)
|
||||
bool obs_enum_outputs(size_t idx, const char **name)
|
||||
{
|
||||
if (idx >= obs->output_types.num)
|
||||
return false;
|
||||
|
@ -221,22 +241,22 @@ bool obs_enum_outputs(obs_t obs, size_t idx, const char **name)
|
|||
}
|
||||
|
||||
|
||||
graphics_t obs_graphics(obs_t obs)
|
||||
graphics_t obs_graphics(void)
|
||||
{
|
||||
return obs->graphics;
|
||||
}
|
||||
|
||||
media_t obs_media(obs_t obs)
|
||||
media_t obs_media(void)
|
||||
{
|
||||
return obs->media;
|
||||
}
|
||||
|
||||
source_t obs_get_primary_source(obs_t obs)
|
||||
obs_source_t obs_get_primary_source(void)
|
||||
{
|
||||
return obs->primary_source;
|
||||
}
|
||||
|
||||
void obs_set_primary_source(obs_t obs, source_t source)
|
||||
void obs_set_primary_source(obs_source_t source)
|
||||
{
|
||||
obs->primary_source = source;
|
||||
}
|
||||
|
|
183
libobs/obs.h
183
libobs/obs.h
|
@ -32,7 +32,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum source_type {
|
||||
enum obs_source_type {
|
||||
SOURCE_INPUT,
|
||||
SOURCE_FILTER,
|
||||
SOURCE_TRANSITION,
|
||||
|
@ -47,19 +47,17 @@ enum order_movement {
|
|||
};
|
||||
|
||||
/* opaque types */
|
||||
struct obs_data;
|
||||
struct obs_display;
|
||||
struct obs_source;
|
||||
struct obs_scene;
|
||||
struct obs_scene_item;
|
||||
struct obs_output;
|
||||
|
||||
typedef struct obs_data *obs_t;
|
||||
typedef struct obs_display *display_t;
|
||||
typedef struct obs_source *source_t;
|
||||
typedef struct obs_scene *scene_t;
|
||||
typedef struct obs_scene_item *sceneitem_t;
|
||||
typedef struct obs_output *output_t;
|
||||
typedef struct obs_display *obs_display_t;
|
||||
typedef struct obs_source *obs_source_t;
|
||||
typedef struct obs_scene *obs_scene_t;
|
||||
typedef struct obs_scene_item *obs_sceneitem_t;
|
||||
typedef struct obs_output *obs_output_t;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* OBS context */
|
||||
|
@ -70,23 +68,25 @@ typedef struct obs_output *output_t;
|
|||
* Using the graphics module specified, creates an OBS context and sets the
|
||||
* primary video/audio output information.
|
||||
*/
|
||||
EXPORT obs_t obs_create(const char *graphics_module,
|
||||
struct gs_init_data *graphics_data,
|
||||
struct video_info *vi, struct audio_info *ai);
|
||||
EXPORT void obs_destroy(obs_t obs);
|
||||
EXPORT bool obs_startup(const char *graphics_module,
|
||||
struct gs_init_data *graphics_data,
|
||||
struct video_info *vi, struct audio_info *ai);
|
||||
EXPORT void obs_shutdown(void);
|
||||
|
||||
/**
|
||||
* Sets base video ouput base resolution/fps/format
|
||||
*
|
||||
* NOTE: Cannot reset base video if currently streaming/recording.
|
||||
*/
|
||||
EXPORT bool obs_reset_video(obs_t obs, struct video_info *vi);
|
||||
|
||||
EXPORT bool obs_reset_video(struct video_info *vi);
|
||||
|
||||
/**
|
||||
* Sets base audio output format/channels/samples/etc
|
||||
*
|
||||
* NOTE: Cannot reset base audio if currently streaming/recording.
|
||||
*/
|
||||
EXPORT bool obs_reset_audio(obs_t obs, struct audio_info *ai);
|
||||
EXPORT bool obs_reset_audio(struct audio_info *ai);
|
||||
|
||||
/**
|
||||
* Loads a plugin module
|
||||
|
@ -95,7 +95,7 @@ EXPORT bool obs_reset_audio(obs_t obs, struct audio_info *ai);
|
|||
* See obs-source.h and obs-output.h for more information on the exports to
|
||||
* use.
|
||||
*/
|
||||
EXPORT int obs_load_module(obs_t obs, const char *path);
|
||||
EXPORT int obs_load_module(const char *path);
|
||||
|
||||
/**
|
||||
* Enumerates all available inputs.
|
||||
|
@ -103,42 +103,45 @@ EXPORT int obs_load_module(obs_t obs, const char *path);
|
|||
* Inputs are general source inputs (such as capture sources, device sources,
|
||||
* etc).
|
||||
*/
|
||||
EXPORT bool obs_enum_inputs(obs_t obs, size_t idx, const char **name);
|
||||
EXPORT bool obs_enum_inputs(size_t idx, const char **name);
|
||||
|
||||
/**
|
||||
* Enumerates all available filters.
|
||||
*
|
||||
* Filters are sources that are used to modify the video/audio output of
|
||||
* other sources.
|
||||
*/
|
||||
EXPORT bool obs_enum_filters(obs_t obs, size_t idx, const char **name);
|
||||
EXPORT bool obs_enum_filters(size_t idx, const char **name);
|
||||
|
||||
/**
|
||||
* Enumerates all available transitions.
|
||||
*
|
||||
* Transitions are sources used to transition between two or more other
|
||||
* sources.
|
||||
*/
|
||||
EXPORT bool obs_enum_transitions(obs_t obs, size_t idx,
|
||||
const char **name);
|
||||
EXPORT bool obs_enum_transitions(size_t idx, const char **name);
|
||||
|
||||
/**
|
||||
* Enumerates all available ouputs.
|
||||
*
|
||||
* Outputs handle color space conversion, encoding, and output to file or
|
||||
* streams.
|
||||
*/
|
||||
EXPORT bool obs_enum_outputs(obs_t obs, size_t idx, const char **name);
|
||||
EXPORT bool obs_enum_outputs(size_t idx, const char **name);
|
||||
|
||||
/** Gets the graphics context for this OBS context */
|
||||
EXPORT graphics_t obs_graphics(obs_t obs);
|
||||
EXPORT graphics_t obs_graphics(void);
|
||||
|
||||
/** Get the media context for this OBS context (used for outputs) */
|
||||
EXPORT media_t obs_media(obs_t obs);
|
||||
EXPORT media_t obs_media(void);
|
||||
|
||||
/**
|
||||
* Sets/gets the primary output source.
|
||||
*
|
||||
* The primary source is the source that's broadcasted/saved.
|
||||
* The primary source is the source that's presented.
|
||||
*/
|
||||
EXPORT void obs_set_primary_source(obs_t obs, source_t source);
|
||||
EXPORT source_t obs_get_primary_source(obs_t obs);
|
||||
EXPORT void obs_set_primary_source(obs_source_t source);
|
||||
EXPORT obs_source_t obs_get_primary_source(void);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -151,11 +154,12 @@ EXPORT source_t obs_get_primary_source(obs_t obs);
|
|||
* viewing sources independently, and other things. Creates a new swap chain
|
||||
* linked to a specific window to display a source.
|
||||
*/
|
||||
EXPORT display_t display_create(obs_t obs, struct gs_init_data *graphics_data);
|
||||
EXPORT void display_destroy(display_t display);
|
||||
EXPORT obs_display_t obs_display_create(struct gs_init_data *graphics_data);
|
||||
EXPORT void obs_display_destroy(obs_display_t display);
|
||||
|
||||
/** Sets the source to be used for a display context. */
|
||||
EXPORT void display_setsource(display_t display, source_t source);
|
||||
EXPORT source_t display_getsource(display_t display);
|
||||
EXPORT void obs_display_setsource(obs_display_t display, obs_source_t source);
|
||||
EXPORT obs_source_t obs_display_getsource(obs_display_t display);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -167,9 +171,10 @@ EXPORT source_t display_getsource(display_t display);
|
|||
* The "source" context is used for anything related to presenting
|
||||
* or modifying video/audio.
|
||||
*/
|
||||
EXPORT source_t source_create(obs_t obs, enum source_type type,
|
||||
EXPORT obs_source_t obs_source_create(enum obs_source_type type,
|
||||
const char *name, const char *settings);
|
||||
EXPORT void source_destroy(source_t source);
|
||||
EXPORT void obs_source_destroy(obs_source_t source);
|
||||
|
||||
/**
|
||||
* Retrieves flags that specify what type of data the source presents/modifies.
|
||||
*
|
||||
|
@ -177,59 +182,73 @@ EXPORT void source_destroy(source_t source);
|
|||
* SOURCE_ASYNC if the video is asynchronous.
|
||||
* SOURCE_AUDIO if it presents/modifies audio (always async)
|
||||
*/
|
||||
EXPORT uint32_t source_get_output_flags(source_t source);
|
||||
EXPORT uint32_t obs_source_get_obs_output_flags(obs_source_t source);
|
||||
|
||||
/** Specifies whether the source can be configured */
|
||||
EXPORT bool source_hasconfig(source_t source);
|
||||
EXPORT bool obs_source_hasconfig(obs_source_t source);
|
||||
|
||||
/** Opens a configuration panel and attaches it to the parent window */
|
||||
EXPORT void source_config(source_t source, void *parent);
|
||||
EXPORT void obs_source_config(obs_source_t source, void *parent);
|
||||
|
||||
/** Renders a video source. */
|
||||
EXPORT void source_video_render(source_t source);
|
||||
EXPORT void obs_source_video_render(obs_source_t source);
|
||||
|
||||
/** Gets the width of a source (if it has video) */
|
||||
EXPORT int source_getwidth(source_t source);
|
||||
EXPORT int obs_source_getwidth(obs_source_t source);
|
||||
|
||||
/** Gets the height of a source (if it has video) */
|
||||
EXPORT int source_getheight(source_t source);
|
||||
EXPORT int obs_source_getheight(obs_source_t source);
|
||||
|
||||
/**
|
||||
* Gets a custom parameter from the source.
|
||||
*
|
||||
* Used for efficiently modifying source properties in real time.
|
||||
*/
|
||||
EXPORT size_t source_getparam(source_t source, const char *param, void *buf,
|
||||
size_t buf_size);
|
||||
EXPORT size_t obs_source_getparam(obs_source_t source, const char *param,
|
||||
void *buf, size_t buf_size);
|
||||
|
||||
/**
|
||||
* Sets a custom parameter for the source.
|
||||
*
|
||||
* Used for efficiently modifying source properties in real time.
|
||||
*/
|
||||
EXPORT void source_setparam(source_t source, const char *param,
|
||||
const void *data, size_t size);
|
||||
EXPORT void obs_source_setparam(obs_source_t source, const char *param,
|
||||
const void *data, size_t size);
|
||||
/**
|
||||
* Enumerates child sources this source has
|
||||
*/
|
||||
EXPORT bool source_enum_children(source_t source, size_t idx,
|
||||
source_t *child);
|
||||
EXPORT bool obs_source_enum_children(obs_source_t source, size_t idx,
|
||||
obs_source_t *child);
|
||||
|
||||
/** If the source is a filter, returns the target source of the filter */
|
||||
EXPORT source_t filter_gettarget(source_t filter);
|
||||
EXPORT obs_source_t obs_filter_gettarget(obs_source_t filter);
|
||||
|
||||
/** Adds a filter to the source (which is used whenever the source is used) */
|
||||
EXPORT void source_filter_add(source_t source, source_t filter);
|
||||
EXPORT void obs_source_filter_add(obs_source_t source,obs_source_t filter);
|
||||
|
||||
/** Removes a filter from the source */
|
||||
EXPORT void source_filter_remove(source_t source, source_t filter);
|
||||
EXPORT void obs_source_filter_remove(obs_source_t source, obs_source_t filter);
|
||||
|
||||
/** Modifies the order of a specific filter */
|
||||
EXPORT void source_filter_setorder(source_t source, source_t filter,
|
||||
enum order_movement movement);
|
||||
EXPORT void obs_source_filter_setorder(obs_source_t source, obs_source_t filter,
|
||||
enum order_movement movement);
|
||||
|
||||
/** Gets the settings string for a source */
|
||||
EXPORT const char *source_get_settings(source_t source);
|
||||
EXPORT const char *obs_source_get_settings(obs_source_t source);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Functions used by sources */
|
||||
|
||||
/** Saves the settings string for a source */
|
||||
EXPORT void source_save_settings(source_t source, const char *settings);
|
||||
EXPORT void obs_source_save_settings(obs_source_t source, const char *settings);
|
||||
|
||||
/** Outputs asynchronous video data */
|
||||
EXPORT void source_output_video(source_t source, struct video_frame *frame);
|
||||
EXPORT void obs_source_obs_output_video(obs_source_t source,
|
||||
struct video_frame *frame);
|
||||
|
||||
/** Outputs audio data (always asynchronous) */
|
||||
EXPORT void source_output_audio(source_t source, struct audio_data *audio);
|
||||
EXPORT void obs_source_obs_output_audio(obs_source_t source,
|
||||
struct audio_data *audio);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -241,28 +260,32 @@ EXPORT void source_output_audio(source_t source, struct audio_data *audio);
|
|||
* A scene is a source which is a container of other sources with specific
|
||||
* display oriantations. Scenes can also be used like any other source.
|
||||
*/
|
||||
EXPORT scene_t scene_create(obs_t obs);
|
||||
EXPORT void scene_destroy(scene_t scene);
|
||||
EXPORT obs_scene_t obs_scene_create(void);
|
||||
EXPORT void obs_scene_destroy(obs_scene_t scene);
|
||||
|
||||
/** Gets the scene's source context */
|
||||
EXPORT source_t scene_source(scene_t scene);
|
||||
EXPORT obs_source_t obs_scene_getsource(obs_scene_t scene);
|
||||
|
||||
/** Adds/creates a new scene item for a source */
|
||||
EXPORT sceneitem_t scene_add(scene_t scene, source_t source);
|
||||
EXPORT obs_sceneitem_t obs_scene_add(obs_scene_t scene, obs_source_t source);
|
||||
|
||||
/** Removes/destroys a scene item */
|
||||
EXPORT void sceneitem_destroy(sceneitem_t item);
|
||||
EXPORT void obs_sceneitem_destroy(obs_sceneitem_t item);
|
||||
|
||||
/* Functions for gettings/setting specific oriantation of a scene item */
|
||||
EXPORT void sceneitem_setpos(sceneitem_t item, const struct vec2 *pos);
|
||||
EXPORT void sceneitem_setrot(sceneitem_t item, float rot);
|
||||
EXPORT void sceneitem_setorigin(sceneitem_t item, const struct vec2 *origin);
|
||||
EXPORT void sceneitem_setscale(sceneitem_t item, const struct vec2 *scale);
|
||||
EXPORT void sceneitem_setorder(sceneitem_t item, enum order_movement movement);
|
||||
EXPORT void obs_sceneitem_setpos(obs_sceneitem_t item, const struct vec2 *pos);
|
||||
EXPORT void obs_sceneitem_setrot(obs_sceneitem_t item, float rot);
|
||||
EXPORT void obs_sceneitem_setorigin(obs_sceneitem_t item,
|
||||
const struct vec2 *origin);
|
||||
EXPORT void obs_sceneitem_setscale(obs_sceneitem_t item,
|
||||
const struct vec2 *scale);
|
||||
EXPORT void obs_sceneitem_setorder(obs_sceneitem_t item,
|
||||
enum order_movement movement);
|
||||
|
||||
EXPORT void sceneitem_getpos(sceneitem_t item, struct vec2 *pos);
|
||||
EXPORT float sceneitem_getrot(sceneitem_t item);
|
||||
EXPORT void sceneitem_getorigin(sceneitem_t item, struct vec2 *center);
|
||||
EXPORT void sceneitem_getscale(sceneitem_t item, struct vec2 *scale);
|
||||
EXPORT void obs_sceneitem_getpos(obs_sceneitem_t item, struct vec2 *pos);
|
||||
EXPORT float obs_sceneitem_getrot(obs_sceneitem_t item);
|
||||
EXPORT void obs_sceneitem_getorigin(obs_sceneitem_t item, struct vec2 *center);
|
||||
EXPORT void obs_sceneitem_getscale(obs_sceneitem_t item, struct vec2 *scale);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -274,27 +297,33 @@ EXPORT void sceneitem_getscale(sceneitem_t item, struct vec2 *scale);
|
|||
* Outputs allow outputting to file, outputting to network, outputting to
|
||||
* directshow, or other custom outputs.
|
||||
*/
|
||||
EXPORT output_t output_create(obs_t obs, const char *name,
|
||||
const char *settings);
|
||||
EXPORT void output_destroy(output_t output);
|
||||
EXPORT obs_output_t obs_output_create(const char *name, const char *settings);
|
||||
EXPORT void obs_output_destroy(obs_output_t output);
|
||||
|
||||
/** Starts the output. */
|
||||
EXPORT void output_start(output_t output);
|
||||
EXPORT void obs_output_start(obs_output_t output);
|
||||
|
||||
/** Stops the output. */
|
||||
EXPORT void output_stop(output_t output);
|
||||
EXPORT void obs_output_stop(obs_output_t output);
|
||||
|
||||
/** Specifies whether the output can be configured */
|
||||
EXPORT bool output_canconfig(output_t output);
|
||||
EXPORT bool obs_output_canconfig(obs_output_t output);
|
||||
|
||||
/** Opens a configuration panel with the specified parent window */
|
||||
EXPORT void output_config(output_t output, void *parent);
|
||||
EXPORT void obs_output_config(obs_output_t output, void *parent);
|
||||
|
||||
/** Specifies whether the output can be paused */
|
||||
EXPORT bool output_canpause(output_t output);
|
||||
EXPORT bool obs_output_canpause(obs_output_t output);
|
||||
|
||||
/** Pauses the output (if the functionality is allowed by the output */
|
||||
EXPORT void output_pause(output_t output);
|
||||
EXPORT void obs_output_pause(obs_output_t output);
|
||||
|
||||
/* Gets the current output settings string */
|
||||
EXPORT const char *output_get_settings(output_t output);
|
||||
EXPORT const char *obs_output_get_settings(obs_output_t output);
|
||||
|
||||
/* Saves the output settings string, typically used only by outputs */
|
||||
EXPORT void output_save_settings(output_t output, const char *settings);
|
||||
EXPORT void obs_output_save_settings(obs_output_t output,
|
||||
const char *settings);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#include "test-filter.h"
|
||||
|
||||
struct test_filter *test_create(const char *settings, source_t source)
|
||||
struct test_filter *test_create(const char *settings, obs_source_t source)
|
||||
{
|
||||
struct test_filter *tf = bmalloc(sizeof(struct test_filter));
|
||||
memset(tf, 0, sizeof(struct test_filter));
|
||||
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
tf->source = source;
|
||||
tf->whatever = gs_create_effect_from_file("test.effect", NULL);
|
||||
if (!tf->whatever) {
|
||||
|
@ -14,15 +16,21 @@ struct test_filter *test_create(const char *settings, source_t source)
|
|||
|
||||
tf->texrender = texrender_create(GS_RGBA, GS_ZS_NONE);
|
||||
|
||||
gs_leavecontext();
|
||||
|
||||
return tf;
|
||||
}
|
||||
|
||||
void test_destroy(struct test_filter *tf)
|
||||
{
|
||||
if (tf) {
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
effect_destroy(tf->whatever);
|
||||
texrender_destroy(tf->texrender);
|
||||
bfree(tf);
|
||||
|
||||
gs_leavecontext();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,9 +46,9 @@ void test_video_tick(struct test_filter *tf, float seconds)
|
|||
|
||||
void test_video_render(struct test_filter *tf)
|
||||
{
|
||||
source_t filter_target = filter_gettarget(tf->source);
|
||||
int cx = source_getwidth(filter_target);
|
||||
int cy = source_getheight(filter_target);
|
||||
obs_source_t filter_target = obs_filter_gettarget(tf->source);
|
||||
int cx = obs_source_getwidth(filter_target);
|
||||
int cy = obs_source_getheight(filter_target);
|
||||
float fcx = (float)cx;
|
||||
float fcy = (float)cy;
|
||||
technique_t tech;
|
||||
|
@ -48,7 +56,7 @@ void test_video_render(struct test_filter *tf)
|
|||
|
||||
if (texrender_begin(tf->texrender, cx, cy)) {
|
||||
gs_ortho(0.0f, fcx, 0.0f, fcy, -100.0f, 100.0f);
|
||||
source_video_render(filter_target);
|
||||
obs_source_video_render(filter_target);
|
||||
texrender_end(tf->texrender);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,12 +7,12 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct test_filter {
|
||||
source_t source;
|
||||
obs_source_t source;
|
||||
effect_t whatever;
|
||||
texrender_t texrender;
|
||||
};
|
||||
|
||||
EXPORT struct test_filter *test_create(const char *settings, source_t source);
|
||||
EXPORT struct test_filter *test_create(const char *settings, obs_source_t source);
|
||||
EXPORT void test_destroy(struct test_filter *rt);
|
||||
EXPORT uint32_t test_get_output_flags(struct test_filter *rt);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <stdlib.h>
|
||||
#include "test-random.h"
|
||||
|
||||
struct random_tex *random_create(const char *settings, source_t source)
|
||||
struct random_tex *random_create(const char *settings, obs_source_t source)
|
||||
{
|
||||
struct random_tex *rt = bmalloc(sizeof(struct random_tex));
|
||||
uint32_t *pixels = bmalloc(20*20*4);
|
||||
|
@ -19,6 +19,8 @@ struct random_tex *random_create(const char *settings, source_t source)
|
|||
}
|
||||
}
|
||||
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
rt->texture = gs_create_texture(20, 20, GS_RGBA, 1, &pixels, 0);
|
||||
bfree(pixels);
|
||||
|
||||
|
@ -33,15 +35,21 @@ struct random_tex *random_create(const char *settings, source_t source)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
gs_leavecontext();
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
void random_destroy(struct random_tex *rt)
|
||||
{
|
||||
if (rt) {
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
effect_destroy(rt->whatever);
|
||||
texture_destroy(rt->texture);
|
||||
bfree(rt);
|
||||
|
||||
gs_leavecontext();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +58,7 @@ uint32_t random_get_output_flags(struct random_tex *rt)
|
|||
return SOURCE_VIDEO;
|
||||
}
|
||||
|
||||
void random_video_render(struct random_tex *rt, source_t filter_target)
|
||||
void random_video_render(struct random_tex *rt, obs_source_t filter_target)
|
||||
{
|
||||
technique_t tech = effect_gettechnique(rt->whatever, "Default");
|
||||
effect_settexture(rt->whatever, effect_getparambyidx(rt->whatever, 1), rt->texture);
|
||||
|
|
|
@ -11,11 +11,11 @@ struct random_tex {
|
|||
effect_t whatever;
|
||||
};
|
||||
|
||||
EXPORT struct random_tex *random_create(const char *settings, source_t source);
|
||||
EXPORT struct random_tex *random_create(const char *settings, obs_source_t source);
|
||||
EXPORT void random_destroy(struct random_tex *rt);
|
||||
EXPORT uint32_t random_get_output_flags(struct random_tex *rt);
|
||||
|
||||
EXPORT void random_video_render(struct random_tex *rt, source_t filter_target);
|
||||
EXPORT void random_video_render(struct random_tex *rt, obs_source_t filter_target);
|
||||
|
||||
EXPORT int random_getwidth(struct random_tex *rt);
|
||||
EXPORT int random_getheight(struct random_tex *rt);
|
||||
|
|
|
@ -5,40 +5,31 @@
|
|||
#include "util/base.h"
|
||||
#include "obs.h"
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
static const int cx = 800;
|
||||
static const int cy = 600;
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
|
||||
class OBSContext {
|
||||
obs_t obs;
|
||||
|
||||
public:
|
||||
inline OBSContext(obs_t obs) : obs(obs) {}
|
||||
inline ~OBSContext() {obs_destroy(obs);}
|
||||
inline operator obs_t() {return obs;}
|
||||
};
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
|
||||
class SourceContext {
|
||||
source_t source;
|
||||
obs_source_t source;
|
||||
|
||||
public:
|
||||
inline SourceContext(source_t source) : source(source) {}
|
||||
inline ~SourceContext() {source_destroy(source);}
|
||||
inline operator source_t() {return source;}
|
||||
inline SourceContext(obs_source_t source) : source(source) {}
|
||||
inline ~SourceContext() {obs_source_destroy(source);}
|
||||
inline operator obs_source_t() {return source;}
|
||||
};
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
|
||||
class SceneContext {
|
||||
scene_t scene;
|
||||
obs_scene_t scene;
|
||||
|
||||
public:
|
||||
inline SceneContext(scene_t scene) : scene(scene) {}
|
||||
inline ~SceneContext() {scene_destroy(scene);}
|
||||
inline operator scene_t() {return scene;}
|
||||
inline SceneContext(obs_scene_t scene) : scene(scene) {}
|
||||
inline ~SceneContext() {obs_scene_destroy(scene);}
|
||||
inline operator obs_scene_t() {return scene;}
|
||||
};
|
||||
|
||||
/* --------------------------------------------------- */
|
||||
|
@ -66,9 +57,12 @@ static void do_log(enum log_type type, const char *msg, va_list args)
|
|||
|
||||
OutputDebugStringA(bla);
|
||||
OutputDebugStringA("\n");
|
||||
|
||||
if (type >= LOG_WARNING)
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
static obs_t CreateOBS(HWND hwnd)
|
||||
static void CreateOBS(HWND hwnd)
|
||||
{
|
||||
struct video_info vi;
|
||||
memset(&vi, 0, sizeof(struct video_info));
|
||||
|
@ -87,31 +81,28 @@ static obs_t CreateOBS(HWND hwnd)
|
|||
gsid.num_backbuffers = 2;
|
||||
gsid.format = GS_RGBA;
|
||||
|
||||
obs_t obs = obs_create("libobs-d3d11.dll", &gsid, &vi, NULL);
|
||||
if (!obs)
|
||||
if (!obs_startup("libobs-d3d11.dll", &gsid, &vi, NULL))
|
||||
throw "Couldn't create OBS";
|
||||
|
||||
return obs;
|
||||
}
|
||||
|
||||
static void AddTestItems(scene_t scene, source_t source)
|
||||
static void AddTestItems(obs_scene_t scene, obs_source_t source)
|
||||
{
|
||||
sceneitem_t item = NULL;
|
||||
obs_sceneitem_t item = NULL;
|
||||
struct vec2 v2;
|
||||
|
||||
item = scene_add(scene, source);
|
||||
item = obs_scene_add(scene, source);
|
||||
vec2_set(&v2, 100.0f, 200.0f);
|
||||
sceneitem_setpos(item, &v2);
|
||||
sceneitem_setrot(item, 10.0f);
|
||||
obs_sceneitem_setpos(item, &v2);
|
||||
obs_sceneitem_setrot(item, 10.0f);
|
||||
vec2_set(&v2, 20.0f, 2.0f);
|
||||
sceneitem_setscale(item, &v2);
|
||||
obs_sceneitem_setscale(item, &v2);
|
||||
|
||||
item = scene_add(scene, source);
|
||||
item = obs_scene_add(scene, source);
|
||||
vec2_set(&v2, 200.0f, 100.0f);
|
||||
sceneitem_setpos(item, &v2);
|
||||
sceneitem_setrot(item, -45.0f);
|
||||
obs_sceneitem_setpos(item, &v2);
|
||||
obs_sceneitem_setrot(item, -45.0f);
|
||||
vec2_set(&v2, 5.0f, 7.0f);
|
||||
sceneitem_setscale(item, &v2);
|
||||
obs_sceneitem_setscale(item, &v2);
|
||||
}
|
||||
|
||||
static HWND CreateTestWindow(HINSTANCE instance)
|
||||
|
@ -148,31 +139,31 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine,
|
|||
|
||||
/* ------------------------------------------------------ */
|
||||
/* create OBS */
|
||||
OBSContext obs = CreateOBS(hwnd);
|
||||
CreateOBS(hwnd);
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
/* load module */
|
||||
if (obs_load_module(obs, "test-input.dll") != 0)
|
||||
if (obs_load_module("test-input.dll") != 0)
|
||||
throw "Couldn't load module";
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
/* create source */
|
||||
SourceContext source = source_create(obs, SOURCE_INPUT,
|
||||
SourceContext source = obs_source_create(SOURCE_INPUT,
|
||||
"random", NULL);
|
||||
if (!source)
|
||||
throw "Couldn't create random test source";
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
/* create filter */
|
||||
SourceContext filter = source_create(obs, SOURCE_FILTER,
|
||||
SourceContext filter = obs_source_create(SOURCE_FILTER,
|
||||
"test", NULL);
|
||||
if (!filter)
|
||||
throw "Couldn't create test filter";
|
||||
source_filter_add(source, filter);
|
||||
obs_source_filter_add(source, filter);
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
/* create scene and add source to scene (twice) */
|
||||
SceneContext scene = scene_create(obs);
|
||||
SceneContext scene = obs_scene_create();
|
||||
if (!scene)
|
||||
throw "Couldn't create scene";
|
||||
|
||||
|
@ -180,7 +171,7 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine,
|
|||
|
||||
/* ------------------------------------------------------ */
|
||||
/* set the scene as the primary draw source and go */
|
||||
obs_set_primary_source(obs, scene_source(scene));
|
||||
obs_set_primary_source(obs_scene_getsource(scene));
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
|
@ -188,12 +179,14 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine,
|
|||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
obs_set_primary_source(obs, NULL);
|
||||
obs_set_primary_source(NULL);
|
||||
|
||||
} catch (char *error) {
|
||||
MessageBoxA(NULL, error, NULL, 0);
|
||||
}
|
||||
|
||||
obs_shutdown();
|
||||
|
||||
blog(LOG_INFO, "Number of memory leaks: %u", bnum_allocs());
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
|
|
|
@ -12,24 +12,24 @@ struct VertexInOut {
|
|||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
VertexInOut VShader(VertexInOut input)
|
||||
VertexInOut VShader(VertexInOut vert_in)
|
||||
{
|
||||
VertexInOut output;
|
||||
output.pos = mul(float4(input.pos.xyz, 1.0), ViewProj);
|
||||
output.uv = input.uv;
|
||||
return output;
|
||||
VertexInOut vert_out;
|
||||
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
|
||||
vert_out.uv = vert_in.uv;
|
||||
return vert_out;
|
||||
}
|
||||
|
||||
float4 PShader(VertexInOut input) : TARGET
|
||||
float4 PShader(VertexInOut fragment_in) : TARGET
|
||||
{
|
||||
return diffuse.Sample(texSampler, input.uv);
|
||||
return diffuse.Sample(texSampler, fragment_in.uv);
|
||||
}
|
||||
|
||||
technique Default
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_shader = VShader(input);
|
||||
pixel_shader = PShader(input);
|
||||
vertex_shader = VShader(vert_in);
|
||||
pixel_shader = PShader(fragment_in);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,24 +14,24 @@ struct VertexInOut {
|
|||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
VertexInOut VShader(VertexInOut input)
|
||||
VertexInOut VShader(VertexInOut vert_in)
|
||||
{
|
||||
VertexInOut output;
|
||||
output.pos = mul(float4(input.pos.xyz, 1.0), ViewProj);
|
||||
output.uv = input.uv;
|
||||
return output;
|
||||
VertexInOut vert_out;
|
||||
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
|
||||
vert_out.uv = vert_in.uv;
|
||||
return vert_out;
|
||||
}
|
||||
|
||||
float4 PShader(VertexInOut input) : TARGET
|
||||
float4 PShader(VertexInOut fragment_in) : TARGET
|
||||
{
|
||||
return diffuse.Sample(texSampler, input.uv) * color;
|
||||
return diffuse.Sample(texSampler, fragment_in.uv) * color;
|
||||
}
|
||||
|
||||
technique Default
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_shader = VShader(input);
|
||||
pixel_shader = PShader(input);
|
||||
vertex_shader = VShader(vert_in);
|
||||
pixel_shader = PShader(fragment_in);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue