mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
add support for automatic termination of the daemon after the last client quit
remove all gcc warnings add boolean types for tagstruct and modargs git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@178 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
fb962b67db
commit
57e473b61c
23 changed files with 155 additions and 37 deletions
6
doc/todo
6
doc/todo
|
|
@ -9,17 +9,13 @@
|
|||
kill client/...
|
||||
autoload management
|
||||
- more complete pactl
|
||||
- cleanup tagstruct and modargs (add s32, pa_volume_t, pa_usec_t)
|
||||
- remove all gcc warnings
|
||||
- make fragments settings runtime configurable
|
||||
- logging
|
||||
- automatic termination of daemon if unused
|
||||
- add sample directory
|
||||
- paman: show scache and sample size
|
||||
- add timing parameter to write callback of stream in client API
|
||||
|
||||
** later ***
|
||||
- xmlrpc/http
|
||||
- dbus
|
||||
- slp/rendezvous
|
||||
- modinfo
|
||||
- make alsa modules use mmap
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ struct pa_client *pa_client_new(struct pa_core *core, const char *protocol_name,
|
|||
|
||||
fprintf(stderr, "client: created %u \"%s\"\n", c->index, c->name);
|
||||
pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index);
|
||||
|
||||
pa_core_check_quit(core);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
|
@ -59,10 +61,14 @@ void pa_client_free(struct pa_client *c) {
|
|||
assert(c && c->core);
|
||||
|
||||
pa_idxset_remove_by_data(c->core->clients, c, NULL);
|
||||
|
||||
pa_core_check_quit(c->core);
|
||||
|
||||
fprintf(stderr, "client: freed %u \"%s\"\n", c->index, c->name);
|
||||
pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index);
|
||||
pa_xfree(c->name);
|
||||
pa_xfree(c);
|
||||
|
||||
}
|
||||
|
||||
void pa_client_kill(struct pa_client *c) {
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ void pa_cmdline_help(const char *argv0) {
|
|||
" -d Disallow module loading after startup\n"
|
||||
" -f Dont quit when the startup fails\n"
|
||||
" -v Verbose startup\n"
|
||||
" -X SECS Terminate the daemon after the last client quit and this time passed\n"
|
||||
" -h Show this help\n"
|
||||
" -V Show version\n", e, cfg);
|
||||
|
||||
|
|
@ -97,11 +98,12 @@ struct pa_cmdline* pa_cmdline_parse(int argc, char * const argv []) {
|
|||
cmdline->version =
|
||||
cmdline->disallow_module_loading = 0;
|
||||
cmdline->fail = 1;
|
||||
cmdline->quit_after_last_client_time = -1;
|
||||
|
||||
buf = pa_strbuf_new();
|
||||
assert(buf);
|
||||
|
||||
while ((c = getopt(argc, argv, "L:F:CDhfvrRVnd")) != -1) {
|
||||
while ((c = getopt(argc, argv, "L:F:CDhfvrRVndX:")) != -1) {
|
||||
switch (c) {
|
||||
case 'L':
|
||||
pa_strbuf_printf(buf, "load %s\n", optarg);
|
||||
|
|
@ -139,6 +141,9 @@ struct pa_cmdline* pa_cmdline_parse(int argc, char * const argv []) {
|
|||
case 'd':
|
||||
cmdline->disallow_module_loading = 1;
|
||||
break;
|
||||
case 'X':
|
||||
cmdline->quit_after_last_client_time = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
|
||||
struct pa_cmdline {
|
||||
int daemonize, help, fail, verbose, high_priority, stay_root, version, disallow_module_loading;
|
||||
int daemonize, help, fail, verbose, high_priority, stay_root, version, disallow_module_loading, quit_after_last_client_time;
|
||||
char *cli_commands;
|
||||
};
|
||||
|
||||
|
|
|
|||
28
polyp/core.c
28
polyp/core.c
|
|
@ -71,6 +71,9 @@ struct pa_core* pa_core_new(struct pa_mainloop_api *m) {
|
|||
c->memblock_stat = pa_memblock_stat_new();
|
||||
|
||||
c->disallow_module_loading = 0;
|
||||
|
||||
c->quit_event = NULL;
|
||||
c->quit_after_last_client_time = -1;
|
||||
|
||||
pa_check_for_sigpipe();
|
||||
|
||||
|
|
@ -102,6 +105,11 @@ void pa_core_free(struct pa_core *c) {
|
|||
pa_namereg_free(c);
|
||||
pa_autoload_free(c);
|
||||
pa_subscription_free_all(c);
|
||||
|
||||
if (c->quit_event) {
|
||||
c->mainloop->time_free(c->quit_event);
|
||||
c->quit_event = NULL;
|
||||
}
|
||||
|
||||
pa_xfree(c->default_source_name);
|
||||
pa_xfree(c->default_sink_name);
|
||||
|
|
@ -111,3 +119,23 @@ void pa_core_free(struct pa_core *c) {
|
|||
pa_xfree(c);
|
||||
}
|
||||
|
||||
static void quit_callback(struct pa_mainloop_api*m, struct pa_time_event *e, const struct timeval *tv, void *userdata) {
|
||||
struct pa_core *c = userdata;
|
||||
assert(c->quit_event = e);
|
||||
|
||||
m->quit(m, 0);
|
||||
}
|
||||
|
||||
void pa_core_check_quit(struct pa_core *c) {
|
||||
assert(c);
|
||||
|
||||
if (!c->quit_event && c->quit_after_last_client_time >= 0 && pa_idxset_ncontents(c->clients) == 0) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
tv.tv_sec+= c->quit_after_last_client_time;
|
||||
c->quit_event = c->mainloop->time_new(c->mainloop, &tv, quit_callback, c);
|
||||
} else if (c->quit_event && pa_idxset_ncontents(c->clients) > 0) {
|
||||
c->mainloop->time_free(c->quit_event);
|
||||
c->quit_event = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,9 +48,15 @@ struct pa_core {
|
|||
struct pa_memblock_stat *memblock_stat;
|
||||
|
||||
int disallow_module_loading;
|
||||
int quit_after_last_client_time;
|
||||
|
||||
struct pa_time_event *quit_event;
|
||||
|
||||
};
|
||||
|
||||
struct pa_core* pa_core_new(struct pa_mainloop_api *m);
|
||||
void pa_core_free(struct pa_core*c);
|
||||
|
||||
void pa_core_check_quit(struct pa_core *c);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@ int main(int argc, char *argv[]) {
|
|||
pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
|
||||
|
||||
c->disallow_module_loading = cmdline->disallow_module_loading;
|
||||
c->quit_after_last_client_time = cmdline->quit_after_last_client_time;
|
||||
|
||||
fprintf(stderr, __FILE__": mainloop entry.\n");
|
||||
if (pa_mainloop_run(mainloop, &retval) < 0)
|
||||
|
|
|
|||
|
|
@ -207,6 +207,46 @@ int pa_modargs_get_value_u32(struct pa_modargs *ma, const char *key, uint32_t *v
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pa_modargs_get_value_s32(struct pa_modargs *ma, const char *key, int32_t *value) {
|
||||
const char *v;
|
||||
char *e;
|
||||
signed long l;
|
||||
assert(ma && key && value);
|
||||
|
||||
if (!(v = pa_modargs_get_value(ma, key, NULL)))
|
||||
return 0;
|
||||
|
||||
if (!*v)
|
||||
return -1;
|
||||
|
||||
l = strtol(v, &e, 0);
|
||||
if (*e)
|
||||
return -1;
|
||||
|
||||
*value = (int32_t) l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pa_modargs_get_value_boolean(struct pa_modargs *ma, const char *key, int *value) {
|
||||
const char *v;
|
||||
assert(ma && key && value);
|
||||
|
||||
if (!(v = pa_modargs_get_value(ma, key, NULL)))
|
||||
return 0;
|
||||
|
||||
if (!*v)
|
||||
return -1;
|
||||
|
||||
if (!strcmp(v, "1") || !strcasecmp(v, "yes") || !strcasecmp(v, "y") || !strcasecmp(v, "on"))
|
||||
*value = 1;
|
||||
else if (!strcmp(v, "0") || !strcasecmp(v, "no") || !strcasecmp(v, "n") || !strcasecmp(v, "off"))
|
||||
*value = 0;
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pa_modargs_get_sample_spec(struct pa_modargs *ma, struct pa_sample_spec *rss) {
|
||||
const char *format;
|
||||
uint32_t channels;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ void pa_modargs_free(struct pa_modargs*ma);
|
|||
|
||||
const char *pa_modargs_get_value(struct pa_modargs *ma, const char *key, const char *def);
|
||||
int pa_modargs_get_value_u32(struct pa_modargs *ma, const char *key, uint32_t *value);
|
||||
int pa_modargs_get_value_s32(struct pa_modargs *ma, const char *key, int32_t *value);
|
||||
int pa_modargs_get_value_boolean(struct pa_modargs *ma, const char *key, int *value);
|
||||
|
||||
int pa_modargs_get_sample_spec(struct pa_modargs *ma, struct pa_sample_spec *ss);
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
|
|||
goto finish;
|
||||
}
|
||||
|
||||
if (pa_modargs_get_value_u32(ma, "fd", &fd) < 0) {
|
||||
if (pa_modargs_get_value_s32(ma, "fd", &fd) < 0) {
|
||||
fprintf(stderr, __FILE__": invalid file descriptor.\n");
|
||||
goto finish;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,20 +234,21 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (pa_modargs_get_value_u32(ma, "record", &record) < 0 || pa_modargs_get_value_u32(ma, "playback", &playback) < 0) {
|
||||
if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) {
|
||||
fprintf(stderr, __FILE__": record= and playback= expect numeric arguments.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
|
||||
if (mode == 0) {
|
||||
if (!playback && !record) {
|
||||
fprintf(stderr, __FILE__": neither playback nor record enabled for device.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
|
||||
|
||||
nfrags = 12;
|
||||
frag_size = 1024;
|
||||
if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 || nfrags < 2 || pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 || frag_size < 1) {
|
||||
if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || nfrags < 2 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0 || frag_size < 1) {
|
||||
fprintf(stderr, __FILE__": failed to parse fragments arguments\n");
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
|
|||
int fd = -1;
|
||||
int nfrags, frag_size, in_frag_size, out_frag_size;
|
||||
int mode;
|
||||
uint32_t record = 1, playback = 1;
|
||||
int record = 1, playback = 1;
|
||||
struct pa_sample_spec ss;
|
||||
struct pa_modargs *ma = NULL;
|
||||
assert(c && m);
|
||||
|
|
@ -187,20 +187,21 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (pa_modargs_get_value_u32(ma, "record", &record) < 0 || pa_modargs_get_value_u32(ma, "playback", &playback) < 0) {
|
||||
if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) {
|
||||
fprintf(stderr, __FILE__": record= and playback= expect numeric argument.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
|
||||
if (mode == 0) {
|
||||
if (!playback && !record) {
|
||||
fprintf(stderr, __FILE__": neither playback nor record enabled for device.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
|
||||
|
||||
nfrags = 12;
|
||||
frag_size = 1024;
|
||||
if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 || nfrags < 2 || pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 || frag_size < 1) {
|
||||
if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || nfrags < 2 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0 || frag_size < 1) {
|
||||
fprintf(stderr, __FILE__": failed to parse fragments arguments\n");
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,15 +83,16 @@ static const char* const valid_modargs[] = {
|
|||
static struct pa_socket_server *create_socket_server(struct pa_core *c, struct pa_modargs *ma) {
|
||||
struct pa_socket_server *s;
|
||||
#ifdef USE_TCP_SOCKETS
|
||||
uint32_t loopback = 1, port = IPV4_PORT;
|
||||
int loopback = 1;
|
||||
uint32_t port = IPV4_PORT;
|
||||
|
||||
if (pa_modargs_get_value_u32(ma, "loopback", &loopback) < 0) {
|
||||
if (pa_modargs_get_value_boolean(ma, "loopback", &loopback) < 0) {
|
||||
fprintf(stderr, "loopback= expects a numerical argument.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pa_modargs_get_value_u32(ma, "port", &port) < 0) {
|
||||
fprintf(stderr, "port= expects a numerical argument.\n");
|
||||
if (pa_modargs_get_value_u32(ma, "port", &port) < 0 || port < 1 || port > 0xFFFF) {
|
||||
fprintf(stderr, "port= expects a numerical argument between 1 and 65535.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,10 @@ fail:
|
|||
|
||||
static void pa_module_free(struct pa_module *m) {
|
||||
assert(m && m->done && m->core);
|
||||
|
||||
if (m->core->disallow_module_loading)
|
||||
return;
|
||||
|
||||
m->done(m->core, m);
|
||||
|
||||
lt_dlclose(m->dl);
|
||||
|
|
@ -130,7 +134,6 @@ static void pa_module_free(struct pa_module *m) {
|
|||
pa_xfree(m);
|
||||
}
|
||||
|
||||
|
||||
void pa_module_unload(struct pa_core *c, struct pa_module *m) {
|
||||
assert(c && m);
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ struct pa_latency_info {
|
|||
pa_usec_t buffer_usec; /**< Time in usecs the current buffer takes to play */
|
||||
pa_usec_t sink_usec; /**< Time in usecs a sample takes to be played on the sink. */
|
||||
int playing; /**< Non-zero when the stream is currently playing */
|
||||
int queue_length; /**< Queue size in bytes. */
|
||||
uint32_t queue_length; /**< Queue size in bytes. */
|
||||
};
|
||||
|
||||
PA_C_DECL_END
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ static void context_get_module_info_callback(struct pa_pdispatch *pd, uint32_t c
|
|||
pa_tagstruct_gets(t, &i.name) < 0 ||
|
||||
pa_tagstruct_gets(t, &i.argument) < 0 ||
|
||||
pa_tagstruct_getu32(t, &i.n_used) < 0 ||
|
||||
pa_tagstruct_getu32(t, &i.auto_unload) < 0) {
|
||||
pa_tagstruct_get_boolean(t, &i.auto_unload) < 0) {
|
||||
pa_context_fail(o->context, PA_ERROR_PROTOCOL);
|
||||
goto finish;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,8 +106,8 @@ struct pa_module_info {
|
|||
uint32_t index; /**< Index of the module */
|
||||
const char*name, /**< Name of the module */
|
||||
*argument; /**< Argument string of the module */
|
||||
uint32_t n_used, /**< Usage counter or PA_INVALID_INDEX */
|
||||
auto_unload; /**< Non-zero if this is an autoloaded module */
|
||||
uint32_t n_used; /**< Usage counter or PA_INVALID_INDEX */
|
||||
int auto_unload; /**< Non-zero if this is an autoloaded module */
|
||||
};
|
||||
|
||||
/** Get some information about a module by its index */
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ static void stream_get_latency_callback(struct pa_pdispatch *pd, uint32_t comman
|
|||
|
||||
} else if (pa_tagstruct_getu32(t, &i.buffer_usec) < 0 ||
|
||||
pa_tagstruct_getu32(t, &i.sink_usec) < 0 ||
|
||||
pa_tagstruct_getu32(t, &i.playing) < 0 ||
|
||||
pa_tagstruct_get_boolean(t, &i.playing) < 0 ||
|
||||
pa_tagstruct_getu32(t, &i.queue_length) < 0 ||
|
||||
!pa_tagstruct_eof(t)) {
|
||||
pa_context_fail(o->context, PA_ERROR_PROTOCOL);
|
||||
|
|
|
|||
|
|
@ -830,7 +830,7 @@ static void command_get_playback_latency(struct pa_pdispatch *pd, uint32_t comma
|
|||
pa_tagstruct_putu32(reply, tag);
|
||||
pa_tagstruct_putu32(reply, pa_sink_input_get_latency(s->sink_input));
|
||||
pa_tagstruct_putu32(reply, pa_sink_get_latency(s->sink_input->sink));
|
||||
pa_tagstruct_putu32(reply, pa_memblockq_is_readable(s->memblockq));
|
||||
pa_tagstruct_put_boolean(reply, pa_memblockq_is_readable(s->memblockq));
|
||||
pa_tagstruct_putu32(reply, pa_memblockq_get_length(s->memblockq));
|
||||
pa_pstream_send_tagstruct(c->pstream, reply);
|
||||
}
|
||||
|
|
@ -1012,7 +1012,7 @@ static void module_fill_tagstruct(struct pa_tagstruct *t, struct pa_module *modu
|
|||
pa_tagstruct_puts(t, module->name);
|
||||
pa_tagstruct_puts(t, module->argument ? module->argument : "");
|
||||
pa_tagstruct_putu32(t, module->n_used);
|
||||
pa_tagstruct_putu32(t, module->auto_unload);
|
||||
pa_tagstruct_put_boolean(t, module->auto_unload);
|
||||
}
|
||||
|
||||
static void sink_input_fill_tagstruct(struct pa_tagstruct *t, struct pa_sink_input *s) {
|
||||
|
|
@ -1505,10 +1505,10 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo
|
|||
|
||||
static struct pa_protocol_native* protocol_new_internal(struct pa_core *c, struct pa_module *m, struct pa_modargs *ma) {
|
||||
struct pa_protocol_native *p;
|
||||
uint32_t public;
|
||||
int public;
|
||||
assert(c && ma);
|
||||
|
||||
if (pa_modargs_get_value_u32(ma, "public", &public) < 0) {
|
||||
if (pa_modargs_get_value_boolean(ma, "public", &public) < 0) {
|
||||
fprintf(stderr, __FILE__": public= expects numeric argument.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ fail:
|
|||
|
||||
struct pa_protocol_simple* pa_protocol_simple_new(struct pa_core *core, struct pa_socket_server *server, struct pa_module *m, struct pa_modargs *ma) {
|
||||
struct pa_protocol_simple* p = NULL;
|
||||
uint32_t enable;
|
||||
int enable;
|
||||
assert(core && server && ma);
|
||||
|
||||
p = pa_xmalloc0(sizeof(struct pa_protocol_simple));
|
||||
|
|
@ -385,14 +385,14 @@ struct pa_protocol_simple* pa_protocol_simple_new(struct pa_core *core, struct p
|
|||
p->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
|
||||
|
||||
enable = 0;
|
||||
if (pa_modargs_get_value_u32(ma, "record", &enable) < 0) {
|
||||
if (pa_modargs_get_value_boolean(ma, "record", &enable) < 0) {
|
||||
fprintf(stderr, __FILE__": record= expects a numeric argument.\n");
|
||||
goto fail;
|
||||
}
|
||||
p->mode = enable ? RECORD : 0;
|
||||
|
||||
enable = 1;
|
||||
if (pa_modargs_get_value_u32(ma, "playback", &enable) < 0) {
|
||||
if (pa_modargs_get_value_boolean(ma, "playback", &enable) < 0) {
|
||||
fprintf(stderr, __FILE__": playback= expects a numeric argument.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ uint32_t pa_scache_get_id_by_name(struct pa_core *c, const char *name) {
|
|||
uint32_t pa_scache_total_size(struct pa_core *c) {
|
||||
struct pa_scache_entry *e;
|
||||
uint32_t index;
|
||||
uint32_t sum;
|
||||
uint32_t sum = 0;
|
||||
|
||||
if (!c->scache)
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@ enum tags {
|
|||
TAG_U8 = 'B',
|
||||
TAG_S8 = 'b',
|
||||
TAG_SAMPLE_SPEC = 'a',
|
||||
TAG_ARBITRARY = 'x'
|
||||
TAG_ARBITRARY = 'x',
|
||||
TAG_BOOLEAN_TRUE = '1',
|
||||
TAG_BOOLEAN_FALSE = '0',
|
||||
};
|
||||
|
||||
struct pa_tagstruct {
|
||||
|
|
@ -125,7 +127,6 @@ void pa_tagstruct_put_sample_spec(struct pa_tagstruct *t, const struct pa_sample
|
|||
t->length += 7;
|
||||
}
|
||||
|
||||
|
||||
void pa_tagstruct_put_arbitrary(struct pa_tagstruct *t, const void *p, size_t length) {
|
||||
assert(t && p);
|
||||
|
||||
|
|
@ -137,6 +138,13 @@ void pa_tagstruct_put_arbitrary(struct pa_tagstruct *t, const void *p, size_t le
|
|||
t->length += 5+length;
|
||||
}
|
||||
|
||||
void pa_tagstruct_put_boolean(struct pa_tagstruct*t, int b) {
|
||||
assert(t);
|
||||
extend(t, 1);
|
||||
t->data[t->length] = b ? TAG_BOOLEAN_TRUE : TAG_BOOLEAN_FALSE;
|
||||
t->length += 1;
|
||||
}
|
||||
|
||||
int pa_tagstruct_gets(struct pa_tagstruct*t, const char **s) {
|
||||
int error = 0;
|
||||
size_t n;
|
||||
|
|
@ -238,3 +246,21 @@ const uint8_t* pa_tagstruct_data(struct pa_tagstruct*t, size_t *l) {
|
|||
return t->data;
|
||||
}
|
||||
|
||||
int pa_tagstruct_get_boolean(struct pa_tagstruct*t, int *b) {
|
||||
assert(t && b);
|
||||
|
||||
if (t->rindex+1 > t->length)
|
||||
return -1;
|
||||
|
||||
if (t->data[t->rindex] == TAG_BOOLEAN_TRUE)
|
||||
*b = 1;
|
||||
else if (t->data[t->rindex] == TAG_BOOLEAN_FALSE)
|
||||
*b = 0;
|
||||
else
|
||||
return -1;
|
||||
|
||||
t->rindex +=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38,12 +38,14 @@ void pa_tagstruct_putu32(struct pa_tagstruct*t, uint32_t i);
|
|||
void pa_tagstruct_putu8(struct pa_tagstruct*t, uint8_t c);
|
||||
void pa_tagstruct_put_sample_spec(struct pa_tagstruct *t, const struct pa_sample_spec *ss);
|
||||
void pa_tagstruct_put_arbitrary(struct pa_tagstruct*t, const void *p, size_t length);
|
||||
void pa_tagstruct_put_boolean(struct pa_tagstruct*t, int b);
|
||||
|
||||
int pa_tagstruct_gets(struct pa_tagstruct*t, const char **s);
|
||||
int pa_tagstruct_getu32(struct pa_tagstruct*t, uint32_t *i);
|
||||
int pa_tagstruct_getu8(struct pa_tagstruct*t, uint8_t *c);
|
||||
int pa_tagstruct_get_sample_spec(struct pa_tagstruct *t, struct pa_sample_spec *ss);
|
||||
int pa_tagstruct_get_arbitrary(struct pa_tagstruct *t, const void **p, size_t length);
|
||||
int pa_tagstruct_get_boolean(struct pa_tagstruct *t, int *b);
|
||||
|
||||
int pa_tagstruct_eof(struct pa_tagstruct*t);
|
||||
const uint8_t* pa_tagstruct_data(struct pa_tagstruct*t, size_t *l);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue