コード例 #1
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;
}
コード例 #2
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;
}
コード例 #3
0
static struct text_node *text_node_bychar(struct text_node *node, char ch)
{
	struct text_node *subnode = node->first_subnode;

	while (subnode) {
		if (!dstr_is_empty(&subnode->str) &&
		    subnode->str.array[0] == ch)
			return subnode;

		subnode = subnode->next;
	}

	return NULL;
}
コード例 #4
0
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_is_empty(&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);
}
コード例 #5
0
ファイル: effect-parser.c プロジェクト: Dead133/obs-studio
/* writes mapped vars used by the call as parameters for main */
static void ep_write_main_params(struct effect_parser *ep,
		struct dstr *shader, struct dstr *param_str,
		struct ep_func *func)
{
	size_t i;
	bool empty_params = dstr_is_empty(param_str);

	for (i = 0; i < func->param_vars.num; i++) {
		struct ep_var *var = func->param_vars.array+i;
		struct ep_struct *st = NULL;
		bool mapped = (var->mapping != NULL);

		if (!mapped) {
			st = ep_getstruct(ep, var->type);
			if (st)
				mapped = ep_struct_mapped(st);
		}

		if (mapped) {
			dstr_cat(shader, var->type);
			dstr_cat(shader, " ");
			dstr_cat(shader, var->name);

			if (!st) {
				dstr_cat(shader, " : ");
				dstr_cat(shader, var->mapping);
			}

			if (!dstr_is_empty(param_str))
				dstr_cat(param_str, ", ");
			dstr_cat(param_str, var->name);
		}
	}

	if (!empty_params)
		dstr_cat(param_str, ", ");
}
コード例 #6
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);*/
}
コード例 #7
0
ファイル: rtmp-stream.c プロジェクト: ytmarc/obs-studio
static int try_connect(struct rtmp_stream *stream)
{
    if (dstr_is_empty(&stream->path)) {
        warn("URL is empty");
        return OBS_OUTPUT_BAD_PATH;
    }

    info("Connecting to RTMP URL %s...", stream->path.array);

    memset(&stream->rtmp.Link, 0, sizeof(stream->rtmp.Link));
    if (!RTMP_SetupURL(&stream->rtmp, stream->path.array))
        return OBS_OUTPUT_BAD_PATH;

    RTMP_EnableWrite(&stream->rtmp);

    set_rtmp_dstr(&stream->rtmp.Link.pubUser,   &stream->username);
    set_rtmp_dstr(&stream->rtmp.Link.pubPasswd, &stream->password);
    stream->rtmp.Link.swfUrl = stream->rtmp.Link.tcUrl;
    set_rtmp_str(&stream->rtmp.Link.flashVer,
                 "FMLE/3.0 (compatible; OBS Studio; FMSc/1.0)");

    RTMP_AddStream(&stream->rtmp, stream->key.array);

    for (size_t idx = 1;; idx++) {
        obs_encoder_t *encoder = obs_output_get_audio_encoder(
                                     stream->output, idx);
        const char *encoder_name;

        if (!encoder)
            break;

        encoder_name = obs_encoder_get_name(encoder);
        RTMP_AddStream(&stream->rtmp, encoder_name);
    }

    stream->rtmp.m_outChunkSize       = 4096;
    stream->rtmp.m_bSendChunkSizeInfo = true;
    stream->rtmp.m_bUseNagle          = true;

    if (!RTMP_Connect(&stream->rtmp, NULL))
        return OBS_OUTPUT_CONNECT_FAILED;
    if (!RTMP_ConnectStream(&stream->rtmp, 0))
        return OBS_OUTPUT_INVALID_STREAM;

    info("Connection to %s successful", stream->path.array);

    return init_send(stream);
}
コード例 #8
0
ファイル: obs-module.c プロジェクト: keyanmca/obs-studio
char *obs_find_module_file(obs_module_t module, const char *file)
{
    struct dstr output = {0};

    if (!module)
        return NULL;

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

    if (!os_file_exists(output.array))
        dstr_free(&output);
    return output.array;
}
コード例 #9
0
ファイル: dstr.c プロジェクト: AmoghSubhedar/obs-studio
void dstr_to_lower(struct dstr *str)
{
	wchar_t *wstr;
	wchar_t *temp;

	if (dstr_is_empty(str))
		return;

	wstr = dstr_to_wcs(str);
	temp = wstr;

	if (!wstr)
		return;

	while (*temp) {
		*temp = (wchar_t)towlower(*temp);
		temp++;
	}

	dstr_from_wcs(str, wstr);
	bfree(wstr);
}
コード例 #10
0
static void find_modules_in_path(struct obs_module_path *omp,
		obs_find_module_callback_t callback, void *param)
{
	struct dstr search_path = {0};
	char *module_start;
	bool search_directories = false;
	os_glob_t *gi;

	dstr_copy(&search_path, omp->bin);

	module_start = strstr(search_path.array, "%module%");
	if (module_start) {
		dstr_resize(&search_path, module_start - search_path.array);
		search_directories = true;
	}

	if (!dstr_is_empty(&search_path) && dstr_end(&search_path) != '/')
		dstr_cat_ch(&search_path, '/');

	dstr_cat_ch(&search_path, '*');
	if (!search_directories)
		dstr_cat(&search_path, get_module_extension());

	if (os_glob(search_path.array, 0, &gi) == 0) {
		for (size_t i = 0; i < gi->gl_pathc; i++) {
			if (search_directories == gi->gl_pathv[i].directory)
				process_found_module(omp,
						gi->gl_pathv[i].path,
						search_directories,
						callback, param);
		}

		os_globfree(gi);
	}

	dstr_free(&search_path);
}
コード例 #11
0
static int try_connect(struct rtmp_stream *stream)
{
	if (dstr_is_empty(&stream->path)) {
		warn("URL is empty");
		return OBS_OUTPUT_BAD_PATH;
	}

	info("Connecting to RTMP URL %s...", stream->path.array);

	memset(&stream->rtmp.Link, 0, sizeof(stream->rtmp.Link));
	if (!RTMP_SetupURL(&stream->rtmp, stream->path.array))
		return OBS_OUTPUT_BAD_PATH;

	RTMP_EnableWrite(&stream->rtmp);

	dstr_copy(&stream->encoder_name, "FMLE/3.0 (compatible; obs-studio/");

#ifdef HAVE_OBSCONFIG_H
	dstr_cat(&stream->encoder_name, OBS_VERSION);
#else
	dstr_catf(&stream->encoder_name, "%d.%d.%d",
			LIBOBS_API_MAJOR_VER,
			LIBOBS_API_MINOR_VER,
			LIBOBS_API_PATCH_VER);
#endif

	dstr_cat(&stream->encoder_name, "; FMSc/1.0)");

	set_rtmp_dstr(&stream->rtmp.Link.pubUser,   &stream->username);
	set_rtmp_dstr(&stream->rtmp.Link.pubPasswd, &stream->password);
	set_rtmp_dstr(&stream->rtmp.Link.flashVer,  &stream->encoder_name);
	stream->rtmp.Link.swfUrl = stream->rtmp.Link.tcUrl;

	RTMP_AddStream(&stream->rtmp, stream->key.array);

	for (size_t idx = 1;; idx++) {
		obs_encoder_t *encoder = obs_output_get_audio_encoder(
				stream->output, idx);
		const char *encoder_name;

		if (!encoder)
			break;

		encoder_name = obs_encoder_get_name(encoder);
		RTMP_AddStream(&stream->rtmp, encoder_name);
	}

	stream->rtmp.m_outChunkSize       = 4096;
	stream->rtmp.m_bSendChunkSizeInfo = true;
	stream->rtmp.m_bUseNagle          = true;

#ifdef _WIN32
	win32_log_interface_type(stream);
#endif

	if (!RTMP_Connect(&stream->rtmp, NULL))
		return OBS_OUTPUT_CONNECT_FAILED;
	if (!RTMP_ConnectStream(&stream->rtmp, 0))
		return OBS_OUTPUT_INVALID_STREAM;

	info("Connection to %s successful", stream->path.array);

	return init_send(stream);
}
コード例 #12
0
static inline void set_rtmp_dstr(AVal *val, struct dstr *str)
{
	bool valid  = !dstr_is_empty(str);
	val->av_val = valid ? str->array    : NULL;
	val->av_len = valid ? (int)str->len : 0;
}
コード例 #13
0
ファイル: dstr.c プロジェクト: AmoghSubhedar/obs-studio
void dstr_replace(struct dstr *str, const char *find,
		const char *replace)
{
	size_t find_len, replace_len;
	char *temp;

	if (dstr_is_empty(str))
		return;

	if (!replace)
		replace = "";

	find_len    = strlen(find);
	replace_len = strlen(replace);
	temp = str->array;

	if (replace_len < find_len) {
		unsigned long count = 0;

		while ((temp = strstr(temp, find)) != NULL) {
			char *end = temp+find_len;
			size_t end_len = strlen(end);

			if (end_len) {
				memmove(temp+replace_len, end, end_len + 1);
				if (replace_len)
					memcpy(temp, replace, replace_len);
			} else {
				strcpy(temp, replace);
			}

			temp += replace_len;
			++count;
		}

		if (count)
			str->len += (replace_len-find_len) * count;

	} else if (replace_len > find_len) {
		unsigned long count = 0;

		while ((temp = strstr(temp, find)) != NULL) {
			temp += find_len;
			++count;
		}

		if (!count)
			return;

		str->len += (replace_len-find_len) * count;
		dstr_ensure_capacity(str, str->len + 1);
		temp = str->array;

		while ((temp = strstr(temp, find)) != NULL) {
			char *end   = temp+find_len;
			size_t end_len = strlen(end);

			if (end_len) {
				memmove(temp+replace_len, end, end_len + 1);
				memcpy(temp, replace, replace_len);
			} else {
				strcpy(temp, replace);
			}

			temp += replace_len;
		}

	} else {
		while ((temp = strstr(temp, find)) != NULL) {
			memcpy(temp, replace, replace_len);
			temp += replace_len;
		}
	}
}
コード例 #14
0
ファイル: rtmp-stream.c プロジェクト: Eegee/obs-studio
static int try_connect(struct rtmp_stream *stream)
{
	if (dstr_is_empty(&stream->path)) {
		warn("URL is empty");
		return OBS_OUTPUT_BAD_PATH;
	}

	info("Connecting to RTMP URL %s...", stream->path.array);

	memset(&stream->rtmp.Link, 0, sizeof(stream->rtmp.Link));
	if (!RTMP_SetupURL(&stream->rtmp, stream->path.array))
		return OBS_OUTPUT_BAD_PATH;

	RTMP_EnableWrite(&stream->rtmp);

	dstr_copy(&stream->encoder_name, "FMLE/3.0 (compatible; FMSc/1.0)");

	set_rtmp_dstr(&stream->rtmp.Link.pubUser,   &stream->username);
	set_rtmp_dstr(&stream->rtmp.Link.pubPasswd, &stream->password);
	set_rtmp_dstr(&stream->rtmp.Link.flashVer,  &stream->encoder_name);
	stream->rtmp.Link.swfUrl = stream->rtmp.Link.tcUrl;

	if (dstr_is_empty(&stream->bind_ip) ||
	    dstr_cmp(&stream->bind_ip, "default") == 0) {
		memset(&stream->rtmp.m_bindIP, 0, sizeof(stream->rtmp.m_bindIP));
	} else {
		bool success = netif_str_to_addr(&stream->rtmp.m_bindIP.addr,
				&stream->rtmp.m_bindIP.addrLen,
				stream->bind_ip.array);
		if (success)
			info("Binding to IP");
	}

	RTMP_AddStream(&stream->rtmp, stream->key.array);

	for (size_t idx = 1;; idx++) {
		obs_encoder_t *encoder = obs_output_get_audio_encoder(
				stream->output, idx);
		const char *encoder_name;

		if (!encoder)
			break;

		encoder_name = obs_encoder_get_name(encoder);
		RTMP_AddStream(&stream->rtmp, encoder_name);
	}

	stream->rtmp.m_outChunkSize       = 4096;
	stream->rtmp.m_bSendChunkSizeInfo = true;
	stream->rtmp.m_bUseNagle          = true;

#ifdef _WIN32
	win32_log_interface_type(stream);
#endif

	if (!RTMP_Connect(&stream->rtmp, NULL))
		return OBS_OUTPUT_CONNECT_FAILED;
	if (!RTMP_ConnectStream(&stream->rtmp, 0))
		return OBS_OUTPUT_INVALID_STREAM;

	info("Connection to %s successful", stream->path.array);

	return init_send(stream);
}