X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=ortp_send.c;h=deb7d94763dfe53b6a58963bd0360175eda171de;hp=fbd4077e828e7e945fc8c0c4497e56f0dcacffa8;hb=d42af6d28fa44d085b048cb064e20c79189b88b2;hpb=044dd6b25189b24d862d50b965fc2feaf93b01d7 diff --git a/ortp_send.c b/ortp_send.c index fbd4077e..deb7d947 100644 --- a/ortp_send.c +++ b/ortp_send.c @@ -32,8 +32,6 @@ #define TARGET_ADDR(oc) inet_ntoa((oc)->addr) /** \endcond */ -extern struct gengetopt_args_info conf; - /** describes one entry in the list of targets for the ortp sender */ struct ortp_target { /** address info */ @@ -54,7 +52,6 @@ struct ortp_target { RtpSession *session; }; -static int numtargets; static struct list_head targets; static struct sender *self; @@ -66,7 +63,6 @@ static void ortp_delete_target(struct ortp_target *ot, const char *msg) rtp_session_destroy(ot->session); ot->session = NULL; } - numtargets--; list_del(&ot->node); free(ot); } @@ -77,14 +73,12 @@ static void ortp_send_buf(char *buf, int len, long unsigned chunks_sent) int ret; list_for_each_entry_safe(ot, tmp, &targets, node) { - struct timeval now; int ts; - gettimeofday(&now, NULL); if (!ot->session) continue; WRITE_CHUNK_TS(buf, ot->chunk_ts); ts = ot->chunk_ts * chunks_sent; - ret = rtp_session_send_with_ts(ot->session, buf, len, ts); + ret = rtp_session_send_with_ts(ot->session, (unsigned char *)buf, len, ts); ot->last_ts = ts; if (ret < 0) ortp_delete_target(ot, "send error"); @@ -93,6 +87,20 @@ static void ortp_send_buf(char *buf, int len, long unsigned chunks_sent) } } +static int set_multicast(RtpSession *s) +{ + unsigned char loop = 1; + int ret; + + ret = setsockopt(s->rtp.socket, + IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)); + if (ret < 0) { + PARA_ERROR_LOG("IP_MULTICAST_LOOP error %d\n", ret); + + } + return 1; +} + static void ortp_init_session(struct ortp_target *ot) { RtpSession *s; @@ -103,55 +111,72 @@ static void ortp_init_session(struct ortp_target *ot) if (!ot->session) return; s = ot->session; -// rtp_session_set_jitter_compensation(ot->session, 100); + if (conf.ortp_jitter_compensation_arg) { + rtp_session_enable_adaptive_jitter_compensation(ot->session, TRUE); + rtp_session_set_jitter_compensation(ot->session, + conf.ortp_jitter_compensation_arg); + } /* always successful */ rtp_session_set_send_payload_type(s, PAYLOAD_AUDIO_CONTINUOUS); ret = rtp_session_set_remote_addr(s, TARGET_ADDR(ot), ot->port); if (ret < 0) { rtp_session_destroy(ot->session); ot->session = NULL; + return; } + set_multicast(s); } /* called by afs */ static void ortp_shutdown_targets(void) { - char buf[2]; + unsigned char buf[ORTP_AUDIO_HEADER_LEN]; struct ortp_target *ot, *tmp; - buf[0] = ORTP_EOF; + WRITE_PACKET_TYPE(buf, ORTP_EOF); list_for_each_entry_safe(ot, tmp, &targets, node) { if (!ot->session || !ot->streaming) continue; - PARA_INFO_LOG("sending eof to ortp target %s:%d, ts = %d\n", TARGET_ADDR(ot), ot->port, - ot->last_ts); - rtp_session_send_with_ts(ot->session, buf, 1, ot->last_ts); + PARA_INFO_LOG("sending eof to ortp target %s:%d, ts = %d\n", + TARGET_ADDR(ot), ot->port, ot->last_ts); + rtp_session_send_with_ts(ot->session, buf, + ORTP_AUDIO_HEADER_LEN, ot->last_ts); ot->streaming = 0; ot->chunk_ts = 0; rtp_session_reset(ot->session); } } -static int need_extra_header(struct audio_format *af, long unsigned chunks_sent) +static int need_extra_header(long unsigned current_chunk) { - /* FIXME: No need to compute this on every run */ - int mod = conf.ortp_header_interval_arg / (tv2ms(&af->chunk_tv) + 1); - if (mod && (chunks_sent % mod)) + static struct timeval last_header; + struct timeval now, diff; + + if (!current_chunk) + return 0; + gettimeofday(&now, NULL); + tv_diff(&now, &last_header, &diff); + if (tv2ms(&diff) < conf.ortp_header_interval_arg) return 0; + last_header = now; return 1; } -static void ortp_send(struct audio_format *af, long unsigned current_chunk, - long unsigned chunks_sent, const char *buf, size_t len) +static void ortp_send(long unsigned current_chunk, long unsigned chunks_sent, + const char *buf, size_t len) { struct ortp_target *ot, *tmp; size_t sendbuf_len; int header_len = 0; - int packet_type = ORTP_DATA, stream_type = af && af->get_header_info; /* header stream? */ + int packet_type = ORTP_DATA; char *sendbuf, *header_buf = NULL; + struct timeval *chunk_tv; if (self->status != SENDER_ON) return; + chunk_tv = afs_chunk_time(); + if (!chunk_tv) + return; list_for_each_entry_safe(ot, tmp, &targets, node) { if (!ot->session) { ortp_init_session(ot); @@ -159,17 +184,17 @@ static void ortp_send(struct audio_format *af, long unsigned current_chunk, continue; } if (!ot->chunk_ts) - ot->chunk_ts = rtp_session_time_to_ts(ot->session, tv2ms(&af->chunk_tv)); -// PARA_DEBUG_LOG("len: %d, af: %p, ts: %d\n", len, af, ot->chunk_ts); + ot->chunk_ts = rtp_session_time_to_ts(ot->session, + tv2ms(chunk_tv)); +// PARA_DEBUG_LOG("len: %d, ts: %lu, ts: %d\n", +// len, ot->chunk_ts * chunks_sent, ot->chunk_ts); ot->streaming = 1; } if (list_empty(&targets)) return; - if (stream_type) { - header_buf = af->get_header_info(&header_len); - if (!need_extra_header(af, chunks_sent)) - header_len = 0; - } + header_buf = afs_get_header(&header_len); + if (!need_extra_header(current_chunk)) + header_len = 0; sendbuf_len = ORTP_AUDIO_HEADER_LEN + header_len + len; sendbuf = para_malloc(sendbuf_len); if (!current_chunk) @@ -177,8 +202,8 @@ static void ortp_send(struct audio_format *af, long unsigned current_chunk, else if (header_len) packet_type = ORTP_HEADER; WRITE_PACKET_TYPE(sendbuf, packet_type); - WRITE_CHUNK_TIME(sendbuf, af->chunk_tv.tv_usec); - WRITE_STREAM_TYPE(sendbuf, stream_type); + WRITE_CHUNK_TIME(sendbuf, chunk_tv->tv_usec); + WRITE_STREAM_TYPE(sendbuf, header_buf? 1 : 0); WRITE_HEADER_LEN(sendbuf, header_len); if (header_len) memcpy(sendbuf + ORTP_AUDIO_HEADER_LEN, header_buf, @@ -188,14 +213,14 @@ static void ortp_send(struct audio_format *af, long unsigned current_chunk, free(sendbuf); } -static int ortp_com_on(struct sender_command_data *scd) +static int ortp_com_on(__a_unused struct sender_command_data *scd) { self->status = SENDER_ON; return 1; } -static int ortp_com_off(struct sender_command_data *scd) +static int ortp_com_off(__a_unused struct sender_command_data *scd) { ortp_shutdown_targets(); self->status = SENDER_OFF; @@ -286,8 +311,8 @@ success: } } -static void ortp_pre_select(struct audio_format *af, int *max_fileno, - fd_set *rfds, fd_set *wfds) +static void ortp_pre_select(__a_unused int *max_fileno, __a_unused fd_set *rfds, + __a_unused fd_set *wfds) { return; }