summaryrefslogtreecommitdiffstats
path: root/src/modules/rtp/rtp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/rtp/rtp.c')
-rw-r--r--src/modules/rtp/rtp.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp.c
index 60df7274..5a33ebc2 100644
--- a/src/modules/rtp/rtp.c
+++ b/src/modules/rtp/rtp.c
@@ -1,5 +1,3 @@
-/* $Id$ */
-
/***
This file is part of PulseAudio.
@@ -55,6 +53,8 @@ pa_rtp_context* pa_rtp_context_init_send(pa_rtp_context *c, int fd, uint32_t ssr
c->payload = payload & 127;
c->frame_size = frame_size;
+ pa_memchunk_reset(&c->memchunk);
+
return c;
}
@@ -78,24 +78,24 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
pa_memchunk chunk;
pa_memchunk_reset(&chunk);
-
+
if ((r = pa_memblockq_peek(q, &chunk)) >= 0) {
size_t k = n + chunk.length > size ? size - n : chunk.length;
pa_assert(chunk.memblock);
-
+
iov[iov_idx].iov_base = ((uint8_t*) pa_memblock_acquire(chunk.memblock) + chunk.index);
iov[iov_idx].iov_len = k;
mb[iov_idx] = chunk.memblock;
iov_idx ++;
-
+
n += k;
pa_memblockq_drop(q, k);
}
pa_assert(n % c->frame_size == 0);
-
+
if (r < 0 || n >= size || iov_idx >= MAX_IOVECS) {
uint32_t header[3];
struct msghdr m;
@@ -152,6 +152,8 @@ pa_rtp_context* pa_rtp_context_init_recv(pa_rtp_context *c, int fd, size_t frame
c->fd = fd;
c->frame_size = frame_size;
+
+ pa_memchunk_reset(&c->memchunk);
return c;
}
@@ -173,12 +175,28 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) {
goto fail;
}
- if (!size)
+ if (size <= 0)
return 0;
- chunk->memblock = pa_memblock_new(pool, size);
+ if (c->memchunk.length < (unsigned) size) {
+ size_t l;
+
+ if (c->memchunk.memblock)
+ pa_memblock_unref(c->memchunk.memblock);
+
+ l = PA_MAX((size_t) size, pa_mempool_block_size_max(pool));
+
+ c->memchunk.memblock = pa_memblock_new(pool, l);
+ c->memchunk.index = 0;
+ c->memchunk.length = pa_memblock_get_length(c->memchunk.memblock);
+ }
+
+ pa_assert(c->memchunk.length >= (size_t) size);
+
+ chunk->memblock = pa_memblock_ref(c->memchunk.memblock);
+ chunk->index = c->memchunk.index;
- iov.iov_base = pa_memblock_acquire(chunk->memblock);
+ iov.iov_base = (uint8_t*) pa_memblock_acquire(chunk->memblock) + chunk->index;
iov.iov_len = size;
m.msg_name = NULL;
@@ -191,11 +209,11 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) {
r = recvmsg(c->fd, &m, 0);
pa_memblock_release(chunk->memblock);
-
+
if (r != size) {
if (r < 0 && errno != EAGAIN && errno != EINTR)
pa_log_warn("recvmsg() failed: %s", r < 0 ? pa_cstrerror(errno) : "size mismatch");
-
+
goto fail;
}
@@ -236,14 +254,22 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) {
goto fail;
}
- chunk->index = 12 + cc*4;
- chunk->length = size - chunk->index;
+ chunk->index += 12 + cc*4;
+ chunk->length = size - 12 + cc*4;
if (chunk->length % c->frame_size != 0) {
pa_log_warn("Bad RTP packet size.");
goto fail;
}
+ c->memchunk.index = chunk->index + chunk->length;
+ c->memchunk.length = pa_memblock_get_length(c->memchunk.memblock) - c->memchunk.index;
+
+ if (c->memchunk.length <= 0) {
+ pa_memblock_unref(c->memchunk.memblock);
+ pa_memchunk_reset(&c->memchunk);
+ }
+
return 0;
fail:
@@ -329,7 +355,10 @@ int pa_rtp_sample_spec_valid(const pa_sample_spec *ss) {
void pa_rtp_context_destroy(pa_rtp_context *c) {
pa_assert(c);
- pa_close(c->fd);
+ pa_assert_se(pa_close(c->fd) == 0);
+
+ if (c->memchunk.memblock)
+ pa_memblock_unref(c->memchunk.memblock);
}
const char* pa_rtp_format_to_string(pa_sample_format_t f) {
@@ -361,4 +390,3 @@ pa_sample_format_t pa_rtp_string_to_format(const char *s) {
else
return PA_SAMPLE_INVALID;
}
-