summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Meerwald <p.meerwald@bct-electronic.com>2013-12-02 17:27:00 +0100
committerTanu Kaskinen <tanu.kaskinen@linux.intel.com>2014-01-28 22:49:15 +0200
commitb51d28bbbf0b544789be7fe6b3d2a148cf0a500a (patch)
tree7fcd59fb48a7aa14b184652976e1d50a24637455
parent5ad310f4f693994a1628fd3b746d4519aae911c8 (diff)
resampler: Implement leftover handling in convert_to_work_format()
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
-rw-r--r--src/pulsecore/resampler.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 4c788dca..db65ceaa 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -65,13 +65,14 @@ struct pa_resampler {
size_t resample_buf_size;
size_t from_work_format_buf_size;
- /* points to buffer before resampling stage, remap */
+ /* points to buffer before resampling stage, remap or to_work */
pa_memchunk *leftover_buf;
size_t *leftover_buf_size;
- /* have_leftover points to leftover_in_remap */
+ /* have_leftover points to leftover_in_remap or leftover_in_to_work */
bool *have_leftover;
bool leftover_in_remap;
+ bool leftover_in_to_work;
pa_sample_format_t work_format;
uint8_t work_channels;
@@ -1169,26 +1170,43 @@ static void fit_buf(pa_resampler *r, pa_memchunk *buf, size_t len, size_t *size,
}
static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) {
- unsigned n_samples;
+ unsigned in_n_samples, out_n_samples;
void *src, *dst;
+ bool have_leftover;
+ size_t leftover_length = 0;
pa_assert(r);
pa_assert(input);
pa_assert(input->memblock);
/* Convert the incoming sample into the work sample format and place them
- * in to_work_format_buf. */
+ * in to_work_format_buf. The leftover data is already converted, so it's
+ * part of the output buffer. */
+
+ have_leftover = r->leftover_in_to_work;
+ r->leftover_in_to_work = false;
- if (!r->to_work_format_func || !input->length)
+ if (!have_leftover && (!r->to_work_format_func || !input->length))
return input;
+ else if (input->length <= 0)
+ return &r->to_work_format_buf;
+
+ in_n_samples = out_n_samples = (unsigned) ((input->length / r->i_fz) * r->i_ss.channels);
- n_samples = (unsigned) ((input->length / r->i_fz) * r->i_ss.channels);
- fit_buf(r, &r->to_work_format_buf, r->w_sz * n_samples, &r->to_work_format_buf_size, 0);
+ if (have_leftover) {
+ leftover_length = r->to_work_format_buf.length;
+ out_n_samples += (unsigned) (leftover_length / r->w_sz);
+ }
+
+ fit_buf(r, &r->to_work_format_buf, r->w_sz * out_n_samples, &r->to_work_format_buf_size, leftover_length);
src = pa_memblock_acquire_chunk(input);
- dst = pa_memblock_acquire(r->to_work_format_buf.memblock);
+ dst = (uint8_t *) pa_memblock_acquire(r->to_work_format_buf.memblock) + leftover_length;
- r->to_work_format_func(n_samples, src, dst);
+ if (r->to_work_format_func)
+ r->to_work_format_func(in_n_samples, src, dst);
+ else
+ memcpy(dst, src, input->length);
pa_memblock_release(input->memblock);
pa_memblock_release(r->to_work_format_buf.memblock);