Add source properties window (very preliminary)
- Add a properties window for sources so that you can now actually edit the settings for sources. Also, display the source by itself in the window (Note: not working on mac, and possibly not working on linux). When changing the settings for a source, it will call obs_source_update on that source when you have modified any values automatically. - Add a properties 'widget', eventually I want to turn this in to a regular nice properties view like you'd see in the designer, but right now it just uses a form layout in a QScrollArea with regular controls to display the properties. It's clunky but works for the time being. - Make it so that swap chains and the main graphics subsystem will automatically use at least one backbuffer if none was specified - Fix bug where displays weren't added to the main display array - Make it so that you can get the properties of a source via the actual pointer of a source/encoder/output in addition to being able to look up properties via identifier. - When registering source types, check for required functions (wasn't doing it before). getheight/getwidth should not be optional if it's a video source as well. - Add an RAII OBSObj wrapper to obs.hpp for non-reference-counted libobs pointers - Add an RAII OBSSignal wrapper to obs.hpp for libobs signals to automatically disconnect them on destruction - Move the "scale and center" calculation in window-basic-main.cpp to its own function and in its own source file - Add an 'update' callback to WASAPI audio sources
This commit is contained in:
@@ -114,6 +114,9 @@ int gs_create(graphics_t *pgraphics, const char *module,
|
||||
graphics_t graphics = bzalloc(sizeof(struct graphics_subsystem));
|
||||
pthread_mutex_init_value(&graphics->mutex);
|
||||
|
||||
if (!data->num_backbuffers)
|
||||
data->num_backbuffers = 1;
|
||||
|
||||
graphics->module = os_dlopen(module);
|
||||
if (!graphics->module) {
|
||||
errcode = GS_ERROR_MODULENOTFOUND;
|
||||
|
@@ -48,11 +48,22 @@ obs_display_t obs_display_create(struct gs_init_data *graphics_data)
|
||||
{
|
||||
struct obs_display *display = bzalloc(sizeof(struct obs_display));
|
||||
|
||||
gs_entercontext(obs_graphics());
|
||||
|
||||
if (!graphics_data->num_backbuffers)
|
||||
graphics_data->num_backbuffers = 1;
|
||||
|
||||
if (!obs_display_init(display, graphics_data)) {
|
||||
obs_display_destroy(display);
|
||||
display = NULL;
|
||||
} else {
|
||||
pthread_mutex_lock(&obs->data.displays_mutex);
|
||||
da_push_back(obs->data.displays, &display);
|
||||
pthread_mutex_unlock(&obs->data.displays_mutex);
|
||||
}
|
||||
|
||||
gs_leavecontext();
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
@@ -74,7 +85,10 @@ void obs_display_destroy(obs_display_t display)
|
||||
da_erase_item(obs->data.displays, &display);
|
||||
pthread_mutex_unlock(&obs->data.displays_mutex);
|
||||
|
||||
gs_entercontext(obs_graphics());
|
||||
obs_display_free(display);
|
||||
gs_leavecontext();
|
||||
|
||||
bfree(display);
|
||||
}
|
||||
}
|
||||
|
@@ -208,7 +208,7 @@ obs_data_t obs_encoder_defaults(const char *id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obs_properties_t obs_encoder_properties(const char *id, const char *locale)
|
||||
obs_properties_t obs_get_encoder_properties(const char *id, const char *locale)
|
||||
{
|
||||
const struct obs_encoder_info *ei = get_encoder_info(id);
|
||||
if (ei && ei->properties)
|
||||
@@ -216,6 +216,14 @@ obs_properties_t obs_encoder_properties(const char *id, const char *locale)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obs_properties_t obs_encoder_properties(obs_encoder_t encoder,
|
||||
const char *locale)
|
||||
{
|
||||
if (encoder && encoder->info.properties)
|
||||
return encoder->info.properties(locale);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void obs_encoder_update(obs_encoder_t encoder, obs_data_t settings)
|
||||
{
|
||||
if (!encoder) return;
|
||||
|
@@ -130,14 +130,42 @@ void free_module(struct obs_module *mod)
|
||||
bfree(mod->name);
|
||||
}
|
||||
|
||||
#define REGISTER_OBS_DEF(size_var, structure, dest, info) \
|
||||
do { \
|
||||
struct structure data = {0}; \
|
||||
if (!size_var) { \
|
||||
blog(LOG_ERROR, "Tried to register " #structure \
|
||||
" outside of obs_module_load"); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
memcpy(&data, info, size_var); \
|
||||
da_push_back(dest, &data); \
|
||||
} while (false)
|
||||
|
||||
#define CHECK_REQUIRED_VAL(info, val, func) \
|
||||
do { \
|
||||
if (!info->val) {\
|
||||
blog(LOG_ERROR, "Required value '" #val " for" \
|
||||
"'%s' not found. " #func \
|
||||
" failed.", info->id); \
|
||||
return; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
void obs_register_source(const struct obs_source_info *info)
|
||||
{
|
||||
struct obs_source_info data = {0};
|
||||
struct darray *array;
|
||||
|
||||
if (!info) {
|
||||
blog(LOG_ERROR, "obs_register_source: NULL info");
|
||||
return;
|
||||
CHECK_REQUIRED_VAL(info, getname, obs_register_source);
|
||||
CHECK_REQUIRED_VAL(info, create, obs_register_source);
|
||||
CHECK_REQUIRED_VAL(info, destroy, obs_register_source);
|
||||
|
||||
if (info->type == OBS_SOURCE_TYPE_INPUT &&
|
||||
info->output_flags & OBS_SOURCE_VIDEO) {
|
||||
CHECK_REQUIRED_VAL(info, getwidth, obs_register_source);
|
||||
CHECK_REQUIRED_VAL(info, getheight, obs_register_source);
|
||||
}
|
||||
|
||||
if (!cur_source_info_size) {
|
||||
@@ -163,29 +191,6 @@ void obs_register_source(const struct obs_source_info *info)
|
||||
darray_push_back(sizeof(struct obs_source_info), array, &data);
|
||||
}
|
||||
|
||||
#define REGISTER_OBS_DEF(size_var, structure, dest, info) \
|
||||
do { \
|
||||
struct structure data = {0}; \
|
||||
if (!size_var) { \
|
||||
blog(LOG_ERROR, "Tried to register " #structure \
|
||||
" outside of obs_module_load"); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
memcpy(&data, info, size_var); \
|
||||
da_push_back(dest, &data); \
|
||||
} while (false)
|
||||
|
||||
#define CHECK_REQUIRED_VAL(info, val, func) \
|
||||
do { \
|
||||
if (!info->val) {\
|
||||
blog(LOG_ERROR, "Required value '" #val " for" \
|
||||
"'%s' not found. " #func \
|
||||
" failed.", info->id); \
|
||||
return; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
void obs_register_output(const struct obs_output_info *info)
|
||||
{
|
||||
CHECK_REQUIRED_VAL(info, getname, obs_register_output);
|
||||
|
@@ -128,7 +128,7 @@ obs_data_t obs_output_defaults(const char *id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obs_properties_t obs_output_properties(const char *id, const char *locale)
|
||||
obs_properties_t obs_get_output_properties(const char *id, const char *locale)
|
||||
{
|
||||
const struct obs_output_info *info = find_output(id);
|
||||
if (info && info->properties)
|
||||
@@ -136,6 +136,13 @@ obs_properties_t obs_output_properties(const char *id, const char *locale)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obs_properties_t obs_output_properties(obs_output_t output, const char *locale)
|
||||
{
|
||||
if (output && output->info.properties)
|
||||
return output->info.properties(locale);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void obs_output_update(obs_output_t output, obs_data_t settings)
|
||||
{
|
||||
if (!output) return;
|
||||
|
@@ -315,7 +315,7 @@ const char *obs_property_description(obs_property_t p)
|
||||
return p ? p->desc : NULL;
|
||||
}
|
||||
|
||||
enum obs_property_type obs_property_type(obs_property_t p)
|
||||
enum obs_property_type obs_property_get_type(obs_property_t p)
|
||||
{
|
||||
return p ? p->type : OBS_PROPERTY_INVALID;
|
||||
}
|
||||
|
@@ -87,7 +87,7 @@ EXPORT void obs_property_list_add_item(obs_property_t p,
|
||||
|
||||
EXPORT const char * obs_property_name(obs_property_t p);
|
||||
EXPORT const char * obs_property_description(obs_property_t p);
|
||||
EXPORT enum obs_property_type obs_property_type(obs_property_t p);
|
||||
EXPORT enum obs_property_type obs_property_get_type(obs_property_t p);
|
||||
|
||||
EXPORT bool obs_property_next(obs_property_t *p);
|
||||
|
||||
|
@@ -327,7 +327,7 @@ obs_data_t obs_source_settings(enum obs_source_type type, const char *id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obs_properties_t obs_source_properties(enum obs_source_type type,
|
||||
obs_properties_t obs_get_source_properties(enum obs_source_type type,
|
||||
const char *id, const char *locale)
|
||||
{
|
||||
const struct obs_source_info *info = get_source_info(type, id);
|
||||
@@ -336,6 +336,13 @@ obs_properties_t obs_source_properties(enum obs_source_type type,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obs_properties_t obs_source_properties(obs_source_t source, const char *locale)
|
||||
{
|
||||
if (source && source->info.properties)
|
||||
return source->info.properties(locale);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t obs_source_get_output_flags(obs_source_t source)
|
||||
{
|
||||
return source ? source->info.output_flags : 0;
|
||||
|
@@ -132,6 +132,12 @@ struct obs_source_info {
|
||||
/** Destroys the private data for the source */
|
||||
void (*destroy)(void *data);
|
||||
|
||||
/** Returns the width of the source. Required if input and video */
|
||||
uint32_t (*getwidth)(void *data);
|
||||
|
||||
/** Returns the height of the source. Required if input and video */
|
||||
uint32_t (*getheight)(void *data);
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
/* Optional implementation */
|
||||
|
||||
@@ -210,12 +216,6 @@ struct obs_source_info {
|
||||
*/
|
||||
void (*video_render)(void *data, effect_t effect);
|
||||
|
||||
/** @return The width of the source */
|
||||
uint32_t (*getwidth)(void *data);
|
||||
|
||||
/** @return The height of the source */
|
||||
uint32_t (*getheight)(void *data);
|
||||
|
||||
/**
|
||||
* Called to filter raw async video data.
|
||||
*
|
||||
|
33
libobs/obs.h
33
libobs/obs.h
@@ -1,5 +1,5 @@
|
||||
/******************************************************************************
|
||||
Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>
|
||||
Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -42,7 +42,7 @@ struct obs_encoder;
|
||||
struct obs_service;
|
||||
|
||||
typedef struct obs_display *obs_display_t;
|
||||
typedef struct obs_view *obs_view_t;
|
||||
typedef struct obs_view *obs_view_t;
|
||||
typedef struct obs_source *obs_source_t;
|
||||
typedef struct obs_scene *obs_scene_t;
|
||||
typedef struct obs_scene_item *obs_sceneitem_t;
|
||||
@@ -438,13 +438,20 @@ EXPORT bool obs_source_removed(obs_source_t source);
|
||||
EXPORT uint32_t obs_source_get_output_flags(obs_source_t source);
|
||||
|
||||
/** Gets the default settings for a source type */
|
||||
EXPORT obs_data_t obs_source_defaults(enum obs_source_type type,
|
||||
EXPORT obs_data_t obs_get_source_defaults(enum obs_source_type type,
|
||||
const char *id);
|
||||
|
||||
/** Returns the property list, if any. Free with obs_properties_destroy */
|
||||
EXPORT obs_properties_t obs_source_properties(enum obs_source_type type,
|
||||
EXPORT obs_properties_t obs_get_source_properties(enum obs_source_type type,
|
||||
const char *id, const char *locale);
|
||||
|
||||
/**
|
||||
* Returns the properties list for a specific existing source. Free with
|
||||
* obs_properties_destroy
|
||||
*/
|
||||
EXPORT obs_properties_t obs_source_properties(obs_source_t source,
|
||||
const char *locale);
|
||||
|
||||
/** Updates settings for this source */
|
||||
EXPORT void obs_source_update(obs_source_t source, obs_data_t settings);
|
||||
|
||||
@@ -662,7 +669,14 @@ EXPORT bool obs_output_active(obs_output_t output);
|
||||
EXPORT obs_data_t obs_output_defaults(const char *id);
|
||||
|
||||
/** Returns the property list, if any. Free with obs_properties_destroy */
|
||||
EXPORT obs_properties_t obs_output_properties(const char *id,
|
||||
EXPORT obs_properties_t obs_get_output_properties(const char *id,
|
||||
const char *locale);
|
||||
|
||||
/**
|
||||
* Returns the property list of an existing output, if any. Free with
|
||||
* obs_properties_destroy
|
||||
*/
|
||||
EXPORT obs_properties_t obs_output_properties(obs_output_t output,
|
||||
const char *locale);
|
||||
|
||||
/** Updates the settings for this output context */
|
||||
@@ -742,7 +756,14 @@ EXPORT void obs_encoder_stop(obs_encoder_t encoder,
|
||||
EXPORT obs_data_t obs_encoder_defaults(const char *id);
|
||||
|
||||
/** Returns the property list, if any. Free with obs_properties_destroy */
|
||||
EXPORT obs_properties_t obs_encoder_properties(const char *id,
|
||||
EXPORT obs_properties_t obs_get_encoder_properties(const char *id,
|
||||
const char *locale);
|
||||
|
||||
/**
|
||||
* Returns the property list of an existing encoder, if any. Free with
|
||||
* obs_properties_destroy
|
||||
*/
|
||||
EXPORT obs_properties_t obs_encoder_properties(obs_encoder_t encoder,
|
||||
const char *locale);
|
||||
|
||||
/**
|
||||
|
@@ -63,10 +63,91 @@ public:
|
||||
};
|
||||
|
||||
using OBSSource = OBSRef<obs_source_t, obs_source_addref, obs_source_release>;
|
||||
using OBSScene = OBSRef<obs_scene_t, obs_scene_addref, obs_scene_release>;
|
||||
using OBSScene = OBSRef<obs_scene_t, obs_scene_addref, obs_scene_release>;
|
||||
using OBSSceneItem = OBSRef<obs_sceneitem_t, obs_sceneitem_addref,
|
||||
obs_sceneitem_release>;
|
||||
|
||||
using OBSData = OBSRef<obs_data_t, obs_data_addref, obs_data_release>;
|
||||
using OBSDataArray = OBSRef<obs_data_array_t, obs_data_array_addref,
|
||||
obs_data_array_release>;
|
||||
|
||||
/* objects that are not meant to be instanced */
|
||||
template<typename T, void destroy(T)> class OBSObj {
|
||||
T obj;
|
||||
|
||||
public:
|
||||
inline OBSObj() : obj(nullptr) {}
|
||||
inline OBSObj(T obj_) : obj(obj_) {}
|
||||
|
||||
inline ~OBSObj() {destroy(obj);}
|
||||
|
||||
inline OBSObj &operator=(T obj_)
|
||||
{
|
||||
if (obj_ != obj)
|
||||
destroy(obj);
|
||||
obj = obj_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline operator T() const {return obj;}
|
||||
|
||||
inline bool operator==(T p) const {return obj == p;}
|
||||
inline bool operator!=(T p) const {return obj != p;}
|
||||
};
|
||||
|
||||
using OBSDisplay = OBSObj<obs_display_t, obs_display_destroy>;
|
||||
using OBSEncoder = OBSObj<obs_encoder_t, obs_encoder_destroy>;
|
||||
using OBSView = OBSObj<obs_view_t, obs_view_destroy>;
|
||||
using OBSOutput = OBSObj<obs_output_t, obs_output_destroy>;
|
||||
|
||||
/* signal handler connection */
|
||||
class OBSSignal {
|
||||
signal_handler_t handler;
|
||||
const char *signal;
|
||||
signal_callback_t callback;
|
||||
void *param;
|
||||
|
||||
public:
|
||||
inline OBSSignal()
|
||||
: handler (nullptr),
|
||||
signal (nullptr),
|
||||
callback (nullptr),
|
||||
param (nullptr)
|
||||
{}
|
||||
|
||||
inline OBSSignal(signal_handler_t handler_,
|
||||
const char *signal_,
|
||||
signal_callback_t callback_,
|
||||
void *param_)
|
||||
: handler (handler_),
|
||||
signal (signal_),
|
||||
callback (callback_),
|
||||
param (param_)
|
||||
{
|
||||
signal_handler_connect(handler, signal, callback, param);
|
||||
}
|
||||
|
||||
inline void Disconnect()
|
||||
{
|
||||
signal_handler_disconnect(handler, signal, callback, param);
|
||||
handler = nullptr;
|
||||
signal = nullptr;
|
||||
callback = nullptr;
|
||||
param = nullptr;
|
||||
}
|
||||
|
||||
inline ~OBSSignal() {Disconnect();}
|
||||
|
||||
inline void Connect(signal_handler_t handler_,
|
||||
const char *signal_,
|
||||
signal_callback_t callback_,
|
||||
void *param_)
|
||||
{
|
||||
Disconnect();
|
||||
|
||||
handler = handler_;
|
||||
signal = signal_;
|
||||
callback = callback_;
|
||||
param = param_;
|
||||
signal_handler_connect(handler, signal, callback, param);
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user