static bool obs_init_textures(struct obs_video_info *ovi) { struct obs_video *video = &obs->video; size_t i; for (i = 0; i < NUM_TEXTURES; i++) { video->copy_surfaces[i] = gs_create_stagesurface( ovi->output_width, ovi->output_height, GS_RGBA); if (!video->copy_surfaces[i]) return false; video->render_textures[i] = gs_create_texture( ovi->base_width, ovi->base_height, GS_RGBA, 1, NULL, GS_RENDERTARGET); if (!video->render_textures[i]) return false; video->output_textures[i] = gs_create_texture( ovi->output_width, ovi->output_height, GS_RGBA, 1, NULL, GS_RENDERTARGET); if (!video->output_textures[i]) return false; } return true; }
static void *random_create(obs_data_t settings, obs_source_t source) { struct random_tex *rt = bzalloc(sizeof(struct random_tex)); uint32_t *pixels = bmalloc(20*20*4); size_t x, y; for (y = 0; y < 20; y++) { for (x = 0; x < 20; x++) { uint32_t pixel = 0xFF000000; pixel |= (rand()%256); pixel |= (rand()%256) << 8; pixel |= (rand()%256) << 16; //pixel |= 0xFFFFFFFF; pixels[y*20 + x] = pixel; } } gs_entercontext(obs_graphics()); rt->texture = gs_create_texture(20, 20, GS_RGBA, 1, (const void**)&pixels, 0); bfree(pixels); if (!rt->texture) { random_destroy(rt); return NULL; } gs_leavecontext(); UNUSED_PARAMETER(settings); UNUSED_PARAMETER(source); return rt; }
static inline bool set_async_texture_size(struct obs_source *source, struct source_frame *frame) { enum convert_type prev, cur; prev = get_convert_type(source->async_format); cur = get_convert_type(frame->format); if (source->async_texture) { if (source->async_width == frame->width && source->async_height == frame->height && prev == cur) return true; } texture_destroy(source->async_texture); texrender_destroy(source->async_convert_texrender); source->async_convert_texrender = NULL; if (cur != CONVERT_NONE && init_gpu_conversion(source, frame)) { source->async_gpu_conversion = true; source->async_convert_texrender = texrender_create(GS_RGBA, GS_ZS_NONE); source->async_texture = gs_create_texture( source->async_convert_width, source->async_convert_height, GS_RGBA, 1, NULL, GS_DYNAMIC); } else { source->async_gpu_conversion = false; source->async_texture = gs_create_texture( frame->width, frame->height, GS_RGBA, 1, NULL, GS_DYNAMIC); } if (!source->async_texture) return false; source->async_width = frame->width; source->async_height = frame->height; return true; }
static bool obs_init_textures(struct obs_video_info *ovi) { struct obs_core_video *video = &obs->video; bool yuv = format_is_yuv(ovi->output_format); uint32_t output_height = video->gpu_conversion ? video->conversion_height : ovi->output_height; size_t i; for (i = 0; i < NUM_TEXTURES; i++) { video->copy_surfaces[i] = gs_create_stagesurface( ovi->output_width, output_height, GS_RGBA); if (!video->copy_surfaces[i]) return false; video->render_textures[i] = gs_create_texture( ovi->base_width, ovi->base_height, GS_RGBA, 1, NULL, GS_RENDERTARGET); if (!video->render_textures[i]) return false; video->output_textures[i] = gs_create_texture( ovi->output_width, ovi->output_height, GS_RGBA, 1, NULL, GS_RENDERTARGET); if (!video->output_textures[i]) return false; if (yuv) source_frame_init(&video->convert_frames[i], ovi->output_format, ovi->output_width, ovi->output_height); } return true; }
static bool set_texture_size(obs_source_t source, struct source_frame *frame) { if (source->output_texture) { uint32_t width = texture_getwidth(source->output_texture); uint32_t height = texture_getheight(source->output_texture); if (width == frame->width && height == frame->height) return true; } texture_destroy(source->output_texture); source->output_texture = gs_create_texture(frame->width, frame->height, GS_RGBA, 1, NULL, GS_DYNAMIC); return source->output_texture != NULL; }
texture_t gs_create_texture_from_file(const char *file) { struct ffmpeg_image image; texture_t tex = NULL; if (ffmpeg_image_init(&image, file)) { uint8_t *data = malloc(image.cx * image.cy * 4); if (ffmpeg_image_decode(&image, data, image.cx * 4)) { tex = gs_create_texture(image.cx, image.cy, convert_format(image.format), 1, (const uint8_t**)&data, 0); } ffmpeg_image_free(&image); free(data); } return tex; }
static inline void init_textures(struct dc_capture *capture) { for (size_t i = 0; i < capture->num_textures; i++) { if (capture->compatibility) capture->textures[i] = gs_create_texture( capture->width, capture->height, GS_BGRA, 1, NULL, GS_DYNAMIC); else capture->textures[i] = gs_create_gdi_texture( capture->width, capture->height); if (!capture->textures[i]) { blog(LOG_WARNING, "[dc_capture_init] Failed to " "create textures"); return; } } capture->valid = true; }
/* * Create the cursor texture, either by updating if the new cursor has the same * size or by creating a new texture if the size is different */ static void xcursor_create(xcursor_t *data, XFixesCursorImage *xc) { uint32_t *pixels = xcursor_pixels(xc); if (data->tex && data->last_height == xc->width && data->last_width == xc->height) { texture_setimage(data->tex, (void **) pixels, xc->width * sizeof(uint32_t), False); } else { if (data->tex) texture_destroy(data->tex); data->tex = gs_create_texture(xc->width, xc->height, GS_BGRA, 1, (const void **) &pixels, GS_DYNAMIC); } bfree(pixels); data->last_serial = xc->cursor_serial; data->last_width = xc->width; data->last_height = xc->height; }
static bool obs_init_gpu_conversion(struct obs_video_info *ovi) { struct obs_core_video *video = &obs->video; calc_gpu_conversion_sizes(ovi); if (!video->conversion_height) { blog(LOG_INFO, "GPU conversion not available for format: %u", (unsigned int)ovi->output_format); video->gpu_conversion = false; return true; } for (size_t i = 0; i < NUM_TEXTURES; i++) { video->convert_textures[i] = gs_create_texture( ovi->output_width, video->conversion_height, GS_RGBA, 1, NULL, GS_RENDERTARGET); if (!video->convert_textures[i]) return false; } return true; }
void XCompcapMain::updateSettings(obs_data_t settings) { PLock lock(&p->lock); XErrorLock xlock; ObsGsContextHolder obsctx; blog(LOG_DEBUG, "Settings updating"); Window prevWin = p->win; xcc_cleanup(p); if (settings) { const char *windowName = obs_data_getstring(settings, "capture_window"); p->win = getWindowFromString(windowName); p->cut_top = obs_data_getint(settings, "cut_top"); p->cut_left = obs_data_getint(settings, "cut_left"); p->cut_right = obs_data_getint(settings, "cut_right"); p->cut_bot = obs_data_getint(settings, "cut_bot"); p->lockX = obs_data_getbool(settings, "lock_x"); p->swapRedBlue = obs_data_getbool(settings, "swap_redblue"); } else { p->win = prevWin; } xlock.resetError(); XCompositeRedirectWindow(xdisp, p->win, CompositeRedirectAutomatic); if (xlock.gotError()) { blog(LOG_ERROR, "XCompositeRedirectWindow failed: %s", xlock.getErrorText().c_str()); return; } XSelectInput(xdisp, p->win, StructureNotifyMask); XSync(xdisp, 0); XWindowAttributes attr; if (!XGetWindowAttributes(xdisp, p->win, &attr)) { p->win = 0; p->width = 0; p->height = 0; return; } gs_color_format cf = GS_RGBA; p->width = attr.width; p->height = attr.height; if (p->cut_top + p->cut_bot < (int)p->height) { p->cur_cut_top = p->cut_top; p->cur_cut_bot = p->cut_bot; } else { p->cur_cut_top = 0; p->cur_cut_bot = 0; } if (p->cut_left + p->cut_right < (int)p->width) { p->cur_cut_left = p->cut_left; p->cur_cut_right = p->cut_right; } else { p->cur_cut_left = 0; p->cur_cut_right = 0; } if (p->tex) texture_destroy(p->tex); uint8_t *texData = new uint8_t[width() * height() * 4]; for (unsigned int i = 0; i < width() * height() * 4; i += 4) { texData[i + 0] = p->swapRedBlue ? 0 : 0xFF; texData[i + 1] = 0; texData[i + 2] = p->swapRedBlue ? 0xFF : 0; texData[i + 3] = 0xFF; } const uint8_t* texDataArr[] = { texData, 0 }; p->tex = gs_create_texture(width(), height(), cf, 1, texDataArr, 0); delete[] texData; if (p->swapRedBlue) { GLuint tex = *(GLuint*)texture_getobj(p->tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); glBindTexture(GL_TEXTURE_2D, 0); } const int attrs[] = { GLX_BIND_TO_TEXTURE_RGBA_EXT, GL_TRUE, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, GLX_DOUBLEBUFFER, GL_FALSE, None }; int nelem = 0; GLXFBConfig* configs = glXChooseFBConfig(xdisp, XCompcap::getRootWindowScreen(attr.root), attrs, &nelem); if (nelem <= 0) { blog(LOG_ERROR, "no matching fb config found"); p->win = 0; p->height = 0; p->width = 0; return; } glXGetFBConfigAttrib(xdisp, configs[0], GLX_Y_INVERTED_EXT, &nelem); p->inverted = nelem != 0; xlock.resetError(); p->pixmap = XCompositeNameWindowPixmap(xdisp, p->win); if (xlock.gotError()) { blog(LOG_ERROR, "XCompositeNameWindowPixmap failed: %s", xlock.getErrorText().c_str()); p->pixmap = 0; XFree(configs); return; } const int attribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, None }; p->glxpixmap = glXCreatePixmap(xdisp, configs[0], p->pixmap, attribs); if (xlock.gotError()) { blog(LOG_ERROR, "glXCreatePixmap failed: %s", xlock.getErrorText().c_str()); XFreePixmap(xdisp, p->pixmap); XFree(configs); p->pixmap = 0; p->glxpixmap = 0; return; } XFree(configs); p->gltex = gs_create_texture(p->width, p->height, cf, 1, 0, GS_GL_DUMMYTEX); GLuint gltex = *(GLuint*)texture_getobj(p->gltex); glBindTexture(GL_TEXTURE_2D, gltex); glXBindTexImageEXT(xdisp, p->glxpixmap, GLX_FRONT_LEFT_EXT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); }