From 5912848d2edbf61158ac7edc72c2302649a0d9ed Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 28 May 2017 10:20:54 +0200 Subject: prepare gapk for dealing with variable-length frames The existing architecture was modelled around fixed-length codec frame sizes, which of course fails with multi-rate codecs such as AMR. --- src/codec_efr.c | 14 ++++++++++---- src/codec_fr.c | 22 ++++++++++++++-------- src/codec_hr.c | 16 ++++++++++++---- src/fmt_amr.c | 16 +++++++++++----- src/fmt_gsm.c | 23 ++++++++++++++--------- src/fmt_hr_ref.c | 32 ++++++++++++++++++++++---------- src/fmt_racal.c | 46 +++++++++++++++++++++++++++++++--------------- src/fmt_rawpcm.c | 15 ++++++++++----- src/fmt_ti.c | 46 ++++++++++++++++++++++++++++++---------------- src/pq_alsa.c | 10 ++++++---- src/pq_file.c | 10 ++++++---- src/pq_format.c | 4 ++-- src/pq_rtp.c | 10 +++++----- src/procqueue.c | 20 +++++++++++++++----- 14 files changed, 188 insertions(+), 96 deletions(-) (limited to 'src') diff --git a/src/codec_efr.c b/src/codec_efr.c index a42b2a7..877a9eb 100644 --- a/src/codec_efr.c +++ b/src/codec_efr.c @@ -26,6 +26,7 @@ #ifdef HAVE_OPENCORE_AMRNB #include +#include #include #include @@ -64,11 +65,12 @@ codec_efr_exit(void *state) } static int -codec_efr_encode(void *state, uint8_t *cod, const uint8_t *pcm) +codec_efr_encode(void *state, uint8_t *cod, const uint8_t *pcm, unsigned int pcm_len) { struct codec_efr_state *st = state; int rv; + assert(pcm_len == PCM_CANON_LEN); BENCHMARK_START; rv = Encoder_Interface_Encode( st->encoder, @@ -79,14 +81,18 @@ codec_efr_encode(void *state, uint8_t *cod, const uint8_t *pcm) ); BENCHMARK_STOP(CODEC_EFR, 1); - return rv != 32; + if (rv != 32) + return -1; + + return EFR_CANON_LEN; } static int -codec_efr_decode(void *state, uint8_t *pcm, const uint8_t *cod) +codec_efr_decode(void *state, uint8_t *pcm, const uint8_t *cod, unsigned int cod_len) { struct codec_efr_state *st = state; + assert(cod_len == EFR_CANON_LEN); BENCHMARK_START; Decoder_Interface_Decode( st->decoder, @@ -96,7 +102,7 @@ codec_efr_decode(void *state, uint8_t *pcm, const uint8_t *cod) ); BENCHMARK_STOP(CODEC_EFR, 0); - return 0; + return PCM_CANON_LEN; } #endif /* HAVE_OPENCORE_AMRNB */ diff --git a/src/codec_fr.c b/src/codec_fr.c index 182eb73..2ce44b4 100644 --- a/src/codec_fr.c +++ b/src/codec_fr.c @@ -17,6 +17,8 @@ * along with gapk. If not, see . */ +#include + #include #include @@ -50,28 +52,32 @@ codec_fr_exit(void *state) } static int -codec_fr_encode(void *state, uint8_t *cod, const uint8_t *pcm) +codec_fr_encode(void *state, uint8_t *cod, const uint8_t *pcm, unsigned int pcm_len) { gsm gh = (gsm)state; - uint8_t pcm_b[2*160]; /* local copy as libgsm src isn't const ! */ - memcpy(pcm_b, pcm, 2*160); + uint8_t pcm_b[PCM_CANON_LEN]; /* local copy as libgsm src isn't const ! */ + assert(pcm_len == PCM_CANON_LEN); + memcpy(pcm_b, pcm, PCM_CANON_LEN); BENCHMARK_START; gsm_encode(gh, (gsm_signal*)pcm, (gsm_byte*)cod); BENCHMARK_STOP(CODEC_FR, 1); - return 0; + return FR_CANON_LEN; } static int -codec_fr_decode(void *state, uint8_t *pcm, const uint8_t *cod) +codec_fr_decode(void *state, uint8_t *pcm, const uint8_t *cod, unsigned int cod_len) { gsm gh = (gsm)state; - uint8_t cod_b[33]; /* local copy as libgsm src isn't const ! */ + uint8_t cod_b[FR_CANON_LEN]; /* local copy as libgsm src isn't const ! */ int rc; - memcpy(cod_b, cod, 33); + assert(cod_len == FR_CANON_LEN); + memcpy(cod_b, cod, FR_CANON_LEN); BENCHMARK_START; rc = gsm_decode(gh, (gsm_byte*)cod_b, (gsm_signal*)pcm); BENCHMARK_STOP(CODEC_FR, 1); - return rc; + if (rc < 0) + return rc; + return PCM_CANON_LEN; } #endif /* HAVE_LIBGSM */ diff --git a/src/codec_hr.c b/src/codec_hr.c index 4377f19..0b16985 100644 --- a/src/codec_hr.c +++ b/src/codec_hr.c @@ -17,6 +17,8 @@ * along with gapk. If not, see . */ +#include + #include #include @@ -41,25 +43,31 @@ codec_hr_exit(void *_state) } static int -codec_hr_encode(void *_state, uint8_t *cod, const uint8_t *pcm) +codec_hr_encode(void *_state, uint8_t *cod, const uint8_t *pcm, unsigned int pcm_len) { struct gsmhr *state = _state; int rc; + assert(pcm_len == PCM_CANON_LEN); BENCHMARK_START; rc = gsmhr_encode(state, (int16_t *)cod, (const int16_t *)pcm); BENCHMARK_STOP(CODEC_HR, 1); - return rc; + if (rc < 0) + return rc; + return HR_CANON_LEN; } static int -codec_hr_decode(void *_state, uint8_t *pcm, const uint8_t *cod) +codec_hr_decode(void *_state, uint8_t *pcm, const uint8_t *cod, unsigned int cod_len) { struct gsmhr *state = _state; int rc; + assert(cod_len == HR_CANON_LEN); BENCHMARK_START; rc = gsmhr_decode(state, (int16_t *)pcm, (const int16_t *)cod); BENCHMARK_STOP(CODEC_HR, 0); - return rc; + if (rc < 0) + return rc; + return PCM_CANON_LEN; } #endif /* HAVE_LIBGSMHR */ diff --git a/src/fmt_amr.c b/src/fmt_amr.c index 2990d7c..e28024c 100644 --- a/src/fmt_amr.c +++ b/src/fmt_amr.c @@ -18,6 +18,7 @@ */ #include +#include #include @@ -25,13 +26,16 @@ #include #include +#define EFR_LEN 32 /* conversion function: .amr file -> canonical format */ static int -amr_efr_from_canon(uint8_t *dst, const uint8_t *src) +amr_efr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; + assert(src_len == EFR_CANON_LEN); + dst[ 0] = 0x3c; dst[31] = 0x00; /* last nibble won't written, pre-clear it */ @@ -41,15 +45,17 @@ amr_efr_from_canon(uint8_t *dst, const uint8_t *src) msb_put_bit(&dst[1], di, msb_get_bit(src, si)); } - return 0; + return EFR_LEN; } /* conversion function: canonical format -> .amr file */ static int -amr_efr_to_canon(uint8_t *dst, const uint8_t *src) +amr_efr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; + assert(src_len == EFR_LEN); + if (src[0] != 0x3c) return -1; @@ -61,7 +67,7 @@ amr_efr_to_canon(uint8_t *dst, const uint8_t *src) msb_put_bit(dst, di, msb_get_bit(&src[1], si)); } - return 0; + return EFR_CANON_LEN; } const struct format_desc fmt_amr_efr = { @@ -70,7 +76,7 @@ const struct format_desc fmt_amr_efr = { .name = "amr-efr", .description = "Classic .amr file containing EFR (=AMR 12.2k) data", - .frame_len = 32, + .frame_len = EFR_LEN, .conv_from_canon = amr_efr_from_canon, .conv_to_canon = amr_efr_to_canon, diff --git a/src/fmt_gsm.c b/src/fmt_gsm.c index 8156bee..604b865 100644 --- a/src/fmt_gsm.c +++ b/src/fmt_gsm.c @@ -17,36 +17,41 @@ * along with gapk. If not, see . */ +#include #include #include - +#define GSM_LEN 33 #define GSM_MAGIC 0xd /* convert canonical -> .gsm */ static int -gsm_from_canon(uint8_t *dst, const uint8_t *src) +gsm_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; + assert(src_len == FR_CANON_LEN); + dst[0] = (GSM_MAGIC << 4) | (src[0] >> 4); - for (i=1; i<33; i++) + for (i=1; i> 4); - return 0; + return GSM_LEN; } /* convert .gsm -> canonical */ static int -gsm_to_canon(uint8_t *dst, const uint8_t *src) +gsm_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; - for (i=0; i<32; i++) + assert(src_len == GSM_LEN); + + for (i=0; i<(GSM_LEN-1); i++) dst[i] = (src[i] << 4) | (src[i+1] >> 4); - dst[32] = src[32] << 4; + dst[GSM_LEN-1] = src[GSM_LEN-1] << 4; - return 0; + return FR_CANON_LEN; } const struct format_desc fmt_gsm = { @@ -55,7 +60,7 @@ const struct format_desc fmt_gsm = { .name = "gsm", .description = "Classic .gsm file format", - .frame_len = 33, + .frame_len = GSM_LEN, .conv_from_canon = gsm_from_canon, .conv_to_canon = gsm_to_canon, }; diff --git a/src/fmt_hr_ref.c b/src/fmt_hr_ref.c index 7a96d3e..32e8d48 100644 --- a/src/fmt_hr_ref.c +++ b/src/fmt_hr_ref.c @@ -20,10 +20,14 @@ * along with gapk. If not, see . */ +#include + #include #include #include +#define HR_REF_DEC_LEN (22 * sizeof(uint16_t)) +#define HR_REF_ENC_LEN (20 * sizeof(uint16_t)) static const int params_unvoiced[] = { 5, /* R0 */ @@ -122,11 +126,13 @@ hr_ref_to_canon(uint8_t *canon, const uint16_t *hr_ref) } static int -hr_ref_dec_from_canon(uint8_t *dst, const uint8_t *src) +hr_ref_dec_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { uint16_t *hr_ref = (uint16_t *)dst; int rv; + assert(src_len == HR_CANON_LEN); + rv = hr_ref_from_canon(hr_ref, src); if (rv) return rv; @@ -136,28 +142,32 @@ hr_ref_dec_from_canon(uint8_t *dst, const uint8_t *src) hr_ref[20] = 0; /* SID : 2 bit */ hr_ref[21] = 0; /* TAF : 1 bit */ - return 0; + return HR_REF_DEC_LEN; } static int -hr_ref_dec_to_canon(uint8_t *dst, const uint8_t *src) +hr_ref_dec_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { const uint16_t *hr_ref = (const uint16_t *)src; int rv; + assert(src_len == HR_REF_DEC_LEN); + rv = hr_ref_to_canon(dst, hr_ref); if (rv) return rv; - return 0; + return HR_CANON_LEN; } static int -hr_ref_enc_from_canon(uint8_t *dst, const uint8_t *src) +hr_ref_enc_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { uint16_t *hr_ref = (uint16_t *)dst; int rv; + assert(src_len == HR_CANON_LEN); + rv = hr_ref_from_canon(hr_ref, src); if (rv) return rv; @@ -165,20 +175,22 @@ hr_ref_enc_from_canon(uint8_t *dst, const uint8_t *src) hr_ref[18] = 0; /* SP : 1 bit */ hr_ref[19] = 0; /* VAD : 1 bit */ - return 0; + return HR_REF_ENC_LEN; } static int -hr_ref_enc_to_canon(uint8_t *dst, const uint8_t *src) +hr_ref_enc_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { const uint16_t *hr_ref = (const uint16_t *)src; int rv; + assert(src_len == HR_REF_ENC_LEN); + rv = hr_ref_to_canon(dst, hr_ref); if (rv) return rv; - return 0; + return HR_CANON_LEN; } @@ -188,7 +200,7 @@ const struct format_desc fmt_hr_ref_dec = { .name = "hr-ref-dec", .description = "3GPP HR Reference decoder code parameters file format", - .frame_len = 22 * sizeof(uint16_t), + .frame_len = HR_REF_DEC_LEN, .conv_from_canon = hr_ref_dec_from_canon, .conv_to_canon = hr_ref_dec_to_canon, }; @@ -199,7 +211,7 @@ const struct format_desc fmt_hr_ref_enc = { .name = "hr-ref-enc", .description = "3GPP HR Reference encoder code parameters file format", - .frame_len = 20 * sizeof(uint16_t), + .frame_len = HR_REF_ENC_LEN, .conv_from_canon = hr_ref_enc_from_canon, .conv_to_canon = hr_ref_enc_to_canon, }; diff --git a/src/fmt_racal.c b/src/fmt_racal.c index 65f810f..1dbc61d 100644 --- a/src/fmt_racal.c +++ b/src/fmt_racal.c @@ -18,6 +18,7 @@ */ #include +#include #include @@ -25,13 +26,18 @@ #include #include +#define RACAL_HR_LEN 14 +#define RACAL_FR_LEN 33 +#define RACAL_EFR_LEN 31 static int -racal_hr_from_canon(uint8_t *dst, const uint8_t *src) +racal_hr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i, voiced; const uint16_t *bit_mapping; + assert(src_len == HR_CANON_LEN); + voiced = (msb_get_bit(src, 34) << 1) | msb_get_bit(src, 35); bit_mapping = voiced ? @@ -44,15 +50,17 @@ racal_hr_from_canon(uint8_t *dst, const uint8_t *src) lsb_put_bit(dst, di, msb_get_bit(src, si)); } - return 0; + return RACAL_HR_LEN; } static int -racal_hr_to_canon(uint8_t *dst, const uint8_t *src) +racal_hr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i, voiced; const uint16_t *bit_mapping; + assert(src_len == HR_CANON_LEN); + voiced = (lsb_get_bit(src, 94) << 1) | lsb_get_bit(src, 93); bit_mapping = voiced ? @@ -65,7 +73,7 @@ racal_hr_to_canon(uint8_t *dst, const uint8_t *src) msb_put_bit(dst, di, lsb_get_bit(src, si)); } - return 0; + return RACAL_HR_LEN; } const struct format_desc fmt_racal_hr = { @@ -74,17 +82,19 @@ const struct format_desc fmt_racal_hr = { .name = "racal-hr", .description = "Racal HR TCH/H recording", - .frame_len = 14, + .frame_len = RACAL_HR_LEN, .conv_from_canon = racal_hr_from_canon, .conv_to_canon = racal_hr_to_canon, }; static int -racal_fr_from_canon(uint8_t *dst, const uint8_t *src) +racal_fr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; + assert(src_len == FR_CANON_LEN); + dst[32] = 0x00; /* last nibble won't written, pre-clear it */ for (i=0; i<260; i++) { @@ -93,14 +103,16 @@ racal_fr_from_canon(uint8_t *dst, const uint8_t *src) lsb_put_bit(dst, di, msb_get_bit(src, si)); } - return 0; + return RACAL_FR_LEN; } static int -racal_fr_to_canon(uint8_t *dst, const uint8_t *src) +racal_fr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; + assert(src_len == RACAL_FR_LEN); + dst[32] = 0x00; /* last nibble won't written, pre-clear it */ for (i=0; i<260; i++) { @@ -109,7 +121,7 @@ racal_fr_to_canon(uint8_t *dst, const uint8_t *src) msb_put_bit(dst, di, lsb_get_bit(src, si)); } - return 0; + return FR_CANON_LEN; } const struct format_desc fmt_racal_fr = { @@ -118,36 +130,40 @@ const struct format_desc fmt_racal_fr = { .name = "racal-fr", .description = "Racal FR TCH/F recording", - .frame_len = 33, + .frame_len = RACAL_FR_LEN, .conv_from_canon = racal_fr_from_canon, .conv_to_canon = racal_fr_to_canon, }; static int -racal_efr_from_canon(uint8_t *dst, const uint8_t *src) +racal_efr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; + assert(src_len == EFR_CANON_LEN); + dst[30] = 0x00; /* last nibble won't written, pre-clear it */ for (i=0; i<244; i++) lsb_put_bit(dst, i, msb_get_bit(src, i)); - return 0; + return RACAL_EFR_LEN; } static int -racal_efr_to_canon(uint8_t *dst, const uint8_t *src) +racal_efr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; + assert(src_len == RACAL_EFR_LEN); + dst[30] = 0x00; /* last nibble won't written, pre-clear it */ for (i=0; i<244; i++) msb_put_bit(dst, i, lsb_get_bit(src, i)); - return 0; + return EFR_CANON_LEN; } const struct format_desc fmt_racal_efr = { @@ -156,7 +172,7 @@ const struct format_desc fmt_racal_efr = { .name = "racal-efr", .description = "Racal EFR TCH/F recording", - .frame_len = 31, + .frame_len = RACAL_EFR_LEN, .conv_from_canon = racal_efr_from_canon, .conv_to_canon = racal_efr_to_canon, }; diff --git a/src/fmt_rawpcm.c b/src/fmt_rawpcm.c index e20fcaf..207708c 100644 --- a/src/fmt_rawpcm.c +++ b/src/fmt_rawpcm.c @@ -17,35 +17,40 @@ * along with gapk. If not, see . */ +#include + #include #include - static int -rawpcm_s16le_from_canon(uint8_t *dst, const uint8_t *src) +rawpcm_s16le_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; const uint16_t *samples = (const uint16_t *)src; + assert(src_len == PCM_CANON_LEN); + for (i=0; i<160; i++) { uint16_t w = samples[i]; dst[(i<<1) ] = w & 0xff; dst[(i<<1)+1] = (w >> 8) & 0xff; } - return 0; + return PCM_CANON_LEN; } static int -rawpcm_s16le_to_canon(uint8_t *dst, const uint8_t *src) +rawpcm_s16le_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; uint16_t *samples = (uint16_t *)dst; + assert(src_len == PCM_CANON_LEN); + for (i=0; i<160; i++) samples[i] = (src[(i<<1)+1] << 8) | src[(i<<1)]; - return 0; + return PCM_CANON_LEN; } const struct format_desc fmt_rawpcm_s16le = { diff --git a/src/fmt_ti.c b/src/fmt_ti.c index 646c74a..627593c 100644 --- a/src/fmt_ti.c +++ b/src/fmt_ti.c @@ -26,6 +26,7 @@ #include #include +#include #include @@ -33,14 +34,17 @@ #include #include +#define TI_LEN 33 static int -ti_hr_from_canon(uint8_t *dst, const uint8_t *src) +ti_hr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i, voiced; const uint16_t *bit_mapping; - memset(dst, 0x00, 33); /* Not even half the bits are written, so we pre-clear */ + assert(src_len == HR_CANON_LEN); + + memset(dst, 0x00, TI_LEN); /* Not even half the bits are written, so we pre-clear */ voiced = (msb_get_bit(src, 34) << 1) | msb_get_bit(src, 35); @@ -54,15 +58,17 @@ ti_hr_from_canon(uint8_t *dst, const uint8_t *src) lsb_put_bit(dst, di, msb_get_bit(src, si)); } - return 0; + return TI_LEN; } static int -ti_hr_to_canon(uint8_t *dst, const uint8_t *src) +ti_hr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i, voiced; const uint16_t *bit_mapping; + assert(src_len == TI_LEN); + voiced = (msb_get_bit(src, 94) << 1) | msb_get_bit(src, 93); bit_mapping = voiced ? @@ -75,7 +81,7 @@ ti_hr_to_canon(uint8_t *dst, const uint8_t *src) msb_put_bit(dst, di, msb_get_bit(src, si)); } - return 0; + return HR_CANON_LEN; } const struct format_desc fmt_ti_hr = { @@ -84,17 +90,19 @@ const struct format_desc fmt_ti_hr = { .name = "ti-hr", .description = "Texas Instrument HR TCH/H buffer format", - .frame_len = 33, + .frame_len = TI_LEN, .conv_from_canon = ti_hr_from_canon, .conv_to_canon = ti_hr_to_canon, }; static int -ti_fr_from_canon(uint8_t *dst, const uint8_t *src) +ti_fr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; + assert(src_len == FR_CANON_LEN); + dst[22] = dst[23] = 0x00; /* some bits won't be writter, pre-clear them */ for (i=0; i<260; i++) { @@ -103,14 +111,16 @@ ti_fr_from_canon(uint8_t *dst, const uint8_t *src) msb_put_bit(dst, di, msb_get_bit(src, si)); } - return 0; + return TI_LEN; } static int -ti_fr_to_canon(uint8_t *dst, const uint8_t *src) +ti_fr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; + assert(src_len == TI_LEN); + dst[32] = 0x00; /* last nibble won't written, pre-clear it */ for (i=0; i<260; i++) { @@ -119,7 +129,7 @@ ti_fr_to_canon(uint8_t *dst, const uint8_t *src) msb_put_bit(dst, di, msb_get_bit(src, si)); } - return 0; + return FR_CANON_LEN; } const struct format_desc fmt_ti_fr = { @@ -128,17 +138,19 @@ const struct format_desc fmt_ti_fr = { .name = "ti-fr", .description = "Texas Instrument FR TCH/F buffer format", - .frame_len = 33, + .frame_len = TI_LEN, .conv_from_canon = ti_fr_from_canon, .conv_to_canon = ti_fr_to_canon, }; static int -ti_efr_from_canon(uint8_t *dst, const uint8_t *src) +ti_efr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; + assert(src_len == EFR_CANON_LEN); + memset(dst, 0x00, 33); /* pre-clear */ for (i=0; i<244; i++) { @@ -169,14 +181,16 @@ ti_efr_from_canon(uint8_t *dst, const uint8_t *src) msb_put_bit(dst, di, msb_get_bit(src, si)); } - return 0; + return TI_LEN; } static int -ti_efr_to_canon(uint8_t *dst, const uint8_t *src) +ti_efr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len) { int i; + assert(src_len == TI_LEN); + dst[30] = 0x00; /* last nibble won't written, pre-clear it */ for (i=0; i<244; i++) { @@ -207,7 +221,7 @@ ti_efr_to_canon(uint8_t *dst, const uint8_t *src) msb_put_bit(dst, di, msb_get_bit(src, si)); } - return 0; + return EFR_CANON_LEN; } const struct format_desc fmt_ti_efr = { @@ -216,7 +230,7 @@ const struct format_desc fmt_ti_efr = { .name = "ti-efr", .description = "Texas Instrument EFR TCH/F buffer format", - .frame_len = 33, + .frame_len = TI_LEN, .conv_from_canon = ti_efr_from_canon, .conv_to_canon = ti_efr_to_canon, }; diff --git a/src/pq_alsa.c b/src/pq_alsa.c index b17faa8..563452e 100644 --- a/src/pq_alsa.c +++ b/src/pq_alsa.c @@ -40,20 +40,22 @@ struct pq_state_alsa { }; static int -pq_cb_alsa_input(void *_state, uint8_t *out, const uint8_t *in) +pq_cb_alsa_input(void *_state, uint8_t *out, const uint8_t *in, unsigned int in_len) { struct pq_state_alsa *state = _state; unsigned int num_samples = state->blk_len/2; int rv; rv = snd_pcm_readi(state->pcm_handle, out, num_samples); - return rv == num_samples ? 0 : -1; + if (rv < 0) + return rv; + return rv * sizeof(uint16_t); } static int -pq_cb_alsa_output(void *_state, uint8_t *out, const uint8_t *in) +pq_cb_alsa_output(void *_state, uint8_t *out, const uint8_t *in, unsigned int in_len) { struct pq_state_alsa *state = _state; - unsigned int num_samples = state->blk_len/2; + unsigned int num_samples = in_len/2; int rv; rv = snd_pcm_writei(state->pcm_handle, in, num_samples); return rv == num_samples ? 0 : -1; diff --git a/src/pq_file.c b/src/pq_file.c index 7b9e356..dd82697 100644 --- a/src/pq_file.c +++ b/src/pq_file.c @@ -34,20 +34,22 @@ struct pq_state_file { static int -pq_cb_file_input(void *_state, uint8_t *out, const uint8_t *in) +pq_cb_file_input(void *_state, uint8_t *out, const uint8_t *in, unsigned int in_len) { struct pq_state_file *state = _state; int rv; rv = fread(out, state->blk_len, 1, state->fh); - return rv == 1 ? 0 : -1; + if (rv < 0) + return rv; + return rv * state->blk_len; } static int -pq_cb_file_output(void *_state, uint8_t *out, const uint8_t *in) +pq_cb_file_output(void *_state, uint8_t *out, const uint8_t *in, unsigned int in_len) { struct pq_state_file *state = _state; int rv; - rv = fwrite(in, state->blk_len, 1, state->fh); + rv = fwrite(in, in_len, 1, state->fh); return rv == 1 ? 0 : -1; } diff --git a/src/pq_format.c b/src/pq_format.c index 4e9515a..2089218 100644 --- a/src/pq_format.c +++ b/src/pq_format.c @@ -26,10 +26,10 @@ static int -pq_cb_fmt_convert(void *_state, uint8_t *out, const uint8_t *in) +pq_cb_fmt_convert(void *_state, uint8_t *out, const uint8_t *in, unsigned int in_len) { fmt_conv_cb_t f = _state; - return f(out, in); + return f(out, in, in_len); } /*! Add format conversion to processing queue diff --git a/src/pq_rtp.c b/src/pq_rtp.c index 1a7edde..99e77bc 100644 --- a/src/pq_rtp.c +++ b/src/pq_rtp.c @@ -88,7 +88,7 @@ struct pq_state_rtp { static int -pq_cb_rtp_input(void *_state, uint8_t *out, const uint8_t *in) +pq_cb_rtp_input(void *_state, uint8_t *out, const uint8_t *in, unsigned int in_len) { struct pq_state_rtp *state = _state; uint8_t buf[state->blk_len+256]; @@ -153,14 +153,14 @@ pq_cb_rtp_input(void *_state, uint8_t *out, const uint8_t *in) memcpy(out, payload, payload_len); - return 0; + return payload_len; } static int -pq_cb_rtp_output(void *_state, uint8_t *out, const uint8_t *in) +pq_cb_rtp_output(void *_state, uint8_t *out, const uint8_t *in, unsigned int in_len) { struct pq_state_rtp *state = _state; - int len = state->blk_len + sizeof(struct rtp_hdr); + int len = in_len + sizeof(struct rtp_hdr); uint8_t buf[len]; struct rtp_hdr *rtph = (struct rtp_hdr *)buf; uint8_t *payload; @@ -178,7 +178,7 @@ pq_cb_rtp_output(void *_state, uint8_t *out, const uint8_t *in) rtph->ssrc = htonl(state->ssrc); payload = buf + sizeof(*rtph); - memcpy(payload, in, state->blk_len); + memcpy(payload, in, in_len); rv = write(state->fd, buf, len); return rv == len ? 0 : -1; diff --git a/src/procqueue.c b/src/procqueue.c index 2451399..66c2967 100644 --- a/src/procqueue.c +++ b/src/procqueue.c @@ -23,7 +23,7 @@ #include - +#define VAR_BUF_SIZE 320 #define MAX_PQ_ITEMS 8 struct pq { @@ -98,11 +98,16 @@ pq_prepare(struct pq *pq) for (i=0; in_items; i++) { struct pq_item *item = pq->items[i]; - if (item->len_in != len_prev) + if (item->len_in && item->len_in != len_prev) return -EINVAL; if (i < (pq->n_items-1)) { - pq->buffers[i] = malloc(item->len_out); + unsigned int buf_size = item->len_out; + /* variable-length codec output, use maximum + * known buffer size */ + if (!buf_size) + buf_size = VAR_BUF_SIZE; + pq->buffers[i] = malloc(buf_size); if (!pq->buffers[i]) return -ENOMEM; } else{ @@ -124,8 +129,10 @@ pq_execute(struct pq *pq) { int i; void *buf_prev, *buf; + unsigned int len_prev; buf_prev = NULL; + len_prev = 0; for (i=0; in_items; i++) { int rv; @@ -133,11 +140,14 @@ pq_execute(struct pq *pq) buf = i < (pq->n_items-1) ? pq->buffers[i] : NULL; - rv = item->proc(item->state, buf, buf_prev); - if (rv) + rv = item->proc(item->state, buf, buf_prev, len_prev); + if (rv < 0) { + fprintf(stderr, "pq_execute(): abort, item returned %d\n", rv); return rv; + } buf_prev = buf; + len_prev = rv; } return 0; -- cgit v1.2.3