diff options
author | Takashi Iwai <tiwai@suse.de> | 2021-06-01 19:24:55 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2021-06-02 10:01:44 +0300 |
commit | e8a8f09cb0b3b82dfacd6a7fce5c99bdf239c5dc (patch) | |
tree | 27a38e11d705504ce9dca3259541e4a7ff9984fb /sound/usb/card.h | |
parent | d303c5d38b37eed066c0f704c5a76353bce27284 (diff) | |
download | linux-e8a8f09cb0b3b82dfacd6a7fce5c99bdf239c5dc.tar.xz |
ALSA: usb-audio: Refactoring delay account code
The PCM delay accounting in USB-audio driver is a bit complex to
follow, and this is an attempt to improve the readability and provide
some potential fix.
Basically, the PCM position delay is calculated from two factors: the
in-flight data on URBs and the USB frame counter. For the playback
stream, we advance the hwptr already at submitting URBs. Those
"in-flight" data amount is now tracked, and this is used as the base
value for the PCM delay correction. The in-flight data is decreased
again at URB completion in return. For the capture stream, OTOH,
there is no in-flight data, hence the delay base is zero.
The USB frame counter is used in addition for correcting the current
position. The reference frame counter is updated at each submission
and receiving time, and the difference from the current counter value
is taken into account.
In this patch, each in-flight data bytes is recorded in the new
snd_usb_ctx.queued field, and the total in-flight amount is tracked in
snd_usb_substream.inflight_bytes field, as the replacement of
last_delay field.
Note that updating the hwptr after URB completion doesn't work for
PulseAudio who tries to scratch the buffer on the fly; USB-audio is
basically a double-buffer implementation, hence the scratching the
buffer can't work for the already submitted data. So we always update
hwptr beforehand. It's not ideal, but the delay account should give
enough correctness.
Link: https://lore.kernel.org/r/20210601162457.4877-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/card.h')
-rw-r--r-- | sound/usb/card.h | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/sound/usb/card.h b/sound/usb/card.h index b346653d4b76..5577a776561b 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -54,6 +54,7 @@ struct snd_urb_ctx { struct snd_usb_endpoint *ep; int index; /* index for urb array */ int packets; /* number of packets per urb */ + int queued; /* queued data bytes by this urb */ int packet_size[MAX_PACKS_HS]; /* size of packets for next submission */ struct list_head ready_list; }; @@ -159,8 +160,9 @@ struct snd_usb_substream { unsigned int running: 1; /* running status */ unsigned int buffer_bytes; /* buffer size in bytes */ + unsigned int inflight_bytes; /* in-flight data bytes on buffer (for playback) */ unsigned int hwptr_done; /* processed byte position in the buffer */ - unsigned int transfer_done; /* processed frames since last period update */ + unsigned int transfer_done; /* processed frames since last period update */ unsigned int frame_limit; /* limits number of packets in URB */ /* data and sync endpoints for this stream */ @@ -175,8 +177,7 @@ struct snd_usb_substream { struct list_head fmt_list; /* format list */ spinlock_t lock; - int last_frame_number; /* stored frame number */ - int last_delay; /* stored delay */ + unsigned int last_frame_number; /* stored frame number */ struct { int marker; |