Пример #1
0
obs_source_t obs_source_create(enum obs_source_type type, const char *id,
		const char *name, obs_data_t settings)
{
	struct obs_source *source;

	const struct obs_source_info *info = get_source_info(type, id);
	if (!info) {
		blog(LOG_ERROR, "Source '%s' not found", id);
		return NULL;
	}

	source = bzalloc(sizeof(struct obs_source));

	if (!obs_source_init_context(source, settings, name))
		goto fail;

	if (info->defaults)
		info->defaults(source->context.settings);

	source->context.data = info->create(source->context.settings, source);
	if (!source->context.data)
		goto fail;

	if (!obs_source_init(source, info))
		goto fail;

	obs_source_dosignal(source, "source_create", NULL);
	return source;

fail:
	blog(LOG_ERROR, "obs_source_create failed");
	obs_source_destroy(source);
	return NULL;
}
Пример #2
0
obs_source_t obs_source_create(enum obs_source_type type, const char *id,
                               const char *name, const char *settings)
{
    struct obs_source *source;

    const struct source_info *info = get_source_info(type, id);
    if (!info) {
        blog(LOG_WARNING, "Source '%s' not found", id);
        return NULL;
    }

    source = bmalloc(sizeof(struct obs_source));
    memset(source, 0, sizeof(struct obs_source));

    if (!obs_source_init_handlers(source))
        goto fail;

    source->name = bstrdup(name);
    source->type = type;
    source->data = info->create(settings, source);
    if (!source->data)
        goto fail;

    if (!obs_source_init(source, settings, info))
        goto fail;

    obs_source_dosignal(source, "source-create");
    return source;

fail:
    blog(LOG_ERROR, "obs_source_create failed");
    obs_source_destroy(source);
    return NULL;
}
Пример #3
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);
}
Пример #4
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);
}
Пример #5
0
void obs_source_destroy(struct obs_source *source)
{
	size_t i;

	if (!source)
		return;

	obs_context_data_remove(&source->context);

	obs_source_dosignal(source, "source_destroy", "destroy");

	if (source->context.data)
		source->info.destroy(source->context.data);

	if (source->filter_parent)
		obs_source_filter_remove(source->filter_parent, source);

	for (i = 0; i < source->filters.num; i++)
		obs_source_release(source->filters.array[i]);

	for (i = 0; i < source->video_frames.num; i++)
		source_frame_destroy(source->video_frames.array[i]);

	gs_entercontext(obs->video.graphics);
	texrender_destroy(source->async_convert_texrender);
	texture_destroy(source->async_texture);
	gs_leavecontext();

	for (i = 0; i < MAX_AV_PLANES; i++)
		bfree(source->audio_data.data[i]);

	audio_line_destroy(source->audio_line);
	audio_resampler_destroy(source->resampler);

	texrender_destroy(source->filter_texrender);
	da_free(source->video_frames);
	da_free(source->filters);
	pthread_mutex_destroy(&source->filter_mutex);
	pthread_mutex_destroy(&source->audio_mutex);
	pthread_mutex_destroy(&source->video_mutex);
	obs_context_data_free(&source->context);
	bfree(source);
}
Пример #6
0
static void obs_source_destroy(obs_source_t source)
{
    size_t i;

    obs_source_dosignal(source, "source-destroy");

    if (source->filter_parent)
        obs_source_filter_remove(source->filter_parent, source);

    for (i = 0; i < source->filters.num; i++)
        obs_source_release(source->filters.array[i]);

    for (i = 0; i < source->audio_wait_buffer.num; i++)
        audiobuf_free(source->audio_wait_buffer.array+i);
    for (i = 0; i < source->video_frames.num; i++)
        source_frame_destroy(source->video_frames.array[i]);

    gs_entercontext(obs->video.graphics);
    texture_destroy(source->output_texture);
    gs_leavecontext();

    if (source->data)
        source->callbacks.destroy(source->data);

    bfree(source->audio_data.data);
    audio_line_destroy(source->audio_line);
    audio_resampler_destroy(source->resampler);

    proc_handler_destroy(source->procs);
    signal_handler_destroy(source->signals);

    da_free(source->video_frames);
    da_free(source->audio_wait_buffer);
    da_free(source->filters);
    pthread_mutex_destroy(&source->filter_mutex);
    pthread_mutex_destroy(&source->audio_mutex);
    pthread_mutex_destroy(&source->video_mutex);
    dstr_free(&source->settings);
    bfree(source->name);
    bfree(source);
}
Пример #7
0
bool obs_transition_start(obs_source_t *transition,
                          enum obs_transition_mode mode, uint32_t duration_ms,
                          obs_source_t *dest)
{
    bool active;
    bool same_as_source;
    bool same_as_dest;

    if (!transition_valid(transition, "obs_transition_start"))
        return false;

    lock_transition(transition);
    same_as_source = dest == transition->transition_sources[0];
    same_as_dest = dest == transition->transition_sources[1];
    active = transition_active(transition);
    unlock_transition(transition);

    if (same_as_source && !active)
        return false;

    if (transition->transition_use_fixed_duration)
        duration_ms = transition->transition_fixed_duration;

    if (!active || (!same_as_dest && !same_as_source)) {
        transition->transition_start_time = os_gettime_ns();
        transition->transition_duration =
            (uint64_t)duration_ms * 1000000ULL;
    }

    set_source(transition, OBS_TRANSITION_SOURCE_B, dest,
               activate_transition);

    obs_source_dosignal(transition, "source_transition_start",
                        "transition_start");

    /* TODO: Add mode */
    UNUSED_PARAMETER(mode);
    return true;
}
Пример #8
0
static void hide_source(obs_source_t source)
{
	if (source->info.hide)
		source->info.hide(source->context.data);
	obs_source_dosignal(source, "source_hide", "hide");
}
Пример #9
0
static void show_source(obs_source_t source)
{
	if (source->info.show)
		source->info.show(source->context.data);
	obs_source_dosignal(source, "source_show", "show");
}
Пример #10
0
static void deactivate_source(obs_source_t source)
{
	if (source->info.deactivate)
		source->info.deactivate(source->context.data);
	obs_source_dosignal(source, "source_deactivate", "deactivate");
}
Пример #11
0
bool obs_transition_audio_render(obs_source_t *transition,
                                 uint64_t *ts_out, struct obs_source_audio_mix *audio,
                                 uint32_t mixers, size_t channels, size_t sample_rate,
                                 obs_transition_audio_mix_callback_t mix_a,
                                 obs_transition_audio_mix_callback_t mix_b)
{
    obs_source_t *sources[2];
    struct transition_state state = {0};
    bool stopped = false;
    uint64_t min_ts;
    float t;

    if (!transition_valid(transition, "obs_transition_audio_render"))
        return false;

    lock_transition(transition);

    sources[0] = transition->transition_sources[0];
    sources[1] = transition->transition_sources[1];

    min_ts = calc_min_ts(sources);

    if (min_ts) {
        t = calc_time(transition, min_ts);

        if (t >= 1.0f && transition->transitioning_audio)
            stopped = stop_audio(transition);

        sources[0] = transition->transition_sources[0];
        sources[1] = transition->transition_sources[1];
        min_ts = calc_min_ts(sources);
        if (min_ts)
            copy_transition_state(transition, &state);

    } else if (transition->transitioning_audio) {
        stopped = stop_audio(transition);
    }

    unlock_transition(transition);

    if (min_ts) {
        if (state.transitioning_audio) {
            if (state.s[0])
                process_audio(transition, state.s[0], audio,
                              min_ts, mixers, channels,
                              sample_rate, mix_a);
            if (state.s[1])
                process_audio(transition, state.s[1], audio,
                              min_ts, mixers, channels,
                              sample_rate, mix_b);
        } else if (state.s[0]) {
            memcpy(audio->output[0].data[0],
                   state.s[0]->audio_output_buf[0][0],
                   TOTAL_AUDIO_SIZE);
        }

        obs_source_release(state.s[0]);
        obs_source_release(state.s[1]);
    }

    if (stopped)
        obs_source_dosignal(transition, "source_transition_stop",
                            "transition_stop");

    *ts_out = min_ts;
    return !!min_ts;
}
Пример #12
0
void obs_transition_video_render(obs_source_t *transition,
                                 obs_transition_video_render_callback_t callback)
{
    struct transition_state state;
    bool locked = false;
    bool stopped = false;
    bool video_stopped = false;
    float t;

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

    t = get_video_time(transition);

    lock_transition(transition);

    if (t >= 1.0f && transition->transitioning_video) {
        transition->transitioning_video = false;
        video_stopped = true;

        if (!transition->transitioning_audio) {
            obs_transition_stop(transition);
            stopped = true;
        }
    }
    copy_transition_state(transition, &state);

    unlock_transition(transition);

    if (state.transitioning_video)
        locked = trylock_textures(transition) == 0;

    if (state.transitioning_video && locked && callback) {
        gs_texture_t *tex[2];

        for (size_t i = 0; i < 2; i++) {
            if (state.s[i]) {
                render_child(transition, state.s[i], i);
                tex[i] = get_texture(transition, i);
                if (!tex[i])
                    tex[i] = obs->video.transparent_texture;
            } else {
                tex[i] = obs->video.transparent_texture;
            }
        }

        callback(transition->context.data, tex[0], tex[1], t,
                 transition->transition_actual_cx,
                 transition->transition_actual_cy);

    } else if (state.transitioning_audio) {
        if (state.s[1])
            obs_source_video_render(state.s[1]);

    } else {
        if (state.s[0])
            obs_source_video_render(state.s[0]);
    }

    if (locked)
        unlock_textures(transition);

    obs_source_release(state.s[0]);
    obs_source_release(state.s[1]);

    if (video_stopped)
        obs_source_dosignal(transition, "source_transition_video_stop",
                            "transition_video_stop");
    if (stopped)
        obs_source_dosignal(transition, "source_transition_stop",
                            "transition_stop");
}