From d14dbbc540cee06347087ed66db2fe1196a29612 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Tue, 21 Oct 2014 20:08:39 -0700 Subject: [PATCH] Add timestamp circlebuf for video input/output At the start of each render loop, it would get the timestamp, and then it would then assign that timestamp to whatever frame was downloaded. However, the frame that was downloaded was usually occurred a number of frames ago, so it would assign the wrong timestamp value to that frame. This fixes that issue by storing the timestamps in a circular buffer. --- libobs/obs-internal.h | 1 + libobs/obs-video.c | 14 ++++++++++---- libobs/obs.c | 2 ++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index 7a73b3063..98d653379 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -140,6 +140,7 @@ struct obs_core_video { bool textures_copied[NUM_TEXTURES]; bool textures_converted[NUM_TEXTURES]; struct obs_source_frame convert_frames[NUM_TEXTURES]; + struct circlebuf timestamp_buffer; gs_effect_t *default_effect; gs_effect_t *default_rect_effect; gs_effect_t *solid_effect; diff --git a/libobs/obs-video.c b/libobs/obs-video.c index fce182f1c..c1fbfdaca 100644 --- a/libobs/obs-video.c +++ b/libobs/obs-video.c @@ -236,13 +236,16 @@ static inline void stage_output_texture(struct obs_core_video *video, } static inline void render_video(struct obs_core_video *video, int cur_texture, - int prev_texture) + int prev_texture, uint64_t timestamp) { gs_begin_scene(); gs_enable_depth_test(false); gs_set_cull_mode(GS_NEITHER); + circlebuf_push_back(&video->timestamp_buffer, ×tamp, + sizeof(timestamp)); + render_main_texture(video, cur_texture); render_output_texture(video, cur_texture, prev_texture); if (video->gpu_conversion) @@ -415,17 +418,20 @@ static inline void output_frame(uint64_t timestamp) bool frame_ready; memset(&frame, 0, sizeof(struct video_data)); - frame.timestamp = timestamp; gs_enter_context(video->graphics); - render_video(video, cur_texture, prev_texture); + render_video(video, cur_texture, prev_texture, timestamp); frame_ready = download_frame(video, prev_texture, &frame); gs_leave_context(); - if (frame_ready) + if (frame_ready) { + circlebuf_pop_front(&video->timestamp_buffer, &frame.timestamp, + sizeof(frame.timestamp)); + output_video_data(video, &frame, cur_texture); + } if (++video->cur_texture == NUM_TEXTURES) video->cur_texture = 0; diff --git a/libobs/obs.c b/libobs/obs.c index b41a22499..11211a69e 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -355,6 +355,8 @@ static void obs_free_video(void) gs_leave_context(); + circlebuf_free(&video->timestamp_buffer); + video->cur_texture = 0; } }