Browse Source

image-source: Use gs_image_file (adds animated gif support)

jp9000 9 năm trước cách đây
mục cha
commit
423f5ea1fc
1 tập tin đã thay đổi với 32 bổ sung27 xóa
  1. 32 27
      plugins/image-source/image-source.c

+ 32 - 27
plugins/image-source/image-source.c

@@ -1,4 +1,5 @@
 #include <obs-module.h>
+#include <graphics/image-file.h>
 #include <util/platform.h>
 #include <sys/stat.h>
 
@@ -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 {
+		obs_enter_graphics();
+		gs_image_file_init_texture(&context->image);
+		obs_leave_graphics();
+
+		if (!context->image.loaded)
 			warn("failed to load texture '%s'", file);
-			context->cx = 0;
-			context->cy = 0;
-		}
 	}
-
-	obs_leave_graphics();
 }
 
 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;