static inline void render_main_texture(struct obs_core_video *video, int cur_texture) { profile_start(render_main_texture_name); struct vec4 clear_color; vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 1.0f); gs_set_render_target(video->render_textures[cur_texture], NULL); gs_clear(GS_CLEAR_COLOR, &clear_color, 1.0f, 0); set_render_size(video->base_width, video->base_height); pthread_mutex_lock(&obs->data.draw_callbacks_mutex); for (size_t i = 0; i < obs->data.draw_callbacks.num; i++) { struct draw_callback *callback; callback = obs->data.draw_callbacks.array+i; callback->draw(callback->param, video->base_width, video->base_height); } pthread_mutex_unlock(&obs->data.draw_callbacks_mutex); obs_view_render(&obs->data.main_view); video->textures_rendered[cur_texture] = true; profile_end(render_main_texture_name); }
static void render_nv12(struct obs_core_video *video, gs_texture_t *target, int cur_texture, int prev_texture, const char *tech_name, uint32_t width, uint32_t height) { gs_texture_t *texture = video->output_textures[prev_texture]; gs_effect_t *effect = video->conversion_effect; gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); gs_technique_t *tech = gs_effect_get_technique(effect, tech_name); size_t passes, i; gs_effect_set_texture(image, texture); gs_set_render_target(target, NULL); set_render_size(width, height); gs_enable_blending(false); passes = gs_technique_begin(tech); for (i = 0; i < passes; i++) { gs_technique_begin_pass(tech, i); gs_draw_sprite(texture, 0, width, height); gs_technique_end_pass(tech); } gs_technique_end(tech); gs_enable_blending(true); }
static inline void render_output_texture(struct obs_core_video *video, int cur_texture, int prev_texture) { profile_start(render_output_texture_name); gs_texture_t *texture = video->render_textures[prev_texture]; gs_texture_t *target = video->output_textures[cur_texture]; uint32_t width = gs_texture_get_width(target); uint32_t height = gs_texture_get_height(target); struct vec2 base_i; vec2_set(&base_i, 1.0f / (float)video->base_width, 1.0f / (float)video->base_height); gs_effect_t *effect = get_scale_effect(video, width, height); gs_technique_t *tech; if (video->ovi.output_format == VIDEO_FORMAT_RGBA) { tech = gs_effect_get_technique(effect, "Draw"); } else { tech = gs_effect_get_technique(effect, "DrawMatrix"); } gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); gs_eparam_t *matrix = gs_effect_get_param_by_name(effect, "color_matrix"); gs_eparam_t *bres_i = gs_effect_get_param_by_name(effect, "base_dimension_i"); size_t passes, i; if (!video->textures_rendered[prev_texture]) goto end; gs_set_render_target(target, NULL); set_render_size(width, height); if (bres_i) gs_effect_set_vec2(bres_i, &base_i); gs_effect_set_val(matrix, video->color_matrix, sizeof(float) * 16); gs_effect_set_texture(image, texture); gs_enable_blending(false); passes = gs_technique_begin(tech); for (i = 0; i < passes; i++) { gs_technique_begin_pass(tech, i); gs_draw_sprite(texture, 0, width, height); gs_technique_end_pass(tech); } gs_technique_end(tech); gs_enable_blending(true); video->textures_output[cur_texture] = true; end: profile_end(render_output_texture_name); }
static void render_convert_texture(struct obs_core_video *video, int cur_texture, int prev_texture) { profile_start(render_convert_texture_name); gs_texture_t *texture = video->output_textures[prev_texture]; gs_texture_t *target = video->convert_textures[cur_texture]; float fwidth = (float)video->output_width; float fheight = (float)video->output_height; size_t passes, i; gs_effect_t *effect = video->conversion_effect; gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); gs_technique_t *tech = gs_effect_get_technique(effect, video->conversion_tech); if (!video->textures_output[prev_texture]) goto end; set_eparam(effect, "u_plane_offset", (float)video->plane_offsets[1]); set_eparam(effect, "v_plane_offset", (float)video->plane_offsets[2]); set_eparam(effect, "width", fwidth); set_eparam(effect, "height", fheight); set_eparam(effect, "width_i", 1.0f / fwidth); set_eparam(effect, "height_i", 1.0f / fheight); set_eparam(effect, "width_d2", fwidth * 0.5f); set_eparam(effect, "height_d2", fheight * 0.5f); set_eparam(effect, "width_d2_i", 1.0f / (fwidth * 0.5f)); set_eparam(effect, "height_d2_i", 1.0f / (fheight * 0.5f)); set_eparam(effect, "input_height", (float)video->conversion_height); gs_effect_set_texture(image, texture); gs_set_render_target(target, NULL); set_render_size(video->output_width, video->conversion_height); gs_enable_blending(false); passes = gs_technique_begin(tech); for (i = 0; i < passes; i++) { gs_technique_begin_pass(tech, i); gs_draw_sprite(texture, 0, video->output_width, video->conversion_height); gs_technique_end_pass(tech); } gs_technique_end(tech); gs_enable_blending(true); video->textures_converted[cur_texture] = true; end: profile_end(render_convert_texture_name); }
static inline void render_main_texture(struct obs_core_video *video, int cur_texture) { struct vec4 clear_color; vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 1.0f); gs_set_render_target(video->render_textures[cur_texture], NULL); gs_clear(GS_CLEAR_COLOR, &clear_color, 1.0f, 0); set_render_size(video->base_width, video->base_height); obs_view_render(&obs->data.main_view); video->textures_rendered[cur_texture] = true; }
static void render_convert_texture(struct obs_core_video *video, int cur_texture, int prev_texture) { texture_t texture = video->output_textures[prev_texture]; texture_t target = video->convert_textures[cur_texture]; float fwidth = (float)video->output_width; float fheight = (float)video->output_height; size_t passes, i; effect_t effect = video->conversion_effect; eparam_t image = effect_getparambyname(effect, "image"); technique_t tech = effect_gettechnique(effect, video->conversion_tech); if (!video->textures_output[prev_texture]) return; set_eparam(effect, "u_plane_offset", (float)video->plane_offsets[1]); set_eparam(effect, "v_plane_offset", (float)video->plane_offsets[2]); set_eparam(effect, "width", fwidth); set_eparam(effect, "height", fheight); set_eparam(effect, "width_i", 1.0f / fwidth); set_eparam(effect, "height_i", 1.0f / fheight); set_eparam(effect, "width_d2", fwidth * 0.5f); set_eparam(effect, "height_d2", fheight * 0.5f); set_eparam(effect, "width_d2_i", 1.0f / (fwidth * 0.5f)); set_eparam(effect, "height_d2_i", 1.0f / (fheight * 0.5f)); set_eparam(effect, "input_height", (float)video->conversion_height); effect_settexture(effect, image, texture); gs_setrendertarget(target, NULL); set_render_size(video->output_width, video->conversion_height); passes = technique_begin(tech); for (i = 0; i < passes; i++) { technique_beginpass(tech, i); gs_draw_sprite(texture, 0, video->output_width, video->conversion_height); technique_endpass(tech); } technique_end(tech); video->textures_converted[cur_texture] = true; }
static inline void render_output_texture(struct obs_core_video *video, int cur_texture, int prev_texture) { texture_t texture = video->render_textures[prev_texture]; texture_t target = video->output_textures[cur_texture]; uint32_t width = texture_getwidth(target); uint32_t height = texture_getheight(target); /* TODO: replace with actual downscalers or unpackers */ effect_t effect = video->default_effect; technique_t tech = effect_gettechnique(effect, "DrawMatrix"); eparam_t image = effect_getparambyname(effect, "image"); eparam_t matrix = effect_getparambyname(effect, "color_matrix"); size_t passes, i; if (!video->textures_rendered[prev_texture]) return; gs_setrendertarget(target, NULL); set_render_size(width, height); /* TODO: replace with programmable code */ const float mat_val[16] = { -0.100644f, -0.338572f, 0.439216f, 0.501961f, 0.182586f, 0.614231f, 0.062007f, 0.062745f, 0.439216f, -0.398942f, -0.040274f, 0.501961f, 0.000000f, 0.000000f, 0.000000f, 1.000000f }; effect_setval(effect, matrix, mat_val, sizeof(mat_val)); effect_settexture(effect, image, texture); passes = technique_begin(tech); for (i = 0; i < passes; i++) { technique_beginpass(tech, i); gs_draw_sprite(texture, 0, width, height); technique_endpass(tech); } technique_end(tech); video->textures_output[cur_texture] = true; }