const char *audio_format_name(int);
void afh_get_chunk(long unsigned chunk_num, struct afh_info *afhi,
void *map, const char **buf, size_t *len);
+int32_t afh_get_start_chunk(int32_t approx_chunk_num,
+ const struct afh_info *afhi);
void afh_get_header(struct afh_info *afhi, uint8_t audio_format_id,
void *map, size_t mapsize, char **buf, size_t *len);
void afh_free_header(char *header_buf, uint8_t audio_format_id);
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.
*
{
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;
}
/**
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;
}
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)
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();
}