mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-12-30 11:08:50 -05:00
properly account for seeks in the requested_bytes counter
This commit is contained in:
parent
380e97a596
commit
373b5efe51
11 changed files with 55 additions and 50 deletions
|
|
@ -601,7 +601,7 @@ size_t pa_memblockq_missing(pa_memblockq *bq) {
|
|||
return l >= bq->minreq ? l : 0;
|
||||
}
|
||||
|
||||
void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) {
|
||||
void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek, pa_bool_t account) {
|
||||
int64_t old, delta;
|
||||
pa_assert(bq);
|
||||
|
||||
|
|
@ -628,12 +628,14 @@ void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) {
|
|||
|
||||
delta = bq->write_index - old;
|
||||
|
||||
if (delta >= (int64_t) bq->requested) {
|
||||
delta -= (int64_t) bq->requested;
|
||||
bq->requested = 0;
|
||||
} else if (delta >= 0) {
|
||||
bq->requested -= (size_t) delta;
|
||||
delta = 0;
|
||||
if (account) {
|
||||
if (delta >= (int64_t) bq->requested) {
|
||||
delta -= (int64_t) bq->requested;
|
||||
bq->requested = 0;
|
||||
} else if (delta >= 0) {
|
||||
bq->requested -= (size_t) delta;
|
||||
delta = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bq->missing -= delta;
|
||||
|
|
@ -895,7 +897,7 @@ int pa_memblockq_splice(pa_memblockq *bq, pa_memblockq *source) {
|
|||
|
||||
pa_memblock_unref(chunk.memblock);
|
||||
} else
|
||||
pa_memblockq_seek(bq, (int64_t) chunk.length, PA_SEEK_RELATIVE);
|
||||
pa_memblockq_seek(bq, (int64_t) chunk.length, PA_SEEK_RELATIVE, TRUE);
|
||||
|
||||
pa_memblockq_drop(bq, chunk.length);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *chunk);
|
|||
int pa_memblockq_push_align(pa_memblockq* bq, const pa_memchunk *chunk);
|
||||
|
||||
/* Manipulate the write pointer */
|
||||
void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek);
|
||||
void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek, pa_bool_t account);
|
||||
|
||||
/* Return a copy of the next memory chunk in the queue. It is not
|
||||
* removed from the queue. There are two reasons this function might
|
||||
|
|
|
|||
|
|
@ -738,24 +738,21 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
|
|||
switch (code) {
|
||||
case PLAYBACK_STREAM_MESSAGE_REQUEST_DATA: {
|
||||
pa_tagstruct *t;
|
||||
uint32_t l = 0;
|
||||
int l = 0;
|
||||
|
||||
for (;;) {
|
||||
if ((l = (uint32_t) pa_atomic_load(&s->missing)) <= 0)
|
||||
break;
|
||||
if ((l = pa_atomic_load(&s->missing)) <= 0)
|
||||
return 0;
|
||||
|
||||
if (pa_atomic_cmpxchg(&s->missing, (int) l, 0))
|
||||
if (pa_atomic_cmpxchg(&s->missing, l, 0))
|
||||
break;
|
||||
}
|
||||
|
||||
if (l <= 0)
|
||||
break;
|
||||
|
||||
t = pa_tagstruct_new(NULL, 0);
|
||||
pa_tagstruct_putu32(t, PA_COMMAND_REQUEST);
|
||||
pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
|
||||
pa_tagstruct_putu32(t, s->index);
|
||||
pa_tagstruct_putu32(t, l);
|
||||
pa_tagstruct_putu32(t, (uint32_t) l);
|
||||
pa_pstream_send_tagstruct(s->connection->pstream, t);
|
||||
|
||||
/* pa_log("Requesting %lu bytes", (unsigned long) l); */
|
||||
|
|
@ -1097,7 +1094,8 @@ static playback_stream* playback_stream_new(
|
|||
|
||||
/* Called from IO context */
|
||||
static void playback_stream_request_bytes(playback_stream *s) {
|
||||
size_t m, previous_missing, minreq;
|
||||
size_t m, minreq;
|
||||
int previous_missing;
|
||||
|
||||
playback_stream_assert_ref(s);
|
||||
|
||||
|
|
@ -1108,11 +1106,11 @@ static void playback_stream_request_bytes(playback_stream *s) {
|
|||
|
||||
/* pa_log("request_bytes(%lu)", (unsigned long) m); */
|
||||
|
||||
previous_missing = (size_t) pa_atomic_add(&s->missing, (int) m);
|
||||
previous_missing = pa_atomic_add(&s->missing, (int) m);
|
||||
minreq = pa_memblockq_get_minreq(s->memblockq);
|
||||
|
||||
if (pa_memblockq_prebuf_active(s->memblockq) ||
|
||||
(previous_missing < minreq && previous_missing+m >= minreq))
|
||||
(previous_missing < (int) minreq && previous_missing + (int) m >= (int) minreq))
|
||||
pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1297,7 +1295,12 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
|
|||
int64_t windex;
|
||||
|
||||
windex = pa_memblockq_get_write_index(s->memblockq);
|
||||
pa_memblockq_seek(s->memblockq, offset, PA_PTR_TO_UINT(userdata));
|
||||
|
||||
/* The client side is incapable of accounting correctly
|
||||
* for seeks of a type != PA_SEEK_RELATIVE. We need to be
|
||||
* able to deal with that. */
|
||||
|
||||
pa_memblockq_seek(s->memblockq, offset, PA_PTR_TO_UINT(userdata), PA_PTR_TO_UINT(userdata) == PA_SEEK_RELATIVE);
|
||||
|
||||
handle_seek(s, windex);
|
||||
return 0;
|
||||
|
|
@ -1315,7 +1318,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
|
|||
if (pa_memblockq_push_align(s->memblockq, chunk) < 0) {
|
||||
pa_log_warn("Failed to push data into queue");
|
||||
pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_OVERFLOW, NULL, 0, NULL, NULL);
|
||||
pa_memblockq_seek(s->memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE);
|
||||
pa_memblockq_seek(s->memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE, TRUE);
|
||||
}
|
||||
|
||||
handle_seek(s, windex);
|
||||
|
|
|
|||
|
|
@ -631,7 +631,7 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
|
|||
* data, so let's just hand out silence */
|
||||
pa_atomic_store(&i->thread_info.drained, 1);
|
||||
|
||||
pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE);
|
||||
pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE, TRUE);
|
||||
i->thread_info.playing_for = 0;
|
||||
if (i->thread_info.underrun_for != (uint64_t) -1)
|
||||
i->thread_info.underrun_for += ilength;
|
||||
|
|
@ -776,7 +776,7 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
|
|||
|
||||
if (amount > 0)
|
||||
/* Ok, now update the write pointer */
|
||||
pa_memblockq_seek(i->thread_info.render_memblockq, - ((int64_t) amount), PA_SEEK_RELATIVE);
|
||||
pa_memblockq_seek(i->thread_info.render_memblockq, - ((int64_t) amount), PA_SEEK_RELATIVE, TRUE);
|
||||
|
||||
if (i->thread_info.rewrite_flush)
|
||||
pa_memblockq_silence(i->thread_info.render_memblockq);
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {
|
|||
|
||||
if (pa_memblockq_push(o->thread_info.delay_memblockq, chunk) < 0) {
|
||||
pa_log_debug("Delay queue overflow!");
|
||||
pa_memblockq_seek(o->thread_info.delay_memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE);
|
||||
pa_memblockq_seek(o->thread_info.delay_memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE, TRUE);
|
||||
}
|
||||
|
||||
limit = o->process_rewind ? 0 : o->source->thread_info.max_rewind;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue