int stream_debug(struct re_printf *pf, const struct stream *s) { struct sa rrtcp; int err; if (!s) return 0; err = re_hprintf(pf, " %s dir=%s pt_enc=%d\n", sdp_media_name(s->sdp), sdp_dir_name(sdp_media_dir(s->sdp)), s->pt_enc); sdp_media_raddr_rtcp(s->sdp, &rrtcp); err |= re_hprintf(pf, " remote: %J/%J\n", sdp_media_raddr(s->sdp), &rrtcp); err |= rtp_debug(pf, s->rtp); err |= jbuf_debug(pf, s->jbuf); return err; }
/* TODO: should we check RTP per stream, or should we have the * check in struct call instead? */ static void check_rtp_handler(void *arg) { struct stream *strm = arg; const uint64_t now = tmr_jiffies(); int diff_ms; tmr_start(&strm->tmr_rtp, RTP_CHECK_INTERVAL, check_rtp_handler, strm); /* If no RTP was received at all, check later */ if (!strm->ts_last) return; /* We are in sendrecv mode, check when the last RTP packet * was received. */ if (sdp_media_dir(strm->sdp) == SDP_SENDRECV) { diff_ms = (int)(now - strm->ts_last); debug("stream: last \"%s\" RTP packet: %d milliseconds\n", sdp_media_name(strm->sdp), diff_ms); if (diff_ms > (int)strm->rtp_timeout_ms) { info("stream: no %s RTP packets received for" " %d milliseconds\n", sdp_media_name(strm->sdp), diff_ms); stream_close(strm, ETIMEDOUT); } } else { re_printf("check_rtp: not checking (dir=%s)\n", sdp_dir_name(sdp_media_dir(strm->sdp))); } }
static int media_encode(const struct sdp_media *m, struct mbuf *mb, bool offer) { enum sdp_bandwidth i; int err, supc = 0; bool disabled; struct le *le; uint16_t port; for (le=m->lfmtl.head; le; le=le->next) { const struct sdp_format *fmt = le->data; if (fmt->sup) ++supc; } if (m->disabled || supc == 0 || (!offer && !sa_port(&m->raddr))) { disabled = true; port = 0; } else { disabled = false; port = sa_port(&m->laddr); } err = mbuf_printf(mb, "m=%s %u %s", m->name, port, m->proto); if (disabled) { err |= mbuf_write_str(mb, " 0\r\n"); return err; } for (le=m->lfmtl.head; le; le=le->next) { const struct sdp_format *fmt = le->data; if (!fmt->sup) continue; err |= mbuf_printf(mb, " %s", fmt->id); } err |= mbuf_write_str(mb, "\r\n"); if (sa_isset(&m->laddr, SA_ADDR)) { const int ipver = sa_af(&m->laddr) == AF_INET ? 4 : 6; err |= mbuf_printf(mb, "c=IN IP%d %j\r\n", ipver, &m->laddr); } for (i=SDP_BANDWIDTH_MIN; i<SDP_BANDWIDTH_MAX; i++) { if (m->lbwv[i] < 0) continue; err |= mbuf_printf(mb, "b=%s:%i\r\n", sdp_bandwidth_name(i), m->lbwv[i]); } for (le=m->lfmtl.head; le; le=le->next) { const struct sdp_format *fmt = le->data; if (!fmt->sup || !str_len(fmt->name)) continue; err |= mbuf_printf(mb, "a=rtpmap:%s %s/%u", fmt->id, fmt->name, fmt->srate); if (fmt->ch > 1) err |= mbuf_printf(mb, "/%u", fmt->ch); err |= mbuf_printf(mb, "\r\n"); if (str_len(fmt->params)) err |= mbuf_printf(mb, "a=fmtp:%s %s\r\n", fmt->id, fmt->params); } if (sa_isset(&m->laddr_rtcp, SA_ALL)) err |= mbuf_printf(mb, "a=rtcp:%u IN IP%d %j\r\n", sa_port(&m->laddr_rtcp), (AF_INET == sa_af(&m->laddr_rtcp)) ? 4 : 6, &m->laddr_rtcp); else if (sa_isset(&m->laddr_rtcp, SA_PORT)) err |= mbuf_printf(mb, "a=rtcp:%u\r\n", sa_port(&m->laddr_rtcp)); err |= mbuf_printf(mb, "a=%s\r\n", sdp_dir_name(offer ? m->ldir : m->ldir & m->rdir)); for (le = m->lattrl.head; le; le = le->next) err |= mbuf_printf(mb, "%H", sdp_attr_print, le->data); return err; }