mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	pcm: dmix_rewind corrupts application pointer fix
sometimes pulseaudio stops with the following assertion in libasound.so: alsa-lib-1.0.29/src/pcm/pcm.c:2761: snd_pcm_area_copy: Assertion `dst < src || dst >= src + bytes' failed. Application pointer is handled properly, in cases of rewind operations. Signed-off-by: Timo Wischer <twischer@de.adit-jv.com> Signed-off-by: Ravikiran Polepalli <ravikiran_polepalli@mentor.com> Signed-off-by: Mikhail Durnev <mikhail_durnev@mentor.com> Signed-off-by: Mounesh Sutar <sutar.mounesh@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
							parent
							
								
									22eca6468b
								
							
						
					
					
						commit
						df7694d80c
					
				
					 1 changed files with 23 additions and 10 deletions
				
			
		| 
						 | 
					@ -706,7 +706,7 @@ static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	snd_pcm_direct_t *dmix = pcm->private_data;
 | 
						snd_pcm_direct_t *dmix = pcm->private_data;
 | 
				
			||||||
	snd_pcm_uframes_t slave_appl_ptr, slave_size;
 | 
						snd_pcm_uframes_t slave_appl_ptr, slave_size;
 | 
				
			||||||
	snd_pcm_uframes_t appl_ptr, size, transfer, result;
 | 
						snd_pcm_uframes_t appl_ptr, size, transfer, result, frames_to_remix;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	const snd_pcm_channel_area_t *src_areas, *dst_areas;
 | 
						const snd_pcm_channel_area_t *src_areas, *dst_areas;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -717,6 +717,13 @@ static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
 | 
				
			||||||
			return err;
 | 
								return err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* (appl_ptr - last_appl_ptr) indicates the frames which are not
 | 
				
			||||||
 | 
						 * already mixed
 | 
				
			||||||
 | 
						 * (last_appl_ptr - hw_ptr)  indicates the frames which are already
 | 
				
			||||||
 | 
						 * mixed but not played yet.
 | 
				
			||||||
 | 
						 * So they can be remixed.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dmix->last_appl_ptr < dmix->appl_ptr)
 | 
						if (dmix->last_appl_ptr < dmix->appl_ptr)
 | 
				
			||||||
		size = dmix->appl_ptr - dmix->last_appl_ptr;
 | 
							size = dmix->appl_ptr - dmix->last_appl_ptr;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
| 
						 | 
					@ -729,6 +736,9 @@ static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
 | 
				
			||||||
		return size;
 | 
							return size;
 | 
				
			||||||
	result = size;
 | 
						result = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Always at this point last_appl_ptr == appl_ptr
 | 
				
			||||||
 | 
						 * So (appl_ptr - hw_ptr) indicates the frames which can be remixed
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	if (dmix->hw_ptr < dmix->appl_ptr)
 | 
						if (dmix->hw_ptr < dmix->appl_ptr)
 | 
				
			||||||
		size = dmix->appl_ptr - dmix->hw_ptr;
 | 
							size = dmix->appl_ptr - dmix->hw_ptr;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
| 
						 | 
					@ -741,8 +751,11 @@ static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
 | 
				
			||||||
		slave_size = dmix->slave_appl_ptr + (pcm->boundary - dmix->slave_hw_ptr);
 | 
							slave_size = dmix->slave_appl_ptr + (pcm->boundary - dmix->slave_hw_ptr);
 | 
				
			||||||
	if (slave_size < size)
 | 
						if (slave_size < size)
 | 
				
			||||||
		size = slave_size;
 | 
							size = slave_size;
 | 
				
			||||||
	frames -= size;
 | 
					
 | 
				
			||||||
	result += size;
 | 
						/* frames which should be remixed will be saved
 | 
				
			||||||
 | 
						 * to also backward the appl pointer on success
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						frames_to_remix = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* add sample areas here */
 | 
						/* add sample areas here */
 | 
				
			||||||
	src_areas = snd_pcm_mmap_areas(pcm);
 | 
						src_areas = snd_pcm_mmap_areas(pcm);
 | 
				
			||||||
| 
						 | 
					@ -769,15 +782,15 @@ static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
 | 
				
			||||||
		appl_ptr += transfer;
 | 
							appl_ptr += transfer;
 | 
				
			||||||
		appl_ptr %= pcm->buffer_size;
 | 
							appl_ptr %= pcm->buffer_size;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dmix->last_appl_ptr -= frames;
 | 
					 | 
				
			||||||
	dmix->last_appl_ptr %= pcm->boundary;
 | 
					 | 
				
			||||||
	dmix->slave_appl_ptr -= frames;
 | 
					 | 
				
			||||||
	dmix->slave_appl_ptr %= dmix->slave_boundary;
 | 
					 | 
				
			||||||
	dmix_up_sem(dmix);
 | 
						dmix_up_sem(dmix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_pcm_mmap_appl_backward(pcm, frames);
 | 
						snd_pcm_mmap_appl_backward(pcm, frames_to_remix);
 | 
				
			||||||
 | 
						result += frames_to_remix;
 | 
				
			||||||
 | 
						/* At this point last_appl_ptr and appl_ptr has to indicate the
 | 
				
			||||||
 | 
						 * position of the first not mixed frame
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return result + frames;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static snd_pcm_sframes_t snd_pcm_dmix_forwardable(snd_pcm_t *pcm)
 | 
					static snd_pcm_sframes_t snd_pcm_dmix_forwardable(snd_pcm_t *pcm)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue