mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	source: When updating a monitor source's rate, update the sink rate too
If the sink rate is not updated, then the monitor source will appear to have a different rate than the sink, but in reality there's never any resampling done when moving data from the sink to the monitor source, so it's a lie that the monitor source has a different rate. The result of lying is that clients that capture from the monitor source will have streams that run too fast or slow.
This commit is contained in:
		
							parent
							
								
									2c14306507
								
							
						
					
					
						commit
						a32c5e4354
					
				
					 1 changed files with 32 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -991,6 +991,13 @@ bool pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
 | 
			
		|||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (s->monitor_of) {
 | 
			
		||||
        if (PA_SINK_IS_RUNNING(s->monitor_of->state)) {
 | 
			
		||||
            pa_log_info("Cannot update rate, this is a monitor source and the sink is running.");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (PA_UNLIKELY (desired_rate < 8000 ||
 | 
			
		||||
                     desired_rate > PA_RATE_MAX))
 | 
			
		||||
        return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -1029,8 +1036,31 @@ bool pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
 | 
			
		|||
        ret = s->update_rate(s, desired_rate);
 | 
			
		||||
    else {
 | 
			
		||||
        /* This is a monitor source. */
 | 
			
		||||
 | 
			
		||||
        /* XXX: This code is written with non-passthrough streams in mind. I
 | 
			
		||||
         * have no idea whether the behaviour with passthrough streams is
 | 
			
		||||
         * sensible. */
 | 
			
		||||
        if (!passthrough) {
 | 
			
		||||
            uint32_t old_rate = s->sample_spec.rate;
 | 
			
		||||
 | 
			
		||||
            s->sample_spec.rate = desired_rate;
 | 
			
		||||
        ret = true;
 | 
			
		||||
            ret = pa_sink_update_rate(s->monitor_of, desired_rate, false);
 | 
			
		||||
 | 
			
		||||
            if (!ret) {
 | 
			
		||||
                /* Changing the sink rate failed, roll back the old rate for
 | 
			
		||||
                 * the monitor source. Why did we set the source rate before
 | 
			
		||||
                 * calling pa_sink_update_rate(), you may ask. The reason is
 | 
			
		||||
                 * that pa_sink_update_rate() tries to update the monitor
 | 
			
		||||
                 * source rate, but we are already in the process of updating
 | 
			
		||||
                 * the monitor source rate, so there's a risk of entering an
 | 
			
		||||
                 * infinite loop. Setting the source rate before calling
 | 
			
		||||
                 * pa_sink_update_rate() makes the rate == s->sample_spec.rate
 | 
			
		||||
                 * check in the beginning of this function return early, so we
 | 
			
		||||
                 * avoid looping. */
 | 
			
		||||
                s->sample_spec.rate = old_rate;
 | 
			
		||||
            }
 | 
			
		||||
        } else
 | 
			
		||||
            ret = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ret) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue