]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 'refs/heads/t/play_fix'
authorAndre Noll <maan@systemlinux.org>
Thu, 31 Jul 2014 06:59:47 +0000 (08:59 +0200)
committerAndre Noll <maan@systemlinux.org>
Thu, 31 Jul 2014 06:59:47 +0000 (08:59 +0200)
Cooking since two weeks.

* 9c1aa5 Never start playback at an empty chunk.

Conflicts:
afh_recv.c

1  2 
afh_common.c
afh_recv.c
vss.c

diff --combined afh_common.c
index b3ba348526cad86c103bcff65e3765fc3b571e2a,c5a25e36bfe889d22318fa28e5cf23088c2cbb67..b06e4eb5a0ef16653476e61574e55ad6878efbe7
@@@ -230,12 -230,11 +230,12 @@@ success
  }
  
  /**
 - * Deallocate contents of a filled-in ahi structure
 + * Deallocate the contents of an afh_info structure.
   *
   * \param afhi The structure to clear.
   *
 - * The given pointer is kept, everything else is freed.
 + * This only frees the memory the various pointer fields of \a afhi point to.
 + * It does *not* free \a afhi itself.
   */
  void clear_afhi(struct afh_info *afhi)
  {
@@@ -265,6 -264,12 +265,12 @@@ const char *audio_format_name(int i
        return afl[i].name;
  }
  
+ static inline size_t get_chunk_len(long unsigned chunk_num,
+               const struct afh_info *afhi)
+ {
+       return afhi->chunk_table[chunk_num + 1] - afhi->chunk_table[chunk_num];
+ }
  /**
   * Get one chunk of audio data.
   *
@@@ -282,7 -287,28 +288,28 @@@ void afh_get_chunk(long unsigned chunk_
  {
        size_t pos = afhi->chunk_table[chunk_num];
        *buf = map + pos;
-       *len = afhi->chunk_table[chunk_num + 1] - pos;
+       *len = get_chunk_len(chunk_num, afhi);
+ }
+ /**
+  * Find a suitable start chunk.
+  *
+  * \param approx_chunk_num Upper bound for the chunk number to return.
+  * \param afhi Needed for the chunk table.
+  *
+  * \return The first non-empty chunk <= \a approx_chunk_num.
+  *
+  * \sa \ref afh_get_chunk().
+  */
+ int32_t afh_get_start_chunk(int32_t approx_chunk_num,
+               const struct afh_info *afhi)
+ {
+       int32_t k;
+       for (k = PARA_MAX(0, approx_chunk_num); k >= 0; k--)
+               if (get_chunk_len(k, afhi) > 0)
+                       break;
+       return k;
  }
  
  /**
diff --combined afh_recv.c
index 657a205737595f370eeb238813a7cd2c009064dc,89722fef5b305351bac9668c1dab966d2f8bfafe..92e9e8394c31143d892a94434e7daa0c3380f3c7
@@@ -59,7 -59,9 +59,8 @@@ static int afh_execute(struct btr_node 
                        return ret;
                if (x >= pard->afhi.chunks_total)
                        return -ERRNO_TO_PARA_ERROR(EINVAL);
-               pard->first_chunk = pard->current_chunk = x;
+               pard->first_chunk = afh_get_start_chunk(x, &pard->afhi);
+               pard->current_chunk = pard->first_chunk;
 -              rn->task.error = 0;
                return 1;
        }
        return -E_BTR_NAVAIL;
@@@ -109,9 -111,12 +110,12 @@@ static int afh_recv_open(struct receive
        if (PARA_ABS(conf->begin_chunk_arg) >= afhi->chunks_total)
                goto out_clear_afhi;
        if (conf->begin_chunk_arg >= 0)
-               pard->first_chunk = conf->begin_chunk_arg;
+               pard->first_chunk = afh_get_start_chunk(
+                       conf->begin_chunk_arg, &pard->afhi);
        else
-               pard->first_chunk = afhi->chunks_total + conf->begin_chunk_arg;
+               pard->first_chunk = afh_get_start_chunk(
+                       afhi->chunks_total + conf->begin_chunk_arg,
+                       &pard->afhi);
        if (conf->end_chunk_given) {
                ret = -ERRNO_TO_PARA_ERROR(EINVAL);
                if (PARA_ABS(conf->end_chunk_arg) > afhi->chunks_total)
@@@ -150,14 -155,14 +154,14 @@@ static void afh_recv_close(struct recei
        freep(&rn->private_data);
  }
  
 -static void afh_recv_pre_select(struct sched *s, struct task *t)
 +static void afh_recv_pre_select(struct sched *s, void *context)
  {
 -      struct receiver_node *rn = container_of(t, struct receiver_node, task);
 +      struct receiver_node *rn = context;
        struct private_afh_recv_data *pard = rn->private_data;
        struct afh_info *afhi = &pard->afhi;
        struct afh_recv_args_info *conf = rn->conf;
        struct timeval chunk_time;
 -      int state = generic_recv_pre_select(s, t);
 +      int state = generic_recv_pre_select(s, rn);
  
        if (state <= 0)
                return;
        sched_request_barrier_or_min_delay(&chunk_time, s);
  }
  
 -static int afh_recv_post_select(__a_unused struct sched *s, struct task *t)
 +static int afh_recv_post_select(__a_unused struct sched *s, void *context)
  {
 -      struct receiver_node *rn = container_of(t, struct receiver_node, task);
 +      struct receiver_node *rn = context;
        struct afh_recv_args_info *conf = rn->conf;
        struct private_afh_recv_data *pard = rn->private_data;
        struct btr_node *btrn = rn->btrn;
diff --combined vss.c
index 928ef6c2e2bf9e564872d60e99f7deef3c23bd6c,d6f914e72870efb58b8fd81570e31e0b939a4c2e..e0b764ab71d43df3cdbd5b309d5f28e6cab5f7d2
--- 1/vss.c
--- 2/vss.c
+++ b/vss.c
@@@ -89,7 -89,7 +89,7 @@@ struct vss_task 
        /** The memory mapped audio file. */
        char *map;
        /** Used by the scheduler. */
 -      struct task task;
 +      struct task *task;
        /** Pointer to the header of the mapped audio file. */
        char *header_buf;
        /** Length of the audio file header. */
@@@ -885,9 -885,12 +885,9 @@@ static void set_mmd_offset(void
        mmd->offset = tv2ms(&offset);
  }
  
 -/**
 +/*
   * Compute the timeout for the main select-loop of the scheduler.
   *
 - * \param s Pointer to the server scheduler.
 - * \param t Pointer to the vss task structure.
 - *
   * Before the timeout is computed, the current vss status flags are evaluated
   * and acted upon by calling appropriate functions from the lower layers.
   * Possible actions include
   *    - shutdown of all senders (stop/pause command),
   *    - reposition the stream (ff/jmp command).
   */
 -static void vss_pre_select(struct sched *s, struct task *t)
 +static void vss_pre_select(struct sched *s, void *context)
  {
        int i;
 -      struct vss_task *vsst = container_of(t, struct vss_task, task);
 +      struct vss_task *vsst = context;
  
        if (!vsst->map || vss_next() || vss_paused() || vss_repos()) {
                struct fec_client *fc, *tmp;
                tv_add(now, &vsst->announce_tv, &vsst->data_send_barrier);
                set_eof_barrier(vsst);
                mmd->chunks_sent = 0;
-               mmd->current_chunk = mmd->repos_request;
+               mmd->current_chunk = afh_get_start_chunk(mmd->repos_request,
+                       &mmd->afd.afhi);
                mmd->new_vss_status_flags &= ~VSS_REPOS;
                set_mmd_offset();
        }
@@@ -1123,10 -1127,10 +1124,10 @@@ static void vss_send(struct vss_task *v
        }
  }
  
 -static int vss_post_select(struct sched *s, struct task *t)
 +static int vss_post_select(struct sched *s, void *context)
  {
        int ret, i;
 -      struct vss_task *vsst = container_of(t, struct vss_task, task);
 +      struct vss_task *vsst = context;
  
        if (mmd->sender_cmd_data.cmd_num >= 0) {
                int num = mmd->sender_cmd_data.cmd_num,
@@@ -1182,6 -1186,8 +1183,6 @@@ void init_vss_task(int afs_socket, stru
                        conf.autoplay_delay_arg : 0;
        vsst->header_interval.tv_sec = 5; /* should this be configurable? */
        vsst->afs_socket = afs_socket;
 -      vsst->task.pre_select = vss_pre_select;
 -      vsst->task.post_select = vss_post_select;
        ms2tv(announce_time, &vsst->announce_tv);
        PARA_INFO_LOG("announce timeval: %lums\n", tv2ms(&vsst->announce_tv));
        INIT_LIST_HEAD(&fec_client_list);
                tv_add(&vsst->autoplay_barrier, &vsst->announce_tv,
                        &vsst->data_send_barrier);
        }
 -      sprintf(vsst->task.status, "vss task");
 -      register_task(s, &vsst->task);
 +      vsst->task = task_register(&(struct task_info) {
 +              .name = "vss task",
 +              .pre_select = vss_pre_select,
 +              .post_select = vss_post_select,
 +              .context = vsst,
 +      }, s);
  }