Browse Source

MT#55283 add flag to discard delay buffer packets in codec_handlers_stop before media playback

if a delay buffer is enabled, the packets get scheduled in the future,
but media playback packets are scheduled immediately. this results
in choppy playback due to the packets coming in at the same time.
This change adds a new bool to chu_args that gets enabled when
play-media is called and passed in to codec_handlers_stop so the delay
buffer queue is cleared instead of flushed

Change-Id: Id534f9087d934481f17341bc577099dc2362f8e1
rfuchs/dubber
Tom Briden 7 months ago
committed by Richard Fuchs
parent
commit
9fd6b31186
4 changed files with 19 additions and 13 deletions
  1. +1
    -1
      daemon/call.c
  2. +9
    -6
      daemon/codec.c
  3. +3
    -3
      daemon/media_player.c
  4. +6
    -3
      include/codec.h

+ 1
- 1
daemon/call.c View File

@ -5207,7 +5207,7 @@ static void media_stop(struct call_media *m) {
return;
t38_gateway_stop(m->t38_gateway);
audio_player_stop(m);
codec_handlers_stop(&m->codec_handlers_store, NULL);
codec_handlers_stop(&m->codec_handlers_store, NULL, false);
rtcp_timer_stop(&m->rtcp_timer);
mqtt_timer_stop(&m->mqtt_timer);
}


+ 9
- 6
daemon/codec.c View File

@ -1466,7 +1466,7 @@ void __codec_handlers_update(struct call_media *receiver, struct call_media *sin
if (proto_is_not_rtp(receiver->protocol)) {
__generator_stop_all(receiver);
__generator_stop_all(sink);
codec_handlers_stop(&receiver->codec_handlers_store, sink);
codec_handlers_stop(&receiver->codec_handlers_store, sink, a.clear_delay_buffer);
return;
}
@ -1482,7 +1482,10 @@ void __codec_handlers_update(struct call_media *receiver, struct call_media *sin
// we're doing some kind of media passthrough - shut down local generators
__generator_stop(receiver);
__generator_stop(sink);
codec_handlers_stop(&receiver->codec_handlers_store, sink);
// clear_delay_buffer is enabled by play-media to ensure media packets don't get scheduled
// alongside the delay buffer packets resulting in choppy audio
codec_handlers_stop(&receiver->codec_handlers_store, sink, a.clear_delay_buffer);
// XXX this can cause unnecessary shutdown/resets of codec handlers
bool is_transcoding = false;
@ -4157,7 +4160,7 @@ static void __ssrc_handler_stop(void *p, void *arg) {
}
codec_cc_stop(ch->chain);
}
void codec_handlers_stop(codec_handlers_q *q, struct call_media *sink) {
void codec_handlers_stop(codec_handlers_q *q, struct call_media *sink, bool clear_delay_buffer) {
for (__auto_type l = q->head; l; l = l->next) {
struct codec_handler *h = l->data;
@ -4166,7 +4169,7 @@ void codec_handlers_stop(codec_handlers_q *q, struct call_media *sink) {
if (h->delay_buffer) {
mutex_lock(&h->delay_buffer->lock);
__delay_buffer_shutdown(h->delay_buffer, true);
__delay_buffer_shutdown(h->delay_buffer, !clear_delay_buffer);
mutex_unlock(&h->delay_buffer->lock);
delay_buffer_stop(&h->delay_buffer);
@ -4876,7 +4879,7 @@ void codec_update_all_handlers(struct call_monologue *ml) {
dialogue_unconfirm(ml, "updating codec handlers");
}
void codec_update_all_source_handlers(struct call_monologue *ml, const sdp_ng_flags *flags) {
void codec_update_all_source_handlers(struct call_monologue *ml, const sdp_ng_flags *flags, bool clear_delay_buffer) {
for (int i = 0; i < ml->medias->len; i++)
{
@ -4892,7 +4895,7 @@ void codec_update_all_source_handlers(struct call_monologue *ml, const sdp_ng_fl
if (!source_media)
continue;
codec_handlers_update(source_media, sink_media, .flags = flags);
codec_handlers_update(source_media, sink_media, .flags = flags, .clear_delay_buffer = clear_delay_buffer);
}
}


+ 3
- 3
daemon/media_player.c View File

@ -1637,7 +1637,7 @@ const char * call_play_media_for_ml(struct call_monologue *ml,
{
#ifdef WITH_TRANSCODING
/* if mixing is enabled, codec handlers of all sources must be updated */
codec_update_all_source_handlers(ml, flags);
codec_update_all_source_handlers(ml, flags, true);
/* this starts the audio player if needed */
update_init_monologue_subscribers(ml, OP_PLAY_MEDIA);
@ -1670,7 +1670,7 @@ long long call_stop_media_for_ml(struct call_monologue *ml)
#ifdef WITH_TRANSCODING
long long ret = media_player_stop(ml->player);
/* restore to non-mixing if needed */
codec_update_all_source_handlers(ml, NULL);
codec_update_all_source_handlers(ml, NULL, false);
update_init_monologue_subscribers(ml, OP_STOP_MEDIA);
/* mark MoH as already not used (it can be unset now) */
ml->player->opts.moh = 0;
@ -2016,7 +2016,7 @@ static void media_player_run(void *ptr) {
if (mp->opts.block_egress)
MEDIA_CLEAR(mp->media, BLOCK_EGRESS);
codec_update_all_source_handlers(mp->media->monologue, NULL);
codec_update_all_source_handlers(mp->media->monologue, NULL, false);
update_init_monologue_subscribers(mp->media->monologue, OP_PLAY_MEDIA);
rwlock_unlock_w(&call->master_lock);


+ 6
- 3
include/codec.h View File

@ -156,7 +156,7 @@ struct codec_handler *codec_handler_make_dummy(const rtp_payload_type *dst_pt, s
str_case_value_ht codec_set);
void codec_calc_jitter(struct ssrc_entry_call *, unsigned long ts, unsigned int clockrate, int64_t);
void codec_update_all_handlers(struct call_monologue *ml);
void codec_update_all_source_handlers(struct call_monologue *ml, const sdp_ng_flags *flags);
void codec_update_all_source_handlers(struct call_monologue *ml, const sdp_ng_flags *flags, bool clear_delay_buffer);
struct codec_store_args {
str_case_value_ht codec_set;
@ -228,6 +228,9 @@ struct chu_args {
const struct stream_params *sp;
bool allow_asymmetric;
bool reset_transcoding;
// when false (default if not passed) the delay buffer is flushed as normal
// used by play-media to ensure media packets aren't sent alongside delayed packets
bool clear_delay_buffer;
};
#define codec_handlers_update(r, s, ...) \
__codec_handlers_update(r, s, (struct chu_args) {__VA_ARGS__})
@ -246,7 +249,7 @@ uint64_t codec_encoder_pts(struct codec_ssrc_handler *ch, struct ssrc_entry_call
void codec_decoder_skip_pts(struct codec_ssrc_handler *ch, uint64_t);
uint64_t codec_decoder_unskip_pts(struct codec_ssrc_handler *ch);
void codec_tracker_update(struct codec_store *, struct codec_store *);
void codec_handlers_stop(codec_handlers_q *, struct call_media *sink);
void codec_handlers_stop(codec_handlers_q *, struct call_media *sink, bool clear_delay_buffer);
void packet_encoded_packetize(AVPacket *pkt, struct codec_ssrc_handler *ch, struct media_packet *mp,
@ -282,7 +285,7 @@ INLINE void __codec_handlers_update(struct call_media *receiver, struct call_med
}
INLINE void codec_handler_free(struct codec_handler **handler) { }
INLINE void codec_tracker_update(struct codec_store *cs, struct codec_store *ocs) { }
INLINE void codec_handlers_stop(codec_handlers_q *q, struct call_media *sink) { }
INLINE void codec_handlers_stop(codec_handlers_q *q, struct call_media *sink, bool clear_delay_buffer) { }
INLINE void ensure_codec_def(rtp_payload_type *pt, struct call_media *media) { }
#endif


Loading…
Cancel
Save