summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Guthrie <pulse@colin.guthr.ie>2008-05-26 23:43:51 +0000
committerColin Guthrie <pulse@colin.guthr.ie>2008-10-08 20:32:09 +0100
commit13bc07587564977a64222f5a4075b7fa63ac5548 (patch)
tree76e0376d857adb65454e52b326b42245b89c4603
parentb93e9e80ecbdc90c0bf6f90c5bd4aafcdb4d2488 (diff)
A few related changes:
* Change the encode_sample routine to simply return normal memchunks allocated from the mempool. * unref the memchunks returned from encode_sample when we are done with them. * Create an encoded 'silence' sample and play this at all times to prevent hangup and to 'hog' the airtunes device This now works and can be used as a regular sink albeit with a constant latency of about 8 seconds :s git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/coling@2485 fefdeb5f-60dc-0310-8127-8f9354f1896f
-rw-r--r--src/modules/module-raop-sink.c79
-rw-r--r--src/modules/rtp/raop_client.c16
2 files changed, 59 insertions, 36 deletions
diff --git a/src/modules/module-raop-sink.c b/src/modules/module-raop-sink.c
index 42092e06..f78abbae 100644
--- a/src/modules/module-raop-sink.c
+++ b/src/modules/module-raop-sink.c
@@ -178,7 +178,8 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
pollfd->fd = u->fd;
- pollfd->events = pollfd->revents = 0;
+ pollfd->events = POLLOUT;
+ pollfd->revents = 0;
return 0;
}
@@ -190,6 +191,9 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
static void thread_func(void *userdata) {
struct userdata *u = userdata;
int write_type = 0;
+ pa_memchunk silence;
+ uint32_t silence_overhead;
+ double silence_ratio;
pa_assert(u);
@@ -200,6 +204,9 @@ static void thread_func(void *userdata) {
pa_smoother_set_time_offset(u->smoother, pa_rtclock_usec());
+ /* Create a chunk of memory that is our encoded silence sample. */
+ pa_memchunk_reset(&silence);
+
for (;;) {
int ret;
@@ -208,33 +215,61 @@ static void thread_func(void *userdata) {
pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
/* Render some data and write it to the fifo */
- if (PA_SINK_OPENED(u->sink->thread_info.state) && pollfd->revents) {
+ if (pollfd->revents) {
pa_usec_t usec;
int64_t n;
+ void *p;
+
+ if (!silence.memblock) {
+ pa_memchunk silence_tmp;
+
+ pa_memchunk_reset(&silence_tmp);
+ silence_tmp.memblock = pa_memblock_new(u->core->mempool, 4096);
+ silence_tmp.length = 4096;
+ p = pa_memblock_acquire(silence_tmp.memblock);
+ memset(p, 0, 4096);
+ pa_memblock_release(silence_tmp.memblock);
+ pa_raop_client_encode_sample(u->raop, &silence_tmp, &silence);
+ pa_assert(0 == silence_tmp.length);
+ silence_overhead = silence_tmp.length - 4096;
+ silence_ratio = silence_tmp.length / 4096;
+ pa_memblock_unref(silence_tmp.memblock);
+ }
for (;;) {
ssize_t l;
- void *p;
if (u->encoded_memchunk.length <= 0) {
- if (u->raw_memchunk.length <= 0) {
- if (u->raw_memchunk.memblock)
- pa_memblock_unref(u->raw_memchunk.memblock);
- pa_memchunk_reset(&u->raw_memchunk);
-
- /* Grab unencoded data */
- pa_sink_render(u->sink, u->block_size, &u->raw_memchunk);
- p = pa_memblock_acquire(u->raw_memchunk.memblock);
- pa_memblock_release(u->raw_memchunk.memblock);
+ if (u->encoded_memchunk.memblock)
+ pa_memblock_unref(u->encoded_memchunk.memblock);
+ if (PA_SINK_OPENED(u->sink->thread_info.state)) {
+ size_t rl;
+
+ /* We render real data */
+ if (u->raw_memchunk.length <= 0) {
+ if (u->raw_memchunk.memblock)
+ pa_memblock_unref(u->raw_memchunk.memblock);
+ pa_memchunk_reset(&u->raw_memchunk);
+
+ /* Grab unencoded data */
+ pa_sink_render(u->sink, u->block_size, &u->raw_memchunk);
+ }
+ pa_assert(u->raw_memchunk.length > 0);
+
+ /* Encode it */
+ rl = u->raw_memchunk.length;
+ u->encoding_overhead += u->next_encoding_overhead;
+ pa_raop_client_encode_sample(u->raop, &u->raw_memchunk, &u->encoded_memchunk);
+ u->next_encoding_overhead = (u->encoded_memchunk.length - (rl - u->raw_memchunk.length));
+ u->encoding_ratio = u->encoded_memchunk.length / (rl - u->raw_memchunk.length);
+ } else {
+ /* We render some silence into our memchunk */
+ u->encoding_overhead += u->next_encoding_overhead;
+ memcpy(&u->encoded_memchunk, &silence, sizeof(pa_memchunk));
+ pa_memblock_ref(silence.memblock);
+ u->next_encoding_overhead = silence_overhead;
+ u->encoding_ratio = silence_ratio;
}
- pa_assert(u->raw_memchunk.length > 0);
-
- /* Encode it */
- size_t rl = u->raw_memchunk.length;
- u->encoding_overhead += u->next_encoding_overhead;
- pa_raop_client_encode_sample(u->raop, &u->raw_memchunk, &u->encoded_memchunk);
- u->next_encoding_overhead = (u->encoded_memchunk.length - (rl - u->raw_memchunk.length));
- u->encoding_ratio = u->encoded_memchunk.length / (rl - u->raw_memchunk.length);
}
pa_assert(u->encoded_memchunk.length > 0);
@@ -303,7 +338,7 @@ static void thread_func(void *userdata) {
}
/* Hmm, nothing to do. Let's sleep */
- pollfd->events = PA_SINK_OPENED(u->sink->thread_info.state) ? POLLOUT : 0;
+ /* pollfd->events = PA_SINK_OPENED(u->sink->thread_info.state) ? POLLOUT : 0; */
}
if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
@@ -331,6 +366,8 @@ fail:
pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
finish:
+ if (silence.memblock)
+ pa_memblock_unref(silence.memblock);
pa_log_debug("Thread shutting down");
}
diff --git a/src/modules/rtp/raop_client.c b/src/modules/rtp/raop_client.c
index 7ba1be74..4085a494 100644
--- a/src/modules/rtp/raop_client.c
+++ b/src/modules/rtp/raop_client.c
@@ -94,12 +94,6 @@ struct pa_raop_client {
void* userdata;
pa_raop_client_closed_cb_t closed_callback;
void* closed_userdata;
-
- uint8_t *buffer;
- pa_memblock *memblock;
- size_t buffer_length;
- uint8_t *buffer_index;
- uint16_t buffer_count;
};
/**
@@ -402,7 +396,6 @@ void pa_raop_client_free(pa_raop_client* c)
{
pa_assert(c);
- pa_xfree(c->buffer);
if (c->rtsp)
pa_rtsp_client_free(c->rtsp);
pa_xfree(c->host);
@@ -443,15 +436,8 @@ int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchun
/* Leave 16 bytes extra to allow for the ALAC header which is about 55 bits */
bufmax = length + header_size + 16;
- if (bufmax > c->buffer_length) {
- c->buffer = pa_xrealloc(c->buffer, bufmax);
- c->buffer_length = bufmax;
- if (c->memblock)
- pa_memblock_unref(c->memblock);
- c->memblock = pa_memblock_new_user(c->core->mempool, c->buffer, bufmax, noop, 0);
- }
pa_memchunk_reset(encoded);
- encoded->memblock = c->memblock;
+ encoded->memblock = pa_memblock_new(c->core->mempool, bufmax);
b = pa_memblock_acquire(encoded->memblock);
memcpy(b, header, header_size);