output/pipewire: detect connection errors
This commit is contained in:
		@@ -56,6 +56,7 @@ class PipeWireOutput final : AudioOutput {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	const uint32_t target_id;
 | 
						const uint32_t target_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool disconnected;
 | 
				
			||||||
	bool interrupted;
 | 
						bool interrupted;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	explicit PipeWireOutput(const ConfigBlock &block);
 | 
						explicit PipeWireOutput(const ConfigBlock &block);
 | 
				
			||||||
@@ -71,11 +72,29 @@ public:
 | 
				
			|||||||
	static constexpr struct pw_stream_events MakeStreamEvents() noexcept {
 | 
						static constexpr struct pw_stream_events MakeStreamEvents() noexcept {
 | 
				
			||||||
		struct pw_stream_events events{};
 | 
							struct pw_stream_events events{};
 | 
				
			||||||
		events.version = PW_VERSION_STREAM_EVENTS;
 | 
							events.version = PW_VERSION_STREAM_EVENTS;
 | 
				
			||||||
 | 
							events.state_changed = StateChanged;
 | 
				
			||||||
		events.process = Process;
 | 
							events.process = Process;
 | 
				
			||||||
		return events;
 | 
							return events;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
						void StateChanged(enum pw_stream_state state,
 | 
				
			||||||
 | 
								  [[maybe_unused]] const char *error) noexcept {
 | 
				
			||||||
 | 
							const bool was_disconnected = disconnected;
 | 
				
			||||||
 | 
							disconnected = state == PW_STREAM_STATE_ERROR ||
 | 
				
			||||||
 | 
								state == PW_STREAM_STATE_UNCONNECTED;
 | 
				
			||||||
 | 
							if (!was_disconnected && disconnected)
 | 
				
			||||||
 | 
								pw_thread_loop_signal(thread_loop, false);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static void StateChanged(void *data,
 | 
				
			||||||
 | 
									 [[maybe_unused]] enum pw_stream_state old,
 | 
				
			||||||
 | 
									 enum pw_stream_state state,
 | 
				
			||||||
 | 
									 const char *error) noexcept {
 | 
				
			||||||
 | 
							auto &o = *(PipeWireOutput *)data;
 | 
				
			||||||
 | 
							o.StateChanged(state, error);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void Process() noexcept;
 | 
						void Process() noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static void Process(void *data) noexcept {
 | 
						static void Process(void *data) noexcept {
 | 
				
			||||||
@@ -186,6 +205,8 @@ ToPipeWireAudioFormat(AudioFormat &audio_format) noexcept
 | 
				
			|||||||
void
 | 
					void
 | 
				
			||||||
PipeWireOutput::Open(AudioFormat &audio_format)
 | 
					PipeWireOutput::Open(AudioFormat &audio_format)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						disconnected = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto props = pw_properties_new(PW_KEY_MEDIA_TYPE, "Audio",
 | 
						auto props = pw_properties_new(PW_KEY_MEDIA_TYPE, "Audio",
 | 
				
			||||||
				       PW_KEY_MEDIA_CATEGORY, "Playback",
 | 
									       PW_KEY_MEDIA_CATEGORY, "Playback",
 | 
				
			||||||
				       PW_KEY_MEDIA_ROLE, "Music",
 | 
									       PW_KEY_MEDIA_ROLE, "Music",
 | 
				
			||||||
@@ -277,6 +298,9 @@ PipeWireOutput::Play(const void *chunk, size_t size)
 | 
				
			|||||||
	const PipeWire::ThreadLoopLock lock(thread_loop);
 | 
						const PipeWire::ThreadLoopLock lock(thread_loop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (true) {
 | 
						while (true) {
 | 
				
			||||||
 | 
							if (disconnected)
 | 
				
			||||||
 | 
								throw std::runtime_error("Disconnected from PipeWire");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::size_t bytes_written =
 | 
							std::size_t bytes_written =
 | 
				
			||||||
			ring_buffer->push((const std::byte *)chunk, size);
 | 
								ring_buffer->push((const std::byte *)chunk, size);
 | 
				
			||||||
		if (bytes_written > 0)
 | 
							if (bytes_written > 0)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user