]>
code.delx.au - pulseaudio/blob - src/modules/rtp/rtp.c
4 This file is part of polypaudio.
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
31 #include <arpa/inet.h>
34 #include <polypcore/log.h>
38 pa_rtp_context
* pa_rtp_context_init_send(pa_rtp_context
*c
, int fd
, uint32_t ssrc
, uint8_t payload
, size_t frame_size
) {
43 c
->sequence
= (uint16_t) (rand()*rand());
45 c
->ssrc
= ssrc
? ssrc
: (uint32_t) (rand()*rand());
46 c
->payload
= payload
& 127;
47 c
->frame_size
= frame_size
;
54 int pa_rtp_send(pa_rtp_context
*c
, size_t size
, pa_memblockq
*q
) {
55 struct iovec iov
[MAX_IOVECS
];
56 pa_memblock
* mb
[MAX_IOVECS
];
58 size_t n
= 0, skip
= 0;
64 if (pa_memblockq_get_length(q
) < size
)
71 if ((r
= pa_memblockq_peek(q
, &chunk
)) >= 0) {
73 size_t k
= n
+ chunk
.length
> size
? size
- n
: chunk
.length
;
76 iov
[iov_idx
].iov_base
= (uint8_t*) chunk
.memblock
->data
+ chunk
.index
;
77 iov
[iov_idx
].iov_len
= k
;
78 mb
[iov_idx
] = chunk
.memblock
;
85 pa_memblockq_drop(q
, &chunk
, k
);
88 if (r
< 0 || !chunk
.memblock
|| n
>= size
|| iov_idx
>= MAX_IOVECS
) {
94 header
[0] = htonl(((uint32_t) 2 << 30) | ((uint32_t) c
->payload
<< 16) | ((uint32_t) c
->sequence
));
95 header
[1] = htonl(c
->timestamp
);
96 header
[2] = htonl(c
->ssrc
);
98 iov
[0].iov_base
= header
;
99 iov
[0].iov_len
= sizeof(header
);
104 m
.msg_iovlen
= iov_idx
;
105 m
.msg_control
= NULL
;
106 m
.msg_controllen
= 0;
109 k
= sendmsg(c
->fd
, &m
, MSG_DONTWAIT
);
111 for (i
= 1; i
< iov_idx
; i
++)
112 pa_memblock_unref(mb
[i
]);
118 c
->timestamp
+= skip
/c
->frame_size
;
121 if (errno
!= EAGAIN
) /* If the queue is full, just ignore it */
122 pa_log(__FILE__
": sendmsg() failed: %s", strerror(errno
));
126 if (r
< 0 || pa_memblockq_get_length(q
) < size
)
138 pa_rtp_context
* pa_rtp_context_init_recv(pa_rtp_context
*c
, int fd
) {
145 int pa_rtp_recv(pa_rtp_context
*c
, pa_memchunk
*chunk
) {
152 uint8_t pa_rtp_payload_type(const pa_sample_spec
*ss
) {
155 if (ss
->format
== PA_SAMPLE_ULAW
&& ss
->rate
== 8000 && ss
->channels
== 1)
157 if (ss
->format
== PA_SAMPLE_ALAW
&& ss
->rate
== 8000 && ss
->channels
== 1)
159 if (ss
->format
== PA_SAMPLE_S16BE
&& ss
->rate
== 44100 && ss
->channels
== 2)
161 if (ss
->format
== PA_SAMPLE_S16BE
&& ss
->rate
== 44100 && ss
->channels
== 1)
167 pa_sample_spec
*pa_rtp_sample_spec_fixup(pa_sample_spec
* ss
) {
170 if (!pa_rtp_sample_spec_valid(ss
))
171 ss
->format
= PA_SAMPLE_S16BE
;
173 assert(pa_rtp_sample_spec_valid(ss
));
177 int pa_rtp_sample_spec_valid(const pa_sample_spec
*ss
) {
180 if (!pa_sample_spec_valid(ss
))
184 ss
->format
== PA_SAMPLE_U8
||
185 ss
->format
== PA_SAMPLE_ALAW
||
186 ss
->format
== PA_SAMPLE_ULAW
||
187 ss
->format
== PA_SAMPLE_S16BE
;
190 void pa_rtp_context_destroy(pa_rtp_context
*c
) {