|
@@ -334,8 +334,8 @@ end:
|
|
|
profile_end(stage_output_texture_name);
|
|
|
}
|
|
|
|
|
|
-static inline void render_video(struct obs_core_video *video, int cur_texture,
|
|
|
- int prev_texture)
|
|
|
+static inline void render_video(struct obs_core_video *video, bool raw_active,
|
|
|
+ int cur_texture, int prev_texture)
|
|
|
{
|
|
|
gs_begin_scene();
|
|
|
|
|
@@ -343,11 +343,14 @@ static inline void render_video(struct obs_core_video *video, int cur_texture,
|
|
|
gs_set_cull_mode(GS_NEITHER);
|
|
|
|
|
|
render_main_texture(video, cur_texture);
|
|
|
- render_output_texture(video, cur_texture, prev_texture);
|
|
|
- if (video->gpu_conversion)
|
|
|
- render_convert_texture(video, cur_texture, prev_texture);
|
|
|
|
|
|
- stage_output_texture(video, cur_texture, prev_texture);
|
|
|
+ if (raw_active) {
|
|
|
+ render_output_texture(video, cur_texture, prev_texture);
|
|
|
+ if (video->gpu_conversion)
|
|
|
+ render_convert_texture(video, cur_texture, prev_texture);
|
|
|
+
|
|
|
+ stage_output_texture(video, cur_texture, prev_texture);
|
|
|
+ }
|
|
|
|
|
|
gs_set_render_target(NULL, NULL);
|
|
|
gs_enable_blending(true);
|
|
@@ -522,7 +525,7 @@ static inline void output_video_data(struct obs_core_video *video,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static inline void video_sleep(struct obs_core_video *video,
|
|
|
+static inline void video_sleep(struct obs_core_video *video, bool active,
|
|
|
uint64_t *p_time, uint64_t interval_ns)
|
|
|
{
|
|
|
struct obs_vframe_info vframe_info;
|
|
@@ -543,8 +546,9 @@ static inline void video_sleep(struct obs_core_video *video,
|
|
|
|
|
|
vframe_info.timestamp = cur_time;
|
|
|
vframe_info.count = count;
|
|
|
- circlebuf_push_back(&video->vframe_info_buffer, &vframe_info,
|
|
|
- sizeof(vframe_info));
|
|
|
+ if (active)
|
|
|
+ circlebuf_push_back(&video->vframe_info_buffer, &vframe_info,
|
|
|
+ sizeof(vframe_info));
|
|
|
}
|
|
|
|
|
|
static const char *output_frame_gs_context_name = "gs_context(video->graphics)";
|
|
@@ -552,7 +556,7 @@ static const char *output_frame_render_video_name = "render_video";
|
|
|
static const char *output_frame_download_frame_name = "download_frame";
|
|
|
static const char *output_frame_gs_flush_name = "gs_flush";
|
|
|
static const char *output_frame_output_video_data_name = "output_video_data";
|
|
|
-static inline void output_frame(void)
|
|
|
+static inline void output_frame(bool raw_active)
|
|
|
{
|
|
|
struct obs_core_video *video = &obs->video;
|
|
|
int cur_texture = video->cur_texture;
|
|
@@ -566,12 +570,14 @@ static inline void output_frame(void)
|
|
|
gs_enter_context(video->graphics);
|
|
|
|
|
|
profile_start(output_frame_render_video_name);
|
|
|
- render_video(video, cur_texture, prev_texture);
|
|
|
+ render_video(video, raw_active, cur_texture, prev_texture);
|
|
|
profile_end(output_frame_render_video_name);
|
|
|
|
|
|
- profile_start(output_frame_download_frame_name);
|
|
|
- frame_ready = download_frame(video, prev_texture, &frame);
|
|
|
- profile_end(output_frame_download_frame_name);
|
|
|
+ if (raw_active) {
|
|
|
+ profile_start(output_frame_download_frame_name);
|
|
|
+ frame_ready = download_frame(video, prev_texture, &frame);
|
|
|
+ profile_end(output_frame_download_frame_name);
|
|
|
+ }
|
|
|
|
|
|
profile_start(output_frame_gs_flush_name);
|
|
|
gs_flush();
|
|
@@ -580,7 +586,7 @@ static inline void output_frame(void)
|
|
|
gs_leave_context();
|
|
|
profile_end(output_frame_gs_context_name);
|
|
|
|
|
|
- if (frame_ready) {
|
|
|
+ if (raw_active && frame_ready) {
|
|
|
struct obs_vframe_info vframe_info;
|
|
|
circlebuf_pop_front(&video->vframe_info_buffer, &vframe_info,
|
|
|
sizeof(vframe_info));
|
|
@@ -597,6 +603,17 @@ static inline void output_frame(void)
|
|
|
|
|
|
#define NBSP "\xC2\xA0"
|
|
|
|
|
|
+static void clear_frame_data(void)
|
|
|
+{
|
|
|
+ struct obs_core_video *video = &obs->video;
|
|
|
+ memset(video->textures_rendered, 0, sizeof(video->textures_rendered));
|
|
|
+ memset(video->textures_output, 0, sizeof(video->textures_output));
|
|
|
+ memset(video->textures_copied, 0, sizeof(video->textures_copied));
|
|
|
+ memset(video->textures_converted, 0, sizeof(video->textures_converted));
|
|
|
+ circlebuf_free(&video->vframe_info_buffer);
|
|
|
+ video->cur_texture = 0;
|
|
|
+}
|
|
|
+
|
|
|
static const char *tick_sources_name = "tick_sources";
|
|
|
static const char *render_displays_name = "render_displays";
|
|
|
static const char *output_frame_name = "output_frame";
|
|
@@ -607,6 +624,7 @@ void *obs_graphics_thread(void *param)
|
|
|
uint64_t frame_time_total_ns = 0;
|
|
|
uint64_t fps_total_ns = 0;
|
|
|
uint32_t fps_total_frames = 0;
|
|
|
+ bool raw_was_active = false;
|
|
|
|
|
|
obs->video.video_time = os_gettime_ns();
|
|
|
|
|
@@ -622,6 +640,11 @@ void *obs_graphics_thread(void *param)
|
|
|
while (!video_output_stopped(obs->video.video)) {
|
|
|
uint64_t frame_start = os_gettime_ns();
|
|
|
uint64_t frame_time_ns;
|
|
|
+ bool raw_active = obs->video.raw_active > 0;
|
|
|
+
|
|
|
+ if (!raw_was_active && raw_active)
|
|
|
+ clear_frame_data();
|
|
|
+ raw_was_active = raw_active;
|
|
|
|
|
|
profile_start(video_thread_name);
|
|
|
|
|
@@ -630,7 +653,7 @@ void *obs_graphics_thread(void *param)
|
|
|
profile_end(tick_sources_name);
|
|
|
|
|
|
profile_start(output_frame_name);
|
|
|
- output_frame();
|
|
|
+ output_frame(raw_active);
|
|
|
profile_end(output_frame_name);
|
|
|
|
|
|
profile_start(render_displays_name);
|
|
@@ -643,7 +666,8 @@ void *obs_graphics_thread(void *param)
|
|
|
|
|
|
profile_reenable_thread();
|
|
|
|
|
|
- video_sleep(&obs->video, &obs->video.video_time, interval);
|
|
|
+ video_sleep(&obs->video, raw_active, &obs->video.video_time,
|
|
|
+ interval);
|
|
|
|
|
|
frame_time_total_ns += frame_time_ns;
|
|
|
fps_total_ns += (obs->video.video_time - last_time);
|