Skip to content

Commit

Permalink
Calculate codec processing delay on first transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
arkq committed Jan 16, 2025
1 parent a6251b4 commit b4cc4f1
Show file tree
Hide file tree
Showing 18 changed files with 151 additions and 103 deletions.
13 changes: 8 additions & 5 deletions src/a2dp-aac.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - a2dp-aac.c
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand Down Expand Up @@ -374,6 +374,12 @@ void *a2dp_aac_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail;
}

if (!io.initiated) {
/* Get the delay due to codec processing. */
t_pcm->processing_delay_dms = asrsync_get_dms_since_last_sync(&io.asrs);
io.initiated = true;
}

/* resend RTP header */
len -= RTP_HEADER_LEN;

Expand All @@ -390,14 +396,11 @@ void *a2dp_aac_enc_thread(struct ba_transport_pcm *t_pcm) {
}

unsigned int pcm_frames = out_args.numInSamples / info.inputChannels;
/* keep data transfer at a constant bit rate */
/* Keep data transfer at a constant bit rate. */
asrsync_sync(&io.asrs, pcm_frames);
/* move forward RTP timestamp clock */
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;

/* If the input buffer was not consumed, we have to append new data to
* the existing one. Since we do not use ring buffer, we will simply
* move unprocessed data to the front of our linear buffer. */
Expand Down
13 changes: 8 additions & 5 deletions src/a2dp-aptx-hd.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - a2dp-aptx-hd.c
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand Down Expand Up @@ -205,15 +205,18 @@ void *a2dp_aptx_hd_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail;
}

if (!io.initiated) {
/* Get the delay due to codec processing. */
t_pcm->processing_delay_dms = asrsync_get_dms_since_last_sync(&io.asrs);
io.initiated = true;
}

unsigned int pcm_frames = pcm_samples / channels;
/* keep data transfer at a constant bit rate */
/* Keep data transfer at a constant bit rate. */
asrsync_sync(&io.asrs, pcm_frames);
/* move forward RTP timestamp clock */
rtp.ts_pcm_frames += pcm_frames;

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;

/* reinitialize output buffer */
ffb_rewind(&bt);

Expand Down
13 changes: 8 additions & 5 deletions src/a2dp-aptx.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - a2dp-aptx.c
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand Down Expand Up @@ -189,11 +189,14 @@ void *a2dp_aptx_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail;
}

/* keep data transfer at a constant bit rate */
asrsync_sync(&io.asrs, pcm_samples / channels);
if (!io.initiated) {
/* Get the delay due to codec processing. */
t_pcm->processing_delay_dms = asrsync_get_dms_since_last_sync(&io.asrs);
io.initiated = true;
}

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;
/* Keep data transfer at a constant bit rate. */
asrsync_sync(&io.asrs, pcm_samples / channels);

/* reinitialize output buffer */
ffb_rewind(&bt);
Expand Down
13 changes: 8 additions & 5 deletions src/a2dp-faststream.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - a2dp-faststream.c
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand Down Expand Up @@ -213,15 +213,18 @@ void *a2dp_fs_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail;
}

if (!io.initiated) {
/* Get the delay due to codec processing. */
t_pcm->processing_delay_dms = asrsync_get_dms_since_last_sync(&io.asrs);
io.initiated = true;
}

/* make room for new FastStream frames */
ffb_rewind(&bt);

/* keep data transfer at a constant bit rate */
/* Keep data transfer at a constant bit rate. */
asrsync_sync(&io.asrs, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;

/* If the input buffer was not consumed (due to codesize limit), we
* have to append new data to the existing one. Since we do not use
* ring buffer, we will simply move unprocessed data to the front
Expand Down
13 changes: 8 additions & 5 deletions src/a2dp-lc3plus.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - a2dp-lc3plus.c
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand Down Expand Up @@ -353,6 +353,12 @@ void *a2dp_lc3plus_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail;
}

if (!io.initiated) {
/* Get the delay due to codec processing. */
t_pcm->processing_delay_dms = asrsync_get_dms_since_last_sync(&io.asrs);
io.initiated = true;
}

/* resend RTP headers */
len -= rtp_headers_len;

Expand All @@ -370,14 +376,11 @@ void *a2dp_lc3plus_enc_thread(struct ba_transport_pcm *t_pcm) {

}

/* keep data transfer at a constant bit rate */
/* Keep data transfer at a constant bit rate. */
asrsync_sync(&io.asrs, pcm_frames);
/* move forward RTP timestamp clock */
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;

/* If the input buffer was not consumed (due to codesize limit), we
* have to append new data to the existing one. Since we do not use
* ring buffer, we will simply move unprocessed data to the front
Expand Down
13 changes: 8 additions & 5 deletions src/a2dp-ldac.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - a2dp-ldac.c
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand Down Expand Up @@ -244,6 +244,12 @@ void *a2dp_ldac_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail;
}

if (!io.initiated) {
/* Get the delay due to codec processing. */
t_pcm->processing_delay_dms = asrsync_get_dms_since_last_sync(&io.asrs);
io.initiated = true;
}

if (errno == EAGAIN)
/* The io_bt_write() call was blocking due to not enough
* space in the BT socket. Set the queued_bytes to some
Expand All @@ -256,14 +262,11 @@ void *a2dp_ldac_enc_thread(struct ba_transport_pcm *t_pcm) {
}

unsigned int pcm_frames = pcm_samples / channels;
/* keep data transfer at a constant bit rate */
/* Keep data transfer at a constant bit rate. */
asrsync_sync(&io.asrs, pcm_frames);
/* move forward RTP timestamp clock */
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;

}

/* If the input buffer was not consumed (due to codesize limit), we
Expand Down
13 changes: 8 additions & 5 deletions src/a2dp-lhdc.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - a2dp-lhdc.c
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
* Copyright (c) 2023 anonymix007
*
* This file is a part of bluez-alsa.
Expand Down Expand Up @@ -275,6 +275,12 @@ void *a2dp_lhdc_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail;
}

if (!io.initiated) {
/* Get the delay due to codec processing. */
t_pcm->processing_delay_dms = asrsync_get_dms_since_last_sync(&io.asrs);
io.initiated = true;
}

if (errno == EAGAIN)
/* The io_bt_write() call was blocking due to not enough
* space in the BT socket. Set the queued_bytes to some
Expand All @@ -287,14 +293,11 @@ void *a2dp_lhdc_enc_thread(struct ba_transport_pcm *t_pcm) {
}

unsigned int pcm_frames = lhdc_pcm_samples / channels;
/* keep data transfer at a constant bit rate */
/* Keep data transfer at a constant bit rate. */
asrsync_sync(&io.asrs, pcm_frames);
/* move forward RTP timestamp clock */
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;

}

/* If the input buffer was not consumed (due to codesize limit), we
Expand Down
13 changes: 8 additions & 5 deletions src/a2dp-mpeg.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - a2dp-mpeg.c
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand Down Expand Up @@ -294,6 +294,12 @@ void *a2dp_mp3_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail;
}

if (!io.initiated) {
/* Get the delay due to codec processing. */
t_pcm->processing_delay_dms = asrsync_get_dms_since_last_sync(&io.asrs);
io.initiated = true;
}

/* account written payload only */
len -= RTP_HEADER_LEN + sizeof(*rtp_mpeg_audio_header);

Expand All @@ -309,14 +315,11 @@ void *a2dp_mp3_enc_thread(struct ba_transport_pcm *t_pcm) {

}

/* keep data transfer at a constant bit rate */
/* Keep data transfer at a constant bit rate. */
asrsync_sync(&io.asrs, pcm_frames);
/* move forward RTP timestamp clock */
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;

/* If the input buffer was not consumed (due to frame alignment), we
* have to append new data to the existing one. Since we do not use
* ring buffer, we will simply move unprocessed data to the front
Expand Down
13 changes: 8 additions & 5 deletions src/a2dp-opus.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - a2dp-opus.c
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand Down Expand Up @@ -230,14 +230,17 @@ void *a2dp_opus_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail;
}

/* keep data transfer at a constant bit rate */
if (!io.initiated) {
/* Get the delay due to codec processing. */
t_pcm->processing_delay_dms = asrsync_get_dms_since_last_sync(&io.asrs);
io.initiated = true;
}

/* Keep data transfer at a constant bit rate. */
asrsync_sync(&io.asrs, opus_frame_pcm_frames);
/* move forward RTP timestamp clock */
rtp_state_update(&rtp, opus_frame_pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;

/* If the input buffer was not consumed (due to encoder frame
* constraint), we have to append new data to the existing one.
* Since we do not use ring buffer, we will simply move data
Expand Down
18 changes: 13 additions & 5 deletions src/a2dp-sbc.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - a2dp-sbc.c
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand Down Expand Up @@ -259,14 +259,22 @@ void *a2dp_sbc_enc_thread(struct ba_transport_pcm *t_pcm) {
goto fail;
}

/* keep data transfer at a constant bit rate */
if (!io.initiated) {
/* Get the codec processing delay, which is a time spent in the
* processing loop between reading PCM data and writing the first
* encoded SBC frame. Subsequently encoded frames do not contribute
* to the delay, because (assuming no underruns) since the first
* frame is written, the BT sink can start decoding and playing
* audio in a continuous fashion. */
t_pcm->processing_delay_dms = asrsync_get_dms_since_last_sync(&io.asrs);
io.initiated = true;
}

/* Keep data transfer at a constant bit rate. */
asrsync_sync(&io.asrs, pcm_frames);
/* move forward RTP timestamp clock */
rtp_state_update(&rtp, pcm_frames);

/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;

/* If the input buffer was not consumed (due to codesize limit), we
* have to append new data to the existing one. Since we do not use
* ring buffer, we will simply move unprocessed data to the front
Expand Down
1 change: 1 addition & 0 deletions src/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ ssize_t io_poll_and_read_pcm(
case BA_TRANSPORT_PCM_SIGNAL_OPEN:
case BA_TRANSPORT_PCM_SIGNAL_RESUME:
io->asrs.frames = 0;
io->initiated = false;
io->timeout = -1;
goto repoll;
case BA_TRANSPORT_PCM_SIGNAL_CLOSE:
Expand Down
5 changes: 4 additions & 1 deletion src/io.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - io.h
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand All @@ -16,6 +16,7 @@
# include <config.h>
#endif

#include <stdbool.h>
#include <sys/types.h>

#include "ba-transport-pcm.h"
Expand All @@ -30,6 +31,8 @@
struct io_poll {
/* transfer bit rate synchronization */
struct asrsync asrs;
/* transfer has been initiated */
bool initiated;
/* keep-alive and sync timeout */
int timeout;
};
Expand Down
6 changes: 2 additions & 4 deletions src/sco-cvsd.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - sco-cvsd.c
* Copyright (c) 2016-2024 Arkadiusz Bokowy
* Copyright (c) 2016-2025 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand Down Expand Up @@ -76,10 +76,8 @@ void *sco_cvsd_enc_thread(struct ba_transport_pcm *t_pcm) {
input += mtu_samples;
input_samples -= mtu_samples;

/* keep data transfer at a constant bit rate */
/* Keep data transfer at a constant bit rate. */
asrsync_sync(&io.asrs, mtu_samples);
/* update busy delay (encoding overhead) */
t_pcm->processing_delay_dms = asrsync_get_busy_usec(&io.asrs) / 100;

}

Expand Down
Loading

0 comments on commit b4cc4f1

Please sign in to comment.