| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- #include <stdlib.h>
- #include <util/threading.h>
- #include <util/platform.h>
- #include <graphics/graphics.h>
- #include <obs.h>
- struct sync_pair_vid {
- obs_source_t *source;
- gs_texture_t *tex;
- gs_texture_t *white;
- gs_texture_t *black;
- };
- uint64_t starting_time = 0;
- uint64_t last_frame = 0;
- static const char *sync_pair_vid_getname(void *unused)
- {
- UNUSED_PARAMETER(unused);
- return "Sync Test Pair (Video)";
- }
- static void sync_pair_vid_destroy(void *data)
- {
- struct sync_pair_vid *spv = data;
- obs_enter_graphics();
- gs_texture_destroy(spv->tex);
- gs_texture_destroy(spv->white);
- gs_texture_destroy(spv->black);
- obs_leave_graphics();
- bfree(spv);
- }
- static inline void fill_texture(uint32_t *pixels, uint32_t pixel)
- {
- size_t x, y;
- for (y = 0; y < 32; y++) {
- for (x = 0; x < 32; x++) {
- pixels[y * 32 + x] = pixel;
- }
- }
- }
- static void *sync_pair_vid_create(obs_data_t *settings, obs_source_t *source)
- {
- UNUSED_PARAMETER(settings);
- struct sync_pair_vid *spv = bzalloc(sizeof(struct sync_pair_vid));
- spv->source = source;
- obs_enter_graphics();
- spv->tex = gs_texture_create(32, 32, GS_RGBA, 1, NULL, GS_DYNAMIC);
- spv->white = gs_texture_create(32, 32, GS_RGBA, 1, NULL, GS_DYNAMIC);
- spv->black = gs_texture_create(32, 32, GS_RGBA, 1, NULL, GS_DYNAMIC);
- uint8_t *ptr;
- uint32_t linesize;
- if (gs_texture_map(spv->white, &ptr, &linesize)) {
- fill_texture((uint32_t *)ptr, 0xFFFFFFFF);
- gs_texture_unmap(spv->white);
- }
- if (gs_texture_map(spv->black, &ptr, &linesize)) {
- fill_texture((uint32_t *)ptr, 0xFF000000);
- gs_texture_unmap(spv->black);
- }
- obs_leave_graphics();
- return spv;
- }
- static inline bool whitelist_time(uint64_t ts, uint64_t interval, uint64_t fps_num, uint64_t fps_den)
- {
- if (!starting_time)
- return false;
- uint64_t count = (ts - starting_time) / interval;
- uint64_t sec = count * fps_den / fps_num;
- return sec % 2 == 1;
- }
- static void sync_pair_vid_render(void *data, gs_effect_t *effect)
- {
- UNUSED_PARAMETER(effect);
- struct sync_pair_vid *spv = data;
- uint64_t ts = obs_get_video_frame_time();
- if (!starting_time)
- starting_time = ts;
- uint64_t interval = video_output_get_frame_time(obs_get_video());
- const struct video_output_info *voi = video_output_get_info(obs_get_video());
- uint64_t fps_num = voi->fps_num;
- uint64_t fps_den = voi->fps_den;
- bool whitelist = whitelist_time(ts, interval, fps_num, fps_den);
- #if 0
- if (last_frame != ts) {
- uint8_t *ptr;
- uint32_t linesize;
- if (gs_texture_map(spv->tex, &ptr, &linesize)) {
- fill_texture((uint32_t*)ptr, whitelist ? 0xFFFFFFFF : 0xFF000000);
- gs_texture_unmap(spv->tex);
- }
- last_frame = ts;
- }
- obs_source_draw(spv->tex, 0, 0, 0, 0, 0);
- #else
- obs_source_draw(whitelist ? spv->white : spv->black, 0, 0, 0, 0, 0);
- #endif
- }
- static uint32_t sync_pair_vid_size(void *data)
- {
- UNUSED_PARAMETER(data);
- return 32;
- }
- struct obs_source_info sync_video = {
- .id = "sync_video",
- .type = OBS_SOURCE_TYPE_INPUT,
- .output_flags = OBS_SOURCE_VIDEO,
- .get_name = sync_pair_vid_getname,
- .create = sync_pair_vid_create,
- .destroy = sync_pair_vid_destroy,
- .video_render = sync_pair_vid_render,
- .get_width = sync_pair_vid_size,
- .get_height = sync_pair_vid_size,
- };
|