TT#136957 split up DTMF event queue into in and out

Change-Id: I2e0619071d43df8537736187104ca12bb2f86f64
pull/1430/head
Richard Fuchs 3 years ago
parent c794c00efa
commit 1ef4eeba80

@ -3444,6 +3444,7 @@ void call_media_free(struct call_media **mdp) {
mutex_destroy(&md->dtmf_lock);
g_slice_free1(sizeof(*md), md);
g_queue_clear_full(&md->dtmf_recv, dtmf_event_free);
g_queue_clear_full(&md->dtmf_send, dtmf_event_free);
mutex_destroy(&md->dtmf_lock);
*mdp = NULL;
}

@ -2511,44 +2511,54 @@ static void delay_frame_manipulate(struct delay_frame *dframe) {
AVFrame *frame = dframe->frame;
if (is_in_dtmf_event(&media->dtmf_recv, dframe->ts, frame->sample_rate, media->buffer_delay,
media->buffer_delay))
{
struct call_monologue *ml = media->monologue;
enum block_dtmf_mode mode = dtmf_get_block_mode(dframe->mp.call, ml);
struct call_monologue *ml = media->monologue;
enum block_dtmf_mode mode = dtmf_get_block_mode(dframe->mp.call, ml);
switch (mode) {
case BLOCK_DTMF_SILENCE:
if (mode == BLOCK_DTMF_OFF)
return;
mutex_lock(&media->dtmf_lock);
struct dtmf_event *dtmf_recv = is_in_dtmf_event(&media->dtmf_recv, dframe->ts, frame->sample_rate,
media->buffer_delay, media->buffer_delay);
struct dtmf_event *dtmf_send = is_in_dtmf_event(&media->dtmf_send, dframe->ts, frame->sample_rate,
media->buffer_delay, media->buffer_delay);
mutex_unlock(&media->dtmf_lock);
if (!dtmf_send) {
if (!dtmf_recv)
return;
mode = BLOCK_DTMF_SILENCE;
}
switch (mode) {
case BLOCK_DTMF_SILENCE:
memset(frame->extended_data[0], 0, frame->linesize[0]);
break;
case BLOCK_DTMF_TONE:
frame_fill_tone_samples(frame->format, frame->extended_data[0], dframe->ts,
frame->nb_samples, ml->tone_freq ? : 400,
ml->tone_vol ? : 10, frame->sample_rate, frame->channels);
break;
case BLOCK_DTMF_ZERO:
case BLOCK_DTMF_DTMF:
// if we have DTMF output, use silence, otherwise use a DTMF zero
if (dframe->ch->handler->dtmf_payload_type != -1)
memset(frame->extended_data[0], 0, frame->linesize[0]);
break;
case BLOCK_DTMF_TONE:
frame_fill_tone_samples(frame->format, frame->extended_data[0], dframe->ts,
frame->nb_samples, ml->tone_freq ? : 400,
ml->tone_vol ? : 10, frame->sample_rate, frame->channels);
break;
case BLOCK_DTMF_ZERO:
case BLOCK_DTMF_DTMF:
// if we have DTMF output, use silence, otherwise use a DTMF zero
if (dframe->ch->handler->dtmf_payload_type != -1)
memset(frame->extended_data[0], 0, frame->linesize[0]);
else
frame_fill_dtmf_samples(frame->format, frame->extended_data[0],
dframe->ts,
frame->nb_samples, dtmf_code_from_char(ml->dtmf_digit),
ml->tone_vol ? : 10, frame->sample_rate,
frame->channels);
break;
case BLOCK_DTMF_RANDOM:
if (!media->dtmf_event_state)
media->dtmf_event_state = '0' + (ssl_random() % 10);
frame_fill_dtmf_samples(frame->format, frame->extended_data[0], dframe->ts,
frame->nb_samples, media->dtmf_event_state - '0',
10, frame->sample_rate,
else
frame_fill_dtmf_samples(frame->format, frame->extended_data[0],
dframe->ts,
frame->nb_samples, dtmf_code_from_char(ml->dtmf_digit),
ml->tone_vol ? : 10, frame->sample_rate,
frame->channels);
break;
default:
break;
}
break;
case BLOCK_DTMF_RANDOM:
frame_fill_dtmf_samples(frame->format, frame->extended_data[0], dframe->ts,
frame->nb_samples, dtmf_send->rand_code - '0',
10, frame->sample_rate,
frame->channels);
break;
default:
break;
}
}
static void delay_packet_manipulate(struct delay_frame *dframe) {

@ -136,6 +136,10 @@ static void dtmf_end_event(struct call_media *media, unsigned int event, unsigne
*ev = (struct dtmf_event) { .code = 0, .ts = ts, .volume = 0 };
g_queue_push_tail(&media->dtmf_recv, ev);
ev = g_slice_alloc0(sizeof(*ev));
*ev = (struct dtmf_event) { .code = 0, .ts = ts, .volume = 0 };
g_queue_push_tail(&media->dtmf_send, ev);
if (!dtmf_do_logging())
return;
@ -275,16 +279,20 @@ static void dtmf_code_event(struct call_media *media, char event, uint64_t ts, i
// check trigger before setting new dtmf_start
dtmf_check_trigger(media, event, ts, clockrate);
media->dtmf_event_state = 0;
ev = g_slice_alloc0(sizeof(*ev));
*ev = (struct dtmf_event) { .code = event, .ts = ts, .volume = volume };
g_queue_push_tail(&media->dtmf_recv, ev);
ev = g_slice_alloc0(sizeof(*ev));
*ev = (struct dtmf_event) { .code = event, .ts = ts, .volume = volume,
.rand_code = '0' + (ssl_random() % 10) };
g_queue_push_tail(&media->dtmf_send, ev);
mutex_unlock(&media->dtmf_lock);
}
bool is_in_dtmf_event(GQueue *events, uint32_t ts, int clockrate, unsigned int head,
struct dtmf_event *is_in_dtmf_event(GQueue *events, uint32_t ts, int clockrate, unsigned int head,
unsigned int trail)
{
if (!clockrate)
@ -308,7 +316,7 @@ bool is_in_dtmf_event(GQueue *events, uint32_t ts, int clockrate, unsigned int h
continue;
// diff >= 0 and less than 10 seconds? that's a match.
if (start_diff <= cutoff)
return true;
return ev;
// anything else is a bad/outdated TS. stop.
break;
}
@ -320,12 +328,12 @@ bool is_in_dtmf_event(GQueue *events, uint32_t ts, int clockrate, unsigned int h
if (end_diff == 0) // for end events, we wait until after the end
continue;
if (end_diff <= cutoff)
return false;
return NULL;
break;
}
}
return false;
return NULL;
}

@ -407,7 +407,7 @@ struct call_media {
unsigned long dtmf_ts; // TS of last processed end event
// lists are append-only
GQueue dtmf_recv;
unsigned int dtmf_event_state;
GQueue dtmf_send;
#ifdef WITH_TRANSCODING
union {

@ -19,6 +19,7 @@ struct dtmf_event {
int code; // char for start, zero for end
int volume;
uint64_t ts;
int rand_code; // state for random replace mode
};
void dtmf_init(void);
@ -35,6 +36,6 @@ void dtmf_dsp_event(const struct dtmf_event *new_event, struct dtmf_event *cur_e
enum block_dtmf_mode dtmf_get_block_mode(struct call *call, struct call_monologue *ml);
bool is_pcm_dtmf_block_mode(enum block_dtmf_mode mode);
bool is_dtmf_replace_mode(enum block_dtmf_mode mode);
bool is_in_dtmf_event(GQueue *, uint32_t ts, int clockrate, unsigned int head, unsigned int trail);
struct dtmf_event *is_in_dtmf_event(GQueue *, uint32_t ts, int clockrate, unsigned int head, unsigned int trail);
#endif

Loading…
Cancel
Save