Skip to content

Commit

Permalink
ausrc, aufile, gst: replace duration by callback handler (baresip#3105)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
cspiel1 authored Aug 29, 2024
1 parent b3a423b commit d8acde9
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 46 deletions.
5 changes: 5 additions & 0 deletions include/baresip.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,13 +582,16 @@ typedef void (ausrc_error_h)(int err, const char *str, void *arg);
typedef int (ausrc_alloc_h)(struct ausrc_st **stp, const struct ausrc *ausrc,
struct ausrc_prm *prm, const char *device,
ausrc_read_h *rh, ausrc_error_h *errh, void *arg);
typedef int (ausrc_info_h)(const struct ausrc *ausrc,
struct ausrc_prm *prm, const char *device);

/** Defines an Audio Source */
struct ausrc {
struct le le;
const char *name;
struct list dev_list;
ausrc_alloc_h *alloch;
ausrc_info_h *infoh;
};

int ausrc_register(struct ausrc **asp, struct list *ausrcl, const char *name,
Expand All @@ -598,6 +601,8 @@ int ausrc_alloc(struct ausrc_st **stp, struct list *ausrcl,
const char *name,
struct ausrc_prm *prm, const char *device,
ausrc_read_h *rh, ausrc_error_h *errh, void *arg);
int ausrc_info(struct list *ausrcl,
const char *name, struct ausrc_prm *prm, const char *device);


/*
Expand Down
4 changes: 4 additions & 0 deletions modules/aufile/aufile.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ static int module_init(void)
aufile_src_alloc);
err |= auplay_register(&auplay, baresip_auplayl(), "aufile",
aufile_play_alloc);
if (err)
return err;

ausrc->infoh = aufile_info_handler;
return err;
}

Expand Down
2 changes: 2 additions & 0 deletions modules/aufile/aufile.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ int aufile_play_alloc(struct auplay_st **stp, const struct auplay *ap,
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);
int aufile_info_handler(const struct ausrc *as,
struct ausrc_prm *prm, const char *dev);
28 changes: 27 additions & 1 deletion modules/aufile/aufile_src.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,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;
Expand Down Expand Up @@ -271,3 +270,30 @@ int aufile_src_alloc(struct ausrc_st **stp, const struct ausrc *as,

return err;
}


int aufile_info_handler(const struct ausrc *as,
struct ausrc_prm *prm, const char *dev)
{
int err;
(void)as;

if (!prm || !str_isset(dev))
return EINVAL;

struct aufile *aufile;
struct aufile_prm fprm;
err = aufile_open(&aufile, &fprm, dev, AUFILE_READ);
if (err) {
warning("aufile: failed to open file '%s' (%m)\n", dev, err);
return err;
}

prm->srate = fprm.srate;
prm->ch = fprm.channels;
prm->fmt = fprm.fmt;
prm->duration = aufile_get_length(aufile, &fprm);

mem_deref(aufile);
return err;
}
43 changes: 9 additions & 34 deletions modules/debug_cmd/debug_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,27 +167,11 @@ static int cmd_play_file(struct re_printf *pf, void *arg)
}


struct fileinfo_st {
struct ausrc_st *ausrc;
struct ausrc_prm prm;
struct tmr tmr;
};


static void fileinfo_destruct(void *arg)
static void print_fileinfo(struct ausrc_prm *prm)
{
struct fileinfo_st *st = arg;

tmr_cancel(&st->tmr);
mem_deref(st->ausrc);
}

double s = ((float) prm->duration) / 1000;

static void print_fileinfo(struct fileinfo_st *st)
{
double s = ((float) st->prm.duration) / 1000;

if (st->prm.duration) {
if (prm->duration) {
info("debug_cmd: length = %1.3lf seconds\n", s);
module_event("debug_cmd", "aufileinfo", NULL, NULL,
"length = %lf seconds", s);
Expand Down Expand Up @@ -222,7 +206,7 @@ static int cmd_aufileinfo(struct re_printf *pf, void *arg)
char *path;
char aumod[16];
const char *file = carg->prm;
struct fileinfo_st *st = NULL;
struct ausrc_prm prm;

if (!str_isset(file)) {
re_hprintf(pf, "fileplay: filename not specified\n");
Expand All @@ -247,25 +231,16 @@ static int cmd_aufileinfo(struct re_printf *pf, void *arg)
conf_config()->audio.audio_path, file) < 0)
return ENOMEM;

st = mem_zalloc(sizeof(*st), fileinfo_destruct);
if (!st) {
err = ENOMEM;
goto out;
}

err = ausrc_alloc(&st->ausrc, baresip_ausrcl(),
aumod,
&st->prm, path, NULL, NULL, st);
err = ausrc_info(baresip_ausrcl(), aumod, &prm, path);
if (err) {
warning("debug_cmd: %s - ausrc %s does not support empty read "
"handler or reading source %s failed. (%m)\n",
__func__, aumod, carg->prm, err);
warning("debug_cmd: %s - ausrc %s does not support info query "
"or reading source %s failed. (%m)\n",
__func__, aumod, carg->prm, err);
goto out;
}

print_fileinfo(st);
print_fileinfo(&prm);
out:
mem_deref(st);

mem_deref(path);
return err;
Expand Down
80 changes: 69 additions & 11 deletions modules/gst/gst.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,13 +345,13 @@ static int gst_setup(struct ausrc_st *st)
}


static int setup_uri(struct ausrc_st *st, const char *device)
static int setup_uri(char **urip, const char *device)
{
int err = 0;

if (g_regex_match_simple(
uri_regex, device, 0, G_REGEX_MATCH_NOTEMPTY)) {
err = str_dup(&st->uri, device);
err = str_dup(urip, device);
}
else {
if (!access(device, R_OK)) {
Expand All @@ -360,7 +360,7 @@ static int setup_uri(struct ausrc_st *st, const char *device)
if (re_snprintf(uri, urilength, "file://%s",
device) < 0)
return ENOMEM;
st->uri = uri;
*urip = uri;
}
else {
err = errno;
Expand Down Expand Up @@ -437,7 +437,7 @@ static int gst_alloc(struct ausrc_st **stp, const struct ausrc *as,
st->rh = rh;
st->arg = arg;

err = setup_uri(st, device);
err = setup_uri(&st->uri, device);
if (err) goto out;

st->ptime = prm->ptime;
Expand Down Expand Up @@ -487,18 +487,71 @@ 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;
}

return err;
}


static int gst_info_handler(const struct ausrc *as,
struct ausrc_prm *prm, const char *device)
{
int err;
(void)as;

if (!prm || !str_isset(device))
return EINVAL;

GstElement *pipeline = NULL;
char *uri = NULL;
err = setup_uri(&uri, device);
if (err) goto out;

pipeline = gst_pipeline_new("pipeline");
if (!pipeline) {
warning("gst: failed to create pipeline element\n");
return ENOMEM;
}

GstElement *playbin = gst_element_factory_make("playbin", NULL);
GstElement *sink = gst_element_factory_make("fakesink", NULL);
if (!playbin || !sink) {
err = ENOMEM;
if (playbin)
gst_object_unref(playbin);
if (sink)
gst_object_unref(sink);
gst_object_unref(pipeline);
goto out;
}

gst_bin_add(GST_BIN(pipeline), playbin);
g_object_set(G_OBJECT(playbin),
"uri", uri,
"audio-sink", sink, NULL);

gst_element_set_state(pipeline, GST_STATE_PLAYING);
gst_element_get_state(pipeline, NULL, NULL, 500*1000*1000);
gint64 duration = 0;
gst_element_query_duration(pipeline,
GST_FORMAT_TIME,
&duration);

prm->duration = (size_t) duration / 1000000;

/* Note: other prm fields are currently not set */

out:
if (pipeline) {
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pipeline));
}

mem_deref(uri);
return err;
}


static int mod_gst_init(void)
{
gchar *s;
Expand All @@ -511,7 +564,12 @@ static int mod_gst_init(void)

g_free(s);

return ausrc_register(&ausrc, baresip_ausrcl(), "gst", gst_alloc);
int err = ausrc_register(&ausrc, baresip_ausrcl(), "gst", gst_alloc);
if (err)
return err;

ausrc->infoh = gst_info_handler;
return 0;
}


Expand Down
26 changes: 26 additions & 0 deletions src/ausrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,29 @@ int ausrc_alloc(struct ausrc_st **stp, struct list *ausrcl,

return as->alloch(stp, as, prm, device, rh, errh, arg);
}


/**
* Retreive audio parameters of an audio source
*
* @param ausrcl List of Audio Sources
* @param name Name of Audio Source
* @param prm Audio Source parameters
* @param device Name of Audio Source device (driver specific)
*
* @return 0 if success, otherwise errorcode
*/
int ausrc_info(struct list *ausrcl,
const char *name, struct ausrc_prm *prm, const char *device)
{
struct ausrc *as;

as = (struct ausrc *)ausrc_find(ausrcl, name);
if (!as)
return ENOENT;

if (!as->infoh)
return EINVAL;

return as->infoh(as, prm, device);
}

0 comments on commit d8acde9

Please sign in to comment.