{
struct private_alsa_data *pad = wn->private_data;
struct writer_node_group *wng = wn->wng;
- size_t frames = *wng->loaded / pad->bytes_per_frame;
+ size_t frames = (*wng->loaded - wn->written) / pad->bytes_per_frame;
snd_pcm_sframes_t ret;
- unsigned char *data = (unsigned char*)wng->buf;
+ unsigned char *data = (unsigned char*)wng->buf + wn->written;
struct timeval tv;
// PARA_INFO_LOG("%zd frames\n", frames);
if (!frames) {
if (*wng->input_eof)
- ret = *wng->loaded;
- return 0;
+ wn->written = *wng->loaded;
+ return 1;
}
if (tv_diff(&s->now, &pad->next_chunk, NULL) < 0)
- return 0;
+ return 1;
ret = snd_pcm_writei(pad->handle, data, frames);
if (ret == -EPIPE) {
PARA_WARNING_LOG("%s", "EPIPE\n");
snd_pcm_prepare(pad->handle);
- return 0;
+ return 1;
}
if (ret < 0) {
PARA_WARNING_LOG("%s", "ALSA ERROR\n");
ms2tv(pad->buffer_time / 4000, &tv);
// ms2tv(1, &tv);
tv_add(&s->now, &tv, &pad->next_chunk);
- return ret * pad->bytes_per_frame;
+ wn->written += ret * pad->bytes_per_frame;
+ return 1;
}
static void alsa_close(struct writer_node *wn)
{
struct private_file_writer_data *pfwd = wn->private_data;
struct writer_node_group *wng = wn->wng;
- int ret = 0;
+ int ret;
if (!pfwd->check_fd)
- return 0;
- if (!*wng->loaded)
- return 0;
+ return 1;
+ if (*wng->loaded <= wn->written)
+ return 1;
if (!FD_ISSET(pfwd->fd, &s->wfds))
- return 0;
+ return 1;
// PARA_INFO_LOG("writing %zd\n", *wng->loaded);
- ret = write(pfwd->fd, wng->buf, *wng->loaded);
+ ret = write(pfwd->fd, wng->buf + wn->written,
+ *wng->loaded - wn->written);
if (ret < 0)
- ret = -E_FW_WRITE;
- return ret;
+ return -E_FW_WRITE;
+ wn->written += ret;
+ return 1;
}
static void file_writer_close(struct writer_node *wn)
void *private_data;
/** send that many bytes in one go */
int chunk_bytes;
+ /** pointer to the group this node belongs to */
struct writer_node_group *wng;
/** the writer-specific configuration of this node */
void *conf;
+ /** how much of the wng's buffer is already written */
+ size_t written;
};
/** describes one supported writer */
unsigned num_writers;
/** array of pointers to the corresponding writer nodes */
struct writer_node *writer_nodes;
- /** keeps track of how many bytes have been written by each node */
- int *written;
/** the maximum of the chunk_bytes values of the writer nodes in this group */
size_t max_chunk_bytes;
/** non-zero if end of file was encountered */
return;
}
if (!i)
- min_written = t->ret;
+ min_written = wn->written;
else
- min_written = PARA_MIN(min_written, t->ret);
+ min_written = PARA_MIN(min_written, wn->written);
+ }
+// PARA_INFO_LOG("loaded: %zd, min_written: %zd bytes\n", *g->loaded, min_written);
+ if (min_written) {
+ *g->loaded -= min_written;
+ FOR_EACH_WRITER_NODE(i, g)
+ g->writer_nodes[i].written -= min_written;
}
- *g->loaded -= min_written;
if (!*g->loaded && *g->input_eof) {
g->eof = 1;
t->ret = -E_WNG_EOF;
- } else
- t->ret = 1;
- if (*g->loaded && min_written)
+ return;
+ }
+ t->ret = 1;
+ if (*g->loaded && min_written) {
+// PARA_INFO_LOG("moving %zd bytes\n", *g->loaded);
memmove(g->buf, g->buf + min_written, *g->loaded);
+ }
}
int wng_open(struct writer_node_group *g)
struct writer_node *wn = &g->writer_nodes[i];
wn->writer->close(wn);
}
- free(g->written);
free(g->writer_nodes);
free(g);
}
g->num_writers = num_writers;
g->writer_nodes = para_calloc(num_writers
* sizeof(struct writer_node));
- g->written = para_calloc(num_writers * sizeof(size_t));
g->task.private_data = g;
g->task.post_select = wng_post_select;
g->task.pre_select = wng_pre_select;