obs-studio/test/test-input/test-random.c
jp9000 2451b80ef6 Fix drawing bug with async video sources
Before, async video sources would flicker because they were only being
drawn when they were updated.  So when updated, they'd draw that frame,
then it would stop drawing it until it updated again.  This fixes that
issue and they should now draw properly.

Also, fix a few other minor bugs and issues relating to async video,
and make it so that non-async video filters can be properly applied to
them.

For the purposes of testing, change the 'test-random' source to an async
video source that updates every quarter of a second with a new random
face.

Also fix a bug where non-async video sources wouldn't have filter
effects applied properly.
2014-04-13 02:22:28 -07:00

107 lines
2.1 KiB
C

#include <stdlib.h>
#include <util/threading.h>
#include <util/platform.h>
#include <obs.h>
struct random_tex {
obs_source_t source;
os_event_t stop_signal;
pthread_t thread;
bool initialized;
};
static const char *random_getname(const char *locale)
{
UNUSED_PARAMETER(locale);
return "20x20 Random Pixel Texture Source (Test)";
}
static void random_destroy(void *data)
{
struct random_tex *rt = data;
if (rt) {
if (rt->initialized) {
os_event_signal(rt->stop_signal);
pthread_join(rt->thread, NULL);
}
os_event_destroy(rt->stop_signal);
bfree(rt);
}
}
static inline void fill_texture(uint32_t *pixels)
{
size_t x, y;
for (y = 0; y < 20; y++) {
for (x = 0; x < 20; x++) {
uint32_t pixel = 0xFF000000;
pixel |= (rand()%256);
pixel |= (rand()%256) << 8;
pixel |= (rand()%256) << 16;
//pixel |= 0xFFFFFFFF;
pixels[y*20 + x] = pixel;
}
}
}
static void *video_thread(void *data)
{
struct random_tex *rt = data;
uint32_t pixels[20*20];
uint64_t cur_time = os_gettime_ns();
struct source_frame frame = {
.data = {[0] = (uint8_t*)pixels},
.linesize = {[0] = 20*4},
.width = 20,
.height = 20,
.format = VIDEO_FORMAT_BGRX
};
while (os_event_try(rt->stop_signal) == EAGAIN) {
fill_texture(pixels);
frame.timestamp = cur_time;
obs_source_output_video(rt->source, &frame);
os_sleepto_ns(cur_time += 250000000);
}
return NULL;
}
static void *random_create(obs_data_t settings, obs_source_t source)
{
struct random_tex *rt = bzalloc(sizeof(struct random_tex));
rt->source = source;
if (os_event_init(&rt->stop_signal, OS_EVENT_TYPE_MANUAL) != 0) {
random_destroy(rt);
return NULL;
}
if (pthread_create(&rt->thread, NULL, video_thread, rt) != 0) {
random_destroy(rt);
return NULL;
}
rt->initialized = true;
UNUSED_PARAMETER(settings);
UNUSED_PARAMETER(source);
return rt;
}
struct obs_source_info test_random = {
.id = "random",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_ASYNC_VIDEO,
.getname = random_getname,
.create = random_create,
.destroy = random_destroy,
};