resample: take into account the number of queued input samples

Take the queued input samples into account when calculating the
required input size. This can be 0 when there is still enough
data queued in the input for another period.

Handle 0 read_size in alsa-source and make it push out a 0 buffer,
this will then drain the resampler and make it ask for a new buffer
size. This makes the transition from one period to another more
seamless for the resampler.

Fixes #805
This commit is contained in:
Wim Taymans 2021-03-04 10:27:44 +01:00
parent e15104c5cb
commit 3af768f124
2 changed files with 14 additions and 4 deletions

View file

@ -1100,7 +1100,7 @@ push_frames(struct state *state,
if (spa_list_is_empty(&state->free)) {
spa_log_warn(state->log, NAME" %s: no more buffers", state->props.device);
total_frames = frames;
} else if (frames > 0) {
} else {
uint8_t *src;
size_t n_bytes, left;
struct buffer *b;

View file

@ -855,16 +855,19 @@ static int impl_node_process(void *object)
inport->offset += in_len * sizeof(float);
if (inport->offset >= size || flush_in) {
inio->status = SPA_STATUS_NEED_DATA;
spa_log_trace_fp(this->log, NAME" %p: return input buffer of %zd samples",
this, size / sizeof(float));
inport->offset = 0;
size = 0;
SPA_FLAG_SET(res, inio->status);
spa_log_trace_fp(this->log, NAME " %p: return input buffer of %zd samples", this, size / sizeof(float));
}
outport->offset += out_len * sizeof(float);
if (outport->offset > 0 && (outport->offset >= maxsize || flush_out)) {
outio->status = SPA_STATUS_HAVE_DATA;
outio->buffer_id = dbuf->id;
spa_log_trace_fp(this->log, NAME " %p: have output buffer of %zd samples", this, outport->offset / sizeof(float));
spa_log_trace_fp(this->log, NAME" %p: have output buffer of %zd samples",
this, outport->offset / sizeof(float));
dequeue_buffer(this, dbuf);
outport->offset = 0;
this->drained = draining;
@ -878,12 +881,19 @@ static int impl_node_process(void *object)
}
if (this->io_rate_match) {
uint32_t match_size;
if (SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE))
resample_update_rate(&this->resample, this->io_rate_match->rate);
else
resample_update_rate(&this->resample, 1.0);
this->io_rate_match->delay = resample_delay(&this->resample);
this->io_rate_match->size = resample_in_len(&this->resample, max - outport->offset / sizeof(float));
match_size = resample_in_len(&this->resample, max - outport->offset / sizeof(float));
match_size -= SPA_MIN(match_size, size - inport->offset / sizeof(float));
this->io_rate_match->size = match_size;
spa_log_trace_fp(this->log, NAME " %p: next match %u", this, match_size);
}
return res;
}