Browse Source

MT#61630 moh: add duration limit

Add duration limit for the moh functionality.
This is required due to a possibility to get
monologues and hence packet streams stuck
forever and sending audio to recipients
which already don't exist.

A configuration option that controls that:
`moh-max-duration` - gets a value in milliseconds.

By default is set to 1800000 (half an hour).

Change-Id: Id50a0a10ce5b52b3876a3122fb16a71accec90ff
pull/1897/head
Donat Zenichev 12 months ago
parent
commit
5c52772183
6 changed files with 35 additions and 11 deletions
  1. +2
    -2
      daemon/call_interfaces.c
  2. +2
    -0
      daemon/main.c
  3. +26
    -9
      daemon/media_player.c
  4. +3
    -0
      etc/rtpengine.conf
  5. +1
    -0
      include/main.h
  6. +1
    -0
      include/media_player.h

+ 2
- 2
daemon/call_interfaces.c View File

@ -2389,9 +2389,9 @@ static const char *call_offer_answer_ng(ng_command_ctx_t *ctx, const char* addr,
* to be provided with moh playbacks */
if (call_ml_wants_moh(from_ml, flags.opmode))
{
/* TODO: should be fine tuned? */
media_player_opts_t opts = MPO(
.repeat = 999, /* TODO: maybe there is a better way to loop it */
.repeat = 999,
.duration_spent = rtpe_config.moh_max_duration,
.start_pos = 0,
.block_egress = 1,
.codec_set = flags.codec_set,


+ 2
- 0
daemon/main.c View File

@ -112,6 +112,7 @@ struct rtpengine_config rtpe_config = {
.mqtt_publish_interval = 5000,
.dtmf_digit_delay = 2500,
.rtcp_interval = 5000,
.moh_max_duration = 1800000, // in ms
.common = {
.log_levels = {
[log_level_index_internals] = -1,
@ -696,6 +697,7 @@ static void options(int *argc, char ***argv, GHashTable *templates) {
#endif
{ "janus-secret", 0,0, G_OPTION_ARG_STRING, &rtpe_config.janus_secret,"Admin secret for Janus protocol","STRING"},
{ "rtcp-interval", 0,0, G_OPTION_ARG_INT, &rtpe_config.rtcp_interval,"Delay in milliseconds between RTCP packets when generate-rtcp flag is on, where random dispersion < 1 sec is added on top","INT"},
{ "moh-max-duration", 0,0, G_OPTION_ARG_INT, &rtpe_config.moh_max_duration, "Music-on-hold max possible duration (in milliseconds). If set to 0 then will be ignored.", "INT"},
{ "max-recv-iters", 0, 0, G_OPTION_ARG_INT, &rtpe_config.max_recv_iters, "Maximum continuous reading cycles in UDP poller loop.", "INT"},
{ "vsc-start-rec",0,0, G_OPTION_ARG_STRING, &rtpe_config.vsc_start_rec.s,"DTMF VSC to start recording.", "STRING"},
{ "vsc-stop-rec",0,0, G_OPTION_ARG_STRING, &rtpe_config.vsc_stop_rec.s,"DTMF VSC to stop recording.", "STRING"},


+ 26
- 9
daemon/media_player.c View File

@ -990,6 +990,19 @@ void media_player_add_packet(struct media_player *mp, char *buf, size_t len,
timerthread_obj_schedule_abs(&mp->tt_obj, &mp->next_run);
}
static int media_player_find_file_begin(struct media_player *mp) {
int ret = 0;
int64_t ret64 = avio_seek(mp->coder.fmtctx->pb, 0, SEEK_SET);
if (ret64 != 0)
ilog(LOG_ERR, "Failed to seek to beginning of media file");
ret = av_seek_frame(mp->coder.fmtctx, -1, 0, 0);
if (ret < 0)
ilog(LOG_ERR, "Failed to seek to beginning of media file");
ret = av_read_frame(mp->coder.fmtctx, mp->coder.pkt);
return ret;
}
// appropriate lock must be held
static bool media_player_read_packet(struct media_player *mp) {
@ -999,17 +1012,21 @@ static bool media_player_read_packet(struct media_player *mp) {
int ret = av_read_frame(mp->coder.fmtctx, mp->coder.pkt);
if (ret < 0) {
if (ret == AVERROR_EOF) {
if (mp->opts.repeat > 1) {
ilog(LOG_DEBUG, "EOF reading from media stream but will repeat %i time",
/* for moh: count based on duration */
if (mp->moh && mp->opts.duration_spent > 0) {
ilog(LOG_DEBUG, "EOF reading from media stream but will be played further for duration of '%lld' ms",
mp->opts.duration_spent);
/* moh counter for the max spent duration (in milliseconds) */
mp->opts.duration_spent = mp->opts.duration_spent - mp->coder.duration;
ret = media_player_find_file_begin(mp);
/* for play media: count based on repeats */
} else if (!mp->moh && mp->opts.repeat > 1) {
ilog(LOG_DEBUG, "EOF reading from media stream but will repeat '%i' time",
mp->opts.repeat);
mp->opts.repeat = mp->opts.repeat - 1;
int64_t ret64 = avio_seek(mp->coder.fmtctx->pb, 0, SEEK_SET);
if (ret64 != 0)
ilog(LOG_ERR, "Failed to seek to beginning of media file");
ret = av_seek_frame(mp->coder.fmtctx, -1, 0, 0);
if (ret < 0)
ilog(LOG_ERR, "Failed to seek to beginning of media file");
ret = av_read_frame(mp->coder.fmtctx, mp->coder.pkt);
ret = media_player_find_file_begin(mp);
} else {
ilog(LOG_DEBUG, "EOF reading from media stream");
return true;


+ 3
- 0
etc/rtpengine.conf View File

@ -152,6 +152,9 @@ recording-method = proc
# socket-cpu-affinity = -1
# rtcp-interval = 5000
# music-on-hold max possible duration (in ms), if set 0 then will be ignored
# moh-max-duration = 1800000
# signalling templates (see key `templates` above)
[templates]
WebRTC = transport-protocol=UDP/TLS/RTP/SAVPF ICE=force trickle-ICE rtcp-mux=[offer require] no-rtcp-attribute SDES=off generate-mid


+ 1
- 0
include/main.h View File

@ -39,6 +39,7 @@ enum endpoint_learning {
X(silent_timeout) \
X(final_timeout) \
X(offer_timeout) \
X(moh_max_duration) \
X(delete_delay) \
X(redis_expires_secs) \
X(default_tos) \


+ 1
- 0
include/media_player.h View File

@ -21,6 +21,7 @@ struct media_player;
typedef struct {
long long start_pos;
int repeat;
long long duration_spent; /* in milliseconds */
str_case_value_ht codec_set;
unsigned int block_egress:1;
str file, blob;


Loading…
Cancel
Save