void obs_register_encoder_s(const struct obs_encoder_info *info, size_t size) { if (find_encoder(info->id)) { encoder_warn("Encoder id '%s' already exists! " "Duplicate library?", info->id); goto error; } #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_encoder_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, obs_register_encoder); CHECK_REQUIRED_VAL_(info, create, obs_register_encoder); CHECK_REQUIRED_VAL_(info, destroy, obs_register_encoder); CHECK_REQUIRED_VAL_(info, encode, obs_register_encoder); if (info->type == OBS_ENCODER_AUDIO) CHECK_REQUIRED_VAL_(info, get_frame_size, obs_register_encoder); #undef CHECK_REQUIRED_VAL_ REGISTER_OBS_DEF(size, obs_encoder_info, obs->encoder_types, info); return; error: HANDLE_ERROR(size, obs_encoder_info, info); }
void obs_register_source_s(const struct obs_source_info *info, size_t size) { struct obs_source_info data = {0}; struct darray *array; if (info->type == OBS_SOURCE_TYPE_INPUT) { array = &obs->input_types.da; } else if (info->type == OBS_SOURCE_TYPE_FILTER) { array = &obs->filter_types.da; } else if (info->type == OBS_SOURCE_TYPE_TRANSITION) { array = &obs->transition_types.da; } else { blog(LOG_ERROR, "Tried to register unknown source type: %u", info->type); goto error; } if (find_source(array, info->id)) { blog(LOG_WARNING, "Source d '%s' already exists! " "Duplicate library?", info->id); goto error; } #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_source_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, 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) != 0 && (info->output_flags & OBS_SOURCE_ASYNC) == 0) { CHECK_REQUIRED_VAL_(info, get_width, obs_register_source); CHECK_REQUIRED_VAL_(info, get_height, obs_register_source); } #undef CHECK_REQUIRED_VAL_ if (size > sizeof(data)) { blog(LOG_ERROR, "Tried to register obs_source_info with size " "%llu which is more than libobs currently " "supports (%llu)", (long long unsigned)size, (long long unsigned)sizeof(data)); goto error; } memcpy(&data, info, size); /* mark audio-only filters as an async filter categorically */ if (data.type == OBS_SOURCE_TYPE_FILTER) { if ((data.output_flags & OBS_SOURCE_VIDEO) == 0) data.output_flags |= OBS_SOURCE_ASYNC; } darray_push_back(sizeof(struct obs_source_info), array, &data); return; error: HANDLE_ERROR(size, obs_source_info, info); }
void obs_regsiter_modal_ui_s(const struct obs_modal_ui *info, size_t size) { #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_modal_ui, info, val, func) CHECK_REQUIRED_VAL_(info, task, obs_regsiter_modal_ui); CHECK_REQUIRED_VAL_(info, target, obs_regsiter_modal_ui); CHECK_REQUIRED_VAL_(info, exec, obs_regsiter_modal_ui); #undef CHECK_REQUIRED_VAL_ REGISTER_OBS_DEF(size, obs_modal_ui, obs->modal_ui_callbacks, info); }
void obs_register_output_s(const struct obs_output_info *info, size_t size) { if (find_output(info->id)) { output_warn("Output id '%s' already exists! " "Duplicate library?", info->id); goto error; } #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_output_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, obs_register_output); CHECK_REQUIRED_VAL_(info, create, obs_register_output); CHECK_REQUIRED_VAL_(info, destroy, obs_register_output); CHECK_REQUIRED_VAL_(info, start, obs_register_output); CHECK_REQUIRED_VAL_(info, stop, obs_register_output); if (info->flags & OBS_OUTPUT_ENCODED) { CHECK_REQUIRED_VAL_(info, encoded_packet, obs_register_output); } else { if (info->flags & OBS_OUTPUT_VIDEO) CHECK_REQUIRED_VAL_(info, raw_video, obs_register_output); if (info->flags & OBS_OUTPUT_AUDIO) CHECK_REQUIRED_VAL_(info, raw_audio, obs_register_output); } #undef CHECK_REQUIRED_VAL_ REGISTER_OBS_DEF(size, obs_output_info, obs->output_types, info); return; error: HANDLE_ERROR(size, obs_output_info, info); }
void obs_regsiter_modeless_ui_s(const struct obs_modeless_ui *info, size_t size) { #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_modeless_ui, info, val, func) CHECK_REQUIRED_VAL_(info, task, obs_regsiter_modeless_ui); CHECK_REQUIRED_VAL_(info, target, obs_regsiter_modeless_ui); CHECK_REQUIRED_VAL_(info, create, obs_regsiter_modeless_ui); #undef CHECK_REQUIRED_VAL_ REGISTER_OBS_DEF(size, obs_modeless_ui, obs->modeless_ui_callbacks, info); return; error: HANDLE_ERROR(size, obs_modeless_ui, info); }
void obs_register_service_s(const struct obs_service_info *info, size_t size) { if (find_service(info->id)) { blog(LOG_WARNING, "Service id '%s' already exists! " "Duplicate library?", info->id); return; } #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_service_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, obs_register_service); CHECK_REQUIRED_VAL_(info, create, obs_register_service); CHECK_REQUIRED_VAL_(info, destroy, obs_register_service); #undef CHECK_REQUIRED_VAL_ REGISTER_OBS_DEF(size, obs_service_info, obs->service_types, info); }
void obs_register_source_s(const struct obs_source_info *info, size_t size) { struct obs_source_info data = {0}; struct darray *array = NULL; if (info->type == OBS_SOURCE_TYPE_INPUT) { array = &obs->input_types.da; } else if (info->type == OBS_SOURCE_TYPE_FILTER) { array = &obs->filter_types.da; } else if (info->type == OBS_SOURCE_TYPE_TRANSITION) { array = &obs->transition_types.da; } else if (info->type != OBS_SOURCE_TYPE_SCENE) { source_warn("Tried to register unknown source type: %u", info->type); goto error; } if (get_source_info(info->id)) { source_warn("Source '%s' already exists! " "Duplicate library?", info->id); goto error; } memcpy(&data, info, size); /* mark audio-only filters as an async filter categorically */ if (data.type == OBS_SOURCE_TYPE_FILTER) { if ((data.output_flags & OBS_SOURCE_VIDEO) == 0) data.output_flags |= OBS_SOURCE_ASYNC; } if (data.type == OBS_SOURCE_TYPE_TRANSITION) { if (data.get_width) source_warn("get_width ignored registering " "transition '%s'", data.id); if (data.get_height) source_warn("get_height ignored registering " "transition '%s'", data.id); data.output_flags |= OBS_SOURCE_COMPOSITE | OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW; } if ((data.output_flags & OBS_SOURCE_COMPOSITE) != 0) { if ((data.output_flags & OBS_SOURCE_AUDIO) != 0) { source_warn("Source '%s': Composite sources " "cannot be audio sources", info->id); goto error; } if ((data.output_flags & OBS_SOURCE_ASYNC) != 0) { source_warn("Source '%s': Composite sources " "cannot be async sources", info->id); goto error; } } #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_source_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, 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_FILTER && info->type != OBS_SOURCE_TYPE_TRANSITION && (info->output_flags & OBS_SOURCE_VIDEO) != 0 && (info->output_flags & OBS_SOURCE_ASYNC) == 0) { CHECK_REQUIRED_VAL_(info, get_width, obs_register_source); CHECK_REQUIRED_VAL_(info, get_height, obs_register_source); } if ((data.output_flags & OBS_SOURCE_COMPOSITE) != 0) { CHECK_REQUIRED_VAL_(info, audio_render, obs_register_source); } #undef CHECK_REQUIRED_VAL_ if (size > sizeof(data)) { source_warn("Tried to register obs_source_info with size " "%llu which is more than libobs currently " "supports (%llu)", (long long unsigned)size, (long long unsigned)sizeof(data)); goto error; } if (array) darray_push_back(sizeof(struct obs_source_info), array, &data); da_push_back(obs->source_types, &data); return; error: HANDLE_ERROR(size, obs_source_info, info); }