static obs_properties_t *rtmp_stream_properties(void *unused) { UNUSED_PARAMETER(unused); obs_properties_t *props = obs_properties_create(); struct netif_saddr_data addrs = {0}; obs_property_t *p; obs_properties_add_int(props, OPT_DROP_THRESHOLD, obs_module_text("RTMPStream.DropThreshold"), 200, 10000, 100); p = obs_properties_add_list(props, OPT_BIND_IP, obs_module_text("RTMPStream.BindIP"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, obs_module_text("Default"), "default"); netif_get_addrs(&addrs); for (size_t i = 0; i < addrs.addrs.num; i++) { struct netif_saddr_item item = addrs.addrs.array[i]; obs_property_list_add_string(p, item.name, item.addr); } netif_saddr_data_free(&addrs); return props; }
static obs_properties_t *chroma_key_properties(void *data) { obs_properties_t *props = obs_properties_create(); obs_property_t *p = obs_properties_add_list(props, SETTING_COLOR_TYPE, TEXT_COLOR_TYPE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, obs_module_text("Green"), "green"); obs_property_list_add_string(p, obs_module_text("Blue"), "blue"); obs_property_list_add_string(p, obs_module_text("Magenta"), "magenta"); obs_property_list_add_string(p, obs_module_text("Custom"), "custom"); obs_property_set_modified_callback(p, key_type_changed); obs_properties_add_color(props, SETTING_KEY_COLOR, TEXT_KEY_COLOR); obs_properties_add_int_slider(props, SETTING_SIMILARITY, TEXT_SIMILARITY, 1, 1000, 1); obs_properties_add_int_slider(props, SETTING_SMOOTHNESS, TEXT_SMOOTHNESS, 1, 1000, 1); obs_properties_add_int_slider(props, SETTING_SPILL, TEXT_SPILL, 1, 1000, 1); obs_properties_add_int(props, SETTING_OPACITY, TEXT_OPACITY, 0, 100, 1); obs_properties_add_float_slider(props, SETTING_CONTRAST, TEXT_CONTRAST, -1.0, 1.0, 0.01); obs_properties_add_float_slider(props, SETTING_BRIGHTNESS, TEXT_BRIGHTNESS, -1.0, 1.0, 0.01); obs_properties_add_float_slider(props, SETTING_GAMMA, TEXT_GAMMA, -1.0, 1.0, 0.01); UNUSED_PARAMETER(data); return props; }
static void add_service(obs_property_t list, json_t *service) { json_t *servers; const char *name; if (!json_is_object(service)) { blog(LOG_WARNING, "rtmp-common.c: [add_service] service " "is not an object"); return; } name = get_string_val(service, "name"); if (!name) { blog(LOG_WARNING, "rtmp-common.c: [add_service] service " "has no name"); return; } servers = json_object_get(service, "servers"); if (!servers || !json_is_array(servers)) { blog(LOG_WARNING, "rtmp-common.c: [add_service] service " "'%s' has no servers", name); return; } obs_property_list_add_string(list, name, name); }
obs_properties_t XCompcapMain::properties() { obs_properties_t props = obs_properties_create(); obs_property_t wins = obs_properties_add_list(props, "capture_window", obs_module_text("Window"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); for (Window win: XCompcap::getTopLevelWindows()) { std::string wname = XCompcap::getWindowName(win); std::string progpath = XCompcap::getWindowCommand(win); std::string winid = std::to_string((long long)win); std::string desc = (winid + WIN_STRING_DIV + wname + WIN_STRING_DIV + progpath); obs_property_list_add_string(wins, wname.c_str(), desc.c_str()); } obs_properties_add_int(props, "cut_top", obs_module_text("CropTop"), 0, 4096, 1); obs_properties_add_int(props, "cut_left", obs_module_text("CropLeft"), 0, 4096, 1); obs_properties_add_int(props, "cut_right", obs_module_text("CropRight"), 0, 4096, 1); obs_properties_add_int(props, "cut_bot", obs_module_text("CropBottom"), 0, 4096, 1); obs_properties_add_bool(props, "swap_redblue", obs_module_text("SwapRedBlue")); obs_properties_add_bool(props, "lock_x", obs_module_text("LockX")); return props; }
static void add_service(obs_property_t *list, json_t *service, bool show_all, const char *cur_service) { json_t *servers; const char *name; bool common; if (!json_is_object(service)) { blog(LOG_WARNING, "rtmp-common.c: [add_service] service " "is not an object"); return; } name = get_string_val(service, "name"); if (!name) { blog(LOG_WARNING, "rtmp-common.c: [add_service] service " "has no name"); return; } common = get_bool_val(service, "common"); if (!show_all && !common && strcmp(cur_service, name) != 0) { return; } servers = json_object_get(service, "servers"); if (!servers || !json_is_array(servers)) { blog(LOG_WARNING, "rtmp-common.c: [add_service] service " "'%s' has no servers", name); return; } obs_property_list_add_string(list, name, name); }
static inline void add_strings(obs_property_t *list, const char *const *strings) { while (*strings) { obs_property_list_add_string(list, *strings, *strings); strings++; } }
obs_properties_t XCompcapMain::properties() { obs_properties_t props = obs_properties_create(); obs_property_t wins = obs_properties_add_list(props, "capture_window", "Captured Window", OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); for (Window win: XCompcap::getTopLevelWindows()) { std::string wname = XCompcap::getWindowName(win); std::string progpath = XCompcap::getWindowCommand(win); std::string winid = std::to_string((long long)win); std::string desc = (winid + WIN_STRING_DIV + wname + WIN_STRING_DIV + progpath); obs_property_list_add_string(wins, wname.c_str(), desc.c_str()); } obs_properties_add_int(props, "cut_top", "Cut top pixels", 0, 4096, 1); obs_properties_add_int(props, "cut_left", "Cut left pixels", 0, 4096, 1); obs_properties_add_int(props, "cut_right", "Cut right pixels", 0, 4096, 1); obs_properties_add_int(props, "cut_bot", "Cut bottom pixels", 0, 4096, 1); obs_properties_add_bool(props, "swap_redblue", "Swap red and blue"); obs_properties_add_bool(props, "lock_x", "Lock X server when " "capturing"); return props; }
static obs_properties_t *scale_filter_properties(void *data) { obs_properties_t *props = obs_properties_create(); struct obs_video_info ovi; obs_property_t *p; uint32_t cx; uint32_t cy; struct { int cx; int cy; } downscales[NUM_DOWNSCALES]; /* ----------------- */ obs_get_video_info(&ovi); cx = ovi.base_width; cy = ovi.base_height; for (size_t i = 0; i < NUM_DOWNSCALES; i++) { downscales[i].cx = (int)((double)cx / downscale_vals[i]); downscales[i].cy = (int)((double)cy / downscale_vals[i]); } p = obs_properties_add_list(props, S_SAMPLING, T_SAMPLING, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_set_modified_callback(p, sampling_modified); obs_property_list_add_string(p, T_SAMPLING_POINT, S_SAMPLING_POINT); obs_property_list_add_string(p, T_SAMPLING_BILINEAR, S_SAMPLING_BILINEAR); obs_property_list_add_string(p, T_SAMPLING_BICUBIC, S_SAMPLING_BICUBIC); obs_property_list_add_string(p, T_SAMPLING_LANCZOS, S_SAMPLING_LANCZOS); /* ----------------- */ p = obs_properties_add_list(props, S_RESOLUTION, T_RESOLUTION, OBS_COMBO_TYPE_EDITABLE, OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, T_NONE, T_NONE); obs_property_list_add_string(p, T_BASE, T_BASE); for (size_t i = 0; i < NUM_ASPECTS; i++) obs_property_list_add_string(p, aspects[i], aspects[i]); for (size_t i = 0; i < NUM_DOWNSCALES; i++) { char str[32]; snprintf(str, 32, "%dx%d", downscales[i].cx, downscales[i].cy); obs_property_list_add_string(p, str, str); } obs_properties_add_bool(props, S_UNDISTORT, T_UNDISTORT); /* ----------------- */ UNUSED_PARAMETER(data); return props; }
static obs_properties_t *obs_x264_props(void *unused) { UNUSED_PARAMETER(unused); obs_properties_t *props = obs_properties_create(); obs_property_t *list; obs_property_t *p; obs_properties_add_int(props, "bitrate", TEXT_BITRATE, 50, 10000000, 1); p = obs_properties_add_bool(props, "use_bufsize", TEXT_CUSTOM_BUF); obs_property_set_modified_callback(p, use_bufsize_modified); obs_properties_add_int(props, "buffer_size", TEXT_BUF_SIZE, 0, 10000000, 1); obs_properties_add_int(props, "keyint_sec", TEXT_KEYINT_SEC, 0, 20, 1); p = obs_properties_add_bool(props, "cbr", TEXT_USE_CBR); obs_properties_add_int(props, "crf", TEXT_CRF, 0, 51, 1); obs_property_set_modified_callback(p, use_cbr_modified); list = obs_properties_add_list(props, "preset", TEXT_PRESET, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); add_strings(list, x264_preset_names); list = obs_properties_add_list(props, "profile", TEXT_PROFILE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(list, TEXT_NONE, ""); obs_property_list_add_string(list, "baseline", "baseline"); obs_property_list_add_string(list, "main", "main"); obs_property_list_add_string(list, "high", "high"); list = obs_properties_add_list(props, "tune", TEXT_TUNE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(list, TEXT_NONE, ""); add_strings(list, x264_tune_names); obs_properties_add_bool(props, "vfr", TEXT_VFR); obs_properties_add_text(props, "x264opts", TEXT_X264_OPTS, OBS_TEXT_DEFAULT); return props; }
static inline void add_rate_controls(obs_property_t *list, const struct qsv_rate_control_info *rc) { enum qsv_cpu_platform plat = qsv_get_cpu_platform(); while (rc->name) { if (!rc->haswell_or_greater || plat >= QSV_CPU_PLATFORM_HSW) obs_property_list_add_string(list, rc->name, rc->name); rc++; } }
/** * output info callback */ static void pulse_output_info(pa_context *c, const pa_source_info *i, int eol, void *userdata) { UNUSED_PARAMETER(c); if (eol != 0 || i->monitor_of_sink == PA_INVALID_INDEX) goto skip; obs_property_list_add_string((obs_property_t*) userdata, i->description, i->name); skip: pulse_signal(0); }
static void fill_out_devices(obs_property_t *list) { deviceEnum->Lock(); const std::vector<DeckLinkDevice*> &devices = deviceEnum->GetDevices(); for (DeckLinkDevice *device : devices) { obs_property_list_add_string(list, device->GetDisplayName().c_str(), device->GetHash().c_str()); } deviceEnum->Unlock(); }
static obs_properties_t *expander_properties(void *data) { struct expander_data *cd = data; obs_properties_t *props = obs_properties_create(); obs_source_t *parent = NULL; if (cd) parent = obs_filter_get_parent(cd->context); obs_property_t *presets = obs_properties_add_list(props, S_PRESETS, TEXT_PRESETS, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(presets, TEXT_PRESETS_EXP, "expander"); obs_property_list_add_string(presets, TEXT_PRESETS_GATE, "gate"); obs_property_set_modified_callback(presets, presets_changed); obs_properties_add_float_slider(props, S_RATIO, TEXT_RATIO, MIN_RATIO, MAX_RATIO, 0.1); obs_properties_add_float_slider(props, S_THRESHOLD, TEXT_THRESHOLD, MIN_THRESHOLD_DB, MAX_THRESHOLD_DB, 0.1); obs_properties_add_int_slider(props, S_ATTACK_TIME, TEXT_ATTACK_TIME, MIN_ATK_RLS_MS, MAX_ATK_MS, 1); obs_properties_add_int_slider(props, S_RELEASE_TIME, TEXT_RELEASE_TIME, MIN_ATK_RLS_MS, MAX_RLS_MS, 1); obs_properties_add_float_slider(props, S_OUTPUT_GAIN, TEXT_OUTPUT_GAIN, MIN_OUTPUT_GAIN_DB, MAX_OUTPUT_GAIN_DB, 0.1); obs_property_t *detect = obs_properties_add_list(props, S_DETECTOR, TEXT_DETECTOR, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(detect, TEXT_RMS, "RMS"); obs_property_list_add_string(detect, TEXT_PEAK, "peak"); obs_property_list_add_string(detect, TEXT_NONE, "none"); UNUSED_PARAMETER(data); return props; }
obs_properties_t *XCompcapMain::properties() { obs_properties_t *props = obs_properties_create(); obs_property_t *wins = obs_properties_add_list(props, "capture_window", obs_module_text("Window"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); for (Window win: XCompcap::getTopLevelWindows()) { std::string wname = XCompcap::getWindowName(win); std::string cls = XCompcap::getWindowClass(win); std::string winid = std::to_string((long long)win); std::string desc = (winid + WIN_STRING_DIV + wname + WIN_STRING_DIV + cls); obs_property_list_add_string(wins, wname.c_str(), desc.c_str()); } obs_properties_add_int(props, "cut_top", obs_module_text("CropTop"), 0, 4096, 1); obs_properties_add_int(props, "cut_left", obs_module_text("CropLeft"), 0, 4096, 1); obs_properties_add_int(props, "cut_right", obs_module_text("CropRight"), 0, 4096, 1); obs_properties_add_int(props, "cut_bot", obs_module_text("CropBottom"), 0, 4096, 1); obs_properties_add_bool(props, "swap_redblue", obs_module_text("SwapRedBlue")); obs_properties_add_bool(props, "lock_x", obs_module_text("LockX")); obs_properties_add_bool(props, "show_cursor", obs_module_text("CaptureCursor")); obs_properties_add_bool(props, "include_border", obs_module_text("IncludeXBorder")); obs_properties_add_bool(props, "exclude_alpha", obs_module_text("ExcludeAlpha")); return props; }
static obs_properties_t *vaapi_properties(void *unused) { UNUSED_PARAMETER(unused); obs_properties_t *props = obs_properties_create(); obs_property_t * list; list = obs_properties_add_list(props, "vaapi_device", "VAAPI Device", OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); char path[128] = "/dev/dri/renderD1"; for (int i = 28;; i++) { sprintf(path, "/dev/dri/renderD1%d", i); if (access(path, F_OK) == 0) { char card[128] = "Card: "; sprintf(card, "Card%d: %s", i - 28, path); obs_property_list_add_string(list, card, path); } else { break; } } list = obs_properties_add_list(props, "vaapi_codec", "VAAPI Codec", OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_property_list_add_int(list, "H.264 (default)", AV_CODEC_ID_H264); list = obs_properties_add_list(props, "level", "Level", OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); obs_property_list_add_int(list, "480p30 (3.0)", 30); obs_property_list_add_int(list, "720p30/480p60 (3.1)", 31); obs_property_list_add_int( list, "Compatibility mode (4.0 default)", 40); obs_property_list_add_int(list, "720p60/1080p30 (4.1)", 41); obs_property_list_add_int(list, "1080p60 (4.2)", 42); obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"), 0, 300000, 50); obs_properties_add_int(props, "keyint_sec", obs_module_text("Keyframe Interval (seconds)"), 0, 20, 1); return props; }
/* * Source properties callback */ static void pulse_source_info(pa_context *c, const pa_source_info *i, int eol, void *userdata) { UNUSED_PARAMETER(c); if (eol != 0) return; struct pulse_enumerate *e = (struct pulse_enumerate *) userdata; if ((e->input) ^ (i->monitor_of_sink == PA_INVALID_INDEX)) return; blog(LOG_DEBUG, "pulse-input: Got source #%u '%s'", i->index, i->description); obs_property_list_add_string(e->devices, i->description, i->name); pa_threaded_mainloop_signal(e->mainloop, 0); }
/* * List available devices */ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) { DIR *dirp; struct dirent *dp; struct dstr device; bool cur_device_found; size_t cur_device_index; const char *cur_device_name; #ifdef __FreeBSD__ dirp = opendir("/dev"); #else dirp = opendir("/sys/class/video4linux"); #endif if (!dirp) return; cur_device_found = false; cur_device_name = obs_data_get_string(settings, "device_id"); obs_property_list_clear(prop); dstr_init_copy(&device, "/dev/"); while ((dp = readdir(dirp)) != NULL) { int fd; uint32_t caps; struct v4l2_capability video_cap; #ifdef __FreeBSD__ if (strstr(dp->d_name, "video") == NULL) continue; #endif if (dp->d_type == DT_DIR) continue; dstr_resize(&device, 5); dstr_cat(&device, dp->d_name); if ((fd = v4l2_open(device.array, O_RDWR | O_NONBLOCK)) == -1) { blog(LOG_INFO, "Unable to open %s", device.array); continue; } if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &video_cap) == -1) { blog(LOG_INFO, "Failed to query capabilities for %s", device.array); v4l2_close(fd); continue; } #ifndef V4L2_CAP_DEVICE_CAPS caps = video_cap.capabilities; #else /* ... since Linux 3.3 */ caps = (video_cap.capabilities & V4L2_CAP_DEVICE_CAPS) ? video_cap.device_caps : video_cap.capabilities; #endif if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) { blog(LOG_INFO, "%s seems to not support video capture", device.array); v4l2_close(fd); continue; } obs_property_list_add_string(prop, (char *) video_cap.card, device.array); blog(LOG_INFO, "Found device '%s' at %s", video_cap.card, device.array); /* check if this is the currently used device */ if (cur_device_name && !strcmp(cur_device_name, device.array)) cur_device_found = true; v4l2_close(fd); } /* add currently selected device if not present, but disable it ... */ if (!cur_device_found && cur_device_name && strlen(cur_device_name)) { cur_device_index = obs_property_list_add_string(prop, cur_device_name, cur_device_name); obs_property_list_item_disable(prop, cur_device_index, true); } closedir(dirp); dstr_free(&device); }