mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	loopback: add max_latency_msec argument
Currently loopback module indefinitely increases latency if underruns occur. This patch allows to set up the upper limit of latency.
This commit is contained in:
		
							parent
							
								
									4762aa45d9
								
							
						
					
					
						commit
						5864c4f976
					
				
					 1 changed files with 30 additions and 4 deletions
				
			
		| 
						 | 
					@ -45,6 +45,7 @@ PA_MODULE_USAGE(
 | 
				
			||||||
        "sink=<sink to connect to> "
 | 
					        "sink=<sink to connect to> "
 | 
				
			||||||
        "adjust_time=<how often to readjust rates in s> "
 | 
					        "adjust_time=<how often to readjust rates in s> "
 | 
				
			||||||
        "latency_msec=<latency in ms> "
 | 
					        "latency_msec=<latency in ms> "
 | 
				
			||||||
 | 
					        "max_latency_msec=<maximum latency in ms> "
 | 
				
			||||||
        "format=<sample format> "
 | 
					        "format=<sample format> "
 | 
				
			||||||
        "rate=<sample rate> "
 | 
					        "rate=<sample rate> "
 | 
				
			||||||
        "channels=<number of channels> "
 | 
					        "channels=<number of channels> "
 | 
				
			||||||
| 
						 | 
					@ -89,6 +90,7 @@ struct userdata {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Values from command line configuration */
 | 
					    /* Values from command line configuration */
 | 
				
			||||||
    pa_usec_t latency;
 | 
					    pa_usec_t latency;
 | 
				
			||||||
 | 
					    pa_usec_t max_latency;
 | 
				
			||||||
    pa_usec_t adjust_time;
 | 
					    pa_usec_t adjust_time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Latency boundaries and current values */
 | 
					    /* Latency boundaries and current values */
 | 
				
			||||||
| 
						 | 
					@ -158,6 +160,7 @@ static const char* const valid_modargs[] = {
 | 
				
			||||||
    "sink",
 | 
					    "sink",
 | 
				
			||||||
    "adjust_time",
 | 
					    "adjust_time",
 | 
				
			||||||
    "latency_msec",
 | 
					    "latency_msec",
 | 
				
			||||||
 | 
					    "max_latency_msec",
 | 
				
			||||||
    "format",
 | 
					    "format",
 | 
				
			||||||
    "rate",
 | 
					    "rate",
 | 
				
			||||||
    "channels",
 | 
					    "channels",
 | 
				
			||||||
| 
						 | 
					@ -325,10 +328,20 @@ static void adjust_rates(struct userdata *u) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* If we are seeing underruns then the latency is too small */
 | 
					    /* If we are seeing underruns then the latency is too small */
 | 
				
			||||||
    if (u->underrun_counter > 2) {
 | 
					    if (u->underrun_counter > 2) {
 | 
				
			||||||
        u->underrun_latency_limit = PA_MAX(u->latency, u->minimum_latency) + 5 * PA_USEC_PER_MSEC;
 | 
					        pa_usec_t target_latency;
 | 
				
			||||||
        u->underrun_latency_limit = PA_CLIP_SUB((int64_t)u->underrun_latency_limit, u->sink_latency_offset + u->source_latency_offset);
 | 
					
 | 
				
			||||||
 | 
					        target_latency = PA_MAX(u->latency, u->minimum_latency) + 5 * PA_USEC_PER_MSEC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (u->max_latency == 0 || target_latency < u->max_latency) {
 | 
				
			||||||
 | 
					            u->underrun_latency_limit = PA_CLIP_SUB((int64_t)target_latency, u->sink_latency_offset + u->source_latency_offset);
 | 
				
			||||||
 | 
					            pa_log_warn("Too many underruns, increasing latency to %0.2f ms", (double)target_latency / PA_USEC_PER_MSEC);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            u->underrun_latency_limit = PA_CLIP_SUB((int64_t)u->max_latency, u->sink_latency_offset + u->source_latency_offset);
 | 
				
			||||||
 | 
					            pa_log_warn("Too many underruns, configured maximum latency of %0.2f ms is reached", (double)u->max_latency / PA_USEC_PER_MSEC);
 | 
				
			||||||
 | 
					            pa_log_warn("Consider increasing the max_latency_msec");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        update_minimum_latency(u, u->sink_input->sink, false);
 | 
					        update_minimum_latency(u, u->sink_input->sink, false);
 | 
				
			||||||
        pa_log_warn("Too many underruns, increasing latency to %0.2f ms", (double)u->minimum_latency / PA_USEC_PER_MSEC);
 | 
					 | 
				
			||||||
        u->underrun_counter = 0;
 | 
					        u->underrun_counter = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1252,6 +1265,7 @@ int pa__init(pa_module *m) {
 | 
				
			||||||
    pa_source_output_new_data source_output_data;
 | 
					    pa_source_output_new_data source_output_data;
 | 
				
			||||||
    bool source_dont_move;
 | 
					    bool source_dont_move;
 | 
				
			||||||
    uint32_t latency_msec;
 | 
					    uint32_t latency_msec;
 | 
				
			||||||
 | 
					    uint32_t max_latency_msec;
 | 
				
			||||||
    pa_sample_spec ss;
 | 
					    pa_sample_spec ss;
 | 
				
			||||||
    pa_channel_map map;
 | 
					    pa_channel_map map;
 | 
				
			||||||
    bool format_set = false;
 | 
					    bool format_set = false;
 | 
				
			||||||
| 
						 | 
					@ -1336,10 +1350,22 @@ int pa__init(pa_module *m) {
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    max_latency_msec = 0;
 | 
				
			||||||
 | 
					    if (pa_modargs_get_value_u32(ma, "max_latency_msec", &max_latency_msec) < 0) {
 | 
				
			||||||
 | 
					        pa_log("Invalid maximum latency specification");
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (max_latency_msec > 0 && max_latency_msec < latency_msec) {
 | 
				
			||||||
 | 
					        pa_log_warn("Configured maximum latency is smaller than latency, using latency instead");
 | 
				
			||||||
 | 
					        max_latency_msec = latency_msec;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m->userdata = u = pa_xnew0(struct userdata, 1);
 | 
					    m->userdata = u = pa_xnew0(struct userdata, 1);
 | 
				
			||||||
    u->core = m->core;
 | 
					    u->core = m->core;
 | 
				
			||||||
    u->module = m;
 | 
					    u->module = m;
 | 
				
			||||||
    u->latency = (pa_usec_t) latency_msec * PA_USEC_PER_MSEC;
 | 
					    u->latency = (pa_usec_t) latency_msec * PA_USEC_PER_MSEC;
 | 
				
			||||||
 | 
					    u->max_latency = (pa_usec_t) max_latency_msec * PA_USEC_PER_MSEC;
 | 
				
			||||||
    u->output_thread_info.pop_called = false;
 | 
					    u->output_thread_info.pop_called = false;
 | 
				
			||||||
    u->output_thread_info.pop_adjust = false;
 | 
					    u->output_thread_info.pop_adjust = false;
 | 
				
			||||||
    u->output_thread_info.push_called = false;
 | 
					    u->output_thread_info.push_called = false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue