Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
[submodule "plugins/obs-ndi"]
path = plugins/obs-ndi
url = https://github.com/streamlabs/obs-ndi.git
branch = streamlabs-obs
branch = streamlabs
[submodule "plugins/slobs-virtual-cam"]
path = plugins/slobs-virtual-cam
url = https://github.com/streamlabs/slobs-virtual-cam.git
Expand Down
2 changes: 1 addition & 1 deletion deps/libdshowcapture/src
Submodule src updated 1 files
+29 −2 source/dshow-enum.cpp
18 changes: 16 additions & 2 deletions libobs-winrt/winrt-capture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,13 +301,22 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data)
return;

ID3D11Device *const d3d_device = (ID3D11Device *)device_void;
if (!d3d_device || FAILED(d3d_device->GetDeviceRemovedReason())) {
blog(LOG_WARNING, "Skipping WinRT capture rebuild; graphics device unavailable or removed");
return;
}

ComPtr<IDXGIDevice> dxgi_device;
if (FAILED(d3d_device->QueryInterface(&dxgi_device)))
if (FAILED(d3d_device->QueryInterface(&dxgi_device))) {
blog(LOG_ERROR, "Failed to get DXGI device");
return;
}

winrt::com_ptr<IInspectable> inspectable;
if (FAILED(CreateDirect3D11DeviceFromDXGIDevice(dxgi_device.Get(), inspectable.put())))
if (FAILED(CreateDirect3D11DeviceFromDXGIDevice(dxgi_device.Get(), inspectable.put()))) {
blog(LOG_ERROR, "Failed to get WinRT device");
return;
}

const winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice device =
inspectable.as<winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice>();
Expand Down Expand Up @@ -349,6 +358,11 @@ static struct winrt_capture *winrt_capture_init_internal(BOOL cursor, HWND windo
HMONITOR monitor)
try {
ID3D11Device *const d3d_device = (ID3D11Device *)gs_get_device_obj();
if (!d3d_device || FAILED(d3d_device->GetDeviceRemovedReason())) {
blog(LOG_WARNING, "Skipping WinRT capture init; graphics device unavailable or removed");
return nullptr;
}

ComPtr<IDXGIDevice> dxgi_device;

HRESULT hr = d3d_device->QueryInterface(&dxgi_device);
Expand Down
4 changes: 2 additions & 2 deletions libobs/obs-audio-controls.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ static void volmeter_process_peak(obs_volmeter_t *volmeter, const struct audio_d
{
int nr_samples = data->frames;
int channel_nr = 0;
for (int plane_nr = 0; channel_nr < nr_channels; plane_nr++) {
for (int plane_nr = 0; channel_nr < nr_channels && plane_nr < MAX_AV_PLANES; plane_nr++) {
float *samples = (float *)data->data[plane_nr];
if (!samples) {
continue;
Expand Down Expand Up @@ -466,7 +466,7 @@ static void volmeter_process_magnitude(obs_volmeter_t *volmeter, const struct au
size_t nr_samples = data->frames;

int channel_nr = 0;
for (int plane_nr = 0; channel_nr < nr_channels; plane_nr++) {
for (int plane_nr = 0; channel_nr < nr_channels && plane_nr < MAX_AV_PLANES; plane_nr++) {
float *samples = (float *)data->data[plane_nr];
if (!samples) {
continue;
Expand Down
3 changes: 3 additions & 0 deletions libobs/obs-canvas.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ void obs_canvas_destroy(obs_canvas_t *canvas)

pthread_mutex_destroy(&canvas->sources_mutex);
obs_context_data_free(&canvas->context);

/* Null mixes referencing this view before freeing it; audio_callback() reads it via mix->view. */
obs_view_remove(&canvas->view);
obs_view_free(&canvas->view);
bfree(canvas);
}
Expand Down
2 changes: 2 additions & 0 deletions libobs/obs-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ struct obs_module {
char *data_path;
void *module;
bool loaded;
char *load_error_code;
char *load_error_message;

bool (*load)(void);
void (*unload)(void);
Expand Down
82 changes: 72 additions & 10 deletions libobs/obs-module.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,18 @@ int obs_open_module(obs_module_t **module, const char *path, const char *data_pa
return MODULE_SUCCESS;
}

static void clear_module_load_error(obs_module_t *module)
{
if (!module)
return;

bfree(module->load_error_code);
module->load_error_code = NULL;

bfree(module->load_error_message);
module->load_error_message = NULL;
}

bool obs_init_module(obs_module_t *module)
{
if (!module || !obs)
Expand All @@ -167,14 +179,34 @@ bool obs_init_module(obs_module_t *module)
profile_store_name(obs_get_profiler_name_store(), "obs_init_module(%s)", module->file);
profile_start(profile_name);

clear_module_load_error(module);
module->loaded = module->load();
if (!module->loaded)
blog(LOG_WARNING, "Failed to initialize module '%s'", module->file);
if (!module->loaded) {
if (module->load_error_code && module->load_error_message) {
blog(LOG_WARNING, "Failed to initialize module '%s': %s (%s)", module->file,
module->load_error_message, module->load_error_code);
} else if (module->load_error_code) {
blog(LOG_WARNING, "Failed to initialize module '%s': %s", module->file,
module->load_error_code);
} else {
blog(LOG_WARNING, "Failed to initialize module '%s'", module->file);
}
}

profile_end(profile_name);
return module->loaded;
}

void obs_module_set_load_error(obs_module_t *module, const char *code, const char *message)
{
if (!module)
return;

clear_module_load_error(module);
module->load_error_code = bstrdup(code ? code : "");
module->load_error_message = bstrdup(message ? message : "");
}

void obs_log_loaded_modules(void)
{
blog(LOG_INFO, " Loaded Modules:");
Expand Down Expand Up @@ -294,9 +326,25 @@ extern void get_plugin_info(const char *path, bool *is_obs_plugin, bool *can_loa

struct fail_info {
struct dstr fail_modules;
size_t fail_count;
DARRAY(struct obs_module_load_failure) failures;
};

static void add_module_failure(struct fail_info *fail_info, const char *module, const char *code, const char *message)
{
if (!fail_info)
return;

struct obs_module_load_failure failure = {
bstrdup(module ? module : ""),
bstrdup((code && *code) ? code : "MODULE_LOAD_FAILED"),
bstrdup((message && *message) ? message : "Module failed to load."),
};

dstr_cat(&fail_info->fail_modules, failure.module);
dstr_cat(&fail_info->fail_modules, ";");
da_push_back(fail_info->failures, &failure);
}

static bool is_safe_module(const char *name)
{
if (!obs->safe_modules.num)
Expand Down Expand Up @@ -356,18 +404,16 @@ static void load_all_callback(void *param, const struct obs_module_info2 *info)
return;
}

if (!obs_init_module(module))
if (!obs_init_module(module)) {
add_module_failure(fail_info, info->name, module->load_error_code, module->load_error_message);
free_module(module);
}

UNUSED_PARAMETER(param);
return;

load_failure:
if (fail_info) {
dstr_cat(&fail_info->fail_modules, info->name);
dstr_cat(&fail_info->fail_modules, ";");
fail_info->fail_count++;
}
add_module_failure(fail_info, info->name, NULL, NULL);
}

static const char *obs_load_all_modules_name = "obs_load_all_modules";
Expand Down Expand Up @@ -403,7 +449,8 @@ void obs_load_all_modules2(struct obs_module_failure_info *mfi)
#endif
profile_end(obs_load_all_modules2_name);

mfi->count = fail_info.fail_count;
mfi->count = fail_info.failures.num;
mfi->failures = fail_info.failures.array;
mfi->failed_modules = strlist_split(fail_info.fail_modules.array, ';', false);
dstr_free(&fail_info.fail_modules);
}
Expand All @@ -414,6 +461,19 @@ void obs_module_failure_info_free(struct obs_module_failure_info *mfi)
bfree(mfi->failed_modules);
mfi->failed_modules = NULL;
}

if (mfi->failures) {
for (size_t i = 0; i < mfi->count; i++) {
bfree(mfi->failures[i].module);
bfree(mfi->failures[i].code);
bfree(mfi->failures[i].message);
}

bfree(mfi->failures);
mfi->failures = NULL;
}

mfi->count = 0;
}

void obs_post_load_modules(void)
Expand Down Expand Up @@ -621,6 +681,8 @@ void free_module(struct obs_module *mod)
bfree(mod->mod_name);
bfree(mod->bin_path);
bfree(mod->data_path);
bfree(mod->load_error_code);
bfree(mod->load_error_message);
bfree(mod);
}

Expand Down
9 changes: 6 additions & 3 deletions libobs/obs-scene.c
Original file line number Diff line number Diff line change
Expand Up @@ -2111,9 +2111,12 @@ static bool scene_audio_render_do(void *data, uint64_t *ts_out,
for (size_t canvas_idx = 0;
canvas_idx < audio_output->outputs.num;
canvas_idx++) {
if (item->canvas !=
obs->video.canvases
.array[canvas_idx]) {
/* NULL canvas = all canvases, as in
* scene_video_render */
if (item->canvas &&
item->canvas !=
obs->video.canvases
.array[canvas_idx]) {
continue;
}

Expand Down
14 changes: 8 additions & 6 deletions libobs/obs-source.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,6 @@ struct obs_source_info {
/** Called when the source has been activated in the main view */
void (*activate)(void *data);

/** Called to send message to the source */
void (*message)(void *data, obs_data_t *settings);

/** Called to get messages from the source */
obs_data_array_t *(*get_messages)(void *data);

/**
* Called when the source has been deactivated from the main view
* (no longer being played/displayed)
Expand Down Expand Up @@ -562,6 +556,14 @@ struct obs_source_info {
* @param source Source that the filter is being added to
*/
void (*filter_add)(void *data, obs_source_t *source);

/* Append-only: mid-struct inserts shift later offsets and break module ABI. */

/** Called to send message to the source */
void (*message)(void *data, obs_data_t *settings);

/** Called to get messages from the source */
obs_data_array_t *(*get_messages)(void *data);
};

EXPORT void obs_register_source_s(const struct obs_source_info *info, size_t size);
Expand Down
8 changes: 8 additions & 0 deletions libobs/obs.h
Original file line number Diff line number Diff line change
Expand Up @@ -589,13 +589,21 @@ EXPORT void obs_add_safe_module(const char *name);
/** Automatically loads all modules from module paths (convenience function) */
EXPORT void obs_load_all_modules(void);

struct obs_module_load_failure {
char *module;
char *code;
char *message;
};

struct obs_module_failure_info {
char **failed_modules;
size_t count;
struct obs_module_load_failure *failures;
};

EXPORT void obs_module_failure_info_free(struct obs_module_failure_info *mfi);
EXPORT void obs_load_all_modules2(struct obs_module_failure_info *mfi);
EXPORT void obs_module_set_load_error(obs_module_t *module, const char *code, const char *message);

/** Notifies modules that all modules have been loaded. This function should
* be called after all modules have been loaded. */
Expand Down
2 changes: 1 addition & 1 deletion plugins/obs-browser
2 changes: 1 addition & 1 deletion plugins/obs-ndi