void obs_source_process_filter(obs_source_t filter, texrender_t texrender, effect_t effect, uint32_t width, uint32_t height, enum allow_direct_render allow_direct) { obs_source_t target = obs_filter_gettarget(filter); obs_source_t parent = obs_filter_getparent(filter); uint32_t target_flags = obs_source_get_output_flags(target); uint32_t parent_flags = obs_source_get_output_flags(parent); int cx = obs_source_getwidth(target); int cy = obs_source_getheight(target); bool yuv = (target_flags & SOURCE_YUV) != 0; bool expects_def = (parent_flags & SOURCE_DEFAULT_EFFECT) != 0; bool can_directly = allow_direct == ALLOW_DIRECT_RENDERING; /* if the parent does not use any custom effects, and this is the last * filter in the chain for the parent, then render the parent directly * using the filter effect instead of rendering to texture to reduce * the total number of passes */ if (can_directly && expects_def && target == parent) { render_filter_bypass(target, effect, width, height, yuv); return; } if (texrender_begin(texrender, cx, cy)) { gs_ortho(0.0f, (float)cx, 0.0f, (float)cy, -100.0f, 100.0f); if (expects_def && parent == target) obs_source_default_render(parent, yuv); else obs_source_video_render(target); texrender_end(texrender); } /* --------------------------- */ render_filter_tex(texrender_gettexture(texrender), effect, width, height, yuv); }
void OBSBasicAdvAudio::SourceRemoved(OBSSource source) { uint32_t flags = obs_source_get_output_flags(source); if ((flags & OBS_SOURCE_AUDIO) == 0) return; for (size_t i = 0; i < controls.size(); i++) { if (controls[i]->GetSource() == source) { delete controls[i]; controls.erase(controls.begin() + i); break; } } }
void obs_source_output_audio(obs_source_t source, const struct source_audio *audio) { uint32_t flags = obs_source_get_output_flags(source); size_t blocksize = audio_output_blocksize(obs->audio.audio); struct filtered_audio *output; process_audio(source, audio); pthread_mutex_lock(&source->filter_mutex); output = filter_async_audio(source, &source->audio_data); if (output) { pthread_mutex_lock(&source->audio_mutex); /* wait for video to start before outputting any audio so we * have a base for sync */ if (!source->timing_set && (flags & SOURCE_ASYNC_VIDEO) != 0) { struct audiobuf newbuf; size_t audio_size = blocksize * output->frames; newbuf.data = bmalloc(audio_size); newbuf.frames = output->frames; newbuf.timestamp = output->timestamp; memcpy(newbuf.data, output->data, audio_size); da_push_back(source->audio_wait_buffer, &newbuf); } else { struct audio_data data; data.data = output->data; data.frames = output->frames; data.timestamp = output->timestamp; source_output_audio_line(source, &data); } pthread_mutex_unlock(&source->audio_mutex); } pthread_mutex_unlock(&source->filter_mutex); }