Browse Source

libobs: Ensure async source sizes are always reset

If an async source is cropped on one side, then when the program is
restarted and the source is loaded from file, the async source will
start out with a width/height of zero.  This will cause the async source
to not be drawn if cropping or scale filtering is added to the scene
item, because it has to be rendered to a texture first.  However, the
source cannot reset its size until it's drawn, so it leaves it in
perpetual state of having a 0x0 size.

This fixes that problem by ensuring that the async source size is always
reset even when not being rendered.

Close jp9000/obs-studio#686
Jim 9 years ago
parent
commit
9982581a4f
2 changed files with 38 additions and 22 deletions
  1. 1 0
      libobs/obs-internal.h
  2. 37 22
      libobs/obs-source.c

+ 1 - 0
libobs/obs-internal.h

@@ -593,6 +593,7 @@ struct obs_source {
 	int                             async_plane_offset[2];
 	bool                            async_flip;
 	bool                            async_active;
+	bool                            async_update_texture;
 	DARRAY(struct async_frame)      async_cache;
 	DARRAY(struct obs_source_frame*)async_frames;
 	pthread_mutex_t                 async_mutex;

+ 37 - 22
libobs/obs-source.c

@@ -921,6 +921,35 @@ void obs_source_deactivate(obs_source_t *source, enum view_type type)
 
 static inline struct obs_source_frame *get_closest_frame(obs_source_t *source,
 		uint64_t sys_time);
+bool set_async_texture_size(struct obs_source *source,
+		const struct obs_source_frame *frame);
+
+static void async_tick(obs_source_t *source)
+{
+	uint64_t sys_time = obs->video.video_time;
+
+	pthread_mutex_lock(&source->async_mutex);
+
+	if (deinterlacing_enabled(source)) {
+		deinterlace_process_last_frame(source, sys_time);
+	} else {
+		if (source->cur_async_frame) {
+			remove_async_frame(source,
+					source->cur_async_frame);
+			source->cur_async_frame = NULL;
+		}
+
+		source->cur_async_frame = get_closest_frame(source,
+				sys_time);
+	}
+
+	source->last_sys_timestamp = sys_time;
+	pthread_mutex_unlock(&source->async_mutex);
+
+	if (source->cur_async_frame)
+		source->async_update_texture = set_async_texture_size(source,
+				source->cur_async_frame);
+}
 
 void obs_source_video_tick(obs_source_t *source, float seconds)
 {
@@ -932,27 +961,8 @@ void obs_source_video_tick(obs_source_t *source, float seconds)
 	if (source->info.type == OBS_SOURCE_TYPE_TRANSITION)
 		obs_transition_tick(source);
 
-	if ((source->info.output_flags & OBS_SOURCE_ASYNC) != 0) {
-		uint64_t sys_time = obs->video.video_time;
-
-		pthread_mutex_lock(&source->async_mutex);
-
-		if (deinterlacing_enabled(source)) {
-			deinterlace_process_last_frame(source, sys_time);
-		} else {
-			if (source->cur_async_frame) {
-				remove_async_frame(source,
-						source->cur_async_frame);
-				source->cur_async_frame = NULL;
-			}
-
-			source->cur_async_frame = get_closest_frame(source,
-					sys_time);
-		}
-
-		source->last_sys_timestamp = sys_time;
-		pthread_mutex_unlock(&source->async_mutex);
-	}
+	if ((source->info.output_flags & OBS_SOURCE_ASYNC) != 0)
+		async_tick(source);
 
 	if (source->defer_update)
 		obs_source_deferred_update(source);
@@ -1333,6 +1343,8 @@ bool set_async_texture_size(struct obs_source *source,
 	source->async_height = frame->height;
 	source->async_format = frame->format;
 
+	gs_enter_context(obs->video.graphics);
+
 	gs_texture_destroy(source->async_texture);
 	gs_texture_destroy(source->async_prev_texture);
 	gs_texrender_destroy(source->async_texrender);
@@ -1367,6 +1379,8 @@ bool set_async_texture_size(struct obs_source *source,
 	if (deinterlacing_enabled(source))
 		set_deinterlace_texture_size(source);
 
+	gs_leave_context();
+
 	return !!source->async_texture;
 }
 
@@ -1614,10 +1628,11 @@ static void obs_source_update_async_video(obs_source_t *source)
 				os_gettime_ns() - frame->timestamp;
 			source->timing_set = true;
 
-			if (set_async_texture_size(source, frame)) {
+			if (source->async_update_texture) {
 				update_async_texture(source, frame,
 						source->async_texture,
 						source->async_texrender);
+				source->async_update_texture = false;
 			}
 
 			obs_source_release_frame(source, frame);