diff --git a/daemon/codec.c b/daemon/codec.c index b1e7653c3..8b5f0369e 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -502,14 +502,17 @@ no_handler_reset: } } +// used for generic playback (audio_player, t38_gateway) struct codec_handler *codec_handler_make_playback(const struct rtp_payload_type *src_pt, - const struct rtp_payload_type *dst_pt, unsigned long last_ts, struct call_media *media) + const struct rtp_payload_type *dst_pt, unsigned long last_ts, struct call_media *media, + uint32_t ssrc) { struct codec_handler *handler = __handler_new(src_pt, media, NULL); rtp_payload_type_copy(&handler->dest_pt, dst_pt); handler->handler_func = handler_func_playback; handler->ssrc_handler = (void *) __ssrc_handler_transcode_new(handler); handler->ssrc_handler->csch.first_ts = last_ts; + handler->ssrc_handler->h.ssrc = ssrc; while (handler->ssrc_handler->csch.first_ts == 0) handler->ssrc_handler->csch.first_ts = ssl_random(); handler->ssrc_handler->rtp_mark = 1; @@ -520,6 +523,16 @@ struct codec_handler *codec_handler_make_playback(const struct rtp_payload_type return handler; } +// used for "play media" player +struct codec_handler *codec_handler_make_media_player(const struct rtp_payload_type *src_pt, + const struct rtp_payload_type *dst_pt, unsigned long last_ts, struct call_media *media, + uint32_t ssrc) +{ + struct codec_handler *h = codec_handler_make_playback(src_pt, dst_pt, last_ts, media, ssrc); + if (!h) + return NULL; + return h; +} struct codec_handler *codec_handler_make_dummy(const struct rtp_payload_type *dst_pt, struct call_media *media) { struct codec_handler *handler = __handler_new(NULL, media, NULL); diff --git a/daemon/media_player.c b/daemon/media_player.c index 051c5c682..dee15ec77 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -682,28 +682,57 @@ bool media_player_pt_match(const struct media_player *mp, const struct rtp_paylo } -int media_player_setup(struct media_player *mp, const struct rtp_payload_type *src_pt, - const struct rtp_payload_type *dst_pt) +static int media_player_setup_common(struct media_player *mp, const struct rtp_payload_type *src_pt, + const struct rtp_payload_type **dst_pt) { - if (!dst_pt) - dst_pt = media_player_get_dst_pt(mp); - if (!dst_pt) + if (!*dst_pt) + *dst_pt = media_player_get_dst_pt(mp); + if (!*dst_pt) return -1; // if we played anything before, scale our sync TS according to the time // that has passed if (mp->sync_ts_tv.tv_sec) { long long ts_diff_us = timeval_diff(&rtpe_now, &mp->sync_ts_tv); - mp->sync_ts += fraction_divl(ts_diff_us * dst_pt->clock_rate / 1000000, &dst_pt->codec_def->default_clockrate_fact); + mp->sync_ts += fraction_divl(ts_diff_us * (*dst_pt)->clock_rate / 1000000, &(*dst_pt)->codec_def->default_clockrate_fact); } // if we already have a handler, see if anything needs changing - if (!media_player_pt_match(mp, src_pt, dst_pt)) { + if (!media_player_pt_match(mp, src_pt, *dst_pt)) { ilog(LOG_DEBUG, "Resetting codec handler for media player"); codec_handler_free(&mp->coder.handler); } + + return 0; +} + +// used for generic playback (audio_player, t38_gateway) +int media_player_setup(struct media_player *mp, const struct rtp_payload_type *src_pt, + const struct rtp_payload_type *dst_pt) +{ + int ret = media_player_setup_common(mp, src_pt, &dst_pt); + if (ret) + return ret; + + if (!mp->coder.handler) + mp->coder.handler = codec_handler_make_playback(src_pt, dst_pt, mp->sync_ts, mp->media, + mp->ssrc_out->parent->h.ssrc); + if (!mp->coder.handler) + return -1; + + return 0; +} +// used for "play media" player +static int __media_player_setup_internal(struct media_player *mp, const struct rtp_payload_type *src_pt, + const struct rtp_payload_type *dst_pt) +{ + int ret = media_player_setup_common(mp, src_pt, &dst_pt); + if (ret) + return ret; + if (!mp->coder.handler) - mp->coder.handler = codec_handler_make_playback(src_pt, dst_pt, mp->sync_ts, mp->media); + mp->coder.handler = codec_handler_make_media_player(src_pt, dst_pt, mp->sync_ts, mp->media, + mp->ssrc_out->parent->h.ssrc); if (!mp->coder.handler) return -1; @@ -726,7 +755,7 @@ static int __ensure_codec_handler(struct media_player *mp, const struct rtp_payl src_pt.clock_rate = mp->coder.avstream->CODECPAR->sample_rate; codec_init_payload_type(&src_pt, MT_AUDIO); - if (media_player_setup(mp, &src_pt, dst_pt)) + if (__media_player_setup_internal(mp, &src_pt, dst_pt)) return -1; mp->coder.duration = mp->coder.avstream->duration * 1000 * mp->coder.avstream->time_base.num diff --git a/include/codec.h b/include/codec.h index 415f4d5ed..affdb3a77 100644 --- a/include/codec.h +++ b/include/codec.h @@ -98,7 +98,9 @@ struct codec_handler *codec_handler_get(struct call_media *, int payload_type, s struct sink_handler *); void codec_handlers_free(struct call_media *); struct codec_handler *codec_handler_make_playback(const struct rtp_payload_type *src_pt, - const struct rtp_payload_type *dst_pt, unsigned long ts, struct call_media *); + const struct rtp_payload_type *dst_pt, unsigned long ts, struct call_media *, uint32_t ssrc); +struct codec_handler *codec_handler_make_media_player(const struct rtp_payload_type *src_pt, + const struct rtp_payload_type *dst_pt, unsigned long ts, struct call_media *, uint32_t ssrc); struct codec_handler *codec_handler_make_dummy(const struct rtp_payload_type *dst_pt, struct call_media *media); void codec_calc_jitter(struct ssrc_ctx *, unsigned long ts, unsigned int clockrate, const struct timeval *); void codec_update_all_handlers(struct call_monologue *ml);