1) Add flexible seeking support (including absolute) for memory block queues and playback streams

2) Add support to synchronize multiple playback streams
3) add two tests for 1) and 2)
4) s/PA_ERROR/PA_ERR/
5) s/PA_ERROR_OK/PA_OK/
6) update simple API to deal properly with new peek/drop recording API
7) add beginnings of proper validity checking on API calls in client libs (needs to be extended)
8) report playback buffer overflows/underflows to the client
9) move client side recording mcalign stuff into the memblockq 
10) create typedefs for a bunch of API callback prototypes
11) simplify handling of HUP poll() events

Yes, i know, it's usually better to commit a lot of small patches instead of a
single big one. In this case however, this would have contradicted the other
rule: never commit broken or incomplete stuff.

*** This stuff needs a lot of additional testing! ***


git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@511 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
Lennart Poettering 2006-02-20 04:05:16 +00:00
parent 0876b1ba82
commit 304449002c
38 changed files with 1983 additions and 796 deletions

View file

@ -45,13 +45,11 @@ struct pa_simple {
int dead;
void *read_data;
const void *read_data;
size_t read_index, read_length;
pa_usec_t latency;
};
static void read_callback(pa_stream *s, const void*data, size_t length, void *userdata);
static int check_error(pa_simple *p, int *rerror) {
pa_context_state_t cst;
pa_stream_state_t sst;
@ -92,7 +90,7 @@ static int iterate(pa_simple *p, int block, int *rerror) {
do {
if (pa_mainloop_iterate(p->mainloop, 1, NULL) < 0) {
if (rerror)
*rerror = PA_ERROR_INTERNAL;
*rerror = PA_ERR_INTERNAL;
return -1;
}
@ -106,7 +104,7 @@ static int iterate(pa_simple *p, int block, int *rerror) {
if (pa_mainloop_iterate(p->mainloop, 0, NULL) < 0) {
if (rerror)
*rerror = PA_ERROR_INTERNAL;
*rerror = PA_ERR_INTERNAL;
return -1;
}
@ -128,7 +126,7 @@ pa_simple* pa_simple_new(
int *rerror) {
pa_simple *p;
int error = PA_ERROR_INTERNAL;
int error = PA_ERR_INTERNAL;
assert(ss && (dir == PA_STREAM_PLAYBACK || dir == PA_STREAM_RECORD));
p = pa_xmalloc(sizeof(pa_simple));
@ -157,7 +155,7 @@ pa_simple* pa_simple_new(
goto fail;
if (dir == PA_STREAM_PLAYBACK)
pa_stream_connect_playback(p->stream, dev, attr, 0, NULL);
pa_stream_connect_playback(p->stream, dev, attr, 0, NULL, NULL);
else
pa_stream_connect_record(p->stream, dev, attr, 0);
@ -167,8 +165,6 @@ pa_simple* pa_simple_new(
goto fail;
}
pa_stream_set_read_callback(p->stream, read_callback, p);
return p;
fail:
@ -181,8 +177,6 @@ fail:
void pa_simple_free(pa_simple *s) {
assert(s);
pa_xfree(s->read_data);
if (s->stream)
pa_stream_unref(s->stream);
@ -215,7 +209,7 @@ int pa_simple_write(pa_simple *p, const void*data, size_t length, int *rerror) {
if (l > length)
l = length;
pa_stream_write(p->stream, data, l, NULL, 0);
pa_stream_write(p->stream, data, l, NULL, 0, PA_SEEK_RELATIVE);
data = (const uint8_t*) data + l;
length -= l;
}
@ -227,19 +221,6 @@ int pa_simple_write(pa_simple *p, const void*data, size_t length, int *rerror) {
return 0;
}
static void read_callback(pa_stream *s, const void*data, size_t length, void *userdata) {
pa_simple *p = userdata;
assert(s && data && length && p);
if (p->read_data) {
pa_log(__FILE__": Buffer overflow, dropping incoming memory blocks.\n");
pa_xfree(p->read_data);
}
p->read_data = pa_xmemdup(data, p->read_length = length);
p->read_index = 0;
}
int pa_simple_read(pa_simple *p, void*data, size_t length, int *rerror) {
assert(p && data && p->direction == PA_STREAM_RECORD);
@ -251,13 +232,18 @@ int pa_simple_read(pa_simple *p, void*data, size_t length, int *rerror) {
}
while (length > 0) {
if (!p->read_data)
if (pa_stream_peek(p->stream, &p->read_data, &p->read_length) >= 0)
p->read_index = 0;
if (p->read_data) {
size_t l = length;
if (p->read_length <= l)
l = p->read_length;
memcpy(data, (uint8_t*) p->read_data+p->read_index, l);
memcpy(data, (const uint8_t*) p->read_data+p->read_index, l);
data = (uint8_t*) data + l;
length -= l;
@ -266,8 +252,9 @@ int pa_simple_read(pa_simple *p, void*data, size_t length, int *rerror) {
p->read_length -= l;
if (!p->read_length) {
pa_xfree(p->read_data);
pa_stream_drop(p->stream);
p->read_data = NULL;
p->read_length = 0;
p->read_index = 0;
}