mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	sink: force suspend/resume on passthrough transitions
A race condition prevents the AES non-audio bit from being set when enabling IEC61937 passthrough on resume with no sink-input connected (pa_sink_is_passthrough returns false). The non-audio bit should really be set when opening the sink. Force the sink to suspend/resume when actually entering passthrough mode, and likewise force a suspend-resume on leaving passthrough mode. Tested with E-AC3 streams which do need the AES bit set for my Onkyon receiver to detect the format instead of playing it as PCM. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
This commit is contained in:
		
							parent
							
								
									b4d2443249
								
							
						
					
					
						commit
						15d28f21b4
					
				
					 2 changed files with 25 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -1626,6 +1626,11 @@ bool pa_sink_is_passthrough(pa_sink *s) {
 | 
			
		|||
void pa_sink_enter_passthrough(pa_sink *s) {
 | 
			
		||||
    pa_cvolume volume;
 | 
			
		||||
 | 
			
		||||
    if (s->is_passthrough_set) {
 | 
			
		||||
	pa_log_debug("Sink %s is already in passthrough mode, nothing to do", s->name);
 | 
			
		||||
	return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* disable the monitor in passthrough mode */
 | 
			
		||||
    if (s->monitor_source) {
 | 
			
		||||
        pa_log_debug("Suspending monitor source %s, because the sink is entering the passthrough mode.", s->monitor_source->name);
 | 
			
		||||
| 
						 | 
				
			
			@ -1638,10 +1643,23 @@ void pa_sink_enter_passthrough(pa_sink *s) {
 | 
			
		|||
 | 
			
		||||
    pa_cvolume_set(&volume, s->sample_spec.channels, PA_MIN(s->base_volume, PA_VOLUME_NORM));
 | 
			
		||||
    pa_sink_set_volume(s, &volume, true, false);
 | 
			
		||||
 | 
			
		||||
    pa_log_debug("Suspending/Restarting sink %s to enter passthrough mode", s->name);
 | 
			
		||||
 | 
			
		||||
    /* force sink to be resumed in passthrough mode */
 | 
			
		||||
    pa_sink_suspend(s, true, PA_SUSPEND_INTERNAL);
 | 
			
		||||
    s->is_passthrough_set = true;
 | 
			
		||||
    pa_sink_suspend(s, false, PA_SUSPEND_INTERNAL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Called from main context */
 | 
			
		||||
void pa_sink_leave_passthrough(pa_sink *s) {
 | 
			
		||||
 | 
			
		||||
    if (!s->is_passthrough_set) {
 | 
			
		||||
	pa_log_debug("Sink %s is not in passthrough mode, nothing to do", s->name);
 | 
			
		||||
	return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Unsuspend monitor */
 | 
			
		||||
    if (s->monitor_source) {
 | 
			
		||||
        pa_log_debug("Resuming monitor source %s, because the sink is leaving the passthrough mode.", s->monitor_source->name);
 | 
			
		||||
| 
						 | 
				
			
			@ -1653,6 +1671,12 @@ void pa_sink_leave_passthrough(pa_sink *s) {
 | 
			
		|||
 | 
			
		||||
    pa_cvolume_init(&s->saved_volume);
 | 
			
		||||
    s->saved_save_volume = false;
 | 
			
		||||
 | 
			
		||||
    /* force sink to be resumed in non-passthrough mode */
 | 
			
		||||
    pa_sink_suspend(s, true, PA_SUSPEND_INTERNAL);
 | 
			
		||||
    s->is_passthrough_set = false;
 | 
			
		||||
    pa_sink_suspend(s, false, PA_SUSPEND_INTERNAL);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Called from main context. */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -108,6 +108,7 @@ struct pa_sink {
 | 
			
		|||
    /* Saved volume state while we're in passthrough mode */
 | 
			
		||||
    pa_cvolume saved_volume;
 | 
			
		||||
    bool saved_save_volume:1;
 | 
			
		||||
    bool is_passthrough_set:1;
 | 
			
		||||
 | 
			
		||||
    pa_asyncmsgq *asyncmsgq;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue