change names, fix some bugs, minor GL/D3D fixes, update tests, fix effect files, output a little more debug information

master
jp9000 2013-10-14 12:37:52 -07:00
parent 1493a325bb
commit 9570f0b8d7
36 changed files with 530 additions and 357 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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, ", ");

View File

@ -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"))

View File

@ -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:

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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;
};

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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 */
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}
}