]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 't/periodic_header_optional'
authorAndre Noll <maan@systemlinux.org>
Sat, 22 Jan 2011 15:57:02 +0000 (16:57 +0100)
committerAndre Noll <maan@systemlinux.org>
Sat, 22 Jan 2011 15:57:02 +0000 (16:57 +0100)
1  2 
command.c
dccp_send.c
http_send.c
send.h
server.c
udp_send.c
vss.c

diff --combined command.c
index e95318c4f1661c50caf7664542d20e5babddbcac,664d25734aa14e877735c891f172600982ad2939..57e851f938c700044be20b62226dc07fae63c07e
+++ b/command.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
 - * Copyright (C) 1997-2010 Andre Noll <maan@systemlinux.org>
 + * Copyright (C) 1997-2011 Andre Noll <maan@systemlinux.org>
   *
   * Licensed under the GPL v2. For licencing details see COPYING.
   */
@@@ -13,6 -13,7 +13,7 @@@
  #include <dirent.h>
  #include <openssl/rc4.h>
  #include <osl.h>
+ #include <stdbool.h>
  
  #include "para.h"
  #include "error.h"
diff --combined dccp_send.c
index 425527fc423e90dfc0396d7680d25d00733379ea,38e4b7c822e20a209c278a219e28b3121578a305..304a42e749a647d5d6a568ae0e9850d183907979
@@@ -1,5 -1,5 +1,5 @@@
  /*
 - * Copyright (C) 2006-2010 Andre Noll <maan@systemlinux.org>
 + * Copyright (C) 2006-2011 Andre Noll <maan@systemlinux.org>
   *
   * Licensed under the GPL v2. For licencing details see COPYING.
   */
@@@ -145,6 -145,7 +145,7 @@@ static void dccp_post_select(fd_set *rf
        dfc->fcp.slices_per_group       = conf.dccp_slices_per_group_arg;
        dfc->fcp.init_fec               = dccp_init_fec;
        dfc->fcp.send_fec               = dccp_send_fec;
+       dfc->fcp.need_periodic_header   = false;
        dfc->fc = vss_add_fec_client(sc, &dfc->fcp);
  }
  
diff --combined http_send.c
index 4ad857662f6ef5d9029129c6714b8c0c20ecdca4,d5c6397e4a52eb096f9ebc13cb364d38b7b47455..086b600f0d043f928e6c2c0f71afa65104045f00
@@@ -1,5 -1,5 +1,5 @@@
  /*
 - * Copyright (C) 2005-2010 Andre Noll <maan@systemlinux.org>
 + * Copyright (C) 2005-2011 Andre Noll <maan@systemlinux.org>
   *
   * Licensed under the GPL v2. For licencing details see COPYING.
   */
@@@ -10,6 -10,7 +10,7 @@@
  #include <sys/types.h>
  #include <dirent.h>
  #include <osl.h>
+ #include <stdbool.h>
  
  #include "para.h"
  #include "error.h"
diff --combined send.h
index e13909321f193b8326bcfda87e1adecedd2ff5ae,52f7a10d11f1699c41b2e81cb0d5e5f278459414..836babd50845088be08a2061fe39cc6ffd7760cb
--- 1/send.h
--- 2/send.h
+++ b/send.h
@@@ -1,5 -1,5 +1,5 @@@
  /*
 - * Copyright (C) 2005-2010 Andre Noll <maan@systemlinux.org>
 + * Copyright (C) 2005-2011 Andre Noll <maan@systemlinux.org>
   *
   * Licensed under the GPL v2. For licencing details see COPYING.
   */
@@@ -131,6 -131,8 +131,8 @@@ struct fec_client_parms 
        uint8_t slices_per_group;
        /** Number of slices minus number of redundant slices. */
        uint8_t data_slices_per_group;
+       /** Whether the header must be sent periodically. */
+       bool need_periodic_header;
        /**
         * Transport-layer initialisation for FEC support.
         *
diff --combined server.c
index dfac4c588910bfbbf3ae1469d26992849b811647,11397d029f8fbff5413ed504ffb758a906eb69b4..efff208b1bd704a1e5bf64aee32491b514b5b14e
+++ b/server.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
 - * Copyright (C) 1997-2010 Andre Noll <maan@systemlinux.org>
 + * Copyright (C) 1997-2011 Andre Noll <maan@systemlinux.org>
   *
   * Licensed under the GPL v2. For licencing details see COPYING.
   */
@@@ -68,6 -68,7 +68,7 @@@
  #include <openssl/rc4.h>
  #include <regex.h>
  #include <osl.h>
+ #include <stdbool.h>
  
  #include "para.h"
  #include "error.h"
diff --combined udp_send.c
index 003757ef8a94b2af8c7218d31fdaca6489ed765b,7d4f1c79939210cb2acf7d74108b3fe34bcac347..4fb10b444be321c51e7d33da2442fd6b8a469138
@@@ -1,5 -1,5 +1,5 @@@
  /*
 - * Copyright (C) 2005-2010 Andre Noll <maan@systemlinux.org>
 + * Copyright (C) 2005-2011 Andre Noll <maan@systemlinux.org>
   *
   * Licensed under the GPL v2. For licencing details see COPYING.
   */
@@@ -14,6 -14,7 +14,7 @@@
  #include <netinet/udp.h>
  #include <net/if.h>
  #include <osl.h>
+ #include <stdbool.h>
  
  #include "server.cmdline.h"
  #include "para.h"
@@@ -30,6 -31,7 +31,6 @@@
  #include "fd.h"
  #include "sched.h"
  #include "close_on_fork.h"
 -#include "chunk_queue.h"
  
  /**
   * Time window during which ICMP Destination/Port Unreachable messages are
@@@ -42,6 -44,8 +43,6 @@@
  struct udp_target {
        /** Track time (seconds) of last ICMP Port Unreachable error */
        time_t last_unreachable;
 -      /** Common sender client data */
 -      struct sender_client *sc;
        /** The opaque structure returned by vss_add_fec_client(). */
        struct fec_client *fc;
        /** The FEC parameters for this target. */
@@@ -53,11 -57,11 +54,11 @@@ static int sender_status
  
  static void udp_close_target(struct sender_client *sc)
  {
 -      if (sc->cq != NULL) {
 -              del_close_on_fork_list(sc->fd);
 -              cq_destroy(sc->cq);
 -              sc->cq = NULL;
 -      }
 +      const char *buf;
 +      size_t len = vss_get_fec_eof_packet(&buf);
 +
 +      /* ignore return value, closing the target anyway. */
 +      (void)write(sc->fd, buf, len);
  }
  
  static void udp_delete_target(struct sender_client *sc, const char *msg)
@@@ -66,8 -70,6 +67,8 @@@
  
        PARA_NOTICE_LOG("deleting %s (%s) from list\n", sc->name, msg);
        udp_close_target(sc);
 +      close(sc->fd);
 +      del_close_on_fork_list(sc->fd);
        vss_del_fec_client(ut->fc);
        list_del(&sc->node);
        free(sc->name);
@@@ -151,16 -153,30 +152,16 @@@ err
        return -ERRNO_TO_PARA_ERROR(errno);
  }
  
 -/** The maximal size of the per-target chunk queue. */
 -#define UDP_CQ_BYTES 40000
 -
  static void udp_init_session(struct sender_client *sc)
  {
 -      if (sc->cq == NULL) {
 -              sc->cq = cq_new(UDP_CQ_BYTES);
 -              add_close_on_fork_list(sc->fd);
 -              PARA_NOTICE_LOG("sending to udp %s\n", sc->name);
 -      }
 +      PARA_NOTICE_LOG("sending to udp %s\n", sc->name);
  }
  
  static void udp_shutdown_targets(void)
  {
        struct sender_client *sc, *tmp;
 -      const char *buf;
 -      size_t len = vss_get_fec_eof_packet(&buf);
 -
        list_for_each_entry_safe(sc, tmp, &targets, node)
 -              if (sc->cq != NULL) {
 -                      /* ignore return value, closing the target anyway. */
 -                      (void)write(sc->fd, buf, len);
 -                      udp_close_target(sc);
 -              }
 +              udp_close_target(sc);
  }
  
  static int udp_resolve_target(const char *url, struct sender_command_data *scd)
@@@ -279,11 -295,19 +280,11 @@@ static int udp_send_fec(struct sender_c
  
        if (sender_status == SENDER_OFF)
                return 0;
 -      if (len == 0 && !cq_peek(sc->cq))
 +      if (len == 0)
                return 0;
        ret = udp_check_socket_state(sc);
        if (ret < 0)
                goto fail;
 -      ret = send_queued_chunks(sc->fd, sc->cq);
 -      if (ret < 0)
 -              goto fail;
 -      if (!ret) { /* still data left in the queue */
 -              ret = cq_force_enqueue(sc->cq, buf, len);
 -              assert(ret >= 0);
 -              return 0;
 -      }
        ret = write_nonblock(sc->fd, buf, len);
        if (ret == -ERRNO_TO_PARA_ERROR(ECONNREFUSED)) {
                /*
        }
        if (ret < 0)
                goto fail;
 -      if (ret != len) {
 -              ret = cq_force_enqueue(sc->cq, buf + ret, len - ret);
 -              assert(ret >= 0);
 -      }
        return 1;
  fail:
        udp_delete_target(sc, para_strerror(-ret));
@@@ -312,11 -340,12 +313,12 @@@ static int udp_com_add(struct sender_co
                return -E_TARGET_EXISTS;
        }
        ut = para_calloc(sizeof(*ut));
 -      sc = ut->sc = para_calloc(sizeof(*sc));
 +      sc = para_calloc(sizeof(*sc));
        ut->fcp.slices_per_group      = scd->slices_per_group;
        ut->fcp.data_slices_per_group = scd->data_slices_per_group;
        ut->fcp.init_fec              = udp_init_fec;
        ut->fcp.send_fec              = udp_send_fec;
+       ut->fcp.need_periodic_header  = true;
  
        sc->private_data = ut;
        sc->fd = -1;
        PARA_INFO_LOG("adding to target list (%s)\n", sc->name);
        ut->fc = vss_add_fec_client(sc, &ut->fcp);
        para_list_add(&sc->node, &targets);
 +      add_close_on_fork_list(sc->fd);
        return 1;
  err:
        if (sc->fd >= 0)
diff --combined vss.c
index 38e829356e2adf1f866ceaaaa84fbdbe603193ea,121373dc2f4fb77bb62985d20909b8ccefc972ae..916a71d518762f63675c65c195f87b6fdce089e1
--- 1/vss.c
--- 2/vss.c
+++ b/vss.c
@@@ -1,5 -1,5 +1,5 @@@
  /*
 - * Copyright (C) 1997-2010 Andre Noll <maan@systemlinux.org>
 + * Copyright (C) 1997-2011 Andre Noll <maan@systemlinux.org>
   *
   * Licensed under the GPL v2. For licencing details see COPYING.
   */
@@@ -227,12 -227,29 +227,29 @@@ static bool need_audio_header(struct fe
                return false;
        if (vsst->header_len == 0)
                return false;
-       if (fc->group.num && tv_diff(&fc->next_header_time, now, NULL) > 0)
-               return false;
+       if (fc->group.num > 0) {
+               if (!fc->fcp->need_periodic_header)
+                       return false;
+               if (tv_diff(&fc->next_header_time, now, NULL) > 0)
+                       return false;
+       }
        tv_add(now, &vsst->header_interval, &fc->next_header_time);
        return true;
  }
  
+ static bool need_data_slices(struct fec_client *fc, struct vss_task *vsst)
+ {
+       if (fc->group.num > 0)
+               return true;
+       if (!vsst->header_buf)
+               return true;
+       if (vsst->header_len == 0)
+               return true;
+       if (fc->fcp->need_periodic_header)
+               return true;
+       return false;
+ }
  static int num_slices(long unsigned bytes, int max_payload, int rs)
  {
        int ret;
  }
  
  /* set group start and group duration */
- static void set_group_timing(struct fec_client *fc, struct fec_group *g)
+ static void set_group_timing(struct fec_client *fc, struct vss_task *vsst)
  {
+       struct fec_group *g = &fc->group;
        struct timeval *chunk_tv = vss_chunk_time();
  
-       tv_scale(g->num_chunks, chunk_tv, &g->duration);
+       if (!need_data_slices(fc, vsst))
+               ms2tv(200, &g->duration);
+       else
+               tv_scale(g->num_chunks, chunk_tv, &g->duration);
        tv_divide(fc->fcp->slices_per_group + fc->num_extra_slices,
                &g->duration, &g->slice_duration);
        PARA_DEBUG_LOG("durations (group/chunk/slice): %lu/%lu/%lu\n",
@@@ -288,7 -309,10 +309,10 @@@ static int initialize_fec_client(struc
        if (ret < 0)
                return ret;
        ds = ret;
-       k = hs + ds;
+       if (fc->fcp->need_periodic_header)
+               k = hs + ds;
+       else
+               k = PARA_MAX(hs, ds);
        if (k < fc->fcp->data_slices_per_group)
                k = fc->fcp->data_slices_per_group;
        fc->num_extra_slices = k - fc->fcp->data_slices_per_group;
@@@ -407,6 -431,13 +431,13 @@@ static int compute_slice_size(struct fe
                        g->slice_bytes = 1;
                return 1;
        }
+       if (!need_data_slices(fc, vsst)) {
+               g->bytes = 0;
+               g->num_chunks = 0;
+               g->slice_bytes = DIV_ROUND_UP(vsst->header_len, k);
+               g->num_header_slices = k;
+               return 1;
+       }
        h = vsst->header_len;
        max_group_bytes = (k - num_slices(h, max_slice_bytes, n - k))
                * max_slice_bytes;
@@@ -467,7 -498,7 +498,7 @@@ static int setup_next_fec_group(struct 
                 */
                tmp = g->start;
                tv_add(&tmp, &g->duration, &g->start);
-               set_group_timing(fc, g);
+               set_group_timing(fc, vsst);
                g->first_chunk += g->num_chunks;
                g->num++;
        }
        assert(g->num_header_slices + data_slices <= k);
        fc->current_slice_num = 0;
        if (g->num == 0)
-               set_group_timing(fc, g);
+               set_group_timing(fc, vsst);
  
        /* setup header slices */
        buf = vsst->header_buf;