void deinterlace_render(obs_source_t *s)
{
	gs_effect_t *effect = s->deinterlace_effect;

	uint64_t frame2_ts;
	gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image");
	gs_eparam_t *prev = gs_effect_get_param_by_name(effect,
			"previous_image");
	gs_eparam_t *field = gs_effect_get_param_by_name(effect, "field_order");
	gs_eparam_t *frame2 = gs_effect_get_param_by_name(effect, "frame2");
	gs_eparam_t *dimensions = gs_effect_get_param_by_name(effect,
			"dimensions");
	struct vec2 size = {(float)s->async_width, (float)s->async_height};
	bool yuv = format_is_yuv(s->async_format);
	bool limited_range = yuv && !s->async_full_range;
	const char *tech = yuv ? "DrawMatrix" : "Draw";

	gs_texture_t *cur_tex = s->async_texrender ?
		gs_texrender_get_texture(s->async_texrender) :
		s->async_texture;
	gs_texture_t *prev_tex = s->async_prev_texrender ?
		gs_texrender_get_texture(s->async_prev_texrender) :
		s->async_prev_texture;

	if (!cur_tex || !prev_tex || !s->async_width || !s->async_height)
		return;

	gs_effect_set_texture(image, cur_tex);
	gs_effect_set_texture(prev, prev_tex);
	gs_effect_set_int(field, s->deinterlace_top_first);
	gs_effect_set_vec2(dimensions, &size);

	if (yuv) {
		gs_eparam_t *color_matrix = gs_effect_get_param_by_name(
				effect, "color_matrix");
		gs_effect_set_val(color_matrix, s->async_color_matrix,
				sizeof(float) * 16);
	}
	if (limited_range) {
		const size_t size = sizeof(float) * 3;
		gs_eparam_t *color_range_min = gs_effect_get_param_by_name(
				effect, "color_range_min");
		gs_eparam_t *color_range_max = gs_effect_get_param_by_name(
				effect, "color_range_max");
		gs_effect_set_val(color_range_min, s->async_color_range_min,
				size);
		gs_effect_set_val(color_range_max, s->async_color_range_max,
				size);
	}

	frame2_ts = s->deinterlace_frame_ts + s->deinterlace_offset +
		s->deinterlace_half_duration - TWOX_TOLERANCE;

	gs_effect_set_bool(frame2, obs->video.video_time >= frame2_ts);

	while (gs_effect_loop(effect, tech))
		gs_draw_sprite(NULL, s->async_flip ? GS_FLIP_V : 0,
				s->async_width, s->async_height);
}
Exemplo n.º 2
0
static inline void render_item(struct obs_scene_item *item)
{
	if (item->crop_render) {
		uint32_t width  = obs_source_get_width(item->source);
		uint32_t height = obs_source_get_height(item->source);
		uint32_t cx = calc_cx(item, width);
		uint32_t cy = calc_cy(item, height);

		if (cx && cy && gs_texrender_begin(item->crop_render, cx, cy)) {
			float cx_scale = (float)width  / (float)cx;
			float cy_scale = (float)height / (float)cy;
			gs_matrix_scale3f(cx_scale, cy_scale, 1.0f);
			gs_matrix_translate3f(
					-(float)item->crop.left,
					-(float)item->crop.top,
					0.0f);

			obs_source_video_render(item->source);
			gs_texrender_end(item->crop_render);
		}
	}

	gs_matrix_push();
	gs_matrix_mul(&item->draw_transform);
	if (item->crop_render) {
		gs_texture_t *tex = gs_texrender_get_texture(item->crop_render);

		while (gs_effect_loop(obs->video.default_effect, "Draw"))
			obs_source_draw(tex, 0, 0, 0, 0, 0);
	} else {
		obs_source_video_render(item->source);
	}
	gs_matrix_pop();
}
Exemplo n.º 3
0
static void render_item_texture(struct obs_scene_item *item)
{
	gs_texture_t *tex = gs_texrender_get_texture(item->item_render);
	gs_effect_t *effect = obs->video.default_effect;
	enum obs_scale_type type = item->scale_filter;
	uint32_t cx = gs_texture_get_width(tex);
	uint32_t cy = gs_texture_get_height(tex);

	if (type != OBS_SCALE_DISABLE) {
		if (type == OBS_SCALE_POINT) {
			gs_eparam_t *image = gs_effect_get_param_by_name(
					effect, "image");
			gs_effect_set_next_sampler(image,
					obs->video.point_sampler);

		} else if (!close_float(item->output_scale.x, 1.0f, EPSILON) ||
		           !close_float(item->output_scale.y, 1.0f, EPSILON)) {
			gs_eparam_t *scale_param;

			if (item->output_scale.x < 0.5f ||
			    item->output_scale.y < 0.5f) {
				effect = obs->video.bilinear_lowres_effect;
			} else if (type == OBS_SCALE_BICUBIC) {
				effect = obs->video.bicubic_effect;
			} else if (type == OBS_SCALE_LANCZOS) {
				effect = obs->video.lanczos_effect;
			}

			scale_param = gs_effect_get_param_by_name(effect,
					"base_dimension_i");
			if (scale_param) {
				struct vec2 base_res_i = {
					1.0f / (float)cx,
					1.0f / (float)cy
				};

				gs_effect_set_vec2(scale_param, &base_res_i);
			}
		}
	}

	while (gs_effect_loop(effect, "Draw"))
		obs_source_draw(tex, 0, 0, 0, 0, 0);
}
Exemplo n.º 4
0
static inline gs_texture_t *get_texture(obs_source_t *transition,
                                        enum obs_transition_target target)
{
    size_t idx = (size_t)target;
    return gs_texrender_get_texture(transition->transition_texrender[idx]);
}