static inline void copy_transition_state(obs_source_t *transition,
        struct transition_state *state)
{
    state->s[0] = transition->transition_sources[0];
    state->s[1] = transition->transition_sources[1];
    obs_source_addref(state->s[0]);
    obs_source_addref(state->s[1]);

    state->transitioning_video = transition->transitioning_video;
    state->transitioning_audio = transition->transitioning_audio;
}
void obs_transition_set(obs_source_t *transition, obs_source_t *source)
{
    obs_source_t *s[2];
    bool active[2];

    if (!transition_valid(transition, "obs_transition_clear"))
        return;

    obs_source_addref(source);

    lock_transition(transition);
    for (size_t i = 0; i < 2; i++) {
        s[i] = transition->transition_sources[i];
        active[i] = transition->transition_source_active[i];
        transition->transition_sources[i] = NULL;
        transition->transition_source_active[i] = false;
    }
    transition->transition_source_active[0] = true;
    transition->transition_sources[0] = source;
    transition->transitioning_video = false;
    transition->transitioning_audio = false;
    unlock_transition(transition);

    for (size_t i = 0; i < 2; i++) {
        if (s[i] && active[i])
            obs_source_remove_active_child(transition, s[i]);
        obs_source_release(s[i]);
    }

    if (source)
        obs_source_add_active_child(transition, source);
}
Example #3
0
void obs_source_remove(obs_source_t source)
{
	struct obs_program_data *data = &obs->data;
	size_t id;

	pthread_mutex_lock(&data->sources_mutex);

	if (!source || source->removed)
		return;

	source->removed = true;

	obs_source_addref(source);

	id = da_find(data->sources, &source, 0);
	if (id != DARRAY_INVALID) {
		da_erase_item(data->sources, &source);
		obs_source_release(source);
	}

	pthread_mutex_unlock(&data->sources_mutex);

	obs_source_dosignal(source, "source-remove");
	obs_source_release(source);
}
Example #4
0
void obs_view_set_source(obs_view_t *view, uint32_t channel,
                         obs_source_t *source)
{
    struct obs_source *prev_source;

    assert(channel < MAX_CHANNELS);

    if (!view) return;
    if (channel >= MAX_CHANNELS) return;

    pthread_mutex_lock(&view->channels_mutex);

    obs_source_addref(source);

    prev_source = view->channels[channel];
    view->channels[channel] = source;

    pthread_mutex_unlock(&view->channels_mutex);

    if (source)
        obs_source_activate(source, AUX_VIEW);

    if (prev_source) {
        obs_source_deactivate(prev_source, AUX_VIEW);
        obs_source_release(prev_source);
    }
}
Example #5
0
	inline OBSSourceRef &operator=(const OBSSourceRef &ref)
	{
		obs_source_addref(ref.source);
		obs_source_release(source);
		source = ref.source;
		return *this;
	}
Example #6
0
	inline OBSSourceRef &operator=(obs_source_t sourceIn)
	{
		obs_source_addref(sourceIn);
		obs_source_release(source);
		source = sourceIn;
		return *this;
	}
Example #7
0
void obs_source_remove(obs_source_t source)
{
	struct obs_core_data *data = &obs->data;
	size_t id;
	bool   exists;

	pthread_mutex_lock(&data->sources_mutex);

	if (!source || source->removed) {
		pthread_mutex_unlock(&data->sources_mutex);
		return;
	}

	source->removed = true;

	obs_source_addref(source);

	id = da_find(data->user_sources, &source, 0);
	exists = (id != DARRAY_INVALID);
	if (exists) {
		da_erase(data->user_sources, id);
		obs_source_release(source);
	}

	pthread_mutex_unlock(&data->sources_mutex);

	if (exists)
		obs_source_dosignal(source, "source_remove", "remove");

	obs_source_release(source);
}
Example #8
0
obs_source_t obs_get_output_source(uint32_t channel)
{
	struct obs_source *source;
	assert(channel < MAX_CHANNELS);
	source = obs->data.channels[channel];

	obs_source_addref(source);
	return source;
}
Example #9
0
/*
 * Ensures that cached frames are displayed on time.  If multiple frames
 * were cached between renders, then releases the unnecessary frames and uses
 * the frame with the closest timing to ensure sync.
 */
struct source_frame *obs_source_getframe(obs_source_t source)
{
    uint64_t last_frame_time = source->last_frame_timestamp;
    struct   source_frame *frame = NULL;
    struct   source_frame *next_frame;
    uint64_t sys_time, frame_time;

    pthread_mutex_lock(&source->video_mutex);

    if (!source->video_frames.num)
        goto unlock;

    next_frame = source->video_frames.array[0];
    sys_time   = os_gettime_ns();
    frame_time = next_frame->timestamp;

    if (!source->last_frame_timestamp) {
        frame = next_frame;
        da_erase(source->video_frames, 0);

        source->last_frame_timestamp = frame_time;
    } else {
        uint64_t sys_offset, frame_offset;
        sys_offset   = sys_time   - source->last_sys_timestamp;
        frame_offset = frame_time - last_frame_time;

        source->last_frame_timestamp += sys_offset;

        while (frame_offset <= sys_offset) {
            if (frame)
                source_frame_destroy(frame);

            frame = next_frame;
            da_erase(source->video_frames, 0);

            if (!source->video_frames.num)
                break;

            next_frame   = source->video_frames.array[0];
            frame_time   = next_frame->timestamp;
            frame_offset = frame_time - last_frame_time;
        }
    }

    source->last_sys_timestamp = sys_time;

unlock:
    pthread_mutex_unlock(&source->video_mutex);

    if (frame != NULL)
        obs_source_addref(source);

    return frame;
}
Example #10
0
static void push_audio_tree(obs_source_t *parent, obs_source_t *source, void *p)
{
	struct obs_core_audio *audio = p;

	if (da_find(audio->render_order, &source, 0) == DARRAY_INVALID) {
		obs_source_addref(source);
		da_push_back(audio->render_order, &source);
	}

	UNUSED_PARAMETER(parent);
}
Example #11
0
obs_source_t obs_display_getsource(obs_display_t display, uint32_t channel)
{
	obs_source_t source;
	assert(channel < MAX_CHANNELS);

	source = display->channels[channel];
	if (source)
		obs_source_addref(source);

	return source;
}
static void set_source(obs_source_t *transition,
                       enum obs_transition_target target, obs_source_t *new_child,
                       bool (*callback)(obs_source_t *t, size_t idx, obs_source_t *c))
{
    size_t idx = (size_t)target;
    obs_source_t *old_child;
    bool add_success = true;
    bool already_active;

    if (new_child)
        obs_source_addref(new_child);

    lock_transition(transition);

    old_child = transition->transition_sources[idx];

    if (new_child == old_child) {
        unlock_transition(transition);
        obs_source_release(new_child);
        return;
    }

    already_active = transition->transition_source_active[idx];

    if (already_active) {
        if (new_child)
            add_success = obs_source_add_active_child(transition,
                          new_child);
        if (old_child && add_success)
            obs_source_remove_active_child(transition, old_child);
    }

    if (callback && add_success)
        add_success = callback(transition, idx, new_child);

    transition->transition_sources[idx] = add_success ? new_child : NULL;

    unlock_transition(transition);

    if (add_success) {
        if (transition->transition_cx == 0 ||
                transition->transition_cy == 0) {
            recalculate_transition_size(transition);
            recalculate_transition_matrices(transition);
        }
    } else {
        obs_source_release(new_child);
    }

    obs_source_release(old_child);
}
Example #13
0
void obs_display_setsource(obs_display_t display, uint32_t channel,
		obs_source_t source)
{
	struct obs_source *prev_source;
	assert(channel < MAX_CHANNELS);

	prev_source = display->channels[channel];
	display->channels[channel] = source;

	if (source)
		obs_source_addref(source);
	if (prev_source)
		obs_source_release(prev_source);
}
Example #14
0
bool obs_add_source(obs_source_t source)
{
	struct calldata params = {0};

	pthread_mutex_lock(&obs->data.sources_mutex);
	da_push_back(obs->data.sources, &source);
	obs_source_addref(source);
	pthread_mutex_unlock(&obs->data.sources_mutex);

	calldata_setptr(&params, "source", source);
	signal_handler_signal(obs->signals, "source-add", &params);
	calldata_free(&params);

	return true;
}
Example #15
0
void obs_source_enum_sources(obs_source_t source,
		obs_source_enum_proc_t enum_callback,
		void *param)
{
	if (!source || !source->info.enum_sources || source->enum_refs)
		return;

	obs_source_addref(source);

	os_atomic_inc_long(&source->enum_refs);
	source->info.enum_sources(source->context.data, enum_callback, param);
	os_atomic_dec_long(&source->enum_refs);

	obs_source_release(source);
}
obs_source_t *obs_transition_get_source(obs_source_t *transition,
                                        enum obs_transition_target target)
{
    size_t idx = (size_t)target;
    obs_source_t *ret;

    if (!transition_valid(transition, "obs_transition_get_source"))
        return NULL;

    lock_transition(transition);
    ret = transition->transition_sources[idx];
    obs_source_addref(ret);
    unlock_transition(transition);

    return ret;
}
obs_source_t *obs_transition_get_active_source(obs_source_t *transition)
{
    obs_source_t *ret;

    if (!transition_valid(transition, "obs_transition_get_source"))
        return NULL;

    lock_transition(transition);
    if (transition->transitioning_audio || transition->transitioning_video)
        ret = transition->transition_sources[1];
    else
        ret = transition->transition_sources[0];
    obs_source_addref(ret);
    unlock_transition(transition);

    return ret;
}
Example #18
0
obs_source_t *obs_view_get_source(obs_view_t *view, uint32_t channel)
{
    obs_source_t *source;
    assert(channel < MAX_CHANNELS);

    if (!view) return NULL;
    if (channel >= MAX_CHANNELS) return NULL;

    pthread_mutex_lock(&view->channels_mutex);

    source = view->channels[channel];
    if (source)
        obs_source_addref(source);

    pthread_mutex_unlock(&view->channels_mutex);

    return source;
}
static inline obs_source_t *copy_source_state(obs_source_t *tr_dest,
        obs_source_t *tr_source, size_t idx)
{
    obs_source_t *old_child = tr_dest->transition_sources[idx];
    obs_source_t *new_child = tr_source->transition_sources[idx];
    bool active = tr_source->transition_source_active[idx];

    if (old_child && tr_dest->transition_source_active[idx])
        obs_source_remove_active_child(tr_dest, old_child);

    tr_dest->transition_sources[idx] = new_child;
    tr_dest->transition_source_active[idx] = active;

    if (active && new_child)
        obs_source_add_active_child(tr_dest, new_child);
    obs_source_addref(new_child);

    return old_child;
}
Example #20
0
obs_source_t obs_get_source_by_name(const char *name)
{
	struct obs_data *data = &obs->data;
	struct obs_source *source = NULL;
	size_t i;

	pthread_mutex_lock(&data->sources_mutex);

	for (i = 0; i < data->sources.num; i++) {
		struct obs_source *cur_source = data->sources.array[i];
		if (strcmp(cur_source->name, name) == 0) {
			source = cur_source;
			obs_source_addref(source);
			break;
		}
	}

	pthread_mutex_unlock(&data->sources_mutex);
	return source;
}
Example #21
0
/*
 * Ensures that cached frames are displayed on time.  If multiple frames
 * were cached between renders, then releases the unnecessary frames and uses
 * the frame with the closest timing to ensure sync.  Also ensures that timing
 * with audio is synchronized.
 */
struct source_frame *obs_source_getframe(obs_source_t source)
{
	struct source_frame *frame = NULL;
	uint64_t sys_time;

	if (!source)
		return NULL;

	pthread_mutex_lock(&source->video_mutex);

	if (!source->video_frames.num)
		goto unlock;

	sys_time = os_gettime_ns();

	if (!source->last_frame_ts) {
		frame = source->video_frames.array[0];
		da_erase(source->video_frames, 0);

		source->last_frame_ts = frame->timestamp;
	} else {
		frame = get_closest_frame(source, sys_time);
	}

	/* reset timing to current system time */
	if (frame) {
		source->timing_adjust = sys_time - frame->timestamp;
		source->timing_set = true;
	}

	source->last_sys_timestamp = sys_time;

unlock:
	pthread_mutex_unlock(&source->video_mutex);

	if (frame)
		obs_source_addref(source);

	return frame;
}
Example #22
0
obs_sceneitem_t obs_scene_add(obs_scene_t scene, obs_source_t source)
{
	struct obs_scene_item *last;
	struct obs_scene_item *item = bmalloc(sizeof(struct obs_scene_item));
	struct calldata params = {0};

	memset(item, 0, sizeof(struct obs_scene_item));
	item->source  = source;
	item->visible = true;
	item->parent  = scene;
	item->ref     = 1;
	vec2_set(&item->scale, 1.0f, 1.0f);

	if (source)
		obs_source_addref(source);

	pthread_mutex_lock(&scene->mutex);

	last = scene->first_item;
	if (!last) {
		scene->first_item = item;
	} else {
		while (last->next)
			last = last->next;

		last->next = item;
		item->prev = last;
	}

	pthread_mutex_unlock(&scene->mutex);

	calldata_setptr(&params, "scene", scene);
	calldata_setptr(&params, "item", item);
	signal_handler_signal(scene->source->signals, "add", &params);
	calldata_free(&params);

	return item;
}
Example #23
0
void obs_set_output_source(uint32_t channel, obs_source_t source)
{
	struct obs_source *prev_source;
	struct calldata params = {0};
	assert(channel < MAX_CHANNELS);

	prev_source = obs->data.channels[channel];

	calldata_setuint32(&params, "channel", channel);
	calldata_setptr(&params, "prev_source", prev_source);
	calldata_setptr(&params, "source", source);
	signal_handler_signal(obs->signals, "channel-change", &params);
	calldata_getptr(&params, "source", &source);
	calldata_free(&params);

	obs->data.channels[channel] = source;

	if (source != prev_source) {
		if (source)
			obs_source_addref(source);
		if (prev_source)
			obs_source_release(prev_source);
	}
}
Example #24
0
void obs_set_output_source(uint32_t channel, obs_source_t *source)
{
	assert(channel < MAX_CHANNELS);

	if (!obs) return;
	if (channel >= MAX_CHANNELS) return;

	struct obs_source *prev_source;
	struct obs_view *view = &obs->data.main_view;
	struct calldata params = {0};

	pthread_mutex_lock(&view->channels_mutex);

	obs_source_addref(source);

	prev_source = view->channels[channel];

	calldata_set_int(&params, "channel", channel);
	calldata_set_ptr(&params, "prev_source", prev_source);
	calldata_set_ptr(&params, "source", source);
	signal_handler_signal(obs->signals, "channel_change", &params);
	calldata_get_ptr(&params, "source", &source);
	calldata_free(&params);

	view->channels[channel] = source;

	pthread_mutex_unlock(&view->channels_mutex);

	if (source)
		obs_source_activate(source, MAIN_VIEW);

	if (prev_source) {
		obs_source_deactivate(prev_source, MAIN_VIEW);
		obs_source_release(prev_source);
	}
}
Example #25
0
void obs_scene_addref(obs_scene_t scene)
{
	if (scene)
		obs_source_addref(scene->source);
}
Example #26
0
	inline OBSSourceRef(obs_source_t source) : source(source)
	{
		obs_source_addref(source);
	}
Example #27
0
	inline OBSSourceRef(const OBSSourceRef &ref) : source(ref.source)
	{
		obs_source_addref(source);
	}