コード例 #1
0
ファイル: rtmp-stream.c プロジェクト: Ju2ender/obs-studio
static bool rtmp_stream_start(void *data)
{
	struct rtmp_stream *stream = data;
	obs_service_t *service = obs_output_get_service(stream->output);
	obs_data_t *settings;

	if (!obs_output_can_begin_data_capture(stream->output, 0))
		return false;
	if (!obs_output_initialize_encoders(stream->output, 0))
		return false;

	stream->total_bytes_sent = 0;
	stream->dropped_frames   = 0;

	settings = obs_output_get_settings(stream->output);
	dstr_copy(&stream->path,     obs_service_get_url(service));
	dstr_copy(&stream->key,      obs_service_get_key(service));
	dstr_copy(&stream->username, obs_service_get_username(service));
	dstr_copy(&stream->password, obs_service_get_password(service));
	stream->drop_threshold_usec =
		(int64_t)obs_data_get_int(settings, OPT_DROP_THRESHOLD) * 1000;
	obs_data_release(settings);

	return pthread_create(&stream->connect_thread, NULL, connect_thread,
			stream) == 0;
}
コード例 #2
0
static obs_properties_t *color_grade_filter_properties(void *data)
{
	struct lut_filter_data *s = data;
	struct dstr path = {0};
	const char *slash;

	obs_properties_t *props = obs_properties_create();
	struct dstr filter_str = {0};

	dstr_cat(&filter_str, "(*.png)");

	if (s && s->file && *s->file) {
		dstr_copy(&path, s->file);
	} else {
		dstr_copy(&path, obs_module_file("LUTs"));
		dstr_cat_ch(&path, '/');
	}

	dstr_replace(&path, "\\", "/");
	slash = strrchr(path.array, '/');
	if (slash)
		dstr_resize(&path, slash - path.array + 1);

	obs_properties_add_path(props, SETTING_IMAGE_PATH, TEXT_IMAGE_PATH,
			OBS_PATH_FILE, filter_str.array, path.array);
	obs_properties_add_float_slider(props, SETTING_CLUT_AMOUNT,
			TEXT_AMOUNT, 0, 1, 0.01);

	dstr_free(&filter_str);

	UNUSED_PARAMETER(data);
	return props;
}
コード例 #3
0
static bool init_connect(struct rtmp_stream *stream)
{
	obs_service_t *service;
	obs_data_t *settings;

	if (stopping(stream))
		pthread_join(stream->send_thread, NULL);

	free_packets(stream);

	service = obs_output_get_service(stream->output);
	if (!service)
		return false;

	os_atomic_set_bool(&stream->disconnected, false);
	stream->total_bytes_sent = 0;
	stream->dropped_frames   = 0;
	stream->min_drop_dts_usec= 0;
	stream->min_priority     = 0;

	settings = obs_output_get_settings(stream->output);
	dstr_copy(&stream->path,     obs_service_get_url(service));
	dstr_copy(&stream->key,      obs_service_get_key(service));
	dstr_copy(&stream->username, obs_service_get_username(service));
	dstr_copy(&stream->password, obs_service_get_password(service));
	stream->drop_threshold_usec =
		(int64_t)obs_data_get_int(settings, OPT_DROP_THRESHOLD) * 1000;
	stream->max_shutdown_time_sec =
		(int)obs_data_get_int(settings, OPT_MAX_SHUTDOWN_TIME_SEC);
	obs_data_release(settings);
	return true;
}
コード例 #4
0
ファイル: find-font.c プロジェクト: AlexNe/obs-studio
const char *get_font_path(const char *family, uint16_t size, const char *style,
		uint32_t flags, FT_Long *idx)
{
	const char  *best_path     = NULL;
	double      best_rating    = 0.0;
	struct dstr face_and_style = {0};
	struct dstr style_str      = {0};
	bool        bold           = !!(flags & OBS_FONT_BOLD);
	bool        italic         = !!(flags & OBS_FONT_ITALIC);

	if (!family || !*family)
		return NULL;

	if (style) {
		dstr_copy(&style_str, style);
		dstr_replace(&style_str, "Bold", "");
		dstr_replace(&style_str, "Italic", "");
		dstr_replace(&style_str, "  ", " ");
		dstr_depad(&style_str);
	}

	dstr_copy(&face_and_style, family);
	if (!dstr_is_empty(&style_str)) {
		dstr_cat(&face_and_style, " ");
		dstr_cat_dstr(&face_and_style, &style_str);
	}

	for (size_t i = 0; i < font_list.num; i++) {
		struct font_path_info *info = font_list.array + i;

		double rating = (double)get_rating(info, &face_and_style);
		if (rating < info->face_len)
			continue;

		if (info->is_bitmap) {
			int best_diff = 1000;
			for (size_t j = 0; j < info->num_sizes; j++) {
				int diff = abs(info->sizes[j] - size);
				if (diff < best_diff)
					best_diff = diff;
			}

			rating /= (double)(best_diff + 1.0);
		}

		if (info->bold   == bold)   rating += 1.0;
		if (info->italic == italic) rating += 1.0;

		if (rating > best_rating) {
			best_path   = info->path;
			*idx        = info->index;
			best_rating = rating;
		}
	}

	dstr_free(&style_str);
	dstr_free(&face_and_style);
	return best_path;
}
コード例 #5
0
static bool init_connect(struct rtmp_stream *stream)
{
	obs_service_t *service;
	obs_data_t *settings;
	const char *bind_ip;
	int64_t drop_p;
	int64_t drop_b;

	if (stopping(stream)) {
		pthread_join(stream->send_thread, NULL);
	}

	free_packets(stream);

	service = obs_output_get_service(stream->output);
	if (!service)
		return false;

	os_atomic_set_bool(&stream->disconnected, false);
	stream->total_bytes_sent = 0;
	stream->dropped_frames   = 0;
	stream->min_priority     = 0;

	settings = obs_output_get_settings(stream->output);
	dstr_copy(&stream->path,     obs_service_get_url(service));
	dstr_copy(&stream->key,      obs_service_get_key(service));
	dstr_copy(&stream->username, obs_service_get_username(service));
	dstr_copy(&stream->password, obs_service_get_password(service));
	dstr_depad(&stream->path);
	dstr_depad(&stream->key);
	drop_b = (int64_t)obs_data_get_int(settings, OPT_DROP_THRESHOLD);
	drop_p = (int64_t)obs_data_get_int(settings, OPT_PFRAME_DROP_THRESHOLD);
	stream->max_shutdown_time_sec =
		(int)obs_data_get_int(settings, OPT_MAX_SHUTDOWN_TIME_SEC);

	if (drop_p < (drop_b + 200))
		drop_p = drop_b + 200;

	stream->drop_threshold_usec = 1000 * drop_b;
	stream->pframe_drop_threshold_usec = 1000 * drop_p;

	bind_ip = obs_data_get_string(settings, OPT_BIND_IP);
	dstr_copy(&stream->bind_ip, bind_ip);

	stream->new_socket_loop = obs_data_get_bool(settings,
			OPT_NEWSOCKETLOOP_ENABLED);
	stream->low_latency_mode = obs_data_get_bool(settings,
			OPT_LOWLATENCY_ENABLED);

	obs_data_release(settings);
	return true;
}
コード例 #6
0
ファイル: gl-shaderparser.c プロジェクト: adylim/obs-studio
static void gl_write_main_storage_assign(struct gl_shader_parser *glsp,
		struct shader_var *var, const char *dst, const char *src,
		bool input)
{
	struct shader_struct *st;
	struct dstr dst_copy = {0};
	char ch_left  = input ? '.' : '_';
	char ch_right = input ? '_' : '.';

	if (dst) {
		dstr_copy(&dst_copy, dst);
		dstr_cat_ch(&dst_copy, ch_left);
	} else {
		dstr_copy(&dst_copy, "\t");
	}

	dstr_cat(&dst_copy, var->name);

	st = shader_parser_getstruct(&glsp->parser, var->type);
	if (st) {
		struct dstr src_copy = {0};
		size_t i;

		if (src)
			dstr_copy(&src_copy, src);
		dstr_cat(&src_copy, var->name);
		dstr_cat_ch(&src_copy, ch_right);

		for (i = 0; i < st->vars.num; i++) {
			struct shader_var *st_var = st->vars.array+i;
			gl_write_main_storage_assign(glsp, st_var,
					dst_copy.array, src_copy.array, input);
		}

		dstr_free(&src_copy);
	} else {
		if (!dstr_isempty(&dst_copy))
			dstr_cat_dstr(&glsp->gl_string, &dst_copy);
		dstr_cat(&glsp->gl_string, " = ");
		if (src)
			dstr_cat(&glsp->gl_string, src);
		dstr_cat(&glsp->gl_string, var->name);
		dstr_cat(&glsp->gl_string, ";\n");

		if (!input)
			gl_write_main_interface_assign(glsp, var, src);
	}

	dstr_free(&dst_copy);
}
コード例 #7
0
ファイル: find-font.c プロジェクト: AlexNe/obs-studio
static void add_font_path(FT_Face face,
		FT_Long idx,
		const char *family_in,
		const char *style_in,
		const char *path)
{
	struct dstr face_and_style = {0};
	struct font_path_info info;

	if (!family_in || !path)
		return;

	dstr_copy(&face_and_style, family_in);
	if (face->style_name) {
		struct dstr style = {0};

		dstr_copy(&style, style_in);
		dstr_replace(&style, "Bold", "");
		dstr_replace(&style, "Italic", "");
		dstr_replace(&style, "  ", " ");
		dstr_depad(&style);

		if (!dstr_is_empty(&style)) {
			dstr_cat(&face_and_style, " ");
			dstr_cat_dstr(&face_and_style, &style);
		}

		dstr_free(&style);
	}

	info.face_and_style = face_and_style.array;
	info.full_len       = face_and_style.len;
	info.face_len       = strlen(family_in);

	info.is_bitmap      = !!(face->face_flags  & FT_FACE_FLAG_FIXED_SIZES);
	info.bold           = !!(face->style_flags & FT_STYLE_FLAG_BOLD);
	info.italic         = !!(face->style_flags & FT_STYLE_FLAG_ITALIC);
	info.index          = idx;

	info.path           = bstrdup(path);

	create_bitmap_sizes(&info, face);
	da_push_back(font_list, &info);

	/*blog(LOG_DEBUG, "name: %s\n\tstyle: %s\n\tpath: %s\n",
			family_in,
			style_in,
			path);*/
}
コード例 #8
0
ファイル: image-source.c プロジェクト: Birdboat/obs-studio
static obs_properties_t *image_source_properties(void *data)
{
	struct image_source *s = data;
	struct dstr path = {0};

	obs_properties_t *props = obs_properties_create();

	if (s && s->file && *s->file) {
		const char *slash;

		dstr_copy(&path, s->file);
		dstr_replace(&path, "\\", "/");
		slash = strrchr(path.array, '/');
		if (slash)
			dstr_resize(&path, slash - path.array + 1);
	}

	obs_properties_add_path(props,
			"file", obs_module_text("File"),
			OBS_PATH_FILE, image_filter, path.array);
	obs_properties_add_bool(props,
			"unload", obs_module_text("UnloadWhenNotShowing"));
	dstr_free(&path);

	return props;
}
コード例 #9
0
os_dir_t os_opendir(const char *path)
{
	struct dstr     path_str = {0};
	struct os_dir   *dir     = NULL;
	WIN32_FIND_DATA wfd;
	HANDLE          handle;
	wchar_t         *w_path;

	dstr_copy(&path_str, path);
	dstr_cat(&path_str, "/*.*");

	if (os_utf8_to_wcs_ptr(path_str.array, path_str.len, &w_path) > 0) {
		handle = FindFirstFileW(w_path, &wfd);
		if (handle != INVALID_HANDLE_VALUE) {
			dir         = bzalloc(sizeof(struct os_dir));
			dir->handle = handle;
			dir->first  = true;
			dir->wfd    = wfd;
		}

		bfree(w_path);
	}

	dstr_free(&path_str);

	return dir;
}
コード例 #10
0
ファイル: v4l2-input.c プロジェクト: Bl00drav3n/obs-studio
/*
 * List formats for device
 */
static void v4l2_format_list(int dev, obs_property_t *prop)
{
	struct v4l2_fmtdesc fmt;
	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	fmt.index = 0;
	struct dstr buffer;
	dstr_init(&buffer);

	obs_property_list_clear(prop);

	while (v4l2_ioctl(dev, VIDIOC_ENUM_FMT, &fmt) == 0) {
		dstr_copy(&buffer, (char *) fmt.description);
		if (fmt.flags & V4L2_FMT_FLAG_EMULATED)
			dstr_cat(&buffer, " (Emulated)");

		if (v4l2_to_obs_video_format(fmt.pixelformat)
				!= VIDEO_FORMAT_NONE) {
			obs_property_list_add_int(prop, buffer.array,
					fmt.pixelformat);
			blog(LOG_INFO, "Pixelformat: %s (available)",
			     buffer.array);
		} else {
			blog(LOG_INFO, "Pixelformat: %s (unavailable)",
			     buffer.array);
		}
		fmt.index++;
	}

	dstr_free(&buffer);
}
コード例 #11
0
static bool ffmpeg_mux_start(void *data)
{
	struct ffmpeg_muxer *stream = data;
	obs_data_t *settings;
	struct dstr cmd;
	const char *path;

	if (!obs_output_can_begin_data_capture(stream->output, 0))
		return false;
	if (!obs_output_initialize_encoders(stream->output, 0))
		return false;

	settings = obs_output_get_settings(stream->output);
	path = obs_data_get_string(settings, "path");
	dstr_copy(&stream->path, path);
	dstr_replace(&stream->path, "\"", "\"\"");
	obs_data_release(settings);

	build_command_line(stream, &cmd);
	stream->pipe = os_process_pipe_create(cmd.array, "w");
	dstr_free(&cmd);

	if (!stream->pipe) {
		warn("Failed to create process pipe");
		return false;
	}

	/* write headers and start capture */
	stream->active = true;
	stream->capturing = true;
	obs_output_begin_data_capture(stream->output, 0);

	info("Writing file '%s'...", stream->path.array);
	return true;
}
コード例 #12
0
static bool parse_binary_from_directory(struct dstr *parsed_bin_path,
		const char *bin_path, const char *file)
{
	struct dstr directory = {0};
	bool found = true;

	dstr_copy(&directory, bin_path);
	dstr_replace(&directory, "%module%", file);
	if (dstr_end(&directory) != '/')
		dstr_cat_ch(&directory, '/');

	dstr_copy_dstr(parsed_bin_path, &directory);
	dstr_cat(parsed_bin_path, file);
	dstr_cat(parsed_bin_path, get_module_extension());

	if (!os_file_exists(parsed_bin_path->array)) {
		/* if the file doesn't exist, check with 'lib' prefix */
		dstr_copy_dstr(parsed_bin_path, &directory);
		dstr_cat(parsed_bin_path, "lib");
		dstr_cat(parsed_bin_path, file);
		dstr_cat(parsed_bin_path, get_module_extension());

		/* if neither exist, don't include this as a library */
		if (!os_file_exists(parsed_bin_path->array)) {
			dstr_free(parsed_bin_path);
			found = false;
		}
	}

	dstr_free(&directory);
	return found;
}
コード例 #13
0
static bool flv_output_start(void *data)
{
	struct flv_output *stream = data;
	obs_data_t *settings;
	const char *path;

	if (!obs_output_can_begin_data_capture(stream->output, 0))
		return false;
	if (!obs_output_initialize_encoders(stream->output, 0))
		return false;

	/* get path */
	settings = obs_output_get_settings(stream->output);
	path = obs_data_get_string(settings, "path");
	dstr_copy(&stream->path, path);
	obs_data_release(settings);

	stream->file = os_fopen(stream->path.array, "wb");
	if (!stream->file) {
		warn("Unable to open FLV file '%s'", stream->path.array);
		return false;
	}

	/* write headers and start capture */
	stream->active = true;
	obs_output_begin_data_capture(stream->output, 0);

	info("Writing FLV file '%s'...", stream->path.array);
	return true;
}
コード例 #14
0
ファイル: obs-source.c プロジェクト: BraginWoW/obs-studio
/* internal initialization */
bool obs_source_init(struct obs_source *source, const char *settings,
                     const struct source_info *info)
{
    uint32_t flags = info->get_output_flags(source->data);

    source->refs = 1;
    source->volume = 1.0f;
    pthread_mutex_init_value(&source->filter_mutex);
    pthread_mutex_init_value(&source->video_mutex);
    pthread_mutex_init_value(&source->audio_mutex);
    dstr_copy(&source->settings, settings);
    memcpy(&source->callbacks, info, sizeof(struct source_info));

    if (pthread_mutex_init(&source->filter_mutex, NULL) != 0)
        return false;
    if (pthread_mutex_init(&source->audio_mutex, NULL) != 0)
        return false;
    if (pthread_mutex_init(&source->video_mutex, NULL) != 0)
        return false;

    if (flags & SOURCE_AUDIO) {
        source->audio_line = audio_output_createline(obs->audio.audio,
                             source->name);
        if (!source->audio_line) {
            blog(LOG_ERROR, "Failed to create audio line for "
                 "source '%s'", source->name);
            return false;
        }
    }

    return true;
}
コード例 #15
0
static inline void make_data_dir(struct dstr *parsed_data_dir,
		const char *data_dir, const char *name)
{
	dstr_copy(parsed_data_dir, data_dir);
	dstr_replace(parsed_data_dir, "%module%", name);
	if (dstr_end(parsed_data_dir) == '/')
		dstr_resize(parsed_data_dir, parsed_data_dir->len - 1);
}
コード例 #16
0
ファイル: window-helpers.c プロジェクト: AmesianX/obs-studio
static inline char *decode_str(const char *src)
{
	struct dstr str = {0};
	dstr_copy(&str, src);
	dstr_replace(&str, "#3A", ":");
	dstr_replace(&str, "#22", "#");
	return str.array;
}
コード例 #17
0
lookup_t *obs_module_load_locale(obs_module_t *module,
		const char *default_locale, const char *locale)
{
	struct dstr str    = {0};
	lookup_t    *lookup = NULL;

	if (!module || !default_locale || !locale) {
		blog(LOG_WARNING, "obs_module_load_locale: Invalid parameters");
		return NULL;
	}

	dstr_copy(&str, "locale/");
	dstr_cat(&str, default_locale);
	dstr_cat(&str, ".ini");

	char *file = obs_find_module_file(module, str.array);
	if (file)
		lookup = text_lookup_create(file);

	bfree(file);

	if (!lookup) {
		blog(LOG_WARNING, "Failed to load '%s' text for module: '%s'",
				default_locale, module->file);
		goto cleanup;
	}

	if (astrcmpi(locale, default_locale) == 0)
		goto cleanup;

	dstr_copy(&str, "/locale/");
	dstr_cat(&str, locale);
	dstr_cat(&str, ".ini");

	file = obs_find_module_file(module, str.array);

	if (!text_lookup_add(lookup, file))
		blog(LOG_WARNING, "Failed to load '%s' text for module: '%s'",
				locale, module->file);

	bfree(file);
cleanup:
	dstr_free(&str);
	return lookup;
}
コード例 #18
0
bool os_quick_write_utf8_file_safe(const char *path, const char *str,
		size_t len, bool marker, const char *temp_ext,
		const char *backup_ext)
{
	struct dstr backup_path = {0};
	struct dstr temp_path = {0};
	bool success = false;

	if (!temp_ext || !*temp_ext) {
		blog(LOG_ERROR, "os_quick_write_utf8_file_safe: invalid "
		                "temporary extension specified");
		return false;
	}

	dstr_copy(&temp_path, path);
	if (*temp_ext != '.')
		dstr_cat(&temp_path, ".");
	dstr_cat(&temp_path, temp_ext);

	if (!os_quick_write_utf8_file(temp_path.array, str, len, marker)) {
		goto cleanup;
	}

	if (backup_ext && *backup_ext) {
		dstr_copy(&backup_path, path);
		if (*backup_ext != '.')
			dstr_cat(&backup_path, ".");
		dstr_cat(&backup_path, backup_ext);

		os_unlink(backup_path.array);
		os_rename(path, backup_path.array);

		dstr_free(&backup_path);
	} else {
		os_unlink(path);
	}

	os_rename(temp_path.array, path);
	success = true;

cleanup:
	dstr_free(&backup_path);
	dstr_free(&temp_path);
	return success;
}
コード例 #19
0
ファイル: config-file.c プロジェクト: Bl00drav3n/obs-studio
int config_save(config_t *config)
{
	FILE *f;
	struct dstr str, tmp;
	size_t i, j;

	if (!config)
		return CONFIG_ERROR;
	if (!config->file)
		return CONFIG_ERROR;

	dstr_init(&str);
	dstr_init(&tmp);

	f = os_fopen(config->file, "wb");
	if (!f)
		return CONFIG_FILENOTFOUND;

	for (i = 0; i < config->sections.num; i++) {
		struct config_section *section = darray_item(
				sizeof(struct config_section),
				&config->sections, i);

		if (i) dstr_cat(&str, "\n");

		dstr_cat(&str, "[");
		dstr_cat(&str, section->name);
		dstr_cat(&str, "]\n");

		for (j = 0; j < section->items.num; j++) {
			struct config_item *item = darray_item(
					sizeof(struct config_item),
					&section->items, j);

			dstr_copy(&tmp, item->value ? item->value : "");
			dstr_replace(&tmp, "\\", "\\\\");
			dstr_replace(&tmp, "\r", "\\r");
			dstr_replace(&tmp, "\n", "\\n");

			dstr_cat(&str, item->name);
			dstr_cat(&str, "=");
			dstr_cat(&str, tmp.array);
			dstr_cat(&str, "\n");
		}
	}

#ifdef _WIN32
	fwrite("\xEF\xBB\xBF", 1, 3, f);
#endif
	fwrite(str.array, 1, str.len, f);
	fclose(f);

	dstr_free(&tmp);
	dstr_free(&str);

	return CONFIG_SUCCESS;
}
コード例 #20
0
ファイル: obs-windows.c プロジェクト: Arkkis/obs-studio
static inline bool check_path(const char* data, const char *path,
		struct dstr * output)
{
	dstr_copy(output, path);
	dstr_cat(output, data);

	blog(LOG_DEBUG, "Attempting path: %s\n", output->array);

	return os_file_exists(output->array);
}
コード例 #21
0
static inline void init_cpu_info(struct exception_handler_data *data)
{
	HKEY key;
	LSTATUS status;

	status = RegOpenKeyW(HKEY_LOCAL_MACHINE, PROCESSOR_REG_KEY, &key);
	if (status == ERROR_SUCCESS) {
		wchar_t str[1024];
		DWORD size = 1024;

		status = RegQueryValueExW(key, L"ProcessorNameString", NULL,
				NULL, (LPBYTE)str, &size);
		if (status == ERROR_SUCCESS)
			dstr_from_wcs(&data->cpu_info, str);
		else
			dstr_copy(&data->cpu_info, CPU_ERROR);
	} else {
		dstr_copy(&data->cpu_info, CPU_ERROR);
	}
}
コード例 #22
0
static void process_found_module(struct obs_module_path *omp,
		const char *path, bool directory,
		obs_find_module_callback_t callback, void *param)
{
	struct obs_module_info info;
	struct dstr            name = {0};
	struct dstr            parsed_bin_path = {0};
	const char             *file;
	char                   *parsed_data_dir;
	bool                   bin_found = true;

	file = strrchr(path, '/');
	file = file ? (file + 1) : path;

	if (strcmp(file, ".") == 0 || strcmp(file, "..") == 0)
		return;

	dstr_copy(&name, file);
	if (!directory) {
		char *ext = strrchr(name.array, '.');
		if (ext)
			dstr_resize(&name, ext - name.array);

		dstr_copy(&parsed_bin_path, path);
	} else {
		bin_found = parse_binary_from_directory(&parsed_bin_path,
				omp->bin, file);
	}

	parsed_data_dir = make_data_directory(name.array, omp->data);

	if (parsed_data_dir && bin_found) {
		info.bin_path  = parsed_bin_path.array;
		info.data_path = parsed_data_dir;
		callback(param, &info);
	}

	bfree(parsed_data_dir);
	dstr_free(&name);
	dstr_free(&parsed_bin_path);
}
コード例 #23
0
static char *get_path(const char *dir, const char *file)
{
	struct dstr str = {0};

	dstr_copy(&str, dir);

	if (str.array && dstr_end(&str) != '/' && dstr_end(&str) != '\\')
		dstr_cat_ch(&str, '/');

	dstr_cat(&str, file);
	return str.array;
}
コード例 #24
0
char *obs_module_get_config_path(obs_module_t *module, const char *file)
{
	struct dstr output = {0};

	dstr_copy(&output, obs->module_config_path);
	if (!dstr_is_empty(&output) && dstr_end(&output) != '/')
		dstr_cat_ch(&output, '/');
	dstr_cat(&output, module->mod_name);
	dstr_cat_ch(&output, '/');
	dstr_cat(&output, file);

	return output.array;
}
コード例 #25
0
static bool init_update(struct update_info *info)
{
	struct dstr user_agent = {0};

	info->curl = curl_easy_init();
	if (!info->curl) {
		warn("Could not initialize Curl");
		return false;
	}

	info->local_package = get_package(info->local, "package.json");
	info->cache_package = get_package(info->cache, "package.json");

	obs_data_t *metadata = get_package(info->cache, "meta.json");
	if (metadata) {
		const char *etag = obs_data_get_string(metadata, "etag");
		if (etag) {
			struct dstr if_none_match = { 0 };
			dstr_copy(&if_none_match, "If-None-Match: ");
			dstr_cat(&if_none_match, etag);

			info->etag_local = bstrdup(etag);

			info->header = curl_slist_append(info->header,
				if_none_match.array);
		}

		obs_data_release(metadata);
	}

	dstr_copy(&user_agent, "User-Agent: ");
	dstr_cat(&user_agent, info->user_agent);

	info->header = curl_slist_append(info->header, user_agent.array);

	dstr_free(&user_agent);
	return true;
}
コード例 #26
0
ファイル: monitor-capture.c プロジェクト: Arkkis/obs-studio
static inline void do_log(int level, const char *msg, ...)
{
	va_list args;
	struct dstr str = {0};

	va_start(args, msg);

	dstr_copy(&str, "[GDI monitor capture]: ");
	dstr_vcatf(&str, msg, args);
	blog(level, "%s", str.array);
	dstr_free(&str);

	va_end(args);
}
コード例 #27
0
ファイル: dstr.c プロジェクト: ootz90/obs-studio
void dstr_safe_printf(struct dstr *dst, const char *format,
		const char *val1, const char *val2, const char *val3,
		const char *val4)
{
	dstr_copy(dst, format);
	if (val1)
		dstr_replace(dst, "$1", val1);
	if (val2)
		dstr_replace(dst, "$2", val2);
	if (val3)
		dstr_replace(dst, "$3", val3);
	if (val4)
		dstr_replace(dst, "$4", val4);
}
コード例 #28
0
static inline char *get_module_name(const char *file)
{
	static size_t ext_len = 0;
	struct dstr name = {0};

	if (ext_len == 0) {
		const char *ext = get_module_extension();
		ext_len = strlen(ext);
	}

	dstr_copy(&name, file);
	dstr_resize(&name, name.len - ext_len);
	return name.array;
}
コード例 #29
0
update_info_t *update_info_create(
		const char *log_prefix,
		const char *user_agent,
		const char *update_url,
		const char *local_dir,
		const char *cache_dir,
		confirm_file_callback_t confirm_callback,
		void *param)
{
	struct update_info *info;
	struct dstr dir = {0};

	if (!log_prefix)
		log_prefix = "";

	if (os_mkdir(cache_dir) < 0) {
		blog(LOG_WARNING, "%sCould not create cache directory %s",
				log_prefix, cache_dir);
		return NULL;
	}

	dstr_copy(&dir, cache_dir);
	if (dstr_end(&dir) != '/' && dstr_end(&dir) != '\\')
		dstr_cat_ch(&dir, '/');
	dstr_cat(&dir, ".temp");

	if (os_mkdir(dir.array) < 0) {
		blog(LOG_WARNING, "%sCould not create temp directory %s",
				log_prefix, cache_dir);
		dstr_free(&dir);
		return NULL;
	}

	info = bzalloc(sizeof(*info));
	info->log_prefix = bstrdup(log_prefix);
	info->user_agent = bstrdup(user_agent);
	info->temp = dir.array;
	info->local = bstrdup(local_dir);
	info->cache = bstrdup(cache_dir);
	info->url = get_path(update_url, "package.json");
	info->callback = confirm_callback;
	info->param = param;

	if (pthread_create(&info->thread, NULL, update_thread, info) == 0)
		info->thread_created = true;

	return info;
}
コード例 #30
0
bool load_graphics_offsets(bool is32bit)
{
	char *offset_exe_path = NULL;
	struct dstr offset_exe = {0};
	char *config_ini = NULL;
	struct dstr str = {0};
	os_process_pipe_t *pp;
	bool success = false;
	char data[128];

	dstr_copy(&offset_exe, "get-graphics-offsets");
	dstr_cat(&offset_exe, is32bit ? "32.exe" : "64.exe");
	offset_exe_path = obs_module_file(offset_exe.array);

	pp = os_process_pipe_create(offset_exe_path, "r");
	if (!pp) {
		blog(LOG_INFO, "load_graphics_offsets: Failed to start '%s'",
				offset_exe.array);
		goto error;
	}

	for (;;) {
		size_t len = os_process_pipe_read(pp, (uint8_t*)data, 128);
		if (!len)
			break;

		dstr_ncat(&str, data, len);
	}

	config_ini = obs_module_config_path(is32bit ? "32.ini" : "64.ini");
	os_quick_write_utf8_file_safe(config_ini, str.array, str.len, false,
			"tmp", NULL);
	bfree(config_ini);

	success = load_offsets_from_string(is32bit ? &offsets32 : &offsets64,
			str.array);
	if (!success) {
		blog(LOG_INFO, "load_graphics_offsets: Failed to load string");
	}

	os_process_pipe_destroy(pp);

error:
	bfree(offset_exe_path);
	dstr_free(&offset_exe);
	dstr_free(&str);
	return success;
}