From 349249f42358f83569ad782ceb1760d97a3f6b49 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 3 Jan 2025 14:40:11 -0400 Subject: [PATCH] MT#61822 add on-demand caching of memory files Change-Id: I39deff0fd89d45df5739900dac3aa236f528161c --- daemon/media_player.c | 34 ++++++++++++++++++++++++++++++++-- docs/rtpengine.md | 5 +++++ etc/rtpengine.conf | 2 +- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/daemon/media_player.c b/daemon/media_player.c index 3fafc51a6..dc46a1ccc 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -1218,7 +1218,7 @@ static struct media_player_media_file *media_player_media_file_read_str(const st return media_player_media_file_read_c(file_s); } -static struct media_player_media_file *media_player_media_files_get(const str *fn) { +static struct media_player_media_file *media_player_media_files_get_only(const str *fn) { struct media_player_media_file *fo; { @@ -1261,6 +1261,31 @@ static mp_cached_code media_player_set_media_file(struct media_player *mp, return __media_player_add_blob_id(mp, opts, dst_pt); } +static struct media_player_media_file *media_player_media_files_get_create(const str *fn) { + __auto_type fo = media_player_media_files_get_only(fn); + if (fo) + return fo; + + fo = media_player_media_file_read_str(fn); + if (!fo) + return NULL; + + RWLOCK_W(&media_player_media_files_names_lock); + LOCK(&media_player_media_files_lock); + // someone else may have beaten us to it + if (t_hash_table_is_set(media_player_media_files) && t_hash_table_lookup(media_player_media_files, fn)) + return fo; // return the only reference, will disappear once player finishes + + // insert new reference + media_player_media_files_insert(fn, obj_get(fo)); + + return fo; +} + +static struct media_player_media_file *(*media_player_media_files_get)(const str *fn) + = media_player_media_files_get_only; + + static void __media_player_set_opts(struct media_player *mp, media_player_opts_t opts) { mp->opts = opts; @@ -1914,6 +1939,11 @@ bool media_player_preload_files(char **files) { while (*file == ' ') file++; + if (!strcmp(file, "ondemand") || !strcmp(file, "on demand") || !strcmp(file, "on-demand")) { + media_player_media_files_get = media_player_media_files_get_create; + continue; + } + ilog(LOG_DEBUG, "Reading media file '%s' for caching", file); str f = STR(file); @@ -1936,7 +1966,7 @@ bool media_player_reload_file(str *name) { bool ret = false; #ifdef WITH_TRANSCODING - __auto_type fo = media_player_media_files_get(name); + __auto_type fo = media_player_media_files_get_only(name); assert(fo != NULL); // get file mtime diff --git a/docs/rtpengine.md b/docs/rtpengine.md index a15b028dd..e8fd1c2d4 100644 --- a/docs/rtpengine.md +++ b/docs/rtpengine.md @@ -1159,6 +1159,11 @@ call to inject-DTMF won't be sent to __\-\-dtmf-log-dest=__ or __\-\-listen-tcp- file name differs (or an entirely different file is requested for playback) then playback will happen from file as usual. + The special string `on-demand` can be used instead of a file name to enable + on-demand loading and caching of media files. Any file requested for + playback that wasn't already present in the memory cache will then be read + only once and then retained in the cache for the lifetime of the daemon. + - __\-\-media-files-reload=__*SECONDS* Spawn a background thread to periodically check and, if needed, update diff --git a/etc/rtpengine.conf b/etc/rtpengine.conf index 338eb6a73..4bddd8806 100644 --- a/etc/rtpengine.conf +++ b/etc/rtpengine.conf @@ -165,7 +165,7 @@ recording-method = proc # whenever MoH is triggered. If not defined, then not in use. # moh-attr-name = rtpengine-hold -# preload-media-files = /var/media/file1.wav ; /var/media/file2.wav ; /var/media/file3.wav +# preload-media-files = /var/media/file1.wav ; /var/media/file2.wav ; /var/media/file3.wav ; on-demand # media-files-reload = 60 # signalling templates (see key `templates` above)