MT#61404 clone previous sequence number for T.38

If the receiver of a previously passthrough T.30 stream gets switched to
a generated PCM stream from a T.38 gateway, continue the sequencing of
the previous SSRC. Technically this is not necessary as the generated
PCM stream gets a new SSRC, but at least Asterisk seems to ignore this
and expect sequencing to continue, and will ignore PCM if the sequence
jump is too large.

Change-Id: Ia4656770db11f5fa1a1e9bf5bd71a0398deb1e00
(cherry picked from commit 18579227a9)
mr13.2
Richard Fuchs 2 months ago
parent 35bf7d313b
commit cf9a1fd396

@ -108,7 +108,7 @@ bool audio_player_setup(struct call_media *m, const rtp_payload_type *dst_pt,
if (mp)
media_player_stop(mp);
else {
media_player_new(&mp, m->monologue);
media_player_new(&mp, m->monologue, NULL);
ap->mp = mp;
}
if (!mp)

@ -2761,7 +2761,7 @@ static void __call_monologue_init_from_flags(struct call_monologue *ml, struct c
#ifdef WITH_TRANSCODING
if (flags->recording_announcement) {
media_player_new(&ml->rec_player, ml);
media_player_new(&ml->rec_player, ml, NULL);
media_player_opts_t opts = MPO(
.repeat = flags->repeat_times,
.duration_spent = flags->repeat_duration,

@ -234,7 +234,7 @@ static void __media_player_free(struct media_player *mp) {
// call->master_lock held in W
void media_player_new(struct media_player **mpp, struct call_monologue *ml) {
void media_player_new(struct media_player **mpp, struct call_monologue *ml, struct ssrc_ctx *prev_ssrc) {
#ifdef WITH_TRANSCODING
struct media_player *mp;
@ -256,7 +256,10 @@ void media_player_new(struct media_player **mpp, struct call_monologue *ml) {
mp->run_func = media_player_read_packet; // default
mp->call = obj_get(ml->call);
mp->ml = ml;
mp->seq = ssl_random();
if (prev_ssrc)
mp->seq = atomic_get_na(&prev_ssrc->stats->ext_seq) + 1;
else
mp->seq = ssl_random();
mp->buffer_ts = ssl_random();
mp->ssrc_out = ssrc_ctx;
}
@ -1601,7 +1604,7 @@ const char * call_play_media_for_ml(struct call_monologue *ml,
update_init_subscribers(ml, OP_PLAY_MEDIA);
/* media_player_new() now knows that audio player is in use
* TODO: player options can have changed if already exists */
media_player_new(&ml->player, ml);
media_player_new(&ml->player, ml, NULL);
if (opts.file.len) {
if (!media_player_play_file(ml->player, opts))

@ -406,7 +406,8 @@ int t38_gateway_pair(struct call_media *t38_media, struct call_media *pcm_media,
if (!(tg->gw = t38_gateway_init(NULL, t38_gateway_handler, tg)))
goto err;
media_player_new(&tg->pcm_player, pcm_media->monologue);
media_player_new(&tg->pcm_player, pcm_media->monologue,
pcm_media->streams.length ? pcm_media->streams.head->data->ssrc_out[0] : NULL);
// even though we call media_player_set_media() here, we need to call it again in
// t38_gateway_start because our sink might not have any streams added here yet,
// leaving the media_player setup incomplete

@ -121,7 +121,7 @@ struct send_timer {
#define MPO(...) (media_player_opts_t){__VA_ARGS__}
void media_player_new(struct media_player **, struct call_monologue *);
void media_player_new(struct media_player **, struct call_monologue *, struct ssrc_ctx *prev_ssrc);
bool media_player_add(struct media_player *mp, media_player_opts_t opts);
bool media_player_start(struct media_player *);
long long media_player_stop(struct media_player *);

Loading…
Cancel
Save