aboutsummaryrefslogtreecommitdiffstats
path: root/src/output/recorder_output_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/output/recorder_output_plugin.c')
-rw-r--r--src/output/recorder_output_plugin.c74
1 files changed, 46 insertions, 28 deletions
diff --git a/src/output/recorder_output_plugin.c b/src/output/recorder_output_plugin.c
index ea299468b..b84cb244c 100644
--- a/src/output/recorder_output_plugin.c
+++ b/src/output/recorder_output_plugin.c
@@ -77,13 +77,12 @@ recorder_output_init(const struct config_param *param, GError **error_r)
return NULL;
}
- const char *encoder_name;
- const struct encoder_plugin *encoder_plugin;
-
/* read configuration */
- encoder_name = config_get_block_string(param, "encoder", "vorbis");
- encoder_plugin = encoder_plugin_get(encoder_name);
+ const char *encoder_name =
+ config_get_block_string(param, "encoder", "vorbis");
+ const struct encoder_plugin *encoder_plugin =
+ encoder_plugin_get(encoder_name);
if (encoder_plugin == NULL) {
g_set_error(error_r, recorder_output_quark(), 0,
"No such encoder: %s", encoder_name);
@@ -121,33 +120,22 @@ recorder_output_finish(struct audio_output *ao)
g_free(recorder);
}
-/**
- * Writes pending data from the encoder to the output file.
- */
static bool
-recorder_output_encoder_to_file(struct recorder_output *recorder,
- GError **error_r)
+recorder_write_to_file(struct recorder_output *recorder,
+ const void *_data, size_t length,
+ GError **error_r)
{
- size_t size = 0, position, nbytes;
-
- assert(recorder->fd >= 0);
-
- /* read from the encoder */
+ assert(length > 0);
- size = encoder_read(recorder->encoder, recorder->buffer,
- sizeof(recorder->buffer));
- if (size == 0)
- return true;
+ const int fd = recorder->fd;
- /* write everything into the file */
+ const uint8_t *data = (const uint8_t *)_data, *end = data + length;
- position = 0;
while (true) {
- nbytes = write(recorder->fd, recorder->buffer + position,
- size - position);
+ ssize_t nbytes = write(fd, data, end - data);
if (nbytes > 0) {
- position += (size_t)nbytes;
- if (position >= size)
+ data += nbytes;
+ if (data == end)
return true;
} else if (nbytes == 0) {
/* shouldn't happen for files */
@@ -163,13 +151,37 @@ recorder_output_encoder_to_file(struct recorder_output *recorder,
}
}
+/**
+ * Writes pending data from the encoder to the output file.
+ */
+static bool
+recorder_output_encoder_to_file(struct recorder_output *recorder,
+ GError **error_r)
+{
+ assert(recorder->fd >= 0);
+
+ while (true) {
+ /* read from the encoder */
+
+ size_t size = encoder_read(recorder->encoder, recorder->buffer,
+ sizeof(recorder->buffer));
+ if (size == 0)
+ return true;
+
+ /* write everything into the file */
+
+ if (!recorder_write_to_file(recorder, recorder->buffer, size,
+ error_r))
+ return false;
+ }
+}
+
static bool
recorder_output_open(struct audio_output *ao,
struct audio_format *audio_format,
GError **error_r)
{
struct recorder_output *recorder = (struct recorder_output *)ao;
- bool success;
/* create the output file */
@@ -185,8 +197,14 @@ recorder_output_open(struct audio_output *ao,
/* open the encoder */
- success = encoder_open(recorder->encoder, audio_format, error_r);
- if (!success) {
+ if (!encoder_open(recorder->encoder, audio_format, error_r)) {
+ close(recorder->fd);
+ unlink(recorder->path);
+ return false;
+ }
+
+ if (!recorder_output_encoder_to_file(recorder, error_r)) {
+ encoder_close(recorder->encoder);
close(recorder->fd);
unlink(recorder->path);
return false;