void obs_transition_clear(obs_source_t *transition) { obs_source_t *s[2]; bool active[2]; if (!transition_valid(transition, "obs_transition_clear")) return; 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->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]); } }
static void apply_scene_item_audio_actions(struct obs_scene_item *item, float **p_buf, uint64_t ts, size_t sample_rate) { bool cur_visible = item->visible; uint64_t frame_num = 0; size_t deref_count = 0; float *buf = NULL; if (p_buf) { if (!*p_buf) *p_buf = malloc(AUDIO_OUTPUT_FRAMES * sizeof(float)); buf = *p_buf; } pthread_mutex_lock(&item->actions_mutex); for (size_t i = 0; i < item->audio_actions.num; i++) { struct item_action action = item->audio_actions.array[i]; uint64_t timestamp = action.timestamp; uint64_t new_frame_num; if (timestamp < ts) timestamp = ts; new_frame_num = (timestamp - ts) * (uint64_t)sample_rate / 1000000000ULL; if (ts && new_frame_num >= AUDIO_OUTPUT_FRAMES) break; da_erase(item->audio_actions, i--); item->visible = action.visible; if (!item->visible) deref_count++; if (buf && new_frame_num > frame_num) { for (; frame_num < new_frame_num; frame_num++) buf[frame_num] = cur_visible ? 1.0f : 0.0f; } cur_visible = item->visible; } if (buf) { for (; frame_num < AUDIO_OUTPUT_FRAMES; frame_num++) buf[frame_num] = cur_visible ? 1.0f : 0.0f; } pthread_mutex_unlock(&item->actions_mutex); while (deref_count--) { if (os_atomic_dec_long(&item->active_refs) == 0) { obs_source_remove_active_child(item->parent->source, item->source); } } }
static void stinger_transition_stop(void *data) { struct stinger_info *s = data; if (s->media_source) obs_source_remove_active_child(s->source, s->media_source); s->transitioning = false; }
static void obs_transition_stop(obs_source_t *transition) { obs_source_t *old_child = transition->transition_sources[0]; if (old_child && transition->transition_source_active[0]) obs_source_remove_active_child(transition, old_child); obs_source_release(old_child); transition->transition_source_active[0] = true; transition->transition_source_active[1] = false; transition->transition_sources[0] = transition->transition_sources[1]; transition->transition_sources[1] = NULL; }
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); }
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; }
static void set_visibility(struct obs_scene_item *item, bool vis) { pthread_mutex_lock(&item->actions_mutex); da_resize(item->audio_actions, 0); if (os_atomic_load_long(&item->active_refs) > 0) { if (!vis) obs_source_remove_active_child(item->parent->source, item->source); } else if (vis) { obs_source_add_active_child(item->parent->source, item->source); } os_atomic_set_long(&item->active_refs, vis ? 1 : 0); item->visible = vis; item->user_visible = vis; pthread_mutex_unlock(&item->actions_mutex); }