diff --git a/iptv_output.c b/iptv_output.c index 7a835893..be8a450f 100644 --- a/iptv_output.c +++ b/iptv_output.c @@ -35,6 +35,7 @@ #include "channels.h" #include "subscriptions.h" #include "tsmux.h" +#include "rtp.h" #define MULTICAST_PKT_SIZ (188 * 7) @@ -48,6 +49,12 @@ typedef struct output_multicast { int om_inter_drop_rate; int om_inter_drop_cnt; + int om_seq; + enum { + OM_RAWUDP, + OM_RTP, + } om_encapsulation; + } output_multicast_t; /** @@ -59,14 +66,26 @@ iptv_output_ts(void *opaque, th_subscription_t *s, { output_multicast_t *om = opaque; + om->om_seq++; + if(om->om_inter_drop_rate && ++om->om_inter_drop_cnt == om->om_inter_drop_rate) { om->om_inter_drop_cnt = 0; return; } - sendto(om->om_fd, pkt, blocks * 188, 0, - (struct sockaddr *)&om->om_dst, sizeof(struct sockaddr_in)); + switch(om->om_encapsulation) { + case OM_RTP: + rtp_sendmsg(pkt, blocks, pcr, om->om_fd, + (struct sockaddr *)&om->om_dst, sizeof(struct sockaddr_in), + om->om_seq); + break; + + case OM_RAWUDP: + sendto(om->om_fd, pkt, blocks * 188, 0, + (struct sockaddr *)&om->om_dst, sizeof(struct sockaddr_in)); + break; + } } @@ -156,6 +175,11 @@ output_multicast_load(struct config_head *head) if((s = config_get_str_sub(head, "inter-drop-rate", NULL)) != NULL) om->om_inter_drop_rate = atoi(s); + if((s = config_get_str_sub(head, "encapsulation", NULL)) != NULL) { + if(!strcasecmp(s, "rtp")) + om->om_encapsulation = OM_RTP; + } + setsockopt(om->om_fd, SOL_IP, IP_MULTICAST_TTL, &ttl, sizeof(int)); snprintf(title, sizeof(title), "%s:%d", inet_ntoa(om->om_dst.sin_addr), diff --git a/rtp.c b/rtp.c index 00e8a819..45a952cb 100644 --- a/rtp.c +++ b/rtp.c @@ -37,39 +37,22 @@ #include #include -//static int64_t lts; -//static int pkts; - -void -rtp_output_ts(void *opaque, struct th_subscription *s, - uint8_t *pkt, int blocks, int64_t pcr) +int +rtp_sendmsg(uint8_t *pkt, int blocks, int64_t pcr, + int fd, struct sockaddr *dst, socklen_t dstlen, + uint16_t seq) { - th_rtp_streamer_t *trs = opaque; struct msghdr msg; struct iovec vec[2]; - int r; - AVRational mpeg_tc = {1, 90000}; char hdr[12]; -#if 0 - int64_t ts; - ts = getclock_hires(); - pkts++; - - if(ts - lts > 100000) { - printf("%d packet per sec\n", pkts * 10); - pkts = 0; - lts = ts; - } -#endif - pcr = av_rescale_q(pcr, AV_TIME_BASE_Q, mpeg_tc); hdr[0] = 0x80; hdr[1] = 33; /* M2TS */ - hdr[2] = trs->trs_seq >> 8; - hdr[3] = trs->trs_seq; + hdr[2] = seq >> 8; + hdr[3] = seq; hdr[4] = pcr >> 24; hdr[5] = pcr >> 16; @@ -88,14 +71,25 @@ rtp_output_ts(void *opaque, struct th_subscription *s, vec[1].iov_len = blocks * 188; memset(&msg, 0, sizeof(msg)); - msg.msg_name = &trs->trs_dest; - msg.msg_namelen = sizeof(struct sockaddr_in); + msg.msg_name = dst; + msg.msg_namelen = dstlen; msg.msg_iov = vec; msg.msg_iovlen = 2; - r = sendmsg(trs->trs_fd, &msg, 0); - if(r < 0) - perror("sendmsg"); + return sendmsg(fd, &msg, 0); +} + + + +void +rtp_output_ts(void *opaque, struct th_subscription *s, + uint8_t *pkt, int blocks, int64_t pcr) +{ + th_rtp_streamer_t *trs = opaque; + + rtp_sendmsg(pkt, blocks, pcr, trs->trs_fd, + (struct sockaddr *)&trs->trs_dest, sizeof(struct sockaddr_in), + trs->trs_seq); trs->trs_seq++; } diff --git a/rtp.h b/rtp.h index 7279a601..ef49b1f7 100644 --- a/rtp.h +++ b/rtp.h @@ -32,4 +32,8 @@ void rtp_streamer_init(th_rtp_streamer_t *trs, int fd, void rtp_output_ts(void *opaque, struct th_subscription *s, uint8_t *pkt, int blocks, int64_t pcr); +int rtp_sendmsg(uint8_t *pkt, int blocks, int64_t pcr, + int fd, struct sockaddr *dst, socklen_t dstlen, + uint16_t seq); + #endif /* RTP_H_ */