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; }
effect_t create_opaque_effect(void) { effect_t opaque_effect; char *effect_file; char *error_string = NULL; effect_file = obs_find_plugin_file("win-capture/opaque.effect"); if (!effect_file) { blog(LOG_ERROR, "[create_opaque_effect] Could not find " "opaque effect file"); return false; } gs_entercontext(obs_graphics()); opaque_effect = gs_create_effect_from_file(effect_file, &error_string); if (!opaque_effect) { if (error_string) blog(LOG_ERROR, "[create_opaque_effect] Failed to " "create opaque effect:\n%s", error_string); else blog(LOG_ERROR, "[create_opaque_effect] Failed to " "create opaque effect"); } bfree(effect_file); bfree(error_string); gs_leavecontext(); return opaque_effect; }
static void image_source_update(void *data, obs_data_t settings) { struct image_source *context = data; const char *file = obs_data_getstring(settings, "file"); gs_entercontext(obs_graphics()); if (context->tex) { texture_destroy(context->tex); context->tex = NULL; } if (file) { context->tex = gs_create_texture_from_file(file); if (context->tex) { context->cx = texture_getwidth(context->tex); context->cy = texture_getheight(context->tex); } else { warn("failed to load texture '%s'", file); context->cx = 0; context->cy = 0; } } gs_leavecontext(); }
void XCompcapMain::tick(float seconds) { UNUSED_PARAMETER(seconds); PLock lock(&p->lock, true); if (!lock.isLocked()) return; XCompcap::processEvents(); if (XCompcap::windowWasReconfigured(p->win)) updateSettings(0); if (!p->tex || !p->gltex) return; gs_entercontext(obs_graphics()); if (p->lockX) { XLockDisplay(xdisp); XSync(xdisp, 0); } gs_copy_texture_region(p->tex, 0, 0, p->gltex, p->cur_cut_left, p->cur_cut_top, width(), height()); if (p->lockX) XUnlockDisplay(xdisp); gs_leavecontext(); }
static void obs_free_graphics() { struct obs_video *video = &obs->video; size_t i; if (video->graphics) { int cur_texture = video->cur_texture; gs_entercontext(video->graphics); if (video->copy_mapped) stagesurface_unmap(video->copy_surfaces[cur_texture]); for (i = 0; i < NUM_TEXTURES; i++) { stagesurface_destroy(video->copy_surfaces[i]); texture_destroy(video->render_textures[i]); texture_destroy(video->output_textures[i]); video->copy_surfaces[i] = NULL; video->render_textures[i] = NULL; video->output_textures[i] = NULL; } effect_destroy(video->default_effect); video->default_effect = NULL; gs_leavecontext(); gs_destroy(video->graphics); video->graphics = NULL; video->cur_texture = 0; } }
static void obs_source_destroy(obs_source_t source) { size_t i; if (source->filter_parent) obs_source_filter_remove(source->filter_parent, source); for (i = 0; i < source->filters.num; i++) obs_source_release(source->filters.array[i]); for (i = 0; i < source->audio_wait_buffer.num; i++) audiobuf_free(source->audio_wait_buffer.array+i); for (i = 0; i < source->video_frames.num; i++) source_frame_destroy(source->video_frames.array[i]); gs_entercontext(obs->video.graphics); texture_destroy(source->output_texture); gs_leavecontext(); if (source->data) source->callbacks.destroy(source->data); bfree(source->audio_data.data); audio_line_destroy(source->audio_line); audio_resampler_destroy(source->resampler); da_free(source->video_frames); da_free(source->audio_wait_buffer); da_free(source->filters); pthread_mutex_destroy(&source->filter_mutex); pthread_mutex_destroy(&source->audio_mutex); pthread_mutex_destroy(&source->video_mutex); dstr_free(&source->settings); bfree(source); }
static void monitor_capture_tick(void *data, float seconds) { struct monitor_capture *capture = data; gs_entercontext(obs_graphics()); dc_capture_capture(&capture->data, NULL); gs_leavecontext(); UNUSED_PARAMETER(seconds); }
static void image_source_destroy(void *data) { struct image_source *context = data; gs_entercontext(obs_graphics()); texture_destroy(context->tex); gs_leavecontext(); bfree(context); }
void test_destroy(struct test_filter *tf) { if (tf) { gs_entercontext(obs_graphics()); effect_destroy(tf->whatever); texrender_destroy(tf->texrender); bfree(tf); gs_leavecontext(); } }
static void random_destroy(void *data) { struct random_tex *rt = data; if (rt) { gs_entercontext(obs_graphics()); texture_destroy(rt->texture); bfree(rt); gs_leavecontext(); } }
static void monitor_capture_destroy(void *data) { struct monitor_capture *capture = data; gs_entercontext(obs_graphics()); dc_capture_free(&capture->data); effect_destroy(capture->opaque_effect); gs_leavecontext(); bfree(capture); }
static void filter_destroy(void *data) { struct test_filter *tf = data; if (tf) { gs_entercontext(obs_graphics()); effect_destroy(tf->whatever); bfree(tf); gs_leavecontext(); } }
static bool obs_init_graphics(struct obs_video_info *ovi) { struct obs_core_video *video = &obs->video; struct gs_init_data graphics_data; bool success = true; int errorcode; make_gs_init_data(&graphics_data, ovi); errorcode = gs_create(&video->graphics, ovi->graphics_module, &graphics_data); if (errorcode != GS_SUCCESS) { if (errorcode == GS_ERROR_MODULE_NOT_FOUND) blog(LOG_ERROR, "Could not find graphics module '%s'", ovi->graphics_module); return false; } gs_entercontext(video->graphics); if (success) { char *filename = find_libobs_data_file("default.effect"); video->default_effect = gs_create_effect_from_file(filename, NULL); bfree(filename); filename = find_libobs_data_file("solid.effect"); video->solid_effect = gs_create_effect_from_file(filename, NULL); bfree(filename); filename = find_libobs_data_file("format_conversion.effect"); video->conversion_effect = gs_create_effect_from_file(filename, NULL); bfree(filename); if (!video->default_effect) success = false; if (!video->solid_effect) success = false; if (!video->conversion_effect) success = false; } gs_leavecontext(); return success; }
static bool obs_init_video(struct obs_video_info *ovi) { struct obs_core_video *video = &obs->video; struct video_output_info vi; int errorcode; make_video_info(&vi, ovi); video->base_width = ovi->base_width; video->base_height = ovi->base_height; video->output_width = ovi->output_width; video->output_height = ovi->output_height; video->gpu_conversion = ovi->gpu_conversion; errorcode = video_output_open(&video->video, &vi); if (errorcode != VIDEO_OUTPUT_SUCCESS) { if (errorcode == VIDEO_OUTPUT_INVALIDPARAM) blog(LOG_ERROR, "Invalid video parameters specified"); else blog(LOG_ERROR, "Could not open video output"); return false; } if (!obs_display_init(&video->main_display, NULL)) return false; video->main_display.cx = ovi->window_width; video->main_display.cy = ovi->window_height; gs_entercontext(video->graphics); if (ovi->gpu_conversion && !obs_init_gpu_conversion(ovi)) return false; if (!obs_init_textures(ovi)) return false; gs_leavecontext(); errorcode = pthread_create(&video->video_thread, NULL, obs_video_thread, obs); if (errorcode != 0) return false; video->thread_initialized = true; return true; }
void dc_capture_free(struct dc_capture *capture) { if (capture->hdc) { SelectObject(capture->hdc, capture->old_bmp); DeleteDC(capture->hdc); DeleteObject(capture->bmp); } gs_entercontext(obs_graphics()); for (size_t i = 0; i < capture->num_textures; i++) texture_destroy(capture->textures[i]); gs_leavecontext(); memset(capture, 0, sizeof(struct dc_capture)); }
static void obs_free_graphics(void) { struct obs_core_video *video = &obs->video; if (video->graphics) { gs_entercontext(video->graphics); effect_destroy(video->default_effect); effect_destroy(video->solid_effect); effect_destroy(video->conversion_effect); video->default_effect = NULL; gs_leavecontext(); gs_destroy(video->graphics); video->graphics = NULL; } }
void *obs_video_thread(void *param) { uint64_t last_time = 0; while (video_output_wait(obs->video.video)) { uint64_t cur_time = video_gettime(obs->video.video); gs_entercontext(obs_graphics()); tick_sources(cur_time, &last_time); render_displays(); swap_frame(cur_time); gs_leavecontext(); } return NULL; }
void obs_source_destroy(struct obs_source *source) { size_t i; if (!source) return; obs_context_data_remove(&source->context); obs_source_dosignal(source, "source_destroy", "destroy"); if (source->context.data) source->info.destroy(source->context.data); if (source->filter_parent) obs_source_filter_remove(source->filter_parent, source); for (i = 0; i < source->filters.num; i++) obs_source_release(source->filters.array[i]); for (i = 0; i < source->video_frames.num; i++) source_frame_destroy(source->video_frames.array[i]); gs_entercontext(obs->video.graphics); texrender_destroy(source->async_convert_texrender); texture_destroy(source->async_texture); gs_leavecontext(); for (i = 0; i < MAX_AV_PLANES; i++) bfree(source->audio_data.data[i]); audio_line_destroy(source->audio_line); audio_resampler_destroy(source->resampler); texrender_destroy(source->filter_texrender); da_free(source->video_frames); da_free(source->filters); pthread_mutex_destroy(&source->filter_mutex); pthread_mutex_destroy(&source->audio_mutex); pthread_mutex_destroy(&source->video_mutex); obs_context_data_free(&source->context); bfree(source); }
static inline void render_displays(void) { if (!obs->data.valid) return; gs_entercontext(obs_graphics()); /* render extra displays/swaps */ pthread_mutex_lock(&obs->data.displays_mutex); for (size_t i = 0; i < obs->data.displays.num; i++) render_display(obs->data.displays.array[i]); pthread_mutex_unlock(&obs->data.displays_mutex); /* render main display */ render_display(&obs->video.main_display); gs_leavecontext(); }
void dc_capture_init(struct dc_capture *capture, int x, int y, uint32_t width, uint32_t height, bool cursor, bool compatibility) { capture->x = x; capture->y = y; capture->width = width; capture->height = height; capture->capture_cursor = cursor; gs_entercontext(obs_graphics()); if (!gs_gdi_texture_available()) compatibility = true; capture->compatibility = compatibility; capture->num_textures = compatibility ? 1 : 2; init_textures(capture); gs_leavecontext(); if (!capture->valid) return; if (compatibility) { BITMAPINFO bi = {0}; BITMAPINFOHEADER *bih = &bi.bmiHeader; bih->biSize = sizeof(BITMAPINFOHEADER); bih->biBitCount = 32; bih->biWidth = width; bih->biHeight = height; bih->biPlanes = 1; capture->hdc = CreateCompatibleDC(NULL); capture->bmp = CreateDIBSection(capture->hdc, &bi, DIB_RGB_COLORS, (void**)&capture->bits, NULL, 0); capture->old_bmp = SelectObject(capture->hdc, capture->bmp); } }
static void *filter_create(obs_data_t settings, obs_source_t source) { struct test_filter *tf = bzalloc(sizeof(struct test_filter)); char *effect_file; gs_entercontext(obs_graphics()); effect_file = obs_find_plugin_file("test-input/test.effect"); tf->source = source; tf->whatever = gs_create_effect_from_file(effect_file, NULL); bfree(effect_file); if (!tf->whatever) { filter_destroy(tf); return NULL; } gs_leavecontext(); UNUSED_PARAMETER(settings); return tf; }
static void obs_source_destroy(obs_source_t source) { size_t i; obs_source_dosignal(source, "source-destroy"); if (source->filter_parent) obs_source_filter_remove(source->filter_parent, source); for (i = 0; i < source->filters.num; i++) obs_source_release(source->filters.array[i]); for (i = 0; i < source->video_frames.num; i++) source_frame_destroy(source->video_frames.array[i]); gs_entercontext(obs->video.graphics); texture_destroy(source->output_texture); gs_leavecontext(); if (source->data) source->callbacks.destroy(source->data); bfree(source->audio_data.data); audio_line_destroy(source->audio_line); audio_resampler_destroy(source->resampler); proc_handler_destroy(source->procs); signal_handler_destroy(source->signals); da_free(source->video_frames); da_free(source->filters); pthread_mutex_destroy(&source->filter_mutex); pthread_mutex_destroy(&source->audio_mutex); pthread_mutex_destroy(&source->video_mutex); obs_data_release(source->settings); bfree(source->name); bfree(source); }
static void obs_free_video(void) { struct obs_core_video *video = &obs->video; if (video->video) { obs_display_free(&video->main_display); video_output_close(video->video); video->video = NULL; if (!video->graphics) return; gs_entercontext(video->graphics); if (video->mapped_surface) { stagesurface_unmap(video->mapped_surface); video->mapped_surface = NULL; } for (size_t i = 0; i < NUM_TEXTURES; i++) { stagesurface_destroy(video->copy_surfaces[i]); texture_destroy(video->render_textures[i]); texture_destroy(video->convert_textures[i]); texture_destroy(video->output_textures[i]); source_frame_free(&video->convert_frames[i]); video->copy_surfaces[i] = NULL; video->render_textures[i] = NULL; video->convert_textures[i] = NULL; video->output_textures[i] = NULL; } gs_leavecontext(); video->cur_texture = 0; } }
struct test_filter *test_create(const char *settings, obs_source_t source) { struct test_filter *tf = bmalloc(sizeof(struct test_filter)); char *effect_file; memset(tf, 0, sizeof(struct test_filter)); gs_entercontext(obs_graphics()); effect_file = obs_find_plugin_file("test-input/test.effect"); tf->source = source; tf->whatever = gs_create_effect_from_file(effect_file, NULL); bfree(effect_file); if (!tf->whatever) { test_destroy(tf); return NULL; } tf->texrender = texrender_create(GS_RGBA, GS_ZS_NONE); gs_leavecontext(); return tf; }
static inline void output_frame(uint64_t timestamp) { struct obs_core_video *video = &obs->video; int cur_texture = video->cur_texture; int prev_texture = cur_texture == 0 ? NUM_TEXTURES-1 : cur_texture-1; struct video_data frame; bool frame_ready; memset(&frame, 0, sizeof(struct video_data)); frame.timestamp = timestamp; gs_entercontext(obs_graphics()); render_video(video, cur_texture, prev_texture); frame_ready = download_frame(video, prev_texture, &frame); gs_leavecontext(); if (frame_ready) output_video_data(video, &frame, cur_texture); if (++video->cur_texture == NUM_TEXTURES) video->cur_texture = 0; }