From 028c840aa428422d5ee1e5d58bfe2e5ef8976000 Mon Sep 17 00:00:00 2001 From: Christian Spielberger Date: Fri, 9 Aug 2024 13:20:06 +0200 Subject: [PATCH] ausrc, aufile, gst: replace duration by callback handler Retrieving the duration of an audio file may lead to long blocking delay. E.g. gst_element_query_duration() Now a callback handler can be called by the application only if needed. --- include/baresip.h | 3 ++- modules/aufile/aufile_src.c | 17 +++++++++++++++-- modules/debug_cmd/debug_cmd.c | 7 +++++-- modules/gst/gst.c | 22 ++++++++++++++++------ 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/include/baresip.h b/include/baresip.h index 37e85d0e7a..fb3bd866ad 100644 --- a/include/baresip.h +++ b/include/baresip.h @@ -565,6 +565,7 @@ int message_encode_dict(struct odict *od, struct account *acc, struct ausrc; struct ausrc_st; +typedef size_t (ausrc_duration_h)(struct ausrc_st *st); /** Audio Source parameters */ struct ausrc_prm { @@ -572,7 +573,7 @@ struct ausrc_prm { uint8_t ch; /**< Number of channels */ uint32_t ptime; /**< Wanted packet-time in [ms] */ int fmt; /**< Sample format (enum aufmt) */ - size_t duration; /**< Duration in [ms], 0 for infinite */ + ausrc_duration_h *durationh; /**< Handler returns duration in [ms] */ }; typedef void (ausrc_read_h)(struct auframe *af, void *arg); diff --git a/modules/aufile/aufile_src.c b/modules/aufile/aufile_src.c index 5df5981764..23acc2766d 100644 --- a/modules/aufile/aufile_src.c +++ b/modules/aufile/aufile_src.c @@ -31,6 +31,7 @@ struct ausrc_st { struct aubuf *aubuf; enum aufmt fmt; /**< Wav file sample format */ struct ausrc_prm prm; /**< Audio src parameter */ + struct aufile_prm fprm; uint32_t ptime; size_t sampc; RE_ATOMIC bool run; @@ -189,6 +190,16 @@ static int read_file(struct ausrc_st *st) } +static size_t aufile_duration_handler(struct ausrc_st *st) +{ + if (!st) + return 0; + + + return aufile_get_length(st->aufile, &st->fprm); +} + + int aufile_src_alloc(struct ausrc_st **stp, const struct ausrc *as, struct ausrc_prm *prm, const char *dev, ausrc_read_h *rh, ausrc_error_h *errh, void *arg) @@ -231,7 +242,6 @@ int aufile_src_alloc(struct ausrc_st **stp, const struct ausrc *as, /* return wav format to caller */ prm->srate = fprm.srate; prm->ch = fprm.channels; - prm->duration = aufile_get_length(st->aufile, &fprm); if (!rh) goto out; @@ -266,8 +276,11 @@ int aufile_src_alloc(struct ausrc_st **stp, const struct ausrc *as, out: if (err) mem_deref(st); - else + else { *stp = st; + st->fprm = fprm; + prm->durationh = aufile_duration_handler; + } return err; } diff --git a/modules/debug_cmd/debug_cmd.c b/modules/debug_cmd/debug_cmd.c index 46f4ed127c..ba743f466c 100644 --- a/modules/debug_cmd/debug_cmd.c +++ b/modules/debug_cmd/debug_cmd.c @@ -185,9 +185,12 @@ static void fileinfo_destruct(void *arg) static void print_fileinfo(struct fileinfo_st *st) { - double s = ((float) st->prm.duration) / 1000; + size_t duration = 0; + if (st->prm.durationh) + duration = st->prm.durationh(st->ausrc); - if (st->prm.duration) { + if (duration) { + double s = ((float) duration) / 1000; info("debug_cmd: length = %1.3lf seconds\n", s); module_event("debug_cmd", "aufileinfo", NULL, NULL, "length = %lf seconds", s); diff --git a/modules/gst/gst.c b/modules/gst/gst.c index b15bdcb1ff..d367f1dc39 100644 --- a/modules/gst/gst.c +++ b/modules/gst/gst.c @@ -411,6 +411,21 @@ static void timeout(void *arg) } +static size_t gst_duration_handler(struct ausrc_st *st) +{ + if (!st) + return 0; + + gst_element_get_state(st->pipeline, NULL, NULL, 500*1000*1000); + gint64 duration = 0; + gst_element_query_duration(st->pipeline, + GST_FORMAT_TIME, + &duration); + + return duration / 1000000; +} + + static int gst_alloc(struct ausrc_st **stp, const struct ausrc *as, struct ausrc_prm *prm, const char *device, ausrc_read_h *rh, ausrc_error_h *errh, void *arg) @@ -487,12 +502,7 @@ static int gst_alloc(struct ausrc_st **stp, const struct ausrc *as, mem_deref(st); else { *stp = st; - gst_element_get_state(st->pipeline, NULL, NULL, 500*1000*1000); - gint64 duration = 0; - gst_element_query_duration(st->pipeline, - GST_FORMAT_TIME, - &duration); - prm->duration = duration / 1000000; + prm->durationh = gst_duration_handler; } return err;