From 0863302a7b556adc95c02024a9ed3399629d2133 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 27 Feb 2023 09:34:05 -0500 Subject: [PATCH] MT#56471 reset codec handlers when player finishes Return true/false from media player run functions to signal whether playback is finished and whether codec handlers should be reset. Change-Id: Ieb2e0861190ad2851d986bae28becc5548e215ce --- daemon/media_player.c | 31 +++++++++++++++++++++++-------- daemon/t38.c | 10 ++++++---- include/media_player.h | 3 ++- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/daemon/media_player.c b/daemon/media_player.c index d54a62714..3efbbbc18 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -59,7 +59,7 @@ struct media_player_cache_packet { static mutex_t media_player_cache_lock; static GHashTable *media_player_cache; // keys and values only ever freed at shutdown -static void media_player_read_packet(struct media_player *mp); +static bool media_player_read_packet(struct media_player *mp); #endif static struct timerthread send_timer_thread; @@ -357,7 +357,7 @@ static void media_player_coder_add_packet(struct media_player_coder *c, } -static void media_player_read_decoded_packet(struct media_player *mp) { +static bool media_player_read_decoded_packet(struct media_player *mp) { struct media_player_cache_entry *entry = mp->cache_entry; if (!entry) return; @@ -392,7 +392,7 @@ retry:; if (mp->repeat <= 1) { ilog(LOG_DEBUG, "EOF reading from media buffer (%s), stopping playback", entry->info_str); - return; + return true; } ilog(LOG_DEBUG, "EOF reading from media buffer (%s) but will repeat %li time", @@ -443,6 +443,8 @@ retry:; // schedule our next run timeval_add_usec(&mp->next_run, us_dur); timerthread_obj_schedule_abs(&mp->tt_obj, &mp->next_run); + + return false; } static void media_player_cached_reader_start(struct media_player *mp, const struct rtp_payload_type *dst_pt, @@ -816,9 +818,9 @@ void media_player_add_packet(struct media_player *mp, char *buf, size_t len, // appropriate lock must be held -static void media_player_read_packet(struct media_player *mp) { +static bool media_player_read_packet(struct media_player *mp) { if (!mp->coder.fmtctx) - return; + return true; int ret = av_read_frame(mp->coder.fmtctx, mp->coder.pkt); if (ret < 0) { @@ -835,14 +837,14 @@ static void media_player_read_packet(struct media_player *mp) { ret = av_read_frame(mp->coder.fmtctx, mp->coder.pkt); } else { ilog(LOG_DEBUG, "EOF reading from media stream"); - return; + return true; } } if (ret < 0 && ret != AVERROR_EOF) { ilog(LOG_ERR, "Error while reading from media stream"); - return; + return true; } } @@ -852,6 +854,8 @@ static void media_player_read_packet(struct media_player *mp) { media_player_coder_add_packet(&mp->coder, (void *) media_player_add_packet, mp); av_packet_unref(mp->coder.pkt); + + return false; } @@ -1180,11 +1184,22 @@ static void media_player_run(void *ptr) { rwlock_lock_r(&call->master_lock); mutex_lock(&mp->lock); - mp->run_func(mp); + bool finished = mp->run_func(mp); mutex_unlock(&mp->lock); rwlock_unlock_r(&call->master_lock); + if (finished) { + rwlock_lock_w(&call->master_lock); + + mp->next_run.tv_sec = 0; + + codec_update_all_source_handlers(mp->media->monologue, NULL); + update_init_subscribers(mp->media->monologue, OP_OTHER); + + rwlock_unlock_w(&call->master_lock); + } + log_info_pop(); } diff --git a/daemon/t38.c b/daemon/t38.c index 3185c136a..ee003e362 100644 --- a/daemon/t38.c +++ b/daemon/t38.c @@ -256,13 +256,13 @@ void __t38_gateway_free(void *p) { } // call is locked in R and mp is locked -static void t38_pcm_player(struct media_player *mp) { +static bool t38_pcm_player(struct media_player *mp) { if (!mp || !mp->media) - return; + return true; struct t38_gateway *tg = mp->media->t38_gateway; if (!tg) - return; + return true; if (tg->pcm_media && tg->pcm_media->streams.head && ((struct packet_stream *) tg->pcm_media->streams.head->data)->selected_sfd) @@ -279,7 +279,7 @@ static void t38_pcm_player(struct media_player *mp) { timeval_add_usec(&mp->next_run, 10000); timerthread_obj_schedule_abs(&mp->tt_obj, &mp->next_run); mutex_unlock(&tg->lock); - return; + return false; } ilog(LOG_DEBUG, "Generated %i T.38 PCM samples", num); @@ -295,6 +295,8 @@ static void t38_pcm_player(struct media_player *mp) { // this reschedules our player as well media_player_add_packet(pcm_player, (char *) smp, num * 2, num * 1000000 / 8000, pts); media_player_put(&pcm_player); + + return false; } diff --git a/include/media_player.h b/include/media_player.h index 6eec2a15d..9224de3af 100644 --- a/include/media_player.h +++ b/include/media_player.h @@ -35,7 +35,8 @@ struct media_player_content_index { }; -typedef void (*media_player_run_func)(struct media_player *); +// returns true to indicate that playback is finished and codec handlers should be reset +typedef bool (*media_player_run_func)(struct media_player *); struct media_player_coder {