|
@@ -34,8 +34,28 @@ static bool ready_deinterlace_frames(obs_source_t *source, uint64_t sys_time)
|
|
next_frame = source->async_frames.array[0];
|
|
next_frame = source->async_frames.array[0];
|
|
}
|
|
}
|
|
|
|
|
|
- if (source->async_frames.num == 2)
|
|
|
|
- source->async_frames.array[0]->prev_frame = true;
|
|
|
|
|
|
+ if (source->async_frames.num == 2) {
|
|
|
|
+ bool prev_frame = true;
|
|
|
|
+ if (source->async_unbuffered &&
|
|
|
|
+ source->deinterlace_offset) {
|
|
|
|
+ const uint64_t timestamp =
|
|
|
|
+ source->async_frames.array[0]->timestamp;
|
|
|
|
+ const uint64_t after_timestamp =
|
|
|
|
+ source->async_frames.array[1]->timestamp;
|
|
|
|
+ const uint64_t duration =
|
|
|
|
+ after_timestamp - timestamp;
|
|
|
|
+ const uint64_t frame_end =
|
|
|
|
+ timestamp + source->deinterlace_offset +
|
|
|
|
+ duration;
|
|
|
|
+ if (sys_time < frame_end) {
|
|
|
|
+ // Don't skip ahead prematurely.
|
|
|
|
+ prev_frame = false;
|
|
|
|
+ source->deinterlace_frame_ts =
|
|
|
|
+ timestamp - duration;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ source->async_frames.array[0]->prev_frame = prev_frame;
|
|
|
|
+ }
|
|
source->deinterlace_offset = 0;
|
|
source->deinterlace_offset = 0;
|
|
source->last_frame_ts = next_frame->timestamp;
|
|
source->last_frame_ts = next_frame->timestamp;
|
|
return true;
|
|
return true;
|
|
@@ -122,12 +142,30 @@ static inline uint64_t uint64_diff(uint64_t ts1, uint64_t ts2)
|
|
return (ts1 < ts2) ? (ts2 - ts1) : (ts1 - ts2);
|
|
return (ts1 < ts2) ? (ts2 - ts1) : (ts1 - ts2);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#define TWOX_TOLERANCE 1000000
|
|
|
|
+#define TS_JUMP_THRESHOLD 70000000ULL
|
|
|
|
+
|
|
static inline void deinterlace_get_closest_frames(obs_source_t *s,
|
|
static inline void deinterlace_get_closest_frames(obs_source_t *s,
|
|
uint64_t sys_time)
|
|
uint64_t sys_time)
|
|
{
|
|
{
|
|
const struct video_output_info *info;
|
|
const struct video_output_info *info;
|
|
uint64_t half_interval;
|
|
uint64_t half_interval;
|
|
|
|
|
|
|
|
+ if (s->async_unbuffered && s->deinterlace_offset) {
|
|
|
|
+ // Want to keep frame if it has not elapsed.
|
|
|
|
+ const uint64_t frame_end =
|
|
|
|
+ s->deinterlace_frame_ts + s->deinterlace_offset +
|
|
|
|
+ ((uint64_t)s->deinterlace_half_duration * 2) -
|
|
|
|
+ TWOX_TOLERANCE;
|
|
|
|
+ if (sys_time < frame_end) {
|
|
|
|
+ // Process new frames if we think time jumped.
|
|
|
|
+ const uint64_t diff = frame_end - sys_time;
|
|
|
|
+ if (diff < TS_JUMP_THRESHOLD) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
if (!s->async_frames.num)
|
|
if (!s->async_frames.num)
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -303,8 +341,6 @@ static inline gs_effect_t *get_effect(enum obs_deinterlace_mode mode)
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
-#define TWOX_TOLERANCE 1000000
|
|
|
|
-
|
|
|
|
void deinterlace_render(obs_source_t *s)
|
|
void deinterlace_render(obs_source_t *s)
|
|
{
|
|
{
|
|
gs_effect_t *effect = s->deinterlace_effect;
|
|
gs_effect_t *effect = s->deinterlace_effect;
|