mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-17 07:18:15 +00:00
res_rtp_asterisk: Address jittery DTMF events in RTP streams
(closes issue ASTERISK-21170)
Reported by: NITESH BANSAL
Patches:
dtmf-timestamp.patch uploaded by NITESH BANSAL (license 6418)
Review: https://reviewboard.asterisk.org/r/2938/
........
Merged revisions 401619 from http://svn.asterisk.org/svn/asterisk/branches/1.8
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/11@401620 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -540,6 +540,10 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
|
|||||||
/* Predict next outgoing timestamp from samples in this
|
/* Predict next outgoing timestamp from samples in this
|
||||||
frame. */
|
frame. */
|
||||||
path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(&out->subclass.format)));
|
path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(&out->subclass.format)));
|
||||||
|
if (f->samples != out->samples && ast_test_flag(out, AST_FRFLAG_HAS_TIMING_INFO)) {
|
||||||
|
ast_debug(4, "Sample size different %u vs %u\n", f->samples, out->samples);
|
||||||
|
ast_clear_flag(out, AST_FRFLAG_HAS_TIMING_INFO);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
out->delivery = ast_tv(0, 0);
|
out->delivery = ast_tv(0, 0);
|
||||||
ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
|
ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
#define RTCP_PT_APP 204
|
#define RTCP_PT_APP 204
|
||||||
|
|
||||||
#define RTP_MTU 1200
|
#define RTP_MTU 1200
|
||||||
|
#define DTMF_SAMPLE_RATE_MS 8 /*!< DTMF samples per millisecond */
|
||||||
|
|
||||||
#define DEFAULT_DTMF_TIMEOUT (150 * (8000 / 1000)) /*!< samples */
|
#define DEFAULT_DTMF_TIMEOUT (150 * (8000 / 1000)) /*!< samples */
|
||||||
|
|
||||||
@@ -1725,6 +1726,35 @@ static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \internal
|
||||||
|
* \brief Calculates the elapsed time from issue of the first tx packet in an
|
||||||
|
* rtp session and a specified time
|
||||||
|
*
|
||||||
|
* \param rtp pointer to the rtp struct with the transmitted rtp packet
|
||||||
|
* \param delivery time of delivery - if NULL or zero value, will be ast_tvnow()
|
||||||
|
*
|
||||||
|
* \return time elapsed in milliseconds
|
||||||
|
*/
|
||||||
|
static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
|
||||||
|
{
|
||||||
|
struct timeval t;
|
||||||
|
long ms;
|
||||||
|
|
||||||
|
if (ast_tvzero(rtp->txcore)) {
|
||||||
|
rtp->txcore = ast_tvnow();
|
||||||
|
rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow();
|
||||||
|
if ((ms = ast_tvdiff_ms(t, rtp->txcore)) < 0) {
|
||||||
|
ms = 0;
|
||||||
|
}
|
||||||
|
rtp->txcore = t;
|
||||||
|
|
||||||
|
return (unsigned int) ms;
|
||||||
|
}
|
||||||
|
|
||||||
static int ast_rtp_new(struct ast_rtp_instance *instance,
|
static int ast_rtp_new(struct ast_rtp_instance *instance,
|
||||||
struct ast_sched_context *sched, struct ast_sockaddr *addr,
|
struct ast_sched_context *sched, struct ast_sockaddr *addr,
|
||||||
void *data)
|
void *data)
|
||||||
@@ -1958,6 +1988,7 @@ static int ast_rtp_dtmf_begin(struct ast_rtp_instance *instance, char digit)
|
|||||||
|
|
||||||
rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
|
rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
|
||||||
rtp->send_duration = 160;
|
rtp->send_duration = 160;
|
||||||
|
rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
|
||||||
rtp->lastdigitts = rtp->lastts + rtp->send_duration;
|
rtp->lastdigitts = rtp->lastts + rtp->send_duration;
|
||||||
|
|
||||||
/* Create the actual packet that we will be sending */
|
/* Create the actual packet that we will be sending */
|
||||||
@@ -2042,6 +2073,7 @@ static int ast_rtp_dtmf_continuation(struct ast_rtp_instance *instance)
|
|||||||
/* And now we increment some values for the next time we swing by */
|
/* And now we increment some values for the next time we swing by */
|
||||||
rtp->seqno++;
|
rtp->seqno++;
|
||||||
rtp->send_duration += 160;
|
rtp->send_duration += 160;
|
||||||
|
rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2121,7 +2153,7 @@ static int ast_rtp_dtmf_end_with_duration(struct ast_rtp_instance *instance, cha
|
|||||||
res = 0;
|
res = 0;
|
||||||
|
|
||||||
/* Oh and we can't forget to turn off the stuff that says we are sending DTMF */
|
/* Oh and we can't forget to turn off the stuff that says we are sending DTMF */
|
||||||
rtp->lastts += rtp->send_duration;
|
rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
|
||||||
cleanup:
|
cleanup:
|
||||||
rtp->sending_digit = 0;
|
rtp->sending_digit = 0;
|
||||||
rtp->send_digit = 0;
|
rtp->send_digit = 0;
|
||||||
@@ -2171,25 +2203,6 @@ static void ast_rtp_change_source(struct ast_rtp_instance *instance)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
|
|
||||||
{
|
|
||||||
struct timeval t;
|
|
||||||
long ms;
|
|
||||||
|
|
||||||
if (ast_tvzero(rtp->txcore)) {
|
|
||||||
rtp->txcore = ast_tvnow();
|
|
||||||
rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
|
|
||||||
}
|
|
||||||
|
|
||||||
t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow();
|
|
||||||
if ((ms = ast_tvdiff_ms(t, rtp->txcore)) < 0) {
|
|
||||||
ms = 0;
|
|
||||||
}
|
|
||||||
rtp->txcore = t;
|
|
||||||
|
|
||||||
return (unsigned int) ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw)
|
static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw)
|
||||||
{
|
{
|
||||||
unsigned int sec, usec, frac;
|
unsigned int sec, usec, frac;
|
||||||
|
|||||||
Reference in New Issue
Block a user