]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - afh_recv.c
paraslash 0.7.3
[paraslash.git] / afh_recv.c
index b76c405a47c686ad5eec5d0e4c569101ff83738a..8449e787f96fa24b60c2c3af9ec5218eb264ff53 100644 (file)
@@ -1,8 +1,4 @@
-/*
- * Copyright (C) 2011 Andre Noll <maan@tuebingen.mpg.de>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* Copyright (C) 2011 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
 
 /** \file afh_recv.c Receiver for streaming local files. */
 
@@ -31,6 +27,7 @@ struct private_afh_recv_data {
        long unsigned last_chunk;
        struct timeval stream_start;
        uint32_t current_chunk;
+       void *afh_context;
 };
 
 static int afh_execute(struct btr_node *btrn, const char *cmd, char **result)
@@ -58,7 +55,8 @@ static int afh_execute(struct btr_node *btrn, const char *cmd, char **result)
                        return ret;
                if (x >= pard->afhi.chunks_total)
                        return -ERRNO_TO_PARA_ERROR(EINVAL);
-               pard->first_chunk = afh_get_start_chunk(x, &pard->afhi);
+               pard->first_chunk = afh_get_start_chunk(x, &pard->afhi,
+                       pard->audio_format_num);
                pard->current_chunk = pard->first_chunk;
                return 1;
        }
@@ -70,14 +68,14 @@ static int afh_recv_open(struct receiver_node *rn)
        struct lls_parse_result *lpr = rn->lpr;
        struct private_afh_recv_data *pard;
        struct afh_info *afhi;
-       const char *fn = RECV_CMD_OPT_STRING_VAL(AFH, FILENAME, lpr);
+       const char *fn = RECV_CMD_OPT_STRING_VAL(AFH, FILENAME, lpr), *msg;
        int32_t bc = RECV_CMD_OPT_INT32_VAL(AFH, BEGIN_CHUNK, lpr);
        const struct lls_opt_result *r_e = RECV_CMD_OPT_RESULT(AFH, END_CHUNK, lpr);
        int ret;
 
        if (!fn || *fn == '\0')
                return -E_AFH_RECV_BAD_FILENAME;
-       rn->private_data = pard = para_calloc(sizeof(*pard));
+       rn->private_data = pard = zalloc(sizeof(*pard));
        afhi = &pard->afhi;
        ret = mmap_full_file(fn, O_RDONLY, &pard->map,
                &pard->map_size, &pard->fd);
@@ -89,18 +87,22 @@ static int afh_recv_open(struct receiver_node *rn)
                goto out_unmap;
        pard->audio_format_num = ret;
        ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+       msg = "no data chunks";
        if (afhi->chunks_total == 0)
                goto out_clear_afhi;
+       msg = "invalid begin chunk";
        if (PARA_ABS(bc) >= afhi->chunks_total)
                goto out_clear_afhi;
        if (bc >= 0)
-               pard->first_chunk = afh_get_start_chunk(bc, &pard->afhi);
+               pard->first_chunk = afh_get_start_chunk(bc, &pard->afhi,
+                       pard->audio_format_num);
        else
                pard->first_chunk = afh_get_start_chunk(afhi->chunks_total + bc,
-                       &pard->afhi);
+                       &pard->afhi, pard->audio_format_num);
        if (lls_opt_given(r_e)) {
                int32_t ec = lls_int32_val(0, r_e);
                ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+               msg = "invalid end chunk";
                if (PARA_ABS(ec) > afhi->chunks_total)
                        goto out_clear_afhi;
                if (ec >= 0)
@@ -110,12 +112,14 @@ static int afh_recv_open(struct receiver_node *rn)
        } else
                pard->last_chunk = afhi->chunks_total - 1;
        ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+       msg = "begin chunk >= end chunk!?";
        if (pard->first_chunk >= pard->last_chunk)
                goto out_clear_afhi;
        pard->current_chunk = pard->first_chunk;
        return pard->audio_format_num;
 out_clear_afhi:
        clear_afhi(afhi);
+       PARA_ERROR_LOG("%s: %s\n", fn, msg);
 out_unmap:
        para_munmap(pard->map, pard->map_size);
        close(pard->fd);
@@ -134,17 +138,18 @@ static void afh_recv_close(struct receiver_node *rn)
        clear_afhi(&pard->afhi);
        para_munmap(pard->map, pard->map_size);
        close(pard->fd);
+       afh_close(pard->afh_context, pard->audio_format_num);
        freep(&rn->private_data);
 }
 
-static void afh_recv_pre_select(struct sched *s, void *context)
+static void afh_recv_pre_monitor(struct sched *s, void *context)
 {
        struct receiver_node *rn = context;
        struct private_afh_recv_data *pard = rn->private_data;
        struct afh_info *afhi = &pard->afhi;
        struct lls_parse_result *lpr = rn->lpr;
        struct timeval chunk_time;
-       int state = generic_recv_pre_select(s, rn);
+       int state = generic_recv_pre_monitor(s, rn);
        unsigned j_given = RECV_CMD_OPT_GIVEN(AFH, JUST_IN_TIME, lpr);
 
        if (state <= 0)
@@ -158,7 +163,7 @@ static void afh_recv_pre_select(struct sched *s, void *context)
        sched_request_barrier_or_min_delay(&chunk_time, s);
 }
 
-static int afh_recv_post_select(__a_unused struct sched *s, void *context)
+static int afh_recv_post_monitor(__a_unused struct sched *s, void *context)
 {
        struct receiver_node *rn = context;
        struct lls_parse_result *lpr = rn->lpr;
@@ -167,8 +172,9 @@ static int afh_recv_post_select(__a_unused struct sched *s, void *context)
        struct afh_info *afhi = &pard->afhi;
        int ret;
        char *buf;
-       const char *start, *end;
+       const char *start;
        size_t size;
+       uint32_t len;
        struct timeval chunk_time;
        unsigned j_given = RECV_CMD_OPT_GIVEN(AFH, JUST_IN_TIME, lpr);
        unsigned H_given = RECV_CMD_OPT_GIVEN(AFH, NO_HEADER, lpr);
@@ -182,19 +188,24 @@ static int afh_recv_post_select(__a_unused struct sched *s, void *context)
                        pard->map_size, &header, &size);
                if (size > 0) {
                        PARA_INFO_LOG("writing header (%zu bytes)\n", size);
-                       buf = para_malloc(size);
+                       buf = alloc(size);
                        memcpy(buf, header, size);
                        btr_add_output(buf, size, btrn);
                        afh_free_header(header, pard->audio_format_num);
                }
        }
        if (!j_given) {
-               afh_get_chunk(pard->first_chunk, afhi, pard->map, &start, &size);
-               afh_get_chunk(pard->last_chunk, afhi, pard->map, &end, &size);
-               end += size;
-               PARA_INFO_LOG("adding %td bytes\n", end - start);
-               btr_add_output_dont_free(start, end - start, btrn);
-               ret = -E_RECV_EOF;
+               long unsigned n;
+               for (n = pard->first_chunk; n < pard->last_chunk; n++) {
+                       ret = afh_get_chunk(n, afhi, pard->audio_format_num,
+                               pard->map, pard->map_size, &start, &len,
+                               &pard->afh_context);
+                       if (ret < 0)
+                               goto out;
+                       PARA_DEBUG_LOG("adding %u bytes\n", len);
+                       btr_add_output_dont_free(start, len, btrn);
+               }
+               ret = -E_EOF;
                goto out;
        }
        if (pard->current_chunk == pard->first_chunk)
@@ -206,11 +217,16 @@ static int afh_recv_post_select(__a_unused struct sched *s, void *context)
                if (ret > 0)
                        goto out;
        }
-       afh_get_chunk(pard->current_chunk, afhi, pard->map, &start, &size);
+       ret = afh_get_chunk(pard->current_chunk, afhi,
+               pard->audio_format_num, pard->map,
+               pard->map_size, &start, &len,
+               &pard->afh_context);
+       if (ret < 0)
+               goto out;
        PARA_DEBUG_LOG("adding chunk %u\n", pard->current_chunk);
-       btr_add_output_dont_free(start, size, btrn);
+       btr_add_output_dont_free(start, len, btrn);
        if (pard->current_chunk >= pard->last_chunk) {
-               ret = -E_RECV_EOF;
+               ret = -E_EOF;
                goto out;
        }
        pard->current_chunk++;
@@ -224,10 +240,9 @@ out:
 }
 
 const struct receiver lsg_recv_cmd_com_afh_user_data = {
-       .init = afh_init,
        .open = afh_recv_open,
        .close = afh_recv_close,
-       .pre_select = afh_recv_pre_select,
-       .post_select = afh_recv_post_select,
+       .pre_monitor = afh_recv_pre_monitor,
+       .post_monitor = afh_recv_post_monitor,
        .execute = afh_execute,
 };