null-sink: Add the ability to dump what we're rendering

This should be useful for manual and automated testing, to examine what
the data coming out of null sink looks like.
This commit is contained in:
Arun Raghavan 2018-09-26 16:38:30 +05:30 committed by Arun Raghavan
parent d46908f9b6
commit ecbe1e8c22

View file

@ -21,9 +21,10 @@
#include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pulse/rtclock.h>
@ -35,6 +36,7 @@
#include <pulsecore/macro.h>
#include <pulsecore/sink.h>
#include <pulsecore/module.h>
#include <pulsecore/core-error.h>
#include <pulsecore/core-util.h>
#include <pulsecore/modargs.h>
#include <pulsecore/log.h>
@ -52,9 +54,12 @@ PA_MODULE_USAGE(
"format=<sample format> "
"rate=<sample rate> "
"channels=<number of channels> "
"channel_map=<channel map>"
"formats=<semi-colon separated sink formats>"
"norewinds=<disable rewinds>");
"channel_map=<channel map> "
"formats=<semi-colon separated sink formats> "
"norewinds=<disable rewinds> "
"dump=<name of file to dump to, automatically prefixed with /tmp/pulse-> "
"avoid_processing=<use stream original sample spec if possible?> "
);
#define DEFAULT_SINK_NAME "null"
#define BLOCK_USEC (2 * PA_USEC_PER_SEC)
@ -75,6 +80,8 @@ struct userdata {
pa_idxset *formats;
bool norewinds;
int dump_fd;
};
static const char* const valid_modargs[] = {
@ -86,6 +93,7 @@ static const char* const valid_modargs[] = {
"channel_map",
"formats",
"norewinds",
"dump",
NULL
};
@ -254,6 +262,25 @@ static void process_render(struct userdata *u, pa_usec_t now) {
request_size = PA_MIN(request_size, u->sink->thread_info.max_request);
pa_sink_render(u->sink, request_size, &chunk);
if (u->dump_fd >= 0) {
void *p;
size_t l = 0;
p = pa_memblock_acquire(chunk.memblock);
while (l < chunk.length) {
ssize_t ret = pa_write(u->dump_fd, (uint8_t*) p + chunk.index + l, chunk.length - l, NULL);
if (ret < 0) {
pa_log_error("Failed to write data to dump file: %s", pa_cstrerror(ret));
break;
}
l += ret;
}
pa_memblock_release(chunk.memblock);
}
pa_memblock_unref(chunk.memblock);
/* pa_log_debug("Ate %lu bytes.", (unsigned long) chunk.length); */
@ -326,7 +353,7 @@ int pa__init(pa_module*m) {
pa_modargs *ma = NULL;
pa_sink_new_data data;
pa_format_info *format;
const char *formats;
const char *formats, *dump_file;
size_t nbytes;
pa_assert(m);
@ -354,6 +381,18 @@ int pa__init(pa_module*m) {
goto fail;
}
u->dump_fd = -1;
if ((dump_file = pa_modargs_get_value(ma, "dump", NULL))) {
char dump_path[1024];
pa_snprintf(dump_path, sizeof(dump_path), "/tmp/pulse-%s", dump_file);
if ((u->dump_fd = pa_open_cloexec(dump_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) < 0) {
pa_log_error("Could not open dump file: %s (%s)", dump_path, pa_cstrerror(errno));
goto fail;
}
}
pa_sink_new_data_init(&data);
data.driver = __FILE__;
data.module = m;
@ -486,5 +525,8 @@ void pa__done(pa_module*m) {
if (u->formats)
pa_idxset_free(u->formats, (pa_free_cb_t) pa_format_info_free);
if (u->dump_fd >= 0)
pa_close(u->dump_fd);
pa_xfree(u);
}