static int update_media(struct call *call) { const struct sdp_format *sc; struct le *le; int err = 0; /* media attributes */ audio_sdp_attr_decode(call->audio); #ifdef USE_VIDEO if (call->video) video_sdp_attr_decode(call->video); #endif /* Update each stream */ FOREACH_STREAM { stream_update(le->data); } if (call->acc->mnat && call->acc->mnat->updateh && call->mnats) err = call->acc->mnat->updateh(call->mnats); sc = sdp_media_rformat(stream_sdpmedia(audio_strm(call->audio)), NULL); if (sc) { struct aucodec *ac = sc->data; if (ac) { err = audio_decoder_set(call->audio, sc->data, sc->pt, sc->params); err |= audio_encoder_set(call->audio, sc->data, sc->pt, sc->params); } else { info("no common audio-codecs..\n"); } } else { info("audio stream is disabled..\n"); } #ifdef USE_VIDEO sc = sdp_media_rformat(stream_sdpmedia(video_strm(call->video)), NULL); if (sc) { err = video_encoder_set(call->video, sc->data, sc->pt, sc->params); if (err) { warning("call: video stream error: %m\n", err); } } else if (call->video) { info("video stream is disabled..\n"); } #endif return err; }
void stream_update(struct stream *s, const char *cname) { const struct sdp_format *fmt; int err = 0; if (!s) return; fmt = sdp_media_rformat(s->sdp, NULL); s->pt_enc = fmt ? fmt->pt : -1; if (stream_has_media(s)) stream_remote_set(s, cname); if (s->menc && s->menc->mediah) { err = s->menc->mediah(&s->mes, s->mencs, IPPROTO_UDP, rtp_sock(s->rtp), s->rtcp ? rtcp_sock(s->rtp) : NULL, s->sdp); if (err) { DEBUG_WARNING("mediaenc update: %m\n", err); } } }
void stream_update(struct stream *s) { const struct sdp_format *fmt; int err = 0; if (!s) return; fmt = sdp_media_rformat(s->sdp, NULL); s->pt_enc = fmt ? fmt->pt : -1; if (sdp_media_has_media(s->sdp)) stream_remote_set(s); if (s->menc && s->menc->mediah) { err = s->menc->mediah(&s->mes, s->mencs, s->rtp, IPPROTO_UDP, rtp_sock(s->rtp), s->rtcp ? rtcp_sock(s->rtp) : NULL, s->sdp); if (err) { warning("stream: mediaenc update: %m\n", err); } } }
static void check_telev(struct audio *a, struct autx *tx) { const struct sdp_format *fmt; bool marker = false; int err; tx->mb->pos = tx->mb->end = STREAM_PRESZ; err = telev_poll(a->telev, &marker, tx->mb); if (err) return; if (marker) tx->ts_tel = tx->ts; fmt = sdp_media_rformat(stream_sdpmedia(audio_strm(a)), telev_rtpfmt); if (!fmt) return; tx->mb->pos = STREAM_PRESZ; err = stream_send(a->strm, marker, fmt->pt, tx->ts_tel, tx->mb); if (err) { DEBUG_WARNING("telev: stream_send %m\n", err); } }
/** * Check if an SDP media object has valid media. It is considered * valid if it has one or more codecs, and the port number is set. * * @param m SDP Media object * * @return True if it has media, false if not */ bool sdp_media_has_media(const struct sdp_media *m) { bool has; has = sdp_media_rformat(m, NULL) != NULL; if (has) return sdp_media_rport(m) != 0; return false; }
static bool have_common_audio_codecs(const struct call *call) { const struct sdp_format *sc; struct aucodec *ac; sc = sdp_media_rformat(stream_sdpmedia(audio_strm(call->audio)), NULL); if (!sc) return false; ac = sc->data; /* note: this will exclude telephone-event */ return ac != NULL; }
bool stream_has_media(const struct stream *s) { bool has; if (!s) return false; has = sdp_media_rformat(s->sdp, NULL) != NULL; if (has) return sdp_media_rport(s->sdp) != 0; return false; }
static bool have_common_audio_codecs(const struct call *call) { const struct sdp_format *sc; struct aucodec *ac; sc = sdp_media_rformat(stream_sdpmedia(audio_strm(call->audio)), NULL); if (!sc) return false; ac = sc->data; return ac != NULL; }
/** * Move the first codec to the bottom of the remote codec list * * @param m SDP Media object * * @return SDP format for the first codec */ const struct sdp_format *sdp_media_format_cycle(struct sdp_media *m) { struct sdp_format *sf; struct list *lst; again: sf = (struct sdp_format *)sdp_media_rformat(m, NULL); if (!sf) return NULL; lst = sf->le.list; /* move top-most codec to end of list */ list_unlink(&sf->le); list_append(lst, &sf->le, sf); sf = (struct sdp_format *)sdp_media_rformat(m, NULL); if (!str_casecmp(sf->name, telev_rtpfmt)) goto again; return sf; }
/* print SDP status */ static void update_media(void) { const struct sdp_format *fmt; re_printf("SDP peer address: %J\n", sdp_media_raddr(sdp_media)); fmt = sdp_media_rformat(sdp_media, NULL); if (!fmt) { re_printf("no common media format found\n"); return; } re_printf("SDP media format: %s/%u/%u (payload type: %u)\n", fmt->name, fmt->srate, fmt->ch, fmt->pt); }
static void stream_start_keepalive(struct stream *s) { const char *rtpkeep; if (!s) return; rtpkeep = call_account(s->call)->rtpkeep; s->rtpkeep = mem_deref(s->rtpkeep); if (rtpkeep && sdp_media_rformat(s->sdp, NULL)) { int err; err = rtpkeep_alloc(&s->rtpkeep, rtpkeep, IPPROTO_UDP, s->rtp, s->sdp); if (err) { warning("stream: rtpkeep_alloc failed: %m\n", err); } } }
void stream_start_keepalive(struct stream *s) { const char *rtpkeep; if (!s) return; rtpkeep = ua_param(call_get_ua(s->call), "rtpkeep"); s->rtpkeep = mem_deref(s->rtpkeep); if (rtpkeep && sdp_media_rformat(s->sdp, NULL)) { int err; err = rtpkeep_alloc(&s->rtpkeep, rtpkeep, IPPROTO_UDP, s->rtp, s->sdp); if (err) { DEBUG_WARNING("rtpkeep_alloc failed: %m\n", err); } } }
static void call_stream_start(struct call *call, bool active) { const struct sdp_format *sc; int err; /* Audio Stream */ sc = sdp_media_rformat(stream_sdpmedia(audio_strm(call->audio)), NULL); if (sc) { struct aucodec *ac = sc->data; if (ac) { err = audio_encoder_set(call->audio, sc->data, sc->pt, sc->params); err |= audio_decoder_set(call->audio, sc->data, sc->pt, sc->params); if (!err) { err = audio_start(call->audio); } if (err) { warning("call: audio stream error: %m\n", err); } } else { info("call: no common audio-codecs..\n"); } } else { info("call: audio stream is disabled..\n"); } #ifdef USE_VIDEO /* Video Stream */ sc = sdp_media_rformat(stream_sdpmedia(video_strm(call->video)), NULL); if (sc) { err = video_encoder_set(call->video, sc->data, sc->pt, sc->params); err |= video_decoder_set(call->video, sc->data, sc->pt, sc->rparams); if (!err) { err = video_start(call->video, call->peer_uri); } if (err) { warning("call: video stream error: %m\n", err); } } else if (call->video) { info("call: video stream is disabled..\n"); } if (call->bfcp) { err = bfcp_start(call->bfcp); if (err) { warning("call: could not start BFCP: %m\n", err); } } #endif if (active) { struct le *le; tmr_cancel(&call->tmr_inv); call->time_start = time(NULL); FOREACH_STREAM { stream_reset(le->data); } } }
int test_sdp_all(void) { struct sdp_session *sess = NULL; struct sdp_media *audio = NULL; struct mbuf *desc = NULL; struct sa ref; const struct sdp_format *rc = NULL, *sc; struct sa laddr; int err; (void)sa_set_str(&laddr, ref_host, 0); err = sdp_session_alloc(&sess, &laddr); if (err) goto out; err = sdp_media_add(&audio, sess, sdp_media_audio, 5004, sdp_proto_rtpavp); if (err) goto out; err = sdp_format_add(NULL, audio, false, ref_pt, ref_cname, ref_srate, 1, NULL, NULL, NULL, false, NULL); err |= sdp_format_add(NULL, audio, false, "110", cname_speex, 16000, 2, NULL, NULL, NULL, false, NULL); if (err) goto out; /* find codec - expected */ sc = sdp_media_format(audio, true, NULL, 0, "PCMU", 8000, 1); if (!sc) { DEBUG_WARNING("codec not found\n"); err = ENOENT; goto out; } sc = sdp_media_format(audio, true, NULL, 110, "Speex", 16000, 2); if (!sc) { DEBUG_WARNING("codec not found: speex\n"); err = ENOENT; goto out; } /* find codec - not expected */ sc = sdp_media_format(audio, true, NULL, -1, "Speex", 8000, 1); if (sc) { DEBUG_WARNING("unexpected codec found\n"); err = EINVAL; goto out; } err = sdp_encode(&desc, sess, true); if (err) goto out; if (!sdp_cmp(desc, ref_msg)) { DEBUG_WARNING("ref: %s\n", ref_msg); DEBUG_WARNING("sdp: %b\n", desc->buf, desc->end); err = EBADMSG; goto out; } err = sdp_decode(sess, desc, false); if (err) goto out; rc = sdp_media_rformat(audio, NULL); if (!rc) { err = ENOENT; goto out; } err = sa_set_str(&ref, ref_host, ref_port); if (err) goto out; err = EINVAL; if (!sa_cmp(sdp_media_raddr(audio), &ref, SA_ALL)) goto out; if (!rc) goto out; if (0 != strcmp(rc->id, ref_pt)) goto out; if (0 != strcmp(ref_cname, rc->name)) goto out; if (rc->srate != ref_srate) goto out; err = 0; out: mem_deref(audio); mem_deref(sess); mem_deref(desc); return err; }