All of lore.kernel.org
 help / color / mirror / Atom feed
* More snd_pcm_ioplug_avail_update() questions
@ 2018-07-25 21:52 Rob Duncan
  2018-07-26  7:04 ` Takashi Iwai
  0 siblings, 1 reply; 8+ messages in thread
From: Rob Duncan @ 2018-07-25 21:52 UTC (permalink / raw)
  To: alsa-devel

Is it required that all available data has been committed between calls
to snd_pcm_ioplug_avail_update() on an IO plugin capture stream?

If this is not a requirement then there can still be uncommitted data in
the mmap after the current appl_ptr.  This data will get overwritten by
the transfer call.

If it is a requirement then snd_pcm_rate_avail_update() seems to be
doing the wrong thing, because it only commits in units of the period
size, which means that there could be a partial period left in the mmap.

Can someone clarify what the contract is for these calls?

Thanks,

Rob.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: More snd_pcm_ioplug_avail_update() questions
  2018-07-25 21:52 More snd_pcm_ioplug_avail_update() questions Rob Duncan
@ 2018-07-26  7:04 ` Takashi Iwai
  2018-07-26 14:19   ` Rob Duncan
  0 siblings, 1 reply; 8+ messages in thread
From: Takashi Iwai @ 2018-07-26  7:04 UTC (permalink / raw)
  To: Rob Duncan; +Cc: alsa-devel

On Wed, 25 Jul 2018 23:52:36 +0200,
Rob Duncan wrote:
> 
> Is it required that all available data has been committed between calls
> to snd_pcm_ioplug_avail_update() on an IO plugin capture stream?

Yes, the capture data is committed.
The snd_pcm_ioplug_hw_ptr_update() should have reported the amount of
data the slave PCM can actually transfer.  Hence the transfer call
thereafter must fulfill the whole requested data.

The capture in ioplug is a sort of mmap emulation.  On real hardware,
the mmap data is already committed before update_avail is called,
update_avail just follows the already committed amount.  In the
emulation mode, it's other way round; the data is committed at the
point hwptr is update, i.e. avail_update is called.


Takashi

> If this is not a requirement then there can still be uncommitted data in
> the mmap after the current appl_ptr.  This data will get overwritten by
> the transfer call.
> 
> If it is a requirement then snd_pcm_rate_avail_update() seems to be
> doing the wrong thing, because it only commits in units of the period
> size, which means that there could be a partial period left in the mmap.
> 
> Can someone clarify what the contract is for these calls?
> 
> Thanks,
> 
> Rob.
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: More snd_pcm_ioplug_avail_update() questions
  2018-07-26  7:04 ` Takashi Iwai
@ 2018-07-26 14:19   ` Rob Duncan
  2018-07-26 14:37     ` Takashi Iwai
  0 siblings, 1 reply; 8+ messages in thread
From: Rob Duncan @ 2018-07-26 14:19 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel


At 00:04 on Thu, Jul 26 2018, Takashi wrote:
>> Is it required that all available data has been committed between calls
>> to snd_pcm_ioplug_avail_update() on an IO plugin capture stream?
>
> Yes, the capture data is committed.
> The snd_pcm_ioplug_hw_ptr_update() should have reported the amount of
> data the slave PCM can actually transfer.  Hence the transfer call
> thereafter must fulfill the whole requested data.

But what I see is that snd_pcm_rate_avail_update() commits data in the
slave PCM in units of slave->period_size (via
snd_pcm_rate_grab_next_period()), which means that if there is a partial
period in the slave PCM mmap it will not be committed.

In other words, not all the available data will be commmitted before the
next call to snd_pcm_ioplug_avail_update().  This means that the data
will be discarded the next time that snd_pcm_ioplug_avail_update() is
called.

Rob.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: More snd_pcm_ioplug_avail_update() questions
  2018-07-26 14:19   ` Rob Duncan
@ 2018-07-26 14:37     ` Takashi Iwai
  2018-07-26 15:02       ` Rob Duncan
  0 siblings, 1 reply; 8+ messages in thread
From: Takashi Iwai @ 2018-07-26 14:37 UTC (permalink / raw)
  To: Rob Duncan; +Cc: alsa-devel

On Thu, 26 Jul 2018 16:19:19 +0200,
Rob Duncan wrote:
> 
> 
> At 00:04 on Thu, Jul 26 2018, Takashi wrote:
> >> Is it required that all available data has been committed between calls
> >> to snd_pcm_ioplug_avail_update() on an IO plugin capture stream?
> >
> > Yes, the capture data is committed.
> > The snd_pcm_ioplug_hw_ptr_update() should have reported the amount of
> > data the slave PCM can actually transfer.  Hence the transfer call
> > thereafter must fulfill the whole requested data.
> 
> But what I see is that snd_pcm_rate_avail_update() commits data in the
> slave PCM in units of slave->period_size (via
> snd_pcm_rate_grab_next_period()), which means that if there is a partial
> period in the slave PCM mmap it will not be committed.
> 
> In other words, not all the available data will be commmitted before the
> next call to snd_pcm_ioplug_avail_update().  This means that the data
> will be discarded the next time that snd_pcm_ioplug_avail_update() is
> called.

OK, I seem to have misunderstood about what you meant as committed in
the context.  Yes, if the available is partial, it might be not
committed.  But I don't understand the next part.

How will it be discarded at the next snd_pcm_ioplug_avail_update()?
The data remains on the buffer, and applptr isn't changed.


Takashi

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: More snd_pcm_ioplug_avail_update() questions
  2018-07-26 14:37     ` Takashi Iwai
@ 2018-07-26 15:02       ` Rob Duncan
  2018-07-26 15:14         ` Takashi Iwai
  0 siblings, 1 reply; 8+ messages in thread
From: Rob Duncan @ 2018-07-26 15:02 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel


At 07:37 on Thu, Jul 26 2018, Takashi wrote:
> OK, I seem to have misunderstood about what you meant as committed in
> the context.  Yes, if the available is partial, it might be not
> committed.  But I don't understand the next part.
>
> How will it be discarded at the next snd_pcm_ioplug_avail_update()?
> The data remains on the buffer, and applptr isn't changed.

Yes, that's the problem.  Because when snd_pcm_ioplug_avail_update() is
subsequently called it uses snd_pcm_mmap_begin() to get the offset into
the mmap for the destination of the capture transfer operation.  This is
essentially appl_ptr, which means that the data that has not yet been
commited will be overwritten by the transfer.

I guess that the offset could somehow be adjusted to point to after the
uncommitted data but I don't see a straightforward way to do that.  A
scheme along these lines would also have to adjust the size parameter
accordingly, of course.  This would sometimes mean that we cannot
transfer all the available data from the IO plugin.  Would that cause
any issues?

Rob.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: More snd_pcm_ioplug_avail_update() questions
  2018-07-26 15:02       ` Rob Duncan
@ 2018-07-26 15:14         ` Takashi Iwai
  2018-07-30 18:55           ` Rob Duncan
  0 siblings, 1 reply; 8+ messages in thread
From: Takashi Iwai @ 2018-07-26 15:14 UTC (permalink / raw)
  To: Rob Duncan; +Cc: alsa-devel

On Thu, 26 Jul 2018 17:02:33 +0200,
Rob Duncan wrote:
> 
> 
> At 07:37 on Thu, Jul 26 2018, Takashi wrote:
> > OK, I seem to have misunderstood about what you meant as committed in
> > the context.  Yes, if the available is partial, it might be not
> > committed.  But I don't understand the next part.
> >
> > How will it be discarded at the next snd_pcm_ioplug_avail_update()?
> > The data remains on the buffer, and applptr isn't changed.
> 
> Yes, that's the problem.  Because when snd_pcm_ioplug_avail_update() is
> subsequently called it uses snd_pcm_mmap_begin() to get the offset into
> the mmap for the destination of the capture transfer operation.  This is
> essentially appl_ptr, which means that the data that has not yet been
> commited will be overwritten by the transfer.

OK, point taken.  Yeah, if the ioplug driver expects that the transfer
happens only once, it's a problem.

> I guess that the offset could somehow be adjusted to point to after the
> uncommitted data but I don't see a straightforward way to do that.  A
> scheme along these lines would also have to adjust the size parameter
> accordingly, of course.  This would sometimes mean that we cannot
> transfer all the available data from the IO plugin.  Would that cause
> any issues?

Maybe we can track the own applptr (e.g. transfer_ptr or such) and
calculate the transfer size from it instead of snd_pcm_mmap_begin();
i.e. write some open codes of alternative snd_pcm_mmap_begin() there.

Then transfer_ptr is updated again in snd_pcm_ioplug_mmap_commit() as
well when applptr is updated.

Of course, there is a smarter way, I'd happily take another approach.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: More snd_pcm_ioplug_avail_update() questions
  2018-07-26 15:14         ` Takashi Iwai
@ 2018-07-30 18:55           ` Rob Duncan
  2018-07-31  8:21             ` Takashi Iwai
  0 siblings, 1 reply; 8+ messages in thread
From: Rob Duncan @ 2018-07-30 18:55 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

At 08:14 on Thu, Jul 26 2018, Takashi wrote:

> Maybe we can track the own applptr (e.g. transfer_ptr or such) and
> calculate the transfer size from it instead of snd_pcm_mmap_begin();
> i.e. write some open codes of alternative snd_pcm_mmap_begin() there.
>
> Then transfer_ptr is updated again in snd_pcm_ioplug_mmap_commit() as
> well when applptr is updated.
>
> Of course, there is a smarter way, I'd happily take another approach.

Thanks for the hint.  I'm not sure I 100% understand your suggestion,
though.  Unfortunately I don't think I'll have an opportunity to try
this for a few weeks.

Rob.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: More snd_pcm_ioplug_avail_update() questions
  2018-07-30 18:55           ` Rob Duncan
@ 2018-07-31  8:21             ` Takashi Iwai
  0 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2018-07-31  8:21 UTC (permalink / raw)
  To: Rob Duncan; +Cc: alsa-devel

On Mon, 30 Jul 2018 20:55:45 +0200,
Rob Duncan wrote:
> 
> At 08:14 on Thu, Jul 26 2018, Takashi wrote:
> 
> > Maybe we can track the own applptr (e.g. transfer_ptr or such) and
> > calculate the transfer size from it instead of snd_pcm_mmap_begin();
> > i.e. write some open codes of alternative snd_pcm_mmap_begin() there.
> >
> > Then transfer_ptr is updated again in snd_pcm_ioplug_mmap_commit() as
> > well when applptr is updated.
> >
> > Of course, there is a smarter way, I'd happily take another approach.
> 
> Thanks for the hint.  I'm not sure I 100% understand your suggestion,
> though.

Well, something like below (totally untested).


Takashi

---
--- a/src/pcm/pcm_ioplug.c
+++ b/src/pcm/pcm_ioplug.c
@@ -44,6 +44,7 @@ typedef struct snd_pcm_ioplug_priv {
 	struct snd_ext_parm params[SND_PCM_IOPLUG_HW_PARAMS];
 	snd_pcm_uframes_t last_hw;
 	snd_pcm_uframes_t avail_max;
+	snd_pcm_uframes_t transfer_offset;
 	snd_htimestamp_t trigger_tstamp;
 } ioplug_priv_t;
 
@@ -154,6 +155,7 @@ static int snd_pcm_ioplug_reset(snd_pcm_t *pcm)
 	io->data->hw_ptr = 0;
 	io->last_hw = 0;
 	io->avail_max = 0;
+	io->transfer_offset = 0;
 	return 0;
 }
 
@@ -595,7 +597,10 @@ static snd_pcm_sframes_t snd_pcm_ioplug_rewindable(snd_pcm_t *pcm)
 
 static snd_pcm_sframes_t snd_pcm_ioplug_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
+	ioplug_priv_t *io = pcm->private_data;
+
 	snd_pcm_mmap_appl_backward(pcm, frames);
+	io->transfer_offset = io->data->appl_ptr;
 	return frames;
 }
 
@@ -606,7 +611,10 @@ static snd_pcm_sframes_t snd_pcm_ioplug_forwardable(snd_pcm_t *pcm)
 
 static snd_pcm_sframes_t snd_pcm_ioplug_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
+	ioplug_priv_t *io = pcm->private_data;
+
 	snd_pcm_mmap_appl_forward(pcm, frames);
+	io->transfer_offset = io->data->appl_ptr;
 	return frames;
 }
 
@@ -723,10 +731,16 @@ static snd_pcm_sframes_t snd_pcm_ioplug_avail_update(snd_pcm_t *pcm)
 	    pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
 		if (io->data->callback->transfer) {
 			const snd_pcm_channel_area_t *areas;
-			snd_pcm_uframes_t offset, size = UINT_MAX;
+			snd_pcm_uframes_t offset, size;
 			snd_pcm_sframes_t result;
 
-			__snd_pcm_mmap_begin(pcm, &areas, &offset, &size);
+			areas = snd_pcm_mmap_areas(pcm);
+			if (!areas)
+				return -EBADFD;
+			offset = io->transfer_offset;
+			size = pcm->buffer_size - offset;
+			if (avail < size)
+				size = avail;
 			result = io->data->callback->transfer(io->data, areas, offset, size);
 			if (result < 0)
 				return result;
@@ -741,6 +755,9 @@ static snd_pcm_sframes_t snd_pcm_ioplug_avail_update(snd_pcm_t *pcm)
 				if (result < 0)
 					return result;
 			}
+
+			io->transfer_offset += avail;
+			io->transfer_offset %= pcm->buffer_size;
 		}
 	}
 	if (avail > io->avail_max)

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-07-31  8:21 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-25 21:52 More snd_pcm_ioplug_avail_update() questions Rob Duncan
2018-07-26  7:04 ` Takashi Iwai
2018-07-26 14:19   ` Rob Duncan
2018-07-26 14:37     ` Takashi Iwai
2018-07-26 15:02       ` Rob Duncan
2018-07-26 15:14         ` Takashi Iwai
2018-07-30 18:55           ` Rob Duncan
2018-07-31  8:21             ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.