mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
alsa-plugin: improve alsa plugin delay precision if alsa period is not align with the quantum
Method on_stream_process can be called multiple times with the same pwt.delay and pwt.now values. Its a case, when snd_pcm_pipewire_process returns less then b->requested frames. For example, if requested is 2048 and alsa period size is 512, then on_stream_process is called 4 times in a row with the same pwt.delay and pwt.now values. Store number of transferred frames for this "session" in separate variable so its incremented each time the on_stream_process is called. Number of transferred frames is cleared when a new "session" starts. Introduce also number of buffered frames, which is number of frames read from alsa but not sent to pipewire yet. This is the case when period is not align with the quantum size. For example alsa period is 480, but quantum is 512. on_stream_process is called 2 times for the first quantum, 512 frames is sent to pipewire and 448 frames are cached for the next round. These 448 frames needs to be included in delay computation in the next on_stream_process. Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
This commit is contained in:
parent
1a4c2ce624
commit
f5f4be5109
1 changed files with 12 additions and 2 deletions
|
|
@ -123,6 +123,8 @@ typedef struct {
|
|||
struct spa_hook stream_listener;
|
||||
|
||||
int64_t delay;
|
||||
int64_t transfered;
|
||||
int64_t buffered;
|
||||
uint64_t now;
|
||||
uintptr_t seq;
|
||||
|
||||
|
|
@ -262,7 +264,7 @@ static int snd_pcm_pipewire_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delay
|
|||
do {
|
||||
seq1 = SEQ_READ(pw->seq);
|
||||
|
||||
delay = pw->delay;
|
||||
delay = pw->delay + pw->transfered;
|
||||
now = pw->now;
|
||||
if (io->stream == SND_PCM_STREAM_PLAYBACK)
|
||||
avail = snd_pcm_ioplug_hw_avail(io, pw->hw_ptr, io->appl_ptr);
|
||||
|
|
@ -463,12 +465,20 @@ static void on_stream_process(void *data)
|
|||
|
||||
SEQ_WRITE(pw->seq);
|
||||
|
||||
if (pw->now != pwt.now) {
|
||||
pw->transfered = pw->buffered;
|
||||
pw->buffered = 0;
|
||||
}
|
||||
|
||||
xfer = snd_pcm_pipewire_process(pw, b, &hw_avail, want);
|
||||
|
||||
pw->delay = delay;
|
||||
/* the buffer is now queued in the stream and consumed */
|
||||
if (io->stream == SND_PCM_STREAM_PLAYBACK)
|
||||
pw->delay += xfer;
|
||||
pw->transfered += xfer;
|
||||
|
||||
/* more then requested data transfered, use them in next iteration */
|
||||
pw->buffered = pw->transfered < b->requested ? 0 : (pw->transfered % b->requested);
|
||||
|
||||
pw->now = pwt.now;
|
||||
SEQ_WRITE(pw->seq);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue