|
|
|
@ -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,
|
|
|
|
static int media_player_setup_common(struct media_player *mp, const struct rtp_payload_type *src_pt,
|
|
|
|
const struct rtp_payload_type *dst_pt)
|
|
|
|
const struct rtp_payload_type **dst_pt)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!dst_pt)
|
|
|
|
if (!*dst_pt)
|
|
|
|
dst_pt = media_player_get_dst_pt(mp);
|
|
|
|
*dst_pt = media_player_get_dst_pt(mp);
|
|
|
|
if (!dst_pt)
|
|
|
|
if (!*dst_pt)
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
// if we played anything before, scale our sync TS according to the time
|
|
|
|
// if we played anything before, scale our sync TS according to the time
|
|
|
|
// that has passed
|
|
|
|
// that has passed
|
|
|
|
if (mp->sync_ts_tv.tv_sec) {
|
|
|
|
if (mp->sync_ts_tv.tv_sec) {
|
|
|
|
long long ts_diff_us = timeval_diff(&rtpe_now, &mp->sync_ts_tv);
|
|
|
|
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 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");
|
|
|
|
ilog(LOG_DEBUG, "Resetting codec handler for media player");
|
|
|
|
codec_handler_free(&mp->coder.handler);
|
|
|
|
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)
|
|
|
|
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)
|
|
|
|
if (!mp->coder.handler)
|
|
|
|
return -1;
|
|
|
|
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;
|
|
|
|
src_pt.clock_rate = mp->coder.avstream->CODECPAR->sample_rate;
|
|
|
|
codec_init_payload_type(&src_pt, MT_AUDIO);
|
|
|
|
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;
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
mp->coder.duration = mp->coder.avstream->duration * 1000 * mp->coder.avstream->time_base.num
|
|
|
|
mp->coder.duration = mp->coder.avstream->duration * 1000 * mp->coder.avstream->time_base.num
|
|
|
|
|