#include <errno.h>
#include <string.h>
#include <unistd.h>
+#include <math.h>
#include <pulse/rtclock.h>
#include <pulse/timeval.h>
#include <pulsecore/namereg.h>
#include <pulsecore/sample-util.h>
#include <pulsecore/macro.h>
-#include <pulsecore/atomic.h>
-#include <pulsecore/atomic.h>
#include <pulsecore/socket-util.h>
+#include <pulsecore/atomic.h>
#include <pulsecore/once.h>
#include <pulsecore/poll.h>
#include <pulsecore/arpa-inet.h>
PA_MODULE_AUTHOR("Lennart Poettering");
PA_MODULE_DESCRIPTION("Receive data from a network via RTP/SAP/SDP");
PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_LOAD_ONCE(FALSE);
+PA_MODULE_LOAD_ONCE(false);
PA_MODULE_USAGE(
"sink=<name of the sink> "
"sap_address=<multicast address to listen on> "
pa_sink_input *sink_input;
pa_memblockq *memblockq;
- pa_bool_t first_packet;
+ bool first_packet;
uint32_t ssrc;
uint32_t offset;
pa_sink_input_assert_ref(i);
pa_assert_se(s = i->userdata);
+ pa_hashmap_remove(s->userdata->by_origin, s->sdp_info.origin);
session_free(s);
}
/* Called from IO context */
-static void sink_input_suspend_within_thread(pa_sink_input* i, pa_bool_t b) {
+static void sink_input_suspend_within_thread(pa_sink_input* i, bool b) {
struct session *s;
pa_sink_input_assert_ref(i);
pa_assert_se(s = i->userdata);
if (b)
pa_memblockq_flush_read(s->memblockq);
else
- s->first_packet = FALSE;
+ s->first_packet = false;
}
/* Called from I/O thread context */
}
if (!s->first_packet) {
- s->first_packet = TRUE;
+ s->first_packet = true;
s->ssrc = s->rtp_context.ssrc;
s->offset = s->rtp_context.timestamp;
else
delta = j;
- pa_memblockq_seek(s->memblockq, delta * (int64_t) s->rtp_context.frame_size, PA_SEEK_RELATIVE, TRUE);
+ pa_memblockq_seek(s->memblockq, delta * (int64_t) s->rtp_context.frame_size, PA_SEEK_RELATIVE, true);
if (now.tv_sec == 0) {
PA_ONCE_BEGIN {
if (pa_memblockq_push(s->memblockq, &chunk) < 0) {
pa_log_warn("Queue overrun");
- pa_memblockq_seek(s->memblockq, (int64_t) chunk.length, PA_SEEK_RELATIVE, TRUE);
+ pa_memblockq_seek(s->memblockq, (int64_t) chunk.length, PA_SEEK_RELATIVE, true);
}
/* pa_log("blocks in q: %u", pa_memblockq_get_nblocks(s->memblockq)); */
pa_log_debug("Requesting rewind due to end of underrun");
pa_sink_input_request_rewind(s->sink_input,
(size_t) (s->sink_input->thread_info.underrun_for == (uint64_t) -1 ? 0 : s->sink_input->thread_info.underrun_for),
- FALSE, TRUE, FALSE);
+ false, true, false);
}
return 1;
pa_make_udp_socket_low_delay(fd);
+#ifdef SO_TIMESTAMP
one = 1;
if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)) < 0) {
pa_log("SO_TIMESTAMP failed: %s", pa_cstrerror(errno));
goto fail;
}
+#else
+ pa_log("SO_TIMESTAMP unsupported on this platform");
+ goto fail;
+#endif
one = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
mr4.imr_multiaddr = ((const struct sockaddr_in*) sa)->sin_addr;
r = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mr4, sizeof(mr4));
#ifdef HAVE_IPV6
- } else {
+ } else if (af == AF_INET6) {
struct ipv6_mreq mr6;
memset(&mr6, 0, sizeof(mr6));
mr6.ipv6mr_multiaddr = ((const struct sockaddr_in6*) sa)->sin6_addr;
r = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mr6, sizeof(mr6));
#endif
- }
+ } else
+ pa_assert_not_reached();
if (r < 0) {
pa_log_info("Joining mcast group failed: %s", pa_cstrerror(errno));
s = pa_xnew0(struct session, 1);
s->userdata = u;
- s->first_packet = FALSE;
+ s->first_packet = false;
s->sdp_info = *sdp_info;
s->rtpoll_item = NULL;
s->intended_latency = LATENCY_USEC;
goto fail;
pa_sink_input_new_data_init(&data);
- data.sink = sink;
+ pa_sink_input_new_data_set_sink(&data, sink, false);
data.driver = __FILE__;
pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "stream");
pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME,
s->intended_latency = s->sink_latency*2;
s->memblockq = pa_memblockq_new(
+ "module-rtp-recv memblockq",
0,
MEMBLOCKQ_MAXLENGTH,
MEMBLOCKQ_MAXLENGTH,
- pa_frame_size(&s->sink_input->sample_spec),
+ &s->sink_input->sample_spec,
pa_usec_to_bytes(s->intended_latency - s->sink_latency, &s->sink_input->sample_spec),
0,
0,
PA_LLIST_REMOVE(struct session, s->userdata->sessions, s);
pa_assert(s->userdata->n_sessions >= 1);
s->userdata->n_sessions--;
- pa_hashmap_remove(s->userdata->by_origin, s->sdp_info.origin);
pa_memblockq_free(s->memblockq);
pa_sdp_info_destroy(&s->sdp_info);
static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t flags, void *userdata) {
struct userdata *u = userdata;
- pa_bool_t goodbye = FALSE;
+ bool goodbye = false;
pa_sdp_info info;
struct session *s;
if (goodbye) {
- if ((s = pa_hashmap_get(u->by_origin, info.origin)))
+ if ((s = pa_hashmap_remove(u->by_origin, info.origin)))
session_free(s);
pa_sdp_info_destroy(&info);
k = pa_atomic_load(&s->timestamp);
- if (k + DEATH_TIMEOUT < now.tv_sec)
+ if (k + DEATH_TIMEOUT < now.tv_sec) {
+ pa_hashmap_remove(u->by_origin, s->sdp_info.origin);
session_free(s);
+ }
}
/* Restart timer */
PA_LLIST_HEAD_INIT(struct session, u->sessions);
u->n_sessions = 0;
- u->by_origin = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+ u->by_origin = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) session_free);
u->check_death_event = pa_core_rttime_new(m->core, pa_rtclock_now() + DEATH_TIMEOUT * PA_USEC_PER_SEC, check_death_event_cb, u);
void pa__done(pa_module*m) {
struct userdata *u;
- struct session *s;
pa_assert(m);
pa_sap_context_destroy(&u->sap_context);
- if (u->by_origin) {
- while ((s = pa_hashmap_first(u->by_origin)))
- session_free(s);
-
- pa_hashmap_free(u->by_origin, NULL, NULL);
- }
+ if (u->by_origin)
+ pa_hashmap_free(u->by_origin);
pa_xfree(u->sink_name);
pa_xfree(u);