VideoMixer::~VideoMixer() { stop_sink(); if (videoLocal_) { videoLocal_->detach(this); // prefer to release it now than after the next join videoLocal_.reset(); } loop_.join(); }
void VideoMixer::start_sink() { stop_sink(); if (width_ == 0 or height_ == 0) { RING_WARN("MX: unable to start with zero-sized output"); return; } if (not sink_->start()) { RING_ERR("MX: sink startup failed"); return; } if (this->attach(sink_.get())) sink_->setFrameSize(width_, height_); }
void AudioSinksManager::InternalAudioSink::free(bool user) { assert(manager->pa_mainloop.get_strand().running_in_this_thread()); static const char* state_name[] = {"NONE", "STARTED", "LOADED", "RECORDING", "DEAD"}; manager->logger->trace("(AudioSink '{}') Freeing, state: {}", name, state_name[static_cast<int>(state)]); switch (state) { case State::NONE: manager->unregister_audio_sink(shared_from_this()); break; case State::STARTED: /* Handled in module_load_callback */ break; case State::LOADED: stop_sink(); break; case State::RECORDING: if (pa_stream_disconnect(stream) < 0) { manager->logger->error( "(AudioSink '{}') Failed to start disconnecting stream {}: {}", name, module_idx, manager->get_pa_error()); } break; case State::DEAD: return; } if (activated && activation_callback && !user) { activation_callback(false); } activated = false; state = State::DEAD; }