diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index a349bbb20..77153af94 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -21,9 +21,10 @@ #include #endif -#include -#include #include +#include +#include +#include #include #include @@ -35,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -52,9 +54,12 @@ PA_MODULE_USAGE( "format= " "rate= " "channels= " - "channel_map=" - "formats=" - "norewinds="); + "channel_map= " + "formats= " + "norewinds= " + "dump= " + "avoid_processing= " +); #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); }