MT#56861 support DTMF injection from DTMF

This replicates the code to replace audio packets with injected DTMF
events. Unfortunately the code paths between forwarding audio and
processing/forwarding DTMF events is quite different, so some slight
duplication is needed.

Additionally the case of blocked DTMF + injected DTMF must be handled.

Change-Id: Ieb576b4b6644c9b154ba4c6ebd48fe12ff08e1de
pull/1657/head
Richard Fuchs 3 years ago
parent 4389aed9e9
commit 0304e025fa

@ -2164,11 +2164,76 @@ static int packet_dtmf(struct codec_ssrc_handler *ch, struct codec_ssrc_handler
if (dtmf_event_processed == -1)
return -1;
int ret = 0;
enum block_dtmf_mode block_dtmf = dtmf_get_block_mode(mp->call, mp->media->monologue);
if (block_dtmf == BLOCK_DTMF_DROP)
bool do_blocking = block_dtmf == BLOCK_DTMF_DROP;
if (packet->payload->len >= sizeof(struct telephone_event_payload)) {
struct telephone_event_payload *dtmf = (void *) packet->payload->s;
struct codec_handler *h = input_ch->handler;
// fudge up TS and duration values
uint64_t duration = h->source_pt.clock_rate * h->source_pt.ptime / 1000;
uint64_t ts = packet->ts + ntohs(dtmf->duration) - duration;
// remember this as last "encoder" TS
atomic64_set(&mp->ssrc_in->last_ts, ts);
// provide an uninitialised buffer as potential output storage for DTMF
char buf[sizeof(struct telephone_event_payload)];
str ev_pl;
str_init_len(&ev_pl, buf, sizeof(buf));
int is_dtmf = dtmf_event_payload(&ev_pl, &ts, duration,
&input_ch->dtmf_event, &input_ch->dtmf_events);
if (is_dtmf) {
// generate appropriate transcode_packets
unsigned int copies = 1;
if (dtmf_event_processed == 1) // discard duplicate end packets
copies = 0;
else if (is_dtmf == 3) // end event
copies = 3;
// fix up RTP header
struct rtp_header r;
r = *mp->rtp;
r.m_pt = h->dtmf_payload_type;
r.timestamp = htonl(ts);
for (; copies > 0; copies--) {
struct transcode_packet *dup = g_slice_alloc(sizeof(*dup));
*dup = *packet;
dup->payload = str_dup(&ev_pl);
dup->rtp = r;
dup->bypass_seq = 0;
dup->ts = ts;
if (is_dtmf == 1)
dup->marker = 1;
int ret = 0;
if (__buffer_dtx(input_ch->dtx_buffer, ch, input_ch, dup, mp, packet_dtmf_fwd))
ret = 1; // consumed
else
ret = packet_dtmf_fwd(ch, input_ch, dup, mp);
if (ret == 0)
__transcode_packet_free(dup);
}
// discard the received event
do_blocking = true;
}
else if (!input_ch->dtmf_events.length)
mp->media->monologue->dtmf_injection_active = 0;
}
int ret = 0;
if (do_blocking)
{ }
else {
// pass through

Loading…
Cancel
Save