mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-10 13:29:58 -05:00
add a "length" argument to the seek functions, as an optimization to request a certain block size if any data needs to be generated. this is merely a hint.
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1833 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
5df7a85473
commit
1d1eda6059
11 changed files with 94 additions and 50 deletions
|
|
@ -275,7 +275,7 @@ finish:
|
||||||
pa_log_debug("Thread shutting down");
|
pa_log_debug("Thread shutting down");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void request_memblock(struct output *o) {
|
static void request_memblock(struct output *o, size_t length) {
|
||||||
pa_memchunk chunk;
|
pa_memchunk chunk;
|
||||||
|
|
||||||
pa_assert(o);
|
pa_assert(o);
|
||||||
|
|
@ -306,7 +306,7 @@ static void request_memblock(struct output *o) {
|
||||||
struct output *j;
|
struct output *j;
|
||||||
|
|
||||||
/* Do it! */
|
/* Do it! */
|
||||||
pa_sink_render(o->userdata->sink, o->userdata->block_size, &chunk);
|
pa_sink_render(o->userdata->sink, length, &chunk);
|
||||||
|
|
||||||
/* OK, let's send this data to the other threads */
|
/* OK, let's send this data to the other threads */
|
||||||
for (j = o->userdata->thread_info.outputs; j; j = j->next)
|
for (j = o->userdata->thread_info.outputs; j; j = j->next)
|
||||||
|
|
@ -323,7 +323,7 @@ static void request_memblock(struct output *o) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from I/O thread context */
|
/* Called from I/O thread context */
|
||||||
static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {
|
||||||
struct output *o;
|
struct output *o;
|
||||||
|
|
||||||
pa_sink_input_assert_ref(i);
|
pa_sink_input_assert_ref(i);
|
||||||
|
|
@ -331,7 +331,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
||||||
pa_assert(o);
|
pa_assert(o);
|
||||||
|
|
||||||
/* If necessary, get some new data */
|
/* If necessary, get some new data */
|
||||||
request_memblock(o);
|
request_memblock(o, length);
|
||||||
|
|
||||||
return pa_memblockq_peek(o->memblockq, chunk);
|
return pa_memblockq_peek(o->memblockq, chunk);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ static const char* const valid_modargs[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {
|
||||||
struct userdata *u;
|
struct userdata *u;
|
||||||
|
|
||||||
pa_assert(i);
|
pa_assert(i);
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ static void sink_input_kill_cb(pa_sink_input *i) {
|
||||||
memblockq_stream_unlink(MEMBLOCKQ_STREAM(i->userdata));
|
memblockq_stream_unlink(MEMBLOCKQ_STREAM(i->userdata));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {
|
||||||
memblockq_stream *u;
|
memblockq_stream *u;
|
||||||
|
|
||||||
pa_assert(i);
|
pa_assert(i);
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ static void sink_input_kill_cb(pa_sink_input *i) {
|
||||||
memchunk_stream_unlink(MEMCHUNK_STREAM(i->userdata));
|
memchunk_stream_unlink(MEMCHUNK_STREAM(i->userdata));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {
|
||||||
memchunk_stream *u;
|
memchunk_stream *u;
|
||||||
|
|
||||||
pa_assert(i);
|
pa_assert(i);
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ typedef struct proto_handler {
|
||||||
} esd_proto_handler_info_t;
|
} esd_proto_handler_info_t;
|
||||||
|
|
||||||
static void sink_input_drop_cb(pa_sink_input *i, size_t length);
|
static void sink_input_drop_cb(pa_sink_input *i, size_t length);
|
||||||
static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk);
|
static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk);
|
||||||
static void sink_input_kill_cb(pa_sink_input *i);
|
static void sink_input_kill_cb(pa_sink_input *i);
|
||||||
static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk);
|
static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk);
|
||||||
static pa_usec_t source_output_get_latency_cb(pa_source_output *o);
|
static pa_usec_t source_output_get_latency_cb(pa_source_output *o);
|
||||||
|
|
@ -1237,7 +1237,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from thread context */
|
/* Called from thread context */
|
||||||
static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {
|
||||||
connection*c;
|
connection*c;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ enum {
|
||||||
CONNECTION_MESSAGE_REVOKE
|
CONNECTION_MESSAGE_REVOKE
|
||||||
};
|
};
|
||||||
|
|
||||||
static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk);
|
static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk);
|
||||||
static void sink_input_drop_cb(pa_sink_input *i, size_t length);
|
static void sink_input_drop_cb(pa_sink_input *i, size_t length);
|
||||||
static void sink_input_kill_cb(pa_sink_input *i);
|
static void sink_input_kill_cb(pa_sink_input *i);
|
||||||
|
|
||||||
|
|
@ -973,7 +973,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from thread context */
|
/* Called from thread context */
|
||||||
static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {
|
||||||
playback_stream *s;
|
playback_stream *s;
|
||||||
|
|
||||||
pa_sink_input_assert_ref(i);
|
pa_sink_input_assert_ref(i);
|
||||||
|
|
|
||||||
|
|
@ -343,7 +343,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from thread context */
|
/* Called from thread context */
|
||||||
static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {
|
||||||
connection *c;
|
connection *c;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,9 @@
|
||||||
|
|
||||||
#include "sink-input.h"
|
#include "sink-input.h"
|
||||||
|
|
||||||
#define CONVERT_BUFFER_LENGTH 4096
|
#define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
|
||||||
#define MOVE_BUFFER_LENGTH (1024*1024)
|
#define SILENCE_BUFFER_LENGTH (PA_PAGE_SIZE*12)
|
||||||
#define SILENCE_BUFFER_LENGTH (64*1024)
|
#define MOVE_BUFFER_LENGTH (PA_PAGE_SIZE*256)
|
||||||
|
|
||||||
static PA_DEFINE_CHECK_TYPE(pa_sink_input, pa_msgobject);
|
static PA_DEFINE_CHECK_TYPE(pa_sink_input, pa_msgobject);
|
||||||
|
|
||||||
|
|
@ -368,13 +368,15 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from thread context */
|
/* Called from thread context */
|
||||||
int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) {
|
int pa_sink_input_peek(pa_sink_input *i, size_t length, pa_memchunk *chunk, pa_cvolume *volume) {
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int do_volume_adj_here;
|
int do_volume_adj_here;
|
||||||
int volume_is_norm;
|
int volume_is_norm;
|
||||||
|
size_t block_size_max;
|
||||||
|
|
||||||
pa_sink_input_assert_ref(i);
|
pa_sink_input_assert_ref(i);
|
||||||
pa_assert(PA_SINK_INPUT_LINKED(i->thread_info.state));
|
pa_assert(PA_SINK_INPUT_LINKED(i->thread_info.state));
|
||||||
|
pa_assert(pa_frame_aligned(length, &i->sink->sample_spec));
|
||||||
pa_assert(chunk);
|
pa_assert(chunk);
|
||||||
pa_assert(volume);
|
pa_assert(volume);
|
||||||
|
|
||||||
|
|
@ -383,6 +385,15 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume)
|
||||||
|
|
||||||
pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING || i->thread_info.state == PA_SINK_INPUT_DRAINED);
|
pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING || i->thread_info.state == PA_SINK_INPUT_DRAINED);
|
||||||
|
|
||||||
|
/* Default buffer size */
|
||||||
|
if (length <= 0)
|
||||||
|
length = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sink->sample_spec);
|
||||||
|
|
||||||
|
/* Make sure the buffer fits in the mempool tile */
|
||||||
|
block_size_max = pa_mempool_block_size_max(i->sink->core->mempool);
|
||||||
|
if (length > block_size_max)
|
||||||
|
length = pa_frame_align(block_size_max, &i->sink->sample_spec);
|
||||||
|
|
||||||
if (i->thread_info.move_silence > 0) {
|
if (i->thread_info.move_silence > 0) {
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
|
|
@ -390,7 +401,10 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume)
|
||||||
* while until the old sink has drained its playback buffer */
|
* while until the old sink has drained its playback buffer */
|
||||||
|
|
||||||
if (!i->thread_info.silence_memblock)
|
if (!i->thread_info.silence_memblock)
|
||||||
i->thread_info.silence_memblock = pa_silence_memblock_new(i->sink->core->mempool, &i->sink->sample_spec, SILENCE_BUFFER_LENGTH);
|
i->thread_info.silence_memblock = pa_silence_memblock_new(
|
||||||
|
i->sink->core->mempool,
|
||||||
|
&i->sink->sample_spec,
|
||||||
|
pa_frame_align(SILENCE_BUFFER_LENGTH, &i->sink->sample_spec));
|
||||||
|
|
||||||
chunk->memblock = pa_memblock_ref(i->thread_info.silence_memblock);
|
chunk->memblock = pa_memblock_ref(i->thread_info.silence_memblock);
|
||||||
chunk->index = 0;
|
chunk->index = 0;
|
||||||
|
|
@ -404,7 +418,7 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume)
|
||||||
|
|
||||||
if (!i->thread_info.resampler) {
|
if (!i->thread_info.resampler) {
|
||||||
do_volume_adj_here = 0; /* FIXME??? */
|
do_volume_adj_here = 0; /* FIXME??? */
|
||||||
ret = i->peek(i, chunk);
|
ret = i->peek(i, length, chunk);
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -413,15 +427,22 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume)
|
||||||
|
|
||||||
while (!i->thread_info.resampled_chunk.memblock) {
|
while (!i->thread_info.resampled_chunk.memblock) {
|
||||||
pa_memchunk tchunk;
|
pa_memchunk tchunk;
|
||||||
size_t l;
|
size_t l, rmbs;
|
||||||
|
|
||||||
if ((ret = i->peek(i, &tchunk)) < 0)
|
l = pa_resampler_request(i->thread_info.resampler, length);
|
||||||
|
|
||||||
|
if (l <= 0)
|
||||||
|
l = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sample_spec);
|
||||||
|
|
||||||
|
rmbs = pa_resampler_max_block_size(i->thread_info.resampler);
|
||||||
|
if (l > rmbs)
|
||||||
|
l = rmbs;
|
||||||
|
|
||||||
|
if ((ret = i->peek(i, l, &tchunk)) < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
pa_assert(tchunk.length > 0);
|
pa_assert(tchunk.length > 0);
|
||||||
|
|
||||||
l = pa_resampler_request(i->thread_info.resampler, CONVERT_BUFFER_LENGTH);
|
|
||||||
|
|
||||||
if (tchunk.length > l)
|
if (tchunk.length > l)
|
||||||
tchunk.length = l;
|
tchunk.length = l;
|
||||||
|
|
||||||
|
|
@ -477,6 +498,7 @@ finish:
|
||||||
void pa_sink_input_drop(pa_sink_input *i, size_t length) {
|
void pa_sink_input_drop(pa_sink_input *i, size_t length) {
|
||||||
pa_sink_input_assert_ref(i);
|
pa_sink_input_assert_ref(i);
|
||||||
pa_assert(PA_SINK_INPUT_LINKED(i->thread_info.state));
|
pa_assert(PA_SINK_INPUT_LINKED(i->thread_info.state));
|
||||||
|
pa_assert(pa_frame_aligned(length, &i->sink->sample_spec));
|
||||||
pa_assert(length > 0);
|
pa_assert(length > 0);
|
||||||
|
|
||||||
if (i->thread_info.move_silence > 0) {
|
if (i->thread_info.move_silence > 0) {
|
||||||
|
|
@ -527,9 +549,9 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) {
|
||||||
pa_memchunk chunk;
|
pa_memchunk chunk;
|
||||||
pa_cvolume volume;
|
pa_cvolume volume;
|
||||||
|
|
||||||
if (pa_sink_input_peek(i, &chunk, &volume) >= 0) {
|
if (pa_sink_input_peek(i, length, &chunk, &volume) >= 0) {
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
pa_memblock_unref(chunk.memblock);
|
pa_memblock_unref(chunk.memblock);
|
||||||
|
|
||||||
l = chunk.length;
|
l = chunk.length;
|
||||||
|
|
@ -541,11 +563,13 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
|
l = pa_resampler_request(i->thread_info.resampler, length);
|
||||||
|
|
||||||
/* Hmmm, peeking failed, so let's at least drop
|
/* Hmmm, peeking failed, so let's at least drop
|
||||||
* the right amount of data */
|
* the right amount of data */
|
||||||
|
|
||||||
if ((l = pa_resampler_request(i->thread_info.resampler, length)) > 0)
|
if (l > 0)
|
||||||
if (i->drop)
|
if (i->drop)
|
||||||
i->drop(i, l);
|
i->drop(i, l);
|
||||||
|
|
||||||
|
|
@ -798,9 +822,9 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) {
|
||||||
i->thread_info.move_silence = 0;
|
i->thread_info.move_silence = 0;
|
||||||
else
|
else
|
||||||
i->thread_info.move_silence = pa_usec_to_bytes(
|
i->thread_info.move_silence = pa_usec_to_bytes(
|
||||||
pa_bytes_to_usec(i->thread_info.move_silence, &i->sample_spec) +
|
pa_bytes_to_usec(i->thread_info.move_silence, &origin->sample_spec) +
|
||||||
silence_usec,
|
silence_usec,
|
||||||
&i->sample_spec);
|
&dest->sample_spec);
|
||||||
|
|
||||||
pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL);
|
pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,12 @@ struct pa_sink_input {
|
||||||
int muted;
|
int muted;
|
||||||
|
|
||||||
/* Returns the chunk of audio data (but doesn't drop it
|
/* Returns the chunk of audio data (but doesn't drop it
|
||||||
* yet!). Returns -1 on failure. Called from IO thread context. */
|
* yet!). Returns -1 on failure. Called from IO thread context. If
|
||||||
int (*peek) (pa_sink_input *i, pa_memchunk *chunk);
|
* data needs to be generated from scratch then please in the
|
||||||
|
* specified length. This is an optimization only. If less data is
|
||||||
|
* available, it's fine to return a smaller block. If more data is
|
||||||
|
* already ready, it is better to return the full block.*/
|
||||||
|
int (*peek) (pa_sink_input *i, size_t length, pa_memchunk *chunk);
|
||||||
|
|
||||||
/* Drops the specified number of bytes, usually called right after
|
/* Drops the specified number of bytes, usually called right after
|
||||||
* peek(), but not necessarily. Called from IO thread context. */
|
* peek(), but not necessarily. Called from IO thread context. */
|
||||||
|
|
@ -217,7 +221,7 @@ pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i);
|
||||||
|
|
||||||
/* To be used exclusively by the sink driver thread */
|
/* To be used exclusively by the sink driver thread */
|
||||||
|
|
||||||
int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume);
|
int pa_sink_input_peek(pa_sink_input *i, size_t length, pa_memchunk *chunk, pa_cvolume *volume);
|
||||||
void pa_sink_input_drop(pa_sink_input *i, size_t length);
|
void pa_sink_input_drop(pa_sink_input *i, size_t length);
|
||||||
int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk);
|
int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,8 @@
|
||||||
#include "sink.h"
|
#include "sink.h"
|
||||||
|
|
||||||
#define MAX_MIX_CHANNELS 32
|
#define MAX_MIX_CHANNELS 32
|
||||||
#define SILENCE_BUFFER_LENGTH (64*1024)
|
#define MIX_BUFFER_LENGTH (PA_PAGE_SIZE)
|
||||||
|
#define SILENCE_BUFFER_LENGTH (PA_PAGE_SIZE*12)
|
||||||
|
|
||||||
static PA_DEFINE_CHECK_TYPE(pa_sink, pa_msgobject);
|
static PA_DEFINE_CHECK_TYPE(pa_sink, pa_msgobject);
|
||||||
|
|
||||||
|
|
@ -311,7 +312,7 @@ void pa_sink_ping(pa_sink *s) {
|
||||||
pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_PING, NULL, 0, NULL, NULL);
|
pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_PING, NULL, 0, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) {
|
static unsigned fill_mix_info(pa_sink *s, size_t length, pa_mix_info *info, unsigned maxinfo) {
|
||||||
pa_sink_input *i;
|
pa_sink_input *i;
|
||||||
unsigned n = 0;
|
unsigned n = 0;
|
||||||
void *state = NULL;
|
void *state = NULL;
|
||||||
|
|
@ -322,7 +323,7 @@ static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) {
|
||||||
while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)) && maxinfo > 0) {
|
while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)) && maxinfo > 0) {
|
||||||
pa_sink_input_assert_ref(i);
|
pa_sink_input_assert_ref(i);
|
||||||
|
|
||||||
if (pa_sink_input_peek(i, &info->chunk, &info->volume) < 0)
|
if (pa_sink_input_peek(i, length, &info->chunk, &info->volume) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
info->userdata = pa_sink_input_ref(i);
|
info->userdata = pa_sink_input_ref(i);
|
||||||
|
|
@ -399,20 +400,32 @@ static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, size_t length
|
||||||
void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
|
void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
|
||||||
pa_mix_info info[MAX_MIX_CHANNELS];
|
pa_mix_info info[MAX_MIX_CHANNELS];
|
||||||
unsigned n;
|
unsigned n;
|
||||||
|
size_t block_size_max;
|
||||||
|
|
||||||
pa_sink_assert_ref(s);
|
pa_sink_assert_ref(s);
|
||||||
pa_assert(PA_SINK_OPENED(s->thread_info.state));
|
pa_assert(PA_SINK_OPENED(s->thread_info.state));
|
||||||
pa_assert(length);
|
pa_assert(pa_frame_aligned(length, &s->sample_spec));
|
||||||
pa_assert(result);
|
pa_assert(result);
|
||||||
|
|
||||||
pa_sink_ref(s);
|
pa_sink_ref(s);
|
||||||
|
|
||||||
n = s->thread_info.state == PA_SINK_RUNNING ? fill_mix_info(s, info, MAX_MIX_CHANNELS) : 0;
|
if (length <= 0)
|
||||||
|
length = pa_frame_align(MIX_BUFFER_LENGTH, &s->sample_spec);
|
||||||
|
|
||||||
|
block_size_max = pa_mempool_block_size_max(s->core->mempool);
|
||||||
|
if (length > block_size_max)
|
||||||
|
length = pa_frame_align(block_size_max, &s->sample_spec);
|
||||||
|
|
||||||
|
pa_assert(length > 0);
|
||||||
|
|
||||||
|
n = s->thread_info.state == PA_SINK_RUNNING ? fill_mix_info(s, length, info, MAX_MIX_CHANNELS) : 0;
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
|
||||||
if (length > SILENCE_BUFFER_LENGTH)
|
if (length > SILENCE_BUFFER_LENGTH)
|
||||||
length = SILENCE_BUFFER_LENGTH;
|
length = pa_frame_align(SILENCE_BUFFER_LENGTH, &s->sample_spec);
|
||||||
|
|
||||||
|
pa_assert(length > 0);
|
||||||
|
|
||||||
if (!s->silence || pa_memblock_get_length(s->silence) < length) {
|
if (!s->silence || pa_memblock_get_length(s->silence) < length) {
|
||||||
if (s->silence)
|
if (s->silence)
|
||||||
|
|
@ -470,11 +483,12 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
|
||||||
pa_assert(PA_SINK_OPENED(s->thread_info.state));
|
pa_assert(PA_SINK_OPENED(s->thread_info.state));
|
||||||
pa_assert(target);
|
pa_assert(target);
|
||||||
pa_assert(target->memblock);
|
pa_assert(target->memblock);
|
||||||
pa_assert(target->length);
|
pa_assert(target->length > 0);
|
||||||
|
pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
|
||||||
|
|
||||||
pa_sink_ref(s);
|
pa_sink_ref(s);
|
||||||
|
|
||||||
n = s->thread_info.state == PA_SINK_RUNNING ? fill_mix_info(s, info, MAX_MIX_CHANNELS) : 0;
|
n = s->thread_info.state == PA_SINK_RUNNING ? fill_mix_info(s, target->length, info, MAX_MIX_CHANNELS) : 0;
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
pa_silence_memchunk(target, &s->sample_spec);
|
pa_silence_memchunk(target, &s->sample_spec);
|
||||||
|
|
@ -536,7 +550,8 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {
|
||||||
pa_assert(PA_SINK_OPENED(s->thread_info.state));
|
pa_assert(PA_SINK_OPENED(s->thread_info.state));
|
||||||
pa_assert(target);
|
pa_assert(target);
|
||||||
pa_assert(target->memblock);
|
pa_assert(target->memblock);
|
||||||
pa_assert(target->length);
|
pa_assert(target->length > 0);
|
||||||
|
pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
|
||||||
|
|
||||||
pa_sink_ref(s);
|
pa_sink_ref(s);
|
||||||
|
|
||||||
|
|
@ -559,13 +574,15 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {
|
||||||
void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
|
void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
|
||||||
pa_sink_assert_ref(s);
|
pa_sink_assert_ref(s);
|
||||||
pa_assert(PA_SINK_OPENED(s->thread_info.state));
|
pa_assert(PA_SINK_OPENED(s->thread_info.state));
|
||||||
pa_assert(length);
|
pa_assert(length > 0);
|
||||||
|
pa_assert(pa_frame_aligned(length, &s->sample_spec));
|
||||||
pa_assert(result);
|
pa_assert(result);
|
||||||
|
|
||||||
/*** This needs optimization ***/
|
/*** This needs optimization ***/
|
||||||
|
|
||||||
result->memblock = pa_memblock_new(s->core->mempool, result->length = length);
|
|
||||||
result->index = 0;
|
result->index = 0;
|
||||||
|
result->length = length;
|
||||||
|
result->memblock = pa_memblock_new(s->core->mempool, length);
|
||||||
|
|
||||||
pa_sink_render_into_full(s, result);
|
pa_sink_render_into_full(s, result);
|
||||||
}
|
}
|
||||||
|
|
@ -577,6 +594,7 @@ void pa_sink_skip(pa_sink *s, size_t length) {
|
||||||
pa_sink_assert_ref(s);
|
pa_sink_assert_ref(s);
|
||||||
pa_assert(PA_SINK_OPENED(s->thread_info.state));
|
pa_assert(PA_SINK_OPENED(s->thread_info.state));
|
||||||
pa_assert(length > 0);
|
pa_assert(length > 0);
|
||||||
|
pa_assert(pa_frame_aligned(length, &s->sample_spec));
|
||||||
|
|
||||||
if (pa_source_used_by(s->monitor_source)) {
|
if (pa_source_used_by(s->monitor_source)) {
|
||||||
pa_memchunk chunk;
|
pa_memchunk chunk;
|
||||||
|
|
@ -853,7 +871,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
|
||||||
pa_cvolume volume;
|
pa_cvolume volume;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
if (pa_sink_input_peek(info->sink_input, &memchunk, &volume) < 0)
|
if (pa_sink_input_peek(info->sink_input, info->buffer_bytes, &memchunk, &volume) < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
n = memchunk.length > info->buffer_bytes ? info->buffer_bytes : memchunk.length;
|
n = memchunk.length > info->buffer_bytes ? info->buffer_bytes : memchunk.length;
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,6 @@
|
||||||
|
|
||||||
#include "sound-file-stream.h"
|
#include "sound-file-stream.h"
|
||||||
|
|
||||||
#define BUF_SIZE (1024*16)
|
|
||||||
|
|
||||||
typedef struct file_stream {
|
typedef struct file_stream {
|
||||||
pa_msgobject parent;
|
pa_msgobject parent;
|
||||||
pa_core *core;
|
pa_core *core;
|
||||||
|
|
@ -113,7 +111,7 @@ static void sink_input_kill_cb(pa_sink_input *i) {
|
||||||
file_stream_unlink(FILE_STREAM(i->userdata));
|
file_stream_unlink(FILE_STREAM(i->userdata));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {
|
||||||
file_stream *u;
|
file_stream *u;
|
||||||
|
|
||||||
pa_assert(i);
|
pa_assert(i);
|
||||||
|
|
@ -128,7 +126,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
||||||
|
|
||||||
if (!u->memchunk.memblock) {
|
if (!u->memchunk.memblock) {
|
||||||
|
|
||||||
u->memchunk.memblock = pa_memblock_new(i->sink->core->mempool, BUF_SIZE);
|
u->memchunk.memblock = pa_memblock_new(i->sink->core->mempool, length);
|
||||||
u->memchunk.index = 0;
|
u->memchunk.index = 0;
|
||||||
|
|
||||||
if (u->readf_function) {
|
if (u->readf_function) {
|
||||||
|
|
@ -137,7 +135,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
||||||
size_t fs = pa_frame_size(&i->sample_spec);
|
size_t fs = pa_frame_size(&i->sample_spec);
|
||||||
|
|
||||||
p = pa_memblock_acquire(u->memchunk.memblock);
|
p = pa_memblock_acquire(u->memchunk.memblock);
|
||||||
n = u->readf_function(u->sndfile, p, BUF_SIZE/fs);
|
n = u->readf_function(u->sndfile, p, length/fs);
|
||||||
pa_memblock_release(u->memchunk.memblock);
|
pa_memblock_release(u->memchunk.memblock);
|
||||||
|
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
|
|
@ -149,7 +147,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
p = pa_memblock_acquire(u->memchunk.memblock);
|
p = pa_memblock_acquire(u->memchunk.memblock);
|
||||||
n = sf_read_raw(u->sndfile, p, BUF_SIZE);
|
n = sf_read_raw(u->sndfile, p, length);
|
||||||
pa_memblock_release(u->memchunk.memblock);
|
pa_memblock_release(u->memchunk.memblock);
|
||||||
|
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue