mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	pcm_rate: Do not discard slave reported delay in status result.
snd_pcm_rate_status() gets the underlying status from the slave PCM. This may contain a delay value that includes elements such as codec and other transfer delays. Use this as the base for the returned delay value, adjusted for any frames buffered locally (within the rate plugin). Also update snd_pcm_rate_delay() similarly. [fixed some comments by tiwai] Signed-off-by: Alan Young <consult.awy@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
							parent
							
								
									5a2bddfc79
								
							
						
					
					
						commit
						e1e211208a
					
				
					 1 changed files with 44 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -559,10 +559,9 @@ snd_pcm_rate_read_areas1(snd_pcm_t *pcm,
 | 
			
		|||
		   pcm->channels, rate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void snd_pcm_rate_sync_hwptr(snd_pcm_t *pcm)
 | 
			
		||||
static inline void snd_pcm_rate_sync_hwptr0(snd_pcm_t *pcm, snd_pcm_uframes_t slave_hw_ptr)
 | 
			
		||||
{
 | 
			
		||||
	snd_pcm_rate_t *rate = pcm->private_data;
 | 
			
		||||
	snd_pcm_uframes_t slave_hw_ptr = *rate->gen.slave->hw.ptr;
 | 
			
		||||
 | 
			
		||||
	if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
 | 
			
		||||
		return;
 | 
			
		||||
| 
						 | 
				
			
			@ -576,6 +575,12 @@ static inline void snd_pcm_rate_sync_hwptr(snd_pcm_t *pcm)
 | 
			
		|||
	rate->hw_ptr %= pcm->boundary;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void snd_pcm_rate_sync_hwptr(snd_pcm_t *pcm)
 | 
			
		||||
{
 | 
			
		||||
	snd_pcm_rate_t *rate = pcm->private_data;
 | 
			
		||||
	snd_pcm_rate_sync_hwptr0(pcm, *rate->gen.slave->hw.ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int snd_pcm_rate_hwsync(snd_pcm_t *pcm)
 | 
			
		||||
{
 | 
			
		||||
	snd_pcm_rate_t *rate = pcm->private_data;
 | 
			
		||||
| 
						 | 
				
			
			@ -586,10 +591,37 @@ static int snd_pcm_rate_hwsync(snd_pcm_t *pcm)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static snd_pcm_uframes_t snd_pcm_rate_playback_internal_delay(snd_pcm_t *pcm)
 | 
			
		||||
{
 | 
			
		||||
	snd_pcm_rate_t *rate = pcm->private_data;
 | 
			
		||||
 | 
			
		||||
	if (rate->appl_ptr < rate->last_commit_ptr) {
 | 
			
		||||
		return rate->appl_ptr - rate->last_commit_ptr + pcm->boundary;
 | 
			
		||||
	} else {
 | 
			
		||||
		return rate->appl_ptr - rate->last_commit_ptr;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int snd_pcm_rate_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 | 
			
		||||
{
 | 
			
		||||
	snd_pcm_rate_t *rate = pcm->private_data;
 | 
			
		||||
	snd_pcm_sframes_t slave_delay;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	snd_pcm_rate_hwsync(pcm);
 | 
			
		||||
	*delayp = snd_pcm_mmap_hw_avail(pcm);
 | 
			
		||||
 | 
			
		||||
	err = snd_pcm_delay(rate->gen.slave, &slave_delay);
 | 
			
		||||
	if (err < 0) {
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
 | 
			
		||||
		*delayp = rate->ops.input_frames(rate->obj, slave_delay)
 | 
			
		||||
				+ snd_pcm_rate_playback_internal_delay(pcm);
 | 
			
		||||
	} else {
 | 
			
		||||
		*delayp = rate->ops.output_frames(rate->obj, slave_delay)
 | 
			
		||||
				+ snd_pcm_mmap_capture_hw_avail(pcm);
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1083,15 +1115,21 @@ static int snd_pcm_rate_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
 | 
			
		|||
			status->state = SND_PCM_STATE_RUNNING;
 | 
			
		||||
		status->trigger_tstamp = rate->trigger_tstamp;
 | 
			
		||||
	}
 | 
			
		||||
	snd_pcm_rate_sync_hwptr(pcm);
 | 
			
		||||
	snd_pcm_rate_sync_hwptr0(pcm, status->hw_ptr);
 | 
			
		||||
	status->appl_ptr = *pcm->appl.ptr;
 | 
			
		||||
	status->hw_ptr = *pcm->hw.ptr;
 | 
			
		||||
	if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
 | 
			
		||||
		status->delay = snd_pcm_mmap_playback_hw_avail(pcm);
 | 
			
		||||
		status->delay = rate->ops.input_frames(rate->obj, status->delay)
 | 
			
		||||
					+ snd_pcm_rate_playback_internal_delay(pcm);
 | 
			
		||||
		status->avail = snd_pcm_mmap_playback_avail(pcm);
 | 
			
		||||
		status->avail_max = rate->ops.input_frames(rate->obj, status->avail_max);
 | 
			
		||||
	} else {
 | 
			
		||||
		status->delay = snd_pcm_mmap_capture_hw_avail(pcm);
 | 
			
		||||
		/* FIXME: Maybe possible to somthing similar to
 | 
			
		||||
		 * snd_pcm_rate_playback_internal_delay()
 | 
			
		||||
		 * for the capture case.
 | 
			
		||||
		 */
 | 
			
		||||
		status->delay = rate->ops.output_frames(rate->obj, status->delay)
 | 
			
		||||
					+ snd_pcm_mmap_capture_hw_avail(pcm);
 | 
			
		||||
		status->avail = snd_pcm_mmap_capture_avail(pcm);
 | 
			
		||||
		status->avail_max = rate->ops.output_frames(rate->obj, status->avail_max);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue