Пример #1
0
static bool sampling_modified(obs_properties_t *props, obs_property_t *p,
	obs_data_t *settings)
{
	const char *sampling = obs_data_get_string(settings, S_SAMPLING);

	bool has_undistort;
	if (astrcmpi(sampling, S_SAMPLING_POINT) == 0) {
		has_undistort = false;

	}
	else if (astrcmpi(sampling, S_SAMPLING_BILINEAR) == 0) {
		has_undistort = false;

	}
	else if (astrcmpi(sampling, S_SAMPLING_LANCZOS) == 0) {
		has_undistort = true;

	}
	else { /* S_SAMPLING_BICUBIC */
		has_undistort = true;
	}

	obs_property_set_visible(obs_properties_get(props, S_UNDISTORT), has_undistort);

	UNUSED_PARAMETER(p);
	return true;
}
Пример #2
0
enum gs_sample_filter get_sample_filter(const char *filter)
{
	if (astrcmpi(filter, "Anisotropy") == 0)
		return GS_FILTER_ANISOTROPIC;

	else if (astrcmpi(filter, "Point")           == 0 ||
	         strcmp(filter, "MIN_MAG_MIP_POINT") == 0)
		return GS_FILTER_POINT;

	else if (astrcmpi(filter, "Linear")           == 0 ||
	         strcmp(filter, "MIN_MAG_MIP_LINEAR") == 0)
		return GS_FILTER_LINEAR;

	else if (strcmp(filter, "MIN_MAG_POINT_MIP_LINEAR") == 0)
		return GS_FILTER_MIN_MAG_POINT_MIP_LINEAR;

	else if (strcmp(filter, "MIN_POINT_MAG_LINEAR_MIP_POINT") == 0)
		return GS_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;

	else if (strcmp(filter, "MIN_POINT_MAG_MIP_LINEAR") == 0)
		return GS_FILTER_MIN_POINT_MAG_MIP_LINEAR;

	else if (strcmp(filter, "MIN_LINEAR_MAG_MIP_POINT") == 0)
		return GS_FILTER_MIN_LINEAR_MAG_MIP_POINT;

	else if (strcmp(filter, "MIN_LINEAR_MAG_POINT_MIP_LINEAR") == 0)
		return GS_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;

	else if (strcmp(filter, "MIN_MAG_LINEAR_MIP_POINT") == 0)
		return GS_FILTER_MIN_MAG_LINEAR_MIP_POINT;

	return GS_FILTER_LINEAR;
}
Пример #3
0
static void override_base_param(struct obs_x264 *obsx264, const char *param,
		char **preset, char **profile, char **tune)
{
	char       *name;
	const char *val;

	if (getparam(param, &name, &val)) {
		if (astrcmpi(name, "preset") == 0) {
			const char *valid_name = validate(obsx264, val,
					"preset", x264_preset_names);
			if (valid_name) {
				bfree(*preset);
				*preset = bstrdup(val);
			}

		} else if (astrcmpi(name, "profile") == 0) {
			const char *valid_name = validate(obsx264, val,
					"profile", x264_profile_names);
			if (valid_name) {
				bfree(*profile);
				*profile = bstrdup(val);
			}

		} else if (astrcmpi(name, "tune") == 0) {
			const char *valid_name = validate(obsx264, val,
					"tune", x264_tune_names);
			if (valid_name) {
				bfree(*tune);
				*tune = bstrdup(val);
			}
		}

		bfree(name);
	}
}
Пример #4
0
static void scale_filter_update(void *data, obs_data_t *settings)
{
	struct scale_filter_data *filter = data;
	int ret;

	const char *res_str = obs_data_get_string(settings, S_RESOLUTION);
	const char *sampling = obs_data_get_string(settings, S_SAMPLING);

	filter->valid = true;
	filter->base_canvas_resolution = false;

	if (strcmp(res_str, T_BASE) == 0) {
		struct obs_video_info ovi;
		obs_get_video_info(&ovi);
		filter->aspect_ratio_only = false;
		filter->base_canvas_resolution = true;
		filter->cx_in = ovi.base_width;
		filter->cy_in = ovi.base_height;
	} else {
		ret = sscanf(res_str, "%dx%d", &filter->cx_in, &filter->cy_in);
		if (ret == 2) {
			filter->aspect_ratio_only = false;
		} else {
			ret = sscanf(res_str, "%d:%d", &filter->cx_in,
					&filter->cy_in);
			if (ret != 2) {
				filter->valid = false;
				return;
			}

			filter->aspect_ratio_only = true;
		}
	}

	if (astrcmpi(sampling, S_SAMPLING_POINT) == 0) {
		filter->sampling = OBS_SCALE_POINT;

	} else if (astrcmpi(sampling, S_SAMPLING_BILINEAR) == 0) {
		filter->sampling = OBS_SCALE_BILINEAR;

	} else if (astrcmpi(sampling, S_SAMPLING_LANCZOS) == 0) {
		filter->sampling = OBS_SCALE_LANCZOS;

	} else { /* S_SAMPLING_BICUBIC */
		filter->sampling = OBS_SCALE_BICUBIC;
	}

	filter->undistort = obs_data_get_bool(settings, S_UNDISTORT);
}
Пример #5
0
bool config_get_default_bool(const config_t *config, const char *section,
		const char *name)
{
	const char *value = config_get_default_string(config, section, name);
	if (value)
		return astrcmpi(value, "true") == 0 ||
		       !!str_to_uint64(value);

	return false;
}
Пример #6
0
bool config_get_bool(config_t config, const char *section,
		const char *name)
{
	const char *value = config_get_string(config, section, name);
	if (value)
		return astrcmpi(value, "true") == 0 ||
		       strtoul(value, NULL, 10);

	return false;
}
Пример #7
0
static void config_set_item(struct darray *sections, const char *section,
		const char *name, char *value)
{
	struct config_section *sec = NULL;
	struct config_section *array = sections->array;
	struct config_item *item;
	size_t i, j;

	for (i = 0; i < sections->num; i++) {
		struct config_section *cur_sec = array+i;
		struct config_item *items = cur_sec->items.array;

		if (astrcmpi(cur_sec->name, section) == 0) {
			for (j = 0; j < cur_sec->items.num; j++) {
				item = items+j;

				if (astrcmpi(item->name, name) == 0) {
					bfree(item->value);
					item->value = value;
					return;
				}
			}

			sec = cur_sec;
			break;
		}
	}

	if (!sec) {
		sec = darray_push_back_new(sizeof(struct config_section),
				sections);
		sec->name = bstrdup(section);
	}

	item = darray_push_back_new(sizeof(struct config_item), &sec->items);
	item->name  = bstrdup(name);
	item->value = value;
}
Пример #8
0
static struct config_item *config_find_item(struct darray *sections,
		const char *section, const char *name)
{
	size_t i, j;

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

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

				if (astrcmpi(item->name, name) == 0)
					return item;
			}
		}
	}

	return NULL;
}
Пример #9
0
void shader_sampler_convert(struct shader_sampler *ss,
		struct gs_sampler_info *info)
{
	size_t i;
	memset(info, 0, sizeof(struct gs_sampler_info));

	for (i = 0; i < ss->states.num; i++) {
		const char *state = ss->states.array[i];
		const char *value = ss->values.array[i];

		if (astrcmpi(state, "Filter") == 0)
			info->filter = get_sample_filter(value);
		else if (astrcmpi(state, "AddressU") == 0)
			info->address_u = get_address_mode(value);
		else if (astrcmpi(state, "AddressV") == 0)
			info->address_v = get_address_mode(value);
		else if (astrcmpi(state, "AddressW") == 0)
			info->address_w = get_address_mode(value);
		else if (astrcmpi(state, "MaxAnisotropy") == 0)
			info->max_anisotropy = (int)strtol(value, NULL, 10);
		/*else if (astrcmpi(state, "BorderColor") == 0)
			// TODO */
	}
}
Пример #10
0
static bool find_device_id_by_uid(struct coreaudio_data *ca)
{
	UInt32      size      = sizeof(AudioDeviceID);
	CFStringRef cf_uid    = NULL;
	CFStringRef qual      = NULL;
	UInt32      qual_size = 0;
	OSStatus    stat;
	bool        success;

	AudioObjectPropertyAddress addr = {
		.mScope   = kAudioObjectPropertyScopeGlobal,
		.mElement = kAudioObjectPropertyElementMaster
	};

	if (!ca->device_uid)
		ca->device_uid = bstrdup("default");

	/* have to do this because mac output devices don't actually exist */
	if (astrcmpi(ca->device_uid, "default") == 0) {
		if (ca->input) {
			ca->default_device = true;
		} else {
			if (!get_default_output_device(ca)) {
				ca->no_devices = true;
				return false;
			}
		}
	}

	cf_uid = CFStringCreateWithCString(NULL, ca->device_uid,
			kCFStringEncodingUTF8);

	if (ca->default_device) {
		addr.mSelector = PROPERTY_DEFAULT_DEVICE;
	} else {
		addr.mSelector = kAudioHardwarePropertyTranslateUIDToDevice;
		qual      = cf_uid;
		qual_size = sizeof(CFStringRef);
	}

	stat = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
			qual_size, &qual, &size, &ca->device_id);
	success = (stat == noErr);

	CFRelease(cf_uid);
	return success;
}
Пример #11
0
extern enum gs_address_mode get_address_mode(const char *mode)
{
	if (astrcmpi(mode, "Wrap") == 0 || astrcmpi(mode, "Repeat") == 0)
		return GS_ADDRESS_WRAP;
	else if (astrcmpi(mode, "Clamp") == 0 || astrcmpi(mode, "None") == 0)
		return GS_ADDRESS_CLAMP;
	else if (astrcmpi(mode, "Mirror") == 0)
		return GS_ADDRESS_MIRROR;
	else if (astrcmpi(mode, "Border") == 0)
		return GS_ADDRESS_BORDER;
	else if (astrcmpi(mode, "MirrorOnce") == 0)
		return GS_ADDRESS_MIRRORONCE;

	return GS_ADDRESS_CLAMP;
}
Пример #12
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;
}
Пример #13
0
void build_font_path_info(FT_Face face, FT_Long idx, const char *path)
{
	FT_UInt num_names = FT_Get_Sfnt_Name_Count(face);
	DARRAY(char*) family_names;

	da_init(family_names);
	da_push_back(family_names, &face->family_name);

	for (FT_UInt i = 0; i < num_names; i++) {
		FT_SfntName name;
		char        *family;
		FT_Error    ret = FT_Get_Sfnt_Name(face, i, &name);

		if (ret != 0 || name.name_id != TT_NAME_ID_FONT_FAMILY)
			continue;

		family = sfnt_name_to_utf8(&name);
		if (!family)
			continue;

		for (size_t i = 0; i < family_names.num; i++) {
			if (astrcmpi(family_names.array[i], family) == 0) {
				bfree(family);
				family = NULL;
				break;
			}
		}

		if (family)
			da_push_back(family_names, &family);
	}

	for (size_t i = 0; i < family_names.num; i++) {
		add_font_path(face, idx, family_names.array[i],
				face->style_name, path);

		/* first item isn't our allocation */
		if (i > 0)
			bfree(family_names.array[i]);
	}

	da_free(family_names);
}
static bool confirm_service_file(void *param, struct file_download_data *file)
{
	if (astrcmpi(file->name, "services.json") == 0) {
		obs_data_t *data;
		int format_version;

		data = obs_data_create_from_json((char*)file->buffer.array);
		if (!data)
			return false;

		format_version = (int)obs_data_get_int(data, "format_version");
		obs_data_release(data);

		if (format_version != RTMP_SERVICES_FORMAT_VERSION)
			return false;
	}

	UNUSED_PARAMETER(param);
	return true;
}
Пример #15
0
static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p,
	obs_data_t *settings)
{
	const char *rate_control = obs_data_get_string(settings, "rate_control");

	bool bVisible =
		astrcmpi(rate_control, "VCM") == 0 ||
		astrcmpi(rate_control, "VBR") == 0;
	p = obs_properties_get(ppts, "max_bitrate");
	obs_property_set_visible(p, bVisible);

	bVisible =
		astrcmpi(rate_control, "CQP") == 0 ||
		astrcmpi(rate_control, "LA_ICQ") == 0 ||
		astrcmpi(rate_control, "ICQ") == 0;
	p = obs_properties_get(ppts, "bitrate");
	obs_property_set_visible(p, !bVisible);

	bVisible = astrcmpi(rate_control, "AVBR") == 0;
	p = obs_properties_get(ppts, "accuracy");
	obs_property_set_visible(p, bVisible);
	p = obs_properties_get(ppts, "convergence");
	obs_property_set_visible(p, bVisible);

	bVisible = astrcmpi(rate_control, "CQP") == 0;
	p = obs_properties_get(ppts, "qpi");
	obs_property_set_visible(p, bVisible);
	p = obs_properties_get(ppts, "qpb");
	obs_property_set_visible(p, bVisible);
	p = obs_properties_get(ppts, "qpp");
	obs_property_set_visible(p, bVisible);

	bVisible = astrcmpi(rate_control, "ICQ") == 0 ||
		astrcmpi(rate_control, "LA_ICQ") == 0;
	p = obs_properties_get(ppts, "icq_quality");
	obs_property_set_visible(p, bVisible);

	bVisible = astrcmpi(rate_control, "LA_ICQ") == 0 ||
		astrcmpi(rate_control, "LA") == 0;
	p = obs_properties_get(ppts, "la_depth");
	obs_property_set_visible(p, bVisible);

	return true;
}
Пример #16
0
static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data)
{
	const char            *name = obs_data_get_string(item_data, "name");
	obs_source_t          *source = obs_get_source_by_name(name);
	const char            *scale_filter_str;
	struct obs_scene_item *item;
	bool visible;

	if (!source) {
		blog(LOG_WARNING, "[scene_load_item] Source %s not found!",
				name);
		return;
	}

	item = obs_scene_add(scene, source);
	if (!item) {
		blog(LOG_WARNING, "[scene_load_item] Could not add source '%s' "
		                  "to scene '%s'!",
		                  name, obs_source_get_name(scene->source));
		
		obs_source_release(source);
		return;
	}

	obs_data_set_default_int(item_data, "align",
			OBS_ALIGN_TOP | OBS_ALIGN_LEFT);

	item->rot     = (float)obs_data_get_double(item_data, "rot");
	item->align   = (uint32_t)obs_data_get_int(item_data, "align");
	visible = obs_data_get_bool(item_data, "visible");
	obs_data_get_vec2(item_data, "pos",    &item->pos);
	obs_data_get_vec2(item_data, "scale",  &item->scale);

	set_visibility(item, visible);

	item->bounds_type =
		(enum obs_bounds_type)obs_data_get_int(item_data,
				"bounds_type");
	item->bounds_align =
		(uint32_t)obs_data_get_int(item_data, "bounds_align");
	obs_data_get_vec2(item_data, "bounds", &item->bounds);

	item->crop.left   = (uint32_t)obs_data_get_int(item_data, "crop_left");
	item->crop.top    = (uint32_t)obs_data_get_int(item_data, "crop_top");
	item->crop.right  = (uint32_t)obs_data_get_int(item_data, "crop_right");
	item->crop.bottom = (uint32_t)obs_data_get_int(item_data, "crop_bottom");

	scale_filter_str = obs_data_get_string(item_data, "scale_filter");
	item->scale_filter = OBS_SCALE_DISABLE;

	if (scale_filter_str) {
		if (astrcmpi(scale_filter_str, "point") == 0)
			item->scale_filter = OBS_SCALE_POINT;
		else if (astrcmpi(scale_filter_str, "bilinear") == 0)
			item->scale_filter = OBS_SCALE_BILINEAR;
		else if (astrcmpi(scale_filter_str, "bicubic") == 0)
			item->scale_filter = OBS_SCALE_BICUBIC;
		else if (astrcmpi(scale_filter_str, "lanczos") == 0)
			item->scale_filter = OBS_SCALE_LANCZOS;
	}

	if (item->item_render && !item_texture_enabled(item)) {
		obs_enter_graphics();
		gs_texrender_destroy(item->item_render);
		item->item_render = NULL;
		obs_leave_graphics();

	} else if (!item->item_render && item_texture_enabled(item)) {
		obs_enter_graphics();
		item->item_render = gs_texrender_create(GS_RGBA, GS_ZS_NONE);
		obs_leave_graphics();
	}

	obs_source_release(source);

	update_item_transform(item);
}
Пример #17
0
static void update_params(struct obs_qsv *obsqsv, obs_data_t *settings)
{
	video_t *video = obs_encoder_video(obsqsv->encoder);
	const struct video_output_info *voi = video_output_get_info(video);

	const char *target_usage = obs_data_get_string(settings, "target_usage");
	const char *profile = obs_data_get_string(settings, "profile");
	const char *rate_control = obs_data_get_string(settings, "rate_control");
	int async_depth = (int)obs_data_get_int(settings, "async_depth");
	int target_bitrate = (int)obs_data_get_int(settings, "bitrate");
	int max_bitrate = (int)obs_data_get_int(settings, "max_bitrate");
	int accuracy = (int)obs_data_get_int(settings, "accuracy");
	int convergence = (int)obs_data_get_int(settings, "convergence");
	int qpi = (int)obs_data_get_int(settings, "qpi");
	int qpp = (int)obs_data_get_int(settings, "qpp");
	int qpb = (int)obs_data_get_int(settings, "qpb");
	int icq_quality = (int)obs_data_get_int(settings, "icq_quality");
	int la_depth = (int)obs_data_get_int(settings, "la_depth");
	int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec");
	bool cbr_override = obs_data_get_bool(settings, "cbr");
	int bFrames = 7;

	int width = (int)obs_encoder_get_width(obsqsv->encoder);
	int height = (int)obs_encoder_get_height(obsqsv->encoder);
	if (astrcmpi(target_usage, "quality") == 0)
		obsqsv->params.nTargetUsage = MFX_TARGETUSAGE_BEST_QUALITY;
	else if (astrcmpi(target_usage, "balanced") == 0)
		obsqsv->params.nTargetUsage = MFX_TARGETUSAGE_BALANCED;
	else if (astrcmpi(target_usage, "speed") == 0)
		obsqsv->params.nTargetUsage = MFX_TARGETUSAGE_BEST_SPEED;

	if (astrcmpi(profile, "baseline") == 0)
		obsqsv->params.nCodecProfile = MFX_PROFILE_AVC_BASELINE;
	else if (astrcmpi(profile, "main") == 0)
		obsqsv->params.nCodecProfile = MFX_PROFILE_AVC_MAIN;
	else if (astrcmpi(profile, "high") == 0)
		obsqsv->params.nCodecProfile = MFX_PROFILE_AVC_HIGH;

	/* internal convenience parameter, overrides rate control param
	 * XXX: Deprecated */
	if (cbr_override) {
		warn("\"cbr\" setting has been deprecated for all encoders!  "
		     "Please set \"rate_control\" to \"CBR\" instead.  "
		     "Forcing CBR mode.  "
		     "(Note to all: this is why you shouldn't use strings for "
		     "common settings)");
		rate_control = "CBR";
	}

	if (astrcmpi(rate_control, "CBR") == 0)
		obsqsv->params.nRateControl = MFX_RATECONTROL_CBR;
	else if (astrcmpi(rate_control, "VBR") == 0)
		obsqsv->params.nRateControl = MFX_RATECONTROL_VBR;
	else if (astrcmpi(rate_control, "VCM") == 0)
		obsqsv->params.nRateControl = MFX_RATECONTROL_VCM;
	else if (astrcmpi(rate_control, "CQP") == 0)
		obsqsv->params.nRateControl = MFX_RATECONTROL_CQP;
	else if (astrcmpi(rate_control, "AVBR") == 0)
		obsqsv->params.nRateControl = MFX_RATECONTROL_AVBR;
	else if (astrcmpi(rate_control, "ICQ") == 0)
		obsqsv->params.nRateControl = MFX_RATECONTROL_ICQ;
	else if (astrcmpi(rate_control, "LA_ICQ") == 0)
		obsqsv->params.nRateControl = MFX_RATECONTROL_LA_ICQ;
	else if (astrcmpi(rate_control, "LA") == 0)
		obsqsv->params.nRateControl = MFX_RATECONTROL_LA;

	obsqsv->params.nAsyncDepth = (mfxU16)async_depth;
	obsqsv->params.nAccuracy = (mfxU16)accuracy;
	obsqsv->params.nConvergence = (mfxU16)convergence;
	obsqsv->params.nQPI = (mfxU16)qpi;
	obsqsv->params.nQPP = (mfxU16)qpp;
	obsqsv->params.nQPB = (mfxU16)qpb;
	obsqsv->params.nLADEPTH = (mfxU16)la_depth;
	obsqsv->params.nTargetBitRate = (mfxU16)target_bitrate;
	obsqsv->params.nMaxBitRate = (mfxU16)max_bitrate;
	obsqsv->params.nWidth = (mfxU16)width;
	obsqsv->params.nHeight = (mfxU16)height;
	obsqsv->params.nFpsNum = (mfxU16)voi->fps_num;
	obsqsv->params.nFpsDen = (mfxU16)voi->fps_den;
	obsqsv->params.nbFrames = (mfxU16)bFrames;
	obsqsv->params.nKeyIntSec = (mfxU16)keyint_sec;
	obsqsv->params.nICQQuality = (mfxU16)icq_quality;

	info("settings:\n\trate_control:   %s", rate_control);

	if (obsqsv->params.nRateControl != MFX_RATECONTROL_LA_ICQ &&
	    obsqsv->params.nRateControl != MFX_RATECONTROL_ICQ    &&
	    obsqsv->params.nRateControl != MFX_RATECONTROL_CQP)
		blog(LOG_INFO,
			"\ttarget_bitrate: %d",
			(int)obsqsv->params.nTargetBitRate);

	if (obsqsv->params.nRateControl == MFX_RATECONTROL_VBR ||
	    obsqsv->params.nRateControl == MFX_RATECONTROL_VCM)
		blog(LOG_INFO,
			"\tmax_bitrate:    %d",
			(int)obsqsv->params.nMaxBitRate);

	if (obsqsv->params.nRateControl == MFX_RATECONTROL_LA_ICQ ||
	    obsqsv->params.nRateControl == MFX_RATECONTROL_ICQ)
		blog(LOG_INFO,
			"\tICQ Quality:    %d",
			(int)obsqsv->params.nICQQuality);

	if (obsqsv->params.nRateControl == MFX_RATECONTROL_LA_ICQ ||
	    obsqsv->params.nRateControl == MFX_RATECONTROL_LA)
		blog(LOG_INFO,
			"\tLookahead Depth:%d",
			(int)obsqsv->params.nLADEPTH);

	if (obsqsv->params.nRateControl == MFX_RATECONTROL_CQP)
		blog(LOG_INFO,
			"\tqpi:            %d\n"
			"\tqpb:            %d\n"
			"\tqpp:            %d",
			qpi, qpb, qpp);

	blog(LOG_INFO,
		"\tfps_num:        %d\n"
		"\tfps_den:        %d\n"
		"\twidth:          %d\n"
		"\theight:         %d",
		voi->fps_num, voi->fps_den,
		width, height);

	info("debug info:");
}