diff options
Diffstat (limited to 'src/modules/rtp/rtp.c')
-rw-r--r-- | src/modules/rtp/rtp.c | 58 |
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; } - |