diff --git a/plugins/image-source/image-source.c b/plugins/image-source/image-source.c index 2eb51e744..f8729663a 100644 --- a/plugins/image-source/image-source.c +++ b/plugins/image-source/image-source.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -20,10 +21,9 @@ struct image_source { bool persistent; time_t file_timestamp; float update_time_elapsed; + uint64_t last_time; - gs_texture_t *tex; - uint32_t cx; - uint32_t cy; + gs_image_file_t image; }; @@ -45,38 +45,28 @@ static void image_source_load(struct image_source *context) char *file = context->file; obs_enter_graphics(); - - if (context->tex) - gs_texture_destroy(context->tex); - context->tex = NULL; + gs_image_file_free(&context->image); + obs_leave_graphics(); if (file && *file) { debug("loading texture '%s'", file); context->file_timestamp = get_modified_timestamp(file); - context->tex = gs_texture_create_from_file(file); + gs_image_file_init(&context->image, file); context->update_time_elapsed = 0; - if (context->tex) { - context->cx = gs_texture_get_width(context->tex); - context->cy = gs_texture_get_height(context->tex); - } else { - warn("failed to load texture '%s'", file); - context->cx = 0; - context->cy = 0; - } - } + obs_enter_graphics(); + gs_image_file_init_texture(&context->image); + obs_leave_graphics(); - obs_leave_graphics(); + if (!context->image.loaded) + warn("failed to load texture '%s'", file); + } } static void image_source_unload(struct image_source *context) { obs_enter_graphics(); - - if (context->tex) - gs_texture_destroy(context->tex); - context->tex = NULL; - + gs_image_file_free(&context->image); obs_leave_graphics(); } @@ -142,31 +132,46 @@ static void image_source_destroy(void *data) static uint32_t image_source_getwidth(void *data) { struct image_source *context = data; - return context->cx; + return context->image.cx; } static uint32_t image_source_getheight(void *data) { struct image_source *context = data; - return context->cy; + return context->image.cy; } static void image_source_render(void *data, gs_effect_t *effect) { struct image_source *context = data; - if (!context->tex) + if (!context->image.texture) return; gs_reset_blend_state(); gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), - context->tex); - gs_draw_sprite(context->tex, 0, context->cx, context->cy); + context->image.texture); + gs_draw_sprite(context->image.texture, 0, + context->image.cx, context->image.cy); } static void image_source_tick(void *data, float seconds) { struct image_source *context = data; + uint64_t frame_time = obs_get_video_frame_time(); + + if (context->last_time && context->image.is_animated_gif) { + uint64_t elapsed = frame_time - context->last_time; + bool updated = gs_image_file_tick(&context->image, elapsed); + + if (updated) { + obs_enter_graphics(); + gs_image_file_update_texture(&context->image); + obs_leave_graphics(); + } + } + + context->last_time = frame_time; if (!obs_source_showing(context->source)) return;