static int add_telev_codec(struct audio *a) { struct sdp_media *m = stream_sdpmedia(audio_strm(a)); struct sdp_format *sf; int err; /* Use payload-type 101 if available, for CiscoGW interop */ err = sdp_format_add(&sf, m, false, (!sdp_media_lformat(m, 101)) ? "101" : NULL, telev_rtpfmt, TELEV_SRATE, 1, NULL, NULL, NULL, false, "0-15"); if (err) return err; a->rx.pt_tel = sf->pt; return err; }
static int pt_handler(struct audio *a, uint8_t pt_old, uint8_t pt_new, void *user_data) { const struct sdp_format *lc; lc = sdp_media_lformat(stream_sdpmedia(a->strm), pt_new); if (!lc) return ENOENT; if (pt_old != (uint8_t)-1) { re_printf("Audio decoder changed payload" " %u -> %u\n", pt_old, pt_new); } a->rx.pt = pt_new; return audio_decoder_set(a, lc->data, lc->pt, lc->params, user_data); }
/* Handle incoming stream data from the network */ static void stream_recv_handler(const struct rtp_header *hdr, struct mbuf *mb, void *arg) { struct audio *a = arg; struct aurx *rx = &a->rx; int err; if (!mb) goto out; /* Telephone event? */ if (hdr->pt != rx->pt) { const struct sdp_format *fmt; fmt = sdp_media_lformat(stream_sdpmedia(a->strm), hdr->pt); if (fmt && !str_casecmp(fmt->name, "telephone-event")) { handle_telev(a, mb); return; } } /* Comfort Noise (CN) as of RFC 3389 */ if (PT_CN == hdr->pt) return; /* Audio payload-type changed? */ /* XXX: this logic should be moved to stream.c */ if (hdr->pt != rx->pt) { err = pt_handler(a, rx->pt, hdr->pt); if (err) return; } out: (void)aurx_stream_decode(&a->rx, mb); }