static void obs_source_draw_texture(texture_t tex, struct source_frame *frame) { effect_t effect = obs->video.default_effect; bool yuv = is_yuv(frame->format); const char *type = yuv ? "DrawYUV" : "DrawRGB"; technique_t tech; eparam_t param; if (!upload_frame(tex, frame)) return; tech = effect_gettechnique(effect, type); technique_begin(tech); technique_beginpass(tech, 0); if (yuv) { param = effect_getparambyname(effect, "yuv_matrix"); effect_setval(effect, param, frame->yuv_matrix, sizeof(float) * 16); } param = effect_getparambyname(effect, "diffuse"); effect_settexture(effect, param, tex); gs_draw_sprite(tex, frame->flip ? GS_FLIP_V : 0, 0, 0); technique_endpass(tech); technique_end(tech); }
static void vpp_get_min_max_variant(struct decon_win_config *config, u32 *max_src, u32 *min_src_w, u32 *min_src_h, u32 *max_dst, u32 *min_dst_w, u32 *min_dst_h) { if (is_rotation(config)) { if (is_yuv(config)) { *max_src = 2560; *max_dst = 4096; *min_src_w = 32; *min_src_h = 64; *min_dst_w = 16; *min_dst_h = 8; } else { *max_src = 2560; *max_dst = 4096; *min_src_w = 16; *min_src_h = 32; *min_dst_w = 16; *min_dst_h = 8; } } else { if (is_yuv(config)) { *max_src = 4096; *max_dst = 4096; *min_src_w = 64; *min_src_h = 32; *min_dst_w = 16; *min_dst_h = 8; } else { *max_src = 4096; *max_dst = 4096; *min_src_w = 32; *min_src_h = 16; *min_dst_w = 16; *min_dst_h = 8; } } }
static void vpp_get_align_variant(struct decon_win_config *config, u32 *offs, u32 *src_f, u32 *src_cr, u32 *dst_cr) { if (is_rotation(config)) { if (is_yuv(config)) { *offs = *src_f = 4; *src_cr = 2; *dst_cr = 1; } else { *offs = *src_f = 2; *src_cr = *dst_cr = 1; } } else { if (is_yuv(config)) { *offs = *src_f = 2; *src_cr = 2; *dst_cr = 1; } else { *offs = *src_f = 1; *src_cr = *dst_cr = 1; } } }
void validate_state(const GraphBuilder::state &state) { if (!state.width || !state.height) throw error::ZeroImageSize{ "image dimensions must be non-zero" }; if (is_greyscale(state)) { if (state.subsample_w || state.subsample_h) throw error::GreyscaleSubsampling{ "cannot subsample greyscale image" }; if (state.colorspace.matrix == zimg::colorspace::MatrixCoefficients::MATRIX_RGB) throw error::ColorFamilyMismatch{ "GREY color family cannot be RGB" }; } if (is_rgb(state)) { if (state.subsample_w || state.subsample_h) throw zimg::error::UnsupportedSubsampling{ "subsampled RGB image not supported" }; if (state.colorspace.matrix != zimg::colorspace::MatrixCoefficients::MATRIX_UNSPECIFIED && state.colorspace.matrix != zimg::colorspace::MatrixCoefficients::MATRIX_RGB) throw error::ColorFamilyMismatch{ "RGB color family cannot be YUV" }; } if (is_yuv(state)) { if (state.colorspace.matrix == zimg::colorspace::MatrixCoefficients::MATRIX_RGB) throw error::ColorFamilyMismatch{ "YUV color family cannot be RGB" }; } if (state.subsample_h > 1 && state.parity != GraphBuilder::FieldParity::FIELD_PROGRESSIVE) throw error::UnsupportedSubsampling{ "vertical subsampling greater than 2x is not supported" }; if (state.subsample_w > 2 || state.subsample_h > 2) throw error::UnsupportedSubsampling{ "subsampling greater than 4x is not supported" }; if (state.width % (1 << state.subsample_w) || state.height % (1 << state.subsample_h)) throw error::ImageNotDivislbe{ "image dimensions must be divisible by subsampling factor" }; if (state.depth > pixel_depth(state.type)) throw error::BitDepthOverflow{ "bit depth exceeds limits of type" }; if (!state.fullrange && state.depth < 8) throw error::BitDepthOverflow{ "bit depth must be at least 8 for limited range" }; }