|
|
|
@ -1070,6 +1070,33 @@ static void __codec_rtcp_timer(struct call_media *receiver) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// returns: 0 = supp codec not present; 1 = sink has codec but receiver does not, 2 = both have codec
|
|
|
|
|
|
|
|
int __supp_codec_match(struct call_media *receiver, struct call_media *sink, int pt,
|
|
|
|
|
|
|
|
struct rtp_payload_type **sink_pt, struct rtp_payload_type **recv_pt)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (pt == -1)
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct rtp_payload_type *sink_pt_stor = NULL;
|
|
|
|
|
|
|
|
struct rtp_payload_type *recv_pt_stor = NULL;
|
|
|
|
|
|
|
|
if (!sink_pt)
|
|
|
|
|
|
|
|
sink_pt = &sink_pt_stor;
|
|
|
|
|
|
|
|
if (!recv_pt)
|
|
|
|
|
|
|
|
recv_pt = &recv_pt_stor;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// find a matching output payload type
|
|
|
|
|
|
|
|
*sink_pt = g_hash_table_lookup(sink->codecs_send, &pt);
|
|
|
|
|
|
|
|
if (!*sink_pt)
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// XXX should go by codec name/params, not payload type number
|
|
|
|
|
|
|
|
*recv_pt = g_hash_table_lookup(receiver->codecs_recv, &pt);
|
|
|
|
|
|
|
|
if (!*recv_pt)
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (rtp_payload_type_cmp(*sink_pt, *recv_pt))
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// call must be locked in W
|
|
|
|
// call must be locked in W
|
|
|
|
void codec_handlers_update(struct call_media *receiver, struct call_media *sink,
|
|
|
|
void codec_handlers_update(struct call_media *receiver, struct call_media *sink,
|
|
|
|
const struct sdp_ng_flags *flags, const struct stream_params *sp)
|
|
|
|
const struct sdp_ng_flags *flags, const struct stream_params *sp)
|
|
|
|
@ -1141,14 +1168,7 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink,
|
|
|
|
|
|
|
|
|
|
|
|
struct rtp_payload_type *dtmf_pt = NULL;
|
|
|
|
struct rtp_payload_type *dtmf_pt = NULL;
|
|
|
|
struct rtp_payload_type *reverse_dtmf_pt = NULL;
|
|
|
|
struct rtp_payload_type *reverse_dtmf_pt = NULL;
|
|
|
|
|
|
|
|
int dtmf_pt_match = __supp_codec_match(receiver, sink, dtmf_payload_type, &dtmf_pt, &reverse_dtmf_pt);
|
|
|
|
if (dtmf_payload_type != -1) {
|
|
|
|
|
|
|
|
// find a matching output DTMF payload type
|
|
|
|
|
|
|
|
dtmf_pt = g_hash_table_lookup(sink->codecs_send, &dtmf_payload_type);
|
|
|
|
|
|
|
|
reverse_dtmf_pt = g_hash_table_lookup(receiver->codecs_recv, &dtmf_payload_type);
|
|
|
|
|
|
|
|
if (reverse_dtmf_pt && dtmf_pt && rtp_payload_type_cmp(reverse_dtmf_pt, dtmf_pt))
|
|
|
|
|
|
|
|
reverse_dtmf_pt = NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// stop transcoding if we've determined that we don't need it
|
|
|
|
// stop transcoding if we've determined that we don't need it
|
|
|
|
if (MEDIA_ISSET(sink, TRANSCODE) && !sink_transcoding) {
|
|
|
|
if (MEDIA_ISSET(sink, TRANSCODE) && !sink_transcoding) {
|
|
|
|
@ -1170,7 +1190,6 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink,
|
|
|
|
|
|
|
|
|
|
|
|
// do we need to detect PCM DTMF tones?
|
|
|
|
// do we need to detect PCM DTMF tones?
|
|
|
|
int pcm_dtmf_detect = 0;
|
|
|
|
int pcm_dtmf_detect = 0;
|
|
|
|
if (reverse_dtmf_pt)
|
|
|
|
|
|
|
|
if ((MEDIA_ISSET(sink, TRANSCODE) || (flags && flags->always_transcode))
|
|
|
|
if ((MEDIA_ISSET(sink, TRANSCODE) || (flags && flags->always_transcode))
|
|
|
|
&& dtmf_payload_type != -1
|
|
|
|
&& dtmf_payload_type != -1
|
|
|
|
&& dtmf_pt && (!reverse_dtmf_pt || reverse_dtmf_pt->for_transcoding ||
|
|
|
|
&& dtmf_pt && (!reverse_dtmf_pt || reverse_dtmf_pt->for_transcoding ||
|
|
|
|
@ -1222,7 +1241,7 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink,
|
|
|
|
GQueue *dest_codecs = NULL;
|
|
|
|
GQueue *dest_codecs = NULL;
|
|
|
|
if (!flags || !flags->always_transcode) {
|
|
|
|
if (!flags || !flags->always_transcode) {
|
|
|
|
// we ignore output codec matches if we must transcode DTMF
|
|
|
|
// we ignore output codec matches if we must transcode DTMF
|
|
|
|
if (dtmf_pt && !reverse_dtmf_pt)
|
|
|
|
if (dtmf_pt_match == 1 && MEDIA_ISSET(sink, TRANSCODE))
|
|
|
|
;
|
|
|
|
;
|
|
|
|
else if (pcm_dtmf_detect)
|
|
|
|
else if (pcm_dtmf_detect)
|
|
|
|
;
|
|
|
|
;
|
|
|
|
@ -1343,7 +1362,7 @@ next:
|
|
|
|
// sink's preferred destination codec.
|
|
|
|
// sink's preferred destination codec.
|
|
|
|
if (!transcode_supplemental && !pcm_dtmf_detect)
|
|
|
|
if (!transcode_supplemental && !pcm_dtmf_detect)
|
|
|
|
__make_passthrough_ssrc(handler);
|
|
|
|
__make_passthrough_ssrc(handler);
|
|
|
|
else if (dtmf_pt && reverse_dtmf_pt)
|
|
|
|
else if (dtmf_pt_match == 2)
|
|
|
|
__make_passthrough_ssrc(handler);
|
|
|
|
__make_passthrough_ssrc(handler);
|
|
|
|
else if (!pref_dest_codec
|
|
|
|
else if (!pref_dest_codec
|
|
|
|
|| !handler->source_pt.codec_def || !pref_dest_codec->codec_def)
|
|
|
|
|| !handler->source_pt.codec_def || !pref_dest_codec->codec_def)
|
|
|
|
@ -2317,13 +2336,21 @@ static int packet_encoded_rtp(encoder_t *enc, void *u1, void *u2) {
|
|
|
|
|
|
|
|
|
|
|
|
ilog(LOG_DEBUG, "Received packet of %i bytes from packetizer", inout.len);
|
|
|
|
ilog(LOG_DEBUG, "Received packet of %i bytes from packetizer", inout.len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check special payloads
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int repeats = 0;
|
|
|
|
unsigned int repeats = 0;
|
|
|
|
|
|
|
|
int payload_type = -1;
|
|
|
|
int is_dtmf = dtmf_event_payload(&inout, (uint64_t *) &enc->avpkt.pts, enc->avpkt.duration,
|
|
|
|
int is_dtmf = dtmf_event_payload(&inout, (uint64_t *) &enc->avpkt.pts, enc->avpkt.duration,
|
|
|
|
&ch->dtmf_event, &ch->dtmf_events);
|
|
|
|
&ch->dtmf_event, &ch->dtmf_events);
|
|
|
|
if (is_dtmf == 1)
|
|
|
|
if (is_dtmf) {
|
|
|
|
ch->rtp_mark = 1; // DTMF start event
|
|
|
|
payload_type = ch->handler->dtmf_payload_type;
|
|
|
|
else if (is_dtmf == 3)
|
|
|
|
if (is_dtmf == 1)
|
|
|
|
repeats = 2; // DTMF end event
|
|
|
|
ch->rtp_mark = 1; // DTMF start event
|
|
|
|
|
|
|
|
else if (is_dtmf == 3)
|
|
|
|
|
|
|
|
repeats = 2; // DTMF end event
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ready to send
|
|
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
do {
|
|
|
|
char *send_buf = buf;
|
|
|
|
char *send_buf = buf;
|
|
|
|
@ -2335,7 +2362,7 @@ static int packet_encoded_rtp(encoder_t *enc, void *u1, void *u2) {
|
|
|
|
__output_rtp(mp, ch, ch->handler, send_buf, inout.len, ch->first_ts
|
|
|
|
__output_rtp(mp, ch, ch->handler, send_buf, inout.len, ch->first_ts
|
|
|
|
+ enc->avpkt.pts / enc->def->clockrate_mult,
|
|
|
|
+ enc->avpkt.pts / enc->def->clockrate_mult,
|
|
|
|
ch->rtp_mark ? 1 : 0, -1, 0,
|
|
|
|
ch->rtp_mark ? 1 : 0, -1, 0,
|
|
|
|
is_dtmf ? ch->handler->dtmf_payload_type : -1);
|
|
|
|
payload_type);
|
|
|
|
mp->ssrc_out->parent->seq_diff++;
|
|
|
|
mp->ssrc_out->parent->seq_diff++;
|
|
|
|
//mp->iter_out++;
|
|
|
|
//mp->iter_out++;
|
|
|
|
ch->rtp_mark = 0;
|
|
|
|
ch->rtp_mark = 0;
|
|
|
|
@ -2702,9 +2729,7 @@ static void __insert_codec_tracker(struct call_media *media, GList *link) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
static void __queue_insert_supp(GQueue *q, struct rtp_payload_type *pt, int supp_check,
|
|
|
|
static void __queue_insert_supp(GQueue *q, struct rtp_payload_type *pt, int supp_check) {
|
|
|
|
struct codec_tracker *sct)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// do we care at all?
|
|
|
|
// do we care at all?
|
|
|
|
if (!supp_check) {
|
|
|
|
if (!supp_check) {
|
|
|
|
g_queue_push_tail(q, pt);
|
|
|
|
g_queue_push_tail(q, pt);
|
|
|
|
@ -2748,7 +2773,7 @@ void __rtp_payload_type_add_recv(struct call_media *media, struct rtp_payload_ty
|
|
|
|
pt->ptime = media->ptime;
|
|
|
|
pt->ptime = media->ptime;
|
|
|
|
g_hash_table_insert(media->codecs_recv, &pt->payload_type, pt);
|
|
|
|
g_hash_table_insert(media->codecs_recv, &pt->payload_type, pt);
|
|
|
|
__rtp_payload_type_add_name(media->codec_names_recv, pt);
|
|
|
|
__rtp_payload_type_add_name(media->codec_names_recv, pt);
|
|
|
|
__queue_insert_supp(&media->codecs_prefs_recv, pt, supp_check, media->codec_tracker);
|
|
|
|
__queue_insert_supp(&media->codecs_prefs_recv, pt, supp_check);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// consumes 'pt'
|
|
|
|
// consumes 'pt'
|
|
|
|
void __rtp_payload_type_add_send(struct call_media *other_media,
|
|
|
|
void __rtp_payload_type_add_send(struct call_media *other_media,
|
|
|
|
|