mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	event: add PULL_INPUT event
Rename some events, add an explicit event to pull input
This commit is contained in:
		
							parent
							
								
									e56f120559
								
							
						
					
					
						commit
						6377b9bd12
					
				
					 4 changed files with 21 additions and 109 deletions
				
			
		| 
						 | 
					@ -33,10 +33,9 @@ typedef struct _SpiEvent SpiEvent;
 | 
				
			||||||
 * @SPI_EVENT_TYPE_INVALID: invalid event, should be ignored
 | 
					 * @SPI_EVENT_TYPE_INVALID: invalid event, should be ignored
 | 
				
			||||||
 * @SPI_EVENT_TYPE_ACTIVATED: emited when the ACTIVATE command completes
 | 
					 * @SPI_EVENT_TYPE_ACTIVATED: emited when the ACTIVATE command completes
 | 
				
			||||||
 * @SPI_EVENT_TYPE_DEACTIVATED: emited when the DEACTIVATE command completes
 | 
					 * @SPI_EVENT_TYPE_DEACTIVATED: emited when the DEACTIVATE command completes
 | 
				
			||||||
 * @SPI_EVENT_TYPE_HAVE_OUTPUT: emited when an async node has output
 | 
					 * @SPI_EVENT_TYPE_CAN_PULL_OUTPUT: emited when an async node has output that can be pulled
 | 
				
			||||||
 * @SPI_EVENT_TYPE_NEED_INPUT: emited when an async node needs input. The data
 | 
					 * @SPI_EVENT_TYPE_CAN_PUSH_INTPUT: emited when more data can be pushed to an async node
 | 
				
			||||||
 *              member could contain a SpiBuffer that should be filled or it
 | 
					 * @SPI_EVENT_TYPE_PULL_INPUT: emited when data needs to be provided on an input
 | 
				
			||||||
 *              can be %NULL.
 | 
					 | 
				
			||||||
 * @SPI_EVENT_TYPE_ADD_POLL: emited when a pollfd should be added
 | 
					 * @SPI_EVENT_TYPE_ADD_POLL: emited when a pollfd should be added
 | 
				
			||||||
 * @SPI_EVENT_TYPE_REMOVE_POLL: emited when a pollfd should be removed
 | 
					 * @SPI_EVENT_TYPE_REMOVE_POLL: emited when a pollfd should be removed
 | 
				
			||||||
 * @SPI_EVENT_TYPE_DRAINED: emited when DRAIN command completed
 | 
					 * @SPI_EVENT_TYPE_DRAINED: emited when DRAIN command completed
 | 
				
			||||||
| 
						 | 
					@ -48,8 +47,9 @@ typedef enum {
 | 
				
			||||||
  SPI_EVENT_TYPE_INVALID                  = 0,
 | 
					  SPI_EVENT_TYPE_INVALID                  = 0,
 | 
				
			||||||
  SPI_EVENT_TYPE_ACTIVATED,
 | 
					  SPI_EVENT_TYPE_ACTIVATED,
 | 
				
			||||||
  SPI_EVENT_TYPE_DEACTIVATED,
 | 
					  SPI_EVENT_TYPE_DEACTIVATED,
 | 
				
			||||||
  SPI_EVENT_TYPE_HAVE_OUTPUT,
 | 
					  SPI_EVENT_TYPE_CAN_PULL_OUTPUT,
 | 
				
			||||||
  SPI_EVENT_TYPE_NEED_INPUT,
 | 
					  SPI_EVENT_TYPE_CAN_PUSH_INTPUT,
 | 
				
			||||||
 | 
					  SPI_EVENT_TYPE_PULL_INPUT,
 | 
				
			||||||
  SPI_EVENT_TYPE_ADD_POLL,
 | 
					  SPI_EVENT_TYPE_ADD_POLL,
 | 
				
			||||||
  SPI_EVENT_TYPE_REMOVE_POLL,
 | 
					  SPI_EVENT_TYPE_REMOVE_POLL,
 | 
				
			||||||
  SPI_EVENT_TYPE_DRAINED,
 | 
					  SPI_EVENT_TYPE_DRAINED,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,19 +41,6 @@ typedef enum {
 | 
				
			||||||
  SPI_INPUT_FLAG_NONE                  =  0,
 | 
					  SPI_INPUT_FLAG_NONE                  =  0,
 | 
				
			||||||
} SpiInputFlags;
 | 
					} SpiInputFlags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * SpiOutputFlags:
 | 
					 | 
				
			||||||
 * @SPI_OUTPUT_FLAG_NONE: no flag
 | 
					 | 
				
			||||||
 * @SPI_OUTPUT_FLAG_PULL: force a #SPI_EVENT_NEED_INPUT event on the
 | 
					 | 
				
			||||||
 *                        peer input ports when no data is available.
 | 
					 | 
				
			||||||
 * @SPI_OUTPUT_FLAG_DISCARD: discard the buffer data
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
  SPI_OUTPUT_FLAG_NONE                  =  0,
 | 
					 | 
				
			||||||
  SPI_OUTPUT_FLAG_PULL                  = (1 << 0),
 | 
					 | 
				
			||||||
  SPI_OUTPUT_FLAG_DISCARD               = (1 << 1),
 | 
					 | 
				
			||||||
} SpiOutputFlags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * SpiInputInfo:
 | 
					 * SpiInputInfo:
 | 
				
			||||||
 * @port_id: the port id
 | 
					 * @port_id: the port id
 | 
				
			||||||
| 
						 | 
					@ -70,6 +57,19 @@ typedef struct {
 | 
				
			||||||
  SpiResult       status;
 | 
					  SpiResult       status;
 | 
				
			||||||
} SpiInputInfo;
 | 
					} SpiInputInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SpiOutputFlags:
 | 
				
			||||||
 | 
					 * @SPI_OUTPUT_FLAG_NONE: no flag
 | 
				
			||||||
 | 
					 * @SPI_OUTPUT_FLAG_PULL: force a #SPI_EVENT_NEED_INPUT event on the
 | 
				
			||||||
 | 
					 *                        peer input ports when no data is available.
 | 
				
			||||||
 | 
					 * @SPI_OUTPUT_FLAG_DISCARD: discard the buffer data
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					  SPI_OUTPUT_FLAG_NONE                  =  0,
 | 
				
			||||||
 | 
					  SPI_OUTPUT_FLAG_PULL                  = (1 << 0),
 | 
				
			||||||
 | 
					  SPI_OUTPUT_FLAG_DISCARD               = (1 << 1),
 | 
				
			||||||
 | 
					} SpiOutputFlags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * SpiOutputInfo:
 | 
					 * SpiOutputInfo:
 | 
				
			||||||
 * @port_id: the port id
 | 
					 * @port_id: the port id
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,74 +9,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int verbose = 0;					/* verbose flag */
 | 
					static int verbose = 0;					/* verbose flag */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
generate_sine(const snd_pcm_channel_area_t *areas,
 | 
					 | 
				
			||||||
			  snd_pcm_uframes_t offset,
 | 
					 | 
				
			||||||
			  int count, double *_phase)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	static double max_phase = 2. * M_PI;
 | 
					 | 
				
			||||||
	double phase = *_phase;
 | 
					 | 
				
			||||||
	double step = max_phase*freq/(double)rate;
 | 
					 | 
				
			||||||
	unsigned char *samples[channels];
 | 
					 | 
				
			||||||
	int steps[channels];
 | 
					 | 
				
			||||||
	unsigned int chn;
 | 
					 | 
				
			||||||
	int format_bits = snd_pcm_format_width(format);
 | 
					 | 
				
			||||||
	unsigned int maxval = (1 << (format_bits - 1)) - 1;
 | 
					 | 
				
			||||||
	int bps = format_bits / 8;  /* bytes per sample */
 | 
					 | 
				
			||||||
	int phys_bps = snd_pcm_format_physical_width(format) / 8;
 | 
					 | 
				
			||||||
	int big_endian = snd_pcm_format_big_endian(format) == 1;
 | 
					 | 
				
			||||||
	int to_unsigned = snd_pcm_format_unsigned(format) == 1;
 | 
					 | 
				
			||||||
	int is_float = (format == SND_PCM_FORMAT_FLOAT_LE ||
 | 
					 | 
				
			||||||
			format == SND_PCM_FORMAT_FLOAT_BE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* verify and prepare the contents of areas */
 | 
					 | 
				
			||||||
	for (chn = 0; chn < channels; chn++) {
 | 
					 | 
				
			||||||
		if ((areas[chn].first % 8) != 0) {
 | 
					 | 
				
			||||||
			printf("areas[%i].first == %i, aborting...\n", chn, areas[chn].first);
 | 
					 | 
				
			||||||
			exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		samples[chn] = /*(signed short *)*/(((unsigned char *)areas[chn].addr) + (areas[chn].first / 8));
 | 
					 | 
				
			||||||
		if ((areas[chn].step % 16) != 0) {
 | 
					 | 
				
			||||||
			printf("areas[%i].step == %i, aborting...\n", chn, areas[chn].step);
 | 
					 | 
				
			||||||
			exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		steps[chn] = areas[chn].step / 8;
 | 
					 | 
				
			||||||
		samples[chn] += offset * steps[chn];
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	/* fill the channel areas */
 | 
					 | 
				
			||||||
	while (count-- > 0) {
 | 
					 | 
				
			||||||
		union {
 | 
					 | 
				
			||||||
			float f;
 | 
					 | 
				
			||||||
			int i;
 | 
					 | 
				
			||||||
		} fval;
 | 
					 | 
				
			||||||
		int res, i;
 | 
					 | 
				
			||||||
		if (is_float) {
 | 
					 | 
				
			||||||
			fval.f = sin(phase) * maxval;
 | 
					 | 
				
			||||||
			res = fval.i;
 | 
					 | 
				
			||||||
		} else
 | 
					 | 
				
			||||||
			res = sin(phase) * maxval;
 | 
					 | 
				
			||||||
		if (to_unsigned)
 | 
					 | 
				
			||||||
			res ^= 1U << (format_bits - 1);
 | 
					 | 
				
			||||||
		for (chn = 0; chn < channels; chn++) {
 | 
					 | 
				
			||||||
			/* Generate data in native endian format */
 | 
					 | 
				
			||||||
			if (big_endian) {
 | 
					 | 
				
			||||||
				for (i = 0; i < bps; i++)
 | 
					 | 
				
			||||||
					*(samples[chn] + phys_bps - 1 - i) = (res >> i * 8) & 0xff;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				for (i = 0; i < bps; i++)
 | 
					 | 
				
			||||||
					*(samples[chn] + i) = (res >>  i * 8) & 0xff;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			samples[chn] += steps[chn];
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		phase += step;
 | 
					 | 
				
			||||||
		if (phase >= max_phase)
 | 
					 | 
				
			||||||
			phase -= max_phase;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*_phase = phase;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CHECK(s,msg) if ((err = (s)) < 0) { printf (msg ": %s\n", snd_strerror(err)); return err; }
 | 
					#define CHECK(s,msg) if ((err = (s)) < 0) { printf (msg ": %s\n", snd_strerror(err)); return err; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static snd_pcm_format_t
 | 
					static snd_pcm_format_t
 | 
				
			||||||
| 
						 | 
					@ -236,26 +168,6 @@ xrun_recovery (snd_pcm_t *handle, int err)
 | 
				
			||||||
  return err;
 | 
					  return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 *   Transfer method - write and wait for room in buffer using poll
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
wait_for_poll (snd_pcm_t *handle, struct pollfd *ufds, unsigned int count)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  unsigned short revents;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  while (1) {
 | 
					 | 
				
			||||||
    poll(ufds, count, -1);
 | 
					 | 
				
			||||||
    snd_pcm_poll_descriptors_revents(handle, ufds, count, &revents);
 | 
					 | 
				
			||||||
    if (revents & POLLERR)
 | 
					 | 
				
			||||||
      return -EIO;
 | 
					 | 
				
			||||||
    if (revents & POLLOUT)
 | 
					 | 
				
			||||||
      return 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 *   Transfer method - direct write only
 | 
					 *   Transfer method - direct write only
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -335,7 +247,7 @@ direct_loop (void *user_data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event.refcount = 1;
 | 
					        event.refcount = 1;
 | 
				
			||||||
        event.notify = NULL;
 | 
					        event.notify = NULL;
 | 
				
			||||||
        event.type = SPI_EVENT_TYPE_NEED_INPUT;
 | 
					        event.type = SPI_EVENT_TYPE_PULL_INPUT;
 | 
				
			||||||
        event.port_id = 0;
 | 
					        event.port_id = 0;
 | 
				
			||||||
        event.data = buffer;
 | 
					        event.data = buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -363,7 +363,7 @@ on_event (SpiNode *node, SpiEvent *event, void *user_data)
 | 
				
			||||||
  AppData *data = user_data;
 | 
					  AppData *data = user_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  switch (event->type) {
 | 
					  switch (event->type) {
 | 
				
			||||||
    case SPI_EVENT_TYPE_NEED_INPUT:
 | 
					    case SPI_EVENT_TYPE_PULL_INPUT:
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      SpiBuffer *buf;
 | 
					      SpiBuffer *buf;
 | 
				
			||||||
      SpiInputInfo iinfo;
 | 
					      SpiInputInfo iinfo;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue