mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	node: schedule upstream first
In pull mode, schedule all upstream nodes first, if any of them produce output, push it into the current node. Underrun streams without input on audiomixer, avoids glitch when starting a new stream.
This commit is contained in:
		
							parent
							
								
									4c7b56020a
								
							
						
					
					
						commit
						d9bb116d27
					
				
					 3 changed files with 18 additions and 17 deletions
				
			
		| 
						 | 
					@ -258,6 +258,7 @@ do_pull (PinosNode *this)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  SpaResult res = SPA_RESULT_OK;
 | 
					  SpaResult res = SPA_RESULT_OK;
 | 
				
			||||||
  PinosPort *inport;
 | 
					  PinosPort *inport;
 | 
				
			||||||
 | 
					  bool have_output = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  spa_list_for_each (inport, &this->input_ports, link) {
 | 
					  spa_list_for_each (inport, &this->input_ports, link) {
 | 
				
			||||||
    PinosLink *link;
 | 
					    PinosLink *link;
 | 
				
			||||||
| 
						 | 
					@ -288,23 +289,23 @@ do_pull (PinosNode *this)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (res == SPA_RESULT_NEED_INPUT) {
 | 
					      if (res == SPA_RESULT_NEED_INPUT) {
 | 
				
			||||||
        res = do_pull (outport->node);
 | 
					        res = do_pull (outport->node);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        *pi = *po;
 | 
					 | 
				
			||||||
        pinos_log_trace ("node %p: pull return %d", outport->node, res);
 | 
					        pinos_log_trace ("node %p: pull return %d", outport->node, res);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else if (res == SPA_RESULT_HAVE_OUTPUT) {
 | 
					      else if (res < 0 && res != SPA_RESULT_HAVE_OUTPUT) {
 | 
				
			||||||
        *pi = *po;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        pinos_log_warn ("node %p: got process output %d", outport->node, res);
 | 
					        pinos_log_warn ("node %p: got process output %d", outport->node, res);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    if (pi->buffer_id != SPA_ID_INVALID) {
 | 
					
 | 
				
			||||||
      pinos_log_trace ("node %p: process input %d %d", this, pi->status, pi->buffer_id);
 | 
					      if (res == SPA_RESULT_HAVE_OUTPUT) {
 | 
				
			||||||
      res =  spa_node_process_input (this->node);
 | 
					        *pi = *po;
 | 
				
			||||||
      if (res == SPA_RESULT_HAVE_OUTPUT)
 | 
					        pinos_log_trace ("node %p: have output %d %d", this, pi->status, pi->buffer_id);
 | 
				
			||||||
        break;
 | 
					        have_output = true;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (have_output) {
 | 
				
			||||||
 | 
					    pinos_log_trace ("node %p: doing process input", this);
 | 
				
			||||||
 | 
					    res =  spa_node_process_input (this->node);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  return res;
 | 
					  return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -733,7 +733,7 @@ spa_audiomixer_node_process_input (SpaNode *node)
 | 
				
			||||||
      spa_log_trace (this->log, "audiomixer %p: queue buffer %d on port %d %zd %zd",
 | 
					      spa_log_trace (this->log, "audiomixer %p: queue buffer %d on port %d %zd %zd",
 | 
				
			||||||
          this, b->outbuf->id, i, port->queued_bytes, min_queued);
 | 
					          this, b->outbuf->id, i, port->queued_bytes, min_queued);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (min_queued == SIZE_MAX || port->queued_bytes < min_queued)
 | 
					    if (port->queued_bytes > 0 && port->queued_bytes < min_queued)
 | 
				
			||||||
      min_queued = port->queued_bytes;
 | 
					      min_queued = port->queued_bytes;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -772,7 +772,7 @@ spa_audiomixer_node_process_output (SpaNode *node)
 | 
				
			||||||
  res = SPA_RESULT_NEED_INPUT;
 | 
					  res = SPA_RESULT_NEED_INPUT;
 | 
				
			||||||
  /* produce more output if possible */
 | 
					  /* produce more output if possible */
 | 
				
			||||||
  if (this->state == STATE_OUT) {
 | 
					  if (this->state == STATE_OUT) {
 | 
				
			||||||
    size_t min_queued = -1;
 | 
					    size_t min_queued = SIZE_MAX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i = 0; i < MAX_PORTS; i++) {
 | 
					    for (i = 0; i < MAX_PORTS; i++) {
 | 
				
			||||||
      SpaAudioMixerPort *port = &this->in_ports[i];
 | 
					      SpaAudioMixerPort *port = &this->in_ports[i];
 | 
				
			||||||
| 
						 | 
					@ -780,10 +780,10 @@ spa_audiomixer_node_process_output (SpaNode *node)
 | 
				
			||||||
      if (port->io == NULL || port->n_buffers == 0)
 | 
					      if (port->io == NULL || port->n_buffers == 0)
 | 
				
			||||||
        continue;
 | 
					        continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (min_queued == -1 || port->queued_bytes < min_queued)
 | 
					      if (port->queued_bytes > 0 && port->queued_bytes < min_queued)
 | 
				
			||||||
        min_queued = port->queued_bytes;
 | 
					        min_queued = port->queued_bytes;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (min_queued != -1 && min_queued > 0) {
 | 
					    if (min_queued != SIZE_MAX && min_queued > 0) {
 | 
				
			||||||
      res = mix_output (this, min_queued);
 | 
					      res = mix_output (this, min_queued);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      this->state = STATE_IN;
 | 
					      this->state = STATE_IN;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -311,7 +311,7 @@ make_nodes (AppData *data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  spa_pod_builder_init (&b, buffer, sizeof (buffer));
 | 
					  spa_pod_builder_init (&b, buffer, sizeof (buffer));
 | 
				
			||||||
  spa_pod_builder_props (&b, &f[0], data->type.props,
 | 
					  spa_pod_builder_props (&b, &f[0], data->type.props,
 | 
				
			||||||
      SPA_POD_PROP (&f[1], data->type.props_device, 0, SPA_POD_TYPE_STRING, 1, "hw:0"),
 | 
					      SPA_POD_PROP (&f[1], data->type.props_device, 0, SPA_POD_TYPE_STRING, 1, "hw:1"),
 | 
				
			||||||
      SPA_POD_PROP (&f[1], data->type.props_min_latency, 0, SPA_POD_TYPE_INT, 1, 256),
 | 
					      SPA_POD_PROP (&f[1], data->type.props_min_latency, 0, SPA_POD_TYPE_INT, 1, 256),
 | 
				
			||||||
      SPA_POD_PROP (&f[1], data->type.props_live, 0, SPA_POD_TYPE_BOOL, 1, false));
 | 
					      SPA_POD_PROP (&f[1], data->type.props_live, 0, SPA_POD_TYPE_BOOL, 1, false));
 | 
				
			||||||
  props = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaProps);
 | 
					  props = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaProps);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue