Browse Source

libobs: Format changes for multiple video mixes

Chip Bradford 3 years ago
parent
commit
0a87797a21
3 changed files with 129 additions and 130 deletions
  1. 8 9
      libobs/obs-video-gpu-encode.c
  2. 21 20
      libobs/obs-video.c
  3. 100 101
      libobs/obs.c

+ 8 - 9
libobs/obs-video-gpu-encode.c

@@ -150,7 +150,8 @@ static void *gpu_encode_thread(struct obs_core_video_mix *video)
 bool init_gpu_encoding(struct obs_core_video_mix *video)
 {
 #ifdef _WIN32
-	const struct video_output_info *info = video_output_get_info(video->video);
+	const struct video_output_info *info =
+		video_output_get_info(video->video);
 
 	video->gpu_encode_stop = false;
 
@@ -160,15 +161,13 @@ bool init_gpu_encoding(struct obs_core_video_mix *video)
 		gs_texture_t *tex_uv;
 
 		if (info->format == VIDEO_FORMAT_P010) {
-			gs_texture_create_p010(&tex, &tex_uv, info->width,
-					       info->height,
-					       GS_RENDER_TARGET |
-						       GS_SHARED_KM_TEX);
+			gs_texture_create_p010(
+				&tex, &tex_uv, info->width, info->height,
+				GS_RENDER_TARGET | GS_SHARED_KM_TEX);
 		} else {
-			gs_texture_create_nv12(&tex, &tex_uv, info->width,
-					       info->height,
-					       GS_RENDER_TARGET |
-						       GS_SHARED_KM_TEX);
+			gs_texture_create_nv12(
+				&tex, &tex_uv, info->width, info->height,
+				GS_RENDER_TARGET | GS_SHARED_KM_TEX);
 		}
 		if (!tex) {
 			return false;

+ 21 - 20
libobs/obs-video.c

@@ -37,8 +37,7 @@ static uint64_t tick_sources(uint64_t cur_time, uint64_t last_time)
 	float seconds;
 
 	if (!last_time)
-		last_time = cur_time -
-			    obs->video.video_frame_interval_ns;
+		last_time = cur_time - obs->video.video_frame_interval_ns;
 
 	delta_time = cur_time - last_time;
 	seconds = (float)((double)delta_time / 1000000000.0);
@@ -148,8 +147,7 @@ static inline void render_main_texture(struct obs_core_video_mix *video)
 		struct draw_callback *callback;
 		callback = obs->data.draw_callbacks.array + (i - 1);
 
-		callback->draw(callback->param, base_width,
-			       base_height);
+		callback->draw(callback->param, base_width, base_height);
 	}
 
 	pthread_mutex_unlock(&obs->data.draw_callbacks_mutex);
@@ -166,7 +164,8 @@ static inline gs_effect_t *
 get_scale_effect_internal(struct obs_core_video_mix *mix)
 {
 	struct obs_core_video *video = &obs->video;
-	const struct video_output_info *info = video_output_get_info(mix->video);
+	const struct video_output_info *info =
+		video_output_get_info(mix->video);
 
 	/* if the dimension is under half the size of the original image,
 	 * bicubic/lanczos can't sample enough pixels to create an accurate
@@ -219,7 +218,8 @@ static inline gs_effect_t *get_scale_effect(struct obs_core_video_mix *mix,
 }
 
 static const char *render_output_texture_name = "render_output_texture";
-static inline gs_texture_t *render_output_texture(struct obs_core_video_mix *mix)
+static inline gs_texture_t *
+render_output_texture(struct obs_core_video_mix *mix)
 {
 	struct obs_core_video *video = &obs->video;
 	gs_texture_t *texture = mix->render_texture;
@@ -427,7 +427,8 @@ stage_output_texture(struct obs_core_video_mix *video, int cur_texture,
 }
 
 #ifdef _WIN32
-static inline bool queue_frame(struct obs_core_video_mix *video, bool raw_active,
+static inline bool queue_frame(struct obs_core_video_mix *video,
+			       bool raw_active,
 			       struct obs_vframe_info *vframe_info)
 {
 	bool duplicate =
@@ -497,7 +498,8 @@ static inline void encode_gpu(struct obs_core_video_mix *video, bool raw_active,
 }
 
 static const char *output_gpu_encoders_name = "output_gpu_encoders";
-static void output_gpu_encoders(struct obs_core_video_mix *video, bool raw_active)
+static void output_gpu_encoders(struct obs_core_video_mix *video,
+				bool raw_active)
 {
 	profile_start(output_gpu_encoders_name);
 
@@ -519,8 +521,9 @@ end:
 }
 #endif
 
-static inline void render_video(struct obs_core_video_mix *video, bool raw_active,
-				const bool gpu_active, int cur_texture)
+static inline void render_video(struct obs_core_video_mix *video,
+				bool raw_active, const bool gpu_active,
+				int cur_texture)
 {
 	gs_begin_scene();
 
@@ -795,8 +798,7 @@ static inline void output_video_data(struct obs_core_video_mix *video,
 	}
 }
 
-static inline void video_sleep(struct obs_core_video *video,
-			       uint64_t *p_time,
+static inline void video_sleep(struct obs_core_video *video, uint64_t *p_time,
 			       uint64_t interval_ns)
 {
 	struct obs_vframe_info vframe_info;
@@ -830,12 +832,12 @@ static inline void video_sleep(struct obs_core_video *video,
 		bool raw_active = video->raw_was_active;
 		bool gpu_active = video->gpu_was_active;
 
-	if (raw_active)
-		circlebuf_push_back(&video->vframe_info_buffer, &vframe_info,
-				    sizeof(vframe_info));
-	if (gpu_active)
-		circlebuf_push_back(&video->vframe_info_buffer_gpu,
-				    &vframe_info, sizeof(vframe_info));
+		if (raw_active)
+			circlebuf_push_back(&video->vframe_info_buffer,
+					    &vframe_info, sizeof(vframe_info));
+		if (gpu_active)
+			circlebuf_push_back(&video->vframe_info_buffer_gpu,
+					    &vframe_info, sizeof(vframe_info));
 	}
 	pthread_mutex_unlock(&obs->video.mixes_mutex);
 }
@@ -1132,8 +1134,7 @@ bool obs_graphics_thread_loop(struct obs_graphics_context *context)
 
 	profile_reenable_thread();
 
-	video_sleep(&obs->video, &obs->video.video_time,
-		    context->interval);
+	video_sleep(&obs->video, &obs->video.video_time, context->interval);
 
 	context->frame_time_total_ns += frame_time_ns;
 	context->fps_total_ns += (obs->video.video_time - context->last_time);

+ 100 - 101
libobs/obs.c

@@ -46,7 +46,8 @@ static inline void make_video_info(struct video_output_info *vi,
 
 static inline void calc_gpu_conversion_sizes(struct obs_core_video_mix *video)
 {
-	const struct video_output_info *info = video_output_get_info(video->video);
+	const struct video_output_info *info =
+		video_output_get_info(video->video);
 
 	video->conversion_needed = false;
 	video->conversion_techs[0] = NULL;
@@ -117,12 +118,10 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
 
 	calc_gpu_conversion_sizes(video);
 
-	video->using_nv12_tex = info->format == VIDEO_FORMAT_NV12
-					? gs_nv12_available()
-					: false;
-	video->using_p010_tex = info->format == VIDEO_FORMAT_P010
-					? gs_p010_available()
-					: false;
+	video->using_nv12_tex =
+		info->format == VIDEO_FORMAT_NV12 ? gs_nv12_available() : false;
+	video->using_p010_tex =
+		info->format == VIDEO_FORMAT_P010 ? gs_p010_available() : false;
 
 	if (!video->conversion_needed) {
 		blog(LOG_INFO, "GPU conversion not available for format: %u",
@@ -152,19 +151,19 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
 	video->convert_textures_encode[1] = NULL;
 	video->convert_textures_encode[2] = NULL;
 	if (video->using_nv12_tex) {
-		if (!gs_texture_create_nv12(
-			    &video->convert_textures_encode[0],
-			    &video->convert_textures_encode[1],
-			    info->width, info->height,
-			    GS_RENDER_TARGET | GS_SHARED_KM_TEX)) {
+		if (!gs_texture_create_nv12(&video->convert_textures_encode[0],
+					    &video->convert_textures_encode[1],
+					    info->width, info->height,
+					    GS_RENDER_TARGET |
+						    GS_SHARED_KM_TEX)) {
 			return false;
 		}
 	} else if (video->using_p010_tex) {
-		if (!gs_texture_create_p010(
-			    &video->convert_textures_encode[0],
-			    &video->convert_textures_encode[1],
-			    info->width, info->height,
-			    GS_RENDER_TARGET | GS_SHARED_KM_TEX)) {
+		if (!gs_texture_create_p010(&video->convert_textures_encode[0],
+					    &video->convert_textures_encode[1],
+					    info->width, info->height,
+					    GS_RENDER_TARGET |
+						    GS_SHARED_KM_TEX)) {
 			return false;
 		}
 	}
@@ -175,63 +174,63 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
 	switch (info->format) {
 	case VIDEO_FORMAT_I420:
 		video->convert_textures[0] =
-			gs_texture_create(info->width, info->height,
+			gs_texture_create(info->width, info->height, GS_R8, 1,
+					  NULL, GS_RENDER_TARGET);
+		video->convert_textures[1] =
+			gs_texture_create(info->width / 2, info->height / 2,
+					  GS_R8, 1, NULL, GS_RENDER_TARGET);
+		video->convert_textures[2] =
+			gs_texture_create(info->width / 2, info->height / 2,
 					  GS_R8, 1, NULL, GS_RENDER_TARGET);
-		video->convert_textures[1] = gs_texture_create(
-			info->width / 2, info->height / 2, GS_R8, 1,
-			NULL, GS_RENDER_TARGET);
-		video->convert_textures[2] = gs_texture_create(
-			info->width / 2, info->height / 2, GS_R8, 1,
-			NULL, GS_RENDER_TARGET);
 		if (!video->convert_textures[0] ||
 		    !video->convert_textures[1] || !video->convert_textures[2])
 			success = false;
 		break;
 	case VIDEO_FORMAT_NV12:
 		video->convert_textures[0] =
-			gs_texture_create(info->width, info->height,
-					  GS_R8, 1, NULL, GS_RENDER_TARGET);
-		video->convert_textures[1] = gs_texture_create(
-			info->width / 2, info->height / 2, GS_R8G8,
-			1, NULL, GS_RENDER_TARGET);
+			gs_texture_create(info->width, info->height, GS_R8, 1,
+					  NULL, GS_RENDER_TARGET);
+		video->convert_textures[1] =
+			gs_texture_create(info->width / 2, info->height / 2,
+					  GS_R8G8, 1, NULL, GS_RENDER_TARGET);
 		if (!video->convert_textures[0] || !video->convert_textures[1])
 			success = false;
 		break;
 	case VIDEO_FORMAT_I444:
 		video->convert_textures[0] =
-			gs_texture_create(info->width, info->height,
-					  GS_R8, 1, NULL, GS_RENDER_TARGET);
+			gs_texture_create(info->width, info->height, GS_R8, 1,
+					  NULL, GS_RENDER_TARGET);
 		video->convert_textures[1] =
-			gs_texture_create(info->width, info->height,
-					  GS_R8, 1, NULL, GS_RENDER_TARGET);
+			gs_texture_create(info->width, info->height, GS_R8, 1,
+					  NULL, GS_RENDER_TARGET);
 		video->convert_textures[2] =
-			gs_texture_create(info->width, info->height,
-					  GS_R8, 1, NULL, GS_RENDER_TARGET);
+			gs_texture_create(info->width, info->height, GS_R8, 1,
+					  NULL, GS_RENDER_TARGET);
 		if (!video->convert_textures[0] ||
 		    !video->convert_textures[1] || !video->convert_textures[2])
 			success = false;
 		break;
 	case VIDEO_FORMAT_I010:
 		video->convert_textures[0] =
-			gs_texture_create(info->width, info->height,
+			gs_texture_create(info->width, info->height, GS_R16, 1,
+					  NULL, GS_RENDER_TARGET);
+		video->convert_textures[1] =
+			gs_texture_create(info->width / 2, info->height / 2,
+					  GS_R16, 1, NULL, GS_RENDER_TARGET);
+		video->convert_textures[2] =
+			gs_texture_create(info->width / 2, info->height / 2,
 					  GS_R16, 1, NULL, GS_RENDER_TARGET);
-		video->convert_textures[1] = gs_texture_create(
-			info->width / 2, info->height / 2, GS_R16,
-			1, NULL, GS_RENDER_TARGET);
-		video->convert_textures[2] = gs_texture_create(
-			info->width / 2, info->height / 2, GS_R16,
-			1, NULL, GS_RENDER_TARGET);
 		if (!video->convert_textures[0] ||
 		    !video->convert_textures[1] || !video->convert_textures[2])
 			success = false;
 		break;
 	case VIDEO_FORMAT_P010:
 		video->convert_textures[0] =
-			gs_texture_create(info->width, info->height,
-					  GS_R16, 1, NULL, GS_RENDER_TARGET);
-		video->convert_textures[1] = gs_texture_create(
-			info->width / 2, info->height / 2, GS_RG16,
-			1, NULL, GS_RENDER_TARGET);
+			gs_texture_create(info->width, info->height, GS_R16, 1,
+					  NULL, GS_RENDER_TARGET);
+		video->convert_textures[1] =
+			gs_texture_create(info->width / 2, info->height / 2,
+					  GS_RG16, 1, NULL, GS_RENDER_TARGET);
 		if (!video->convert_textures[0] || !video->convert_textures[1])
 			success = false;
 		break;
@@ -256,7 +255,8 @@ static bool obs_init_gpu_conversion(struct obs_core_video_mix *video)
 	return success;
 }
 
-static bool obs_init_gpu_copy_surfaces(struct obs_core_video_mix *video, size_t i)
+static bool obs_init_gpu_copy_surfaces(struct obs_core_video_mix *video,
+				       size_t i)
 {
 	const struct video_output_info *info =
 		video_output_get_info(video->video);
@@ -332,7 +332,8 @@ static bool obs_init_gpu_copy_surfaces(struct obs_core_video_mix *video, size_t
 
 static bool obs_init_textures(struct obs_core_video_mix *video)
 {
-	const struct video_output_info *info = video_output_get_info(video->video);
+	const struct video_output_info *info =
+		video_output_get_info(video->video);
 
 	bool success = true;
 
@@ -396,15 +397,14 @@ static bool obs_init_textures(struct obs_core_video_mix *video)
 		}
 	}
 
-	video->render_texture = gs_texture_create(obs->video.base_width,
-						  obs->video.base_height, format, 1,
-						  NULL, GS_RENDER_TARGET);
+	video->render_texture =
+		gs_texture_create(obs->video.base_width, obs->video.base_height,
+				  format, 1, NULL, GS_RENDER_TARGET);
 	if (!video->render_texture)
 		success = false;
 
-	video->output_texture = gs_texture_create(info->width,
-						  info->height, format, 1,
-						  NULL, GS_RENDER_TARGET);
+	video->output_texture = gs_texture_create(
+		info->width, info->height, format, 1, NULL, GS_RENDER_TARGET);
 	if (!video->output_texture)
 		success = false;
 
@@ -625,8 +625,10 @@ static int obs_init_video(struct obs_video_info *ovi)
 	struct obs_core_video *video = &obs->video;
 	video->base_width = ovi->base_width;
 	video->base_height = ovi->base_height;
-	video->video_frame_interval_ns = util_mul_div64(1000000000ULL, ovi->fps_den, ovi->fps_num);
-	video->video_half_frame_interval_ns = util_mul_div64(500000000ULL, ovi->fps_den, ovi->fps_num);
+	video->video_frame_interval_ns =
+		util_mul_div64(1000000000ULL, ovi->fps_den, ovi->fps_num);
+	video->video_half_frame_interval_ns =
+		util_mul_div64(500000000ULL, ovi->fps_den, ovi->fps_num);
 
 	if (pthread_mutex_init(&video->task_mutex, NULL) < 0)
 		return OBS_VIDEO_FAIL;
@@ -663,67 +665,64 @@ static void stop_video(void)
 	struct obs_core_video *video = &obs->video;
 	void *thread_retval;
 
-		if (video->thread_initialized) {
-			pthread_join(video->video_thread, &thread_retval);
-			video->thread_initialized = false;
-		}
+	if (video->thread_initialized) {
+		pthread_join(video->video_thread, &thread_retval);
+		video->thread_initialized = false;
+	}
 }
 
 static void obs_free_render_textures(struct obs_core_video_mix *video)
 {
-		if (!obs->video.graphics)
-			return;
+	if (!obs->video.graphics)
+		return;
 
-		gs_enter_context(obs->video.graphics);
+	gs_enter_context(obs->video.graphics);
 
-		for (size_t c = 0; c < NUM_CHANNELS; c++) {
-			if (video->mapped_surfaces[c]) {
-				gs_stagesurface_unmap(
-					video->mapped_surfaces[c]);
-				video->mapped_surfaces[c] = NULL;
-			}
+	for (size_t c = 0; c < NUM_CHANNELS; c++) {
+		if (video->mapped_surfaces[c]) {
+			gs_stagesurface_unmap(video->mapped_surfaces[c]);
+			video->mapped_surfaces[c] = NULL;
 		}
+	}
 
-		for (size_t i = 0; i < NUM_TEXTURES; i++) {
-			for (size_t c = 0; c < NUM_CHANNELS; c++) {
-				if (video->copy_surfaces[i][c]) {
-					gs_stagesurface_destroy(
-						video->copy_surfaces[i][c]);
-					video->copy_surfaces[i][c] = NULL;
-				}
-
-				video->active_copy_surfaces[i][c] = NULL;
-			}
-#ifdef _WIN32
-			if (video->copy_surfaces_encode[i]) {
+	for (size_t i = 0; i < NUM_TEXTURES; i++) {
+		for (size_t c = 0; c < NUM_CHANNELS; c++) {
+			if (video->copy_surfaces[i][c]) {
 				gs_stagesurface_destroy(
-					video->copy_surfaces_encode[i]);
-				video->copy_surfaces_encode[i] = NULL;
+					video->copy_surfaces[i][c]);
+				video->copy_surfaces[i][c] = NULL;
 			}
-#endif
+
+			video->active_copy_surfaces[i][c] = NULL;
+		}
+#ifdef _WIN32
+		if (video->copy_surfaces_encode[i]) {
+			gs_stagesurface_destroy(video->copy_surfaces_encode[i]);
+			video->copy_surfaces_encode[i] = NULL;
 		}
+#endif
+	}
 
-		gs_texture_destroy(video->render_texture);
+	gs_texture_destroy(video->render_texture);
 
-		for (size_t c = 0; c < NUM_CHANNELS; c++) {
-			if (video->convert_textures[c]) {
-				gs_texture_destroy(video->convert_textures[c]);
-				video->convert_textures[c] = NULL;
-			}
+	for (size_t c = 0; c < NUM_CHANNELS; c++) {
+		if (video->convert_textures[c]) {
+			gs_texture_destroy(video->convert_textures[c]);
+			video->convert_textures[c] = NULL;
+		}
 #ifdef _WIN32
-			if (video->convert_textures_encode[c]) {
-				gs_texture_destroy(
-					video->convert_textures_encode[c]);
-				video->convert_textures_encode[c] = NULL;
-			}
-#endif
+		if (video->convert_textures_encode[c]) {
+			gs_texture_destroy(video->convert_textures_encode[c]);
+			video->convert_textures_encode[c] = NULL;
 		}
+#endif
+	}
 
-		gs_texture_destroy(video->output_texture);
-		video->render_texture = NULL;
-		video->output_texture = NULL;
+	gs_texture_destroy(video->output_texture);
+	video->render_texture = NULL;
+	video->output_texture = NULL;
 
-		gs_leave_context();
+	gs_leave_context();
 }
 
 void obs_free_video_mix(struct obs_core_video_mix *video)