mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	alsa: implement poll_descriptors
In there we can evaluate the poll fd and make sure it blocks or not in the following poll based on the buffer filled levels. Some API is very sensitive about this, it seems. Fixes #433
This commit is contained in:
		
							parent
							
								
									a57d3e4dae
								
							
						
					
					
						commit
						0aadc0450d
					
				
					 1 changed files with 35 additions and 9 deletions
				
			
		| 
						 | 
					@ -94,22 +94,31 @@ typedef struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int snd_pcm_pipewire_stop(snd_pcm_ioplug_t *io);
 | 
					static int snd_pcm_pipewire_stop(snd_pcm_ioplug_t *io);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pcm_poll_block_check(snd_pcm_ioplug_t *io)
 | 
					static int block_check(snd_pcm_ioplug_t *io)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint64_t val;
 | 
					 | 
				
			||||||
	snd_pcm_sframes_t avail;
 | 
					 | 
				
			||||||
	snd_pcm_pipewire_t *pw = io->private_data;
 | 
						snd_pcm_pipewire_t *pw = io->private_data;
 | 
				
			||||||
 | 
						snd_pcm_sframes_t avail;
 | 
				
			||||||
 | 
						uint64_t val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (io->state == SND_PCM_STATE_DRAINING) {
 | 
						avail = snd_pcm_ioplug_avail(io, pw->hw_ptr, io->appl_ptr);
 | 
				
			||||||
		spa_system_eventfd_read(pw->system, io->poll_fd, &val);
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	} else if (io->state == SND_PCM_STATE_RUNNING ||
 | 
					 | 
				
			||||||
			   (io->state == SND_PCM_STATE_PREPARED && io->stream == SND_PCM_STREAM_CAPTURE)) {
 | 
					 | 
				
			||||||
		avail = snd_pcm_avail_update(io->pcm);
 | 
					 | 
				
			||||||
	if (avail >= 0 && avail < (snd_pcm_sframes_t)pw->min_avail) {
 | 
						if (avail >= 0 && avail < (snd_pcm_sframes_t)pw->min_avail) {
 | 
				
			||||||
		spa_system_eventfd_read(pw->system, io->poll_fd, &val);
 | 
							spa_system_eventfd_read(pw->system, io->poll_fd, &val);
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int pcm_poll_block_check(snd_pcm_ioplug_t *io)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						snd_pcm_pipewire_t *pw = io->private_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (io->state == SND_PCM_STATE_DRAINING) {
 | 
				
			||||||
 | 
							uint64_t val;
 | 
				
			||||||
 | 
							spa_system_eventfd_read(pw->system, io->poll_fd, &val);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						} else if (io->state == SND_PCM_STATE_RUNNING ||
 | 
				
			||||||
 | 
								   (io->state == SND_PCM_STATE_PREPARED && io->stream == SND_PCM_STREAM_CAPTURE)) {
 | 
				
			||||||
 | 
							return block_check(io);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -117,9 +126,15 @@ static int pcm_poll_block_check(snd_pcm_ioplug_t *io)
 | 
				
			||||||
static inline int pcm_poll_unblock_check(snd_pcm_ioplug_t *io)
 | 
					static inline int pcm_poll_unblock_check(snd_pcm_ioplug_t *io)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	snd_pcm_pipewire_t *pw = io->private_data;
 | 
						snd_pcm_pipewire_t *pw = io->private_data;
 | 
				
			||||||
 | 
						snd_pcm_uframes_t avail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						avail = snd_pcm_ioplug_avail(io, pw->hw_ptr, io->appl_ptr);
 | 
				
			||||||
 | 
						if (avail >= pw->min_avail || io->state == SND_PCM_STATE_DRAINING) {
 | 
				
			||||||
		spa_system_eventfd_write(pw->system, pw->fd, 1);
 | 
							spa_system_eventfd_write(pw->system, pw->fd, 1);
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void snd_pcm_pipewire_free(snd_pcm_pipewire_t *pw)
 | 
					static void snd_pcm_pipewire_free(snd_pcm_pipewire_t *pw)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -147,6 +162,15 @@ static int snd_pcm_pipewire_close(snd_pcm_ioplug_t *io)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int snd_pcm_pipewire_poll_descriptors(snd_pcm_ioplug_t *io, struct pollfd *pfds, unsigned int space)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						snd_pcm_pipewire_t *pw = io->private_data;
 | 
				
			||||||
 | 
						pcm_poll_unblock_check(io); /* unblock socket for polling if needed */
 | 
				
			||||||
 | 
						pfds->fd = pw->fd;
 | 
				
			||||||
 | 
						pfds->events = POLLIN | POLLERR | POLLNVAL;
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int snd_pcm_pipewire_poll_revents(snd_pcm_ioplug_t *io,
 | 
					static int snd_pcm_pipewire_poll_revents(snd_pcm_ioplug_t *io,
 | 
				
			||||||
				     struct pollfd *pfds, unsigned int nfds,
 | 
									     struct pollfd *pfds, unsigned int nfds,
 | 
				
			||||||
				     unsigned short *revents)
 | 
									     unsigned short *revents)
 | 
				
			||||||
| 
						 | 
					@ -523,6 +547,7 @@ static int snd_pcm_pipewire_start(snd_pcm_ioplug_t *io)
 | 
				
			||||||
	pw_thread_loop_lock(pw->main_loop);
 | 
						pw_thread_loop_lock(pw->main_loop);
 | 
				
			||||||
	pw_log_debug(NAME" %p:", pw);
 | 
						pw_log_debug(NAME" %p:", pw);
 | 
				
			||||||
	pipewire_start(pw);
 | 
						pipewire_start(pw);
 | 
				
			||||||
 | 
						block_check(io); /* unblock socket for polling if needed */
 | 
				
			||||||
	pw_thread_loop_unlock(pw->main_loop);
 | 
						pw_thread_loop_unlock(pw->main_loop);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -771,6 +796,7 @@ static snd_pcm_ioplug_callback_t pipewire_pcm_callback = {
 | 
				
			||||||
	.delay = snd_pcm_pipewire_delay,
 | 
						.delay = snd_pcm_pipewire_delay,
 | 
				
			||||||
	.drain = snd_pcm_pipewire_drain,
 | 
						.drain = snd_pcm_pipewire_drain,
 | 
				
			||||||
	.prepare = snd_pcm_pipewire_prepare,
 | 
						.prepare = snd_pcm_pipewire_prepare,
 | 
				
			||||||
 | 
						.poll_descriptors = snd_pcm_pipewire_poll_descriptors,
 | 
				
			||||||
	.poll_revents = snd_pcm_pipewire_poll_revents,
 | 
						.poll_revents = snd_pcm_pipewire_poll_revents,
 | 
				
			||||||
	.hw_params = snd_pcm_pipewire_hw_params,
 | 
						.hw_params = snd_pcm_pipewire_hw_params,
 | 
				
			||||||
	.set_chmap = snd_pcm_pipewire_set_chmap,
 | 
						.set_chmap = snd_pcm_pipewire_set_chmap,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue