diff --git a/include/baresip.h b/include/baresip.h index 8ff0b9efc3..29ef25810f 100644 --- a/include/baresip.h +++ b/include/baresip.h @@ -1383,7 +1383,7 @@ struct stream *audio_strm(const struct audio *au); uint64_t audio_jb_current_value(const struct audio *au); int audio_set_bitrate(struct audio *au, uint32_t bitrate); bool audio_rxaubuf_started(const struct audio *au); -int audio_start(struct audio *a); +int audio_update(struct audio *a); int audio_start_source(struct audio *a, struct list *ausrcl, struct list *aufiltl); void audio_stop(struct audio *a); diff --git a/src/audio.c b/src/audio.c index 1255f73186..e4b0703e16 100644 --- a/src/audio.c +++ b/src/audio.c @@ -194,16 +194,6 @@ static void stop_tx(struct autx *tx, struct audio *a) } -static void stop_aur(struct audio_recv *aur) -{ - if (!aur) - return; - - /* audio player must be stopped first */ - aurecv_stop(aur); -} - - static void audio_destructor(void *arg) { struct audio *a = arg; @@ -212,7 +202,7 @@ static void audio_destructor(void *arg) stream_enable(a->strm, false); stop_tx(&a->tx, a); - stop_aur(a->aur); + aurecv_stop(a->aur); mem_deref(a->tx.enc); mem_deref(a->tx.aubuf); @@ -1151,25 +1141,36 @@ static void audio_flush_filters(struct audio *a) /** - * Start the audio playback and recording + * Update audio object and start/stop according to media direction * * @param a Audio object * * @return 0 if success, otherwise errorcode */ -int audio_start(struct audio *a) +int audio_update(struct audio *a) { struct list *aufiltl = baresip_aufiltl(); - const struct sdp_media *m; - enum sdp_dir dir; + const struct sdp_format *sc = NULL; + enum sdp_dir dir = SDP_INACTIVE; + struct sdp_media *m; int err = 0; if (!a) return EINVAL; - debug("audio: start\n"); + debug("audio: update\n"); m = stream_sdpmedia(audio_strm(a)); - dir = sdp_media_dir(m); + + if (!sdp_media_disabled(m)) { + dir = sdp_media_dir(m); + sc = sdp_media_rformat(m, NULL); + } + + if (!sc) { + info("audio: stream is disabled\n"); + audio_stop(a); + return 0; + } /* Audio filter */ if (!list_isempty(aufiltl)) { @@ -1180,10 +1181,33 @@ int audio_start(struct audio *a) } if (dir & SDP_RECVONLY) - err |= aurecv_start_player(a->aur, baresip_auplayl()); + err |= audio_decoder_set(a, sc->data, sc->pt, sc->rparams); if (dir & SDP_SENDONLY) + err = audio_encoder_set(a, sc->data, sc->pt, sc->params); + + if (dir & SDP_RECVONLY) { + stream_enable_rx(a->strm, true); + } + else { + stream_enable_rx(a->strm, false); + aurecv_stop(a->aur); + } + + if (dir == SDP_RECVONLY) + stream_open_natpinhole(a->strm); + else + stream_stop_natpinhole(a->strm); + + if (dir & SDP_SENDONLY) { err |= start_source(&a->tx, a, baresip_ausrcl()); + stream_enable_tx(a->strm, true); + } + else { + stream_enable_tx(a->strm, false); + stop_tx(&a->tx, a); + } + if (err) { warning("audio: start error (%m)\n", err); return err; @@ -1257,7 +1281,7 @@ void audio_stop(struct audio *a) stop_tx(&a->tx, a); stream_enable(a->strm, false); - stop_aur(a->aur); + aurecv_stop(a->aur); a->started = false; } @@ -1281,6 +1305,8 @@ bool audio_started(const struct audio *a) /** * Set the audio encoder used * + * @note The audio source has to be started separately + * * @param a Audio object * @param ac Audio codec to use * @param pt_tx Payload type for sending @@ -1338,10 +1364,6 @@ int audio_encoder_set(struct audio *a, const struct aucodec *ac, if (ac->ptime) tx->ptime = ac->ptime; - if (!tx->ausrc) { - err |= audio_start(a); - } - return err; } @@ -1349,6 +1371,8 @@ int audio_encoder_set(struct audio *a, const struct aucodec *ac, /** * Set the audio decoder used * + * @note Starts also the player if not already running + * * @param a Audio object * @param ac Audio codec to use * @param pt Payload type for receiving @@ -1384,7 +1408,7 @@ int audio_decoder_set(struct audio *a, const struct aucodec *ac, stream_set_srate(a->strm, 0, ac->crate); if (reset || !aurecv_player_started(a->aur)) - err |= audio_start(a); + err |= aurecv_start_player(a->aur, baresip_auplayl()); return err; } @@ -1743,6 +1767,7 @@ int audio_set_player(struct audio *a, const char *mod, const char *device) return EINVAL; aurecv_stop_auplay(a->aur); + stream_flush(a->strm); if (!str_isset(mod)) return 0; diff --git a/src/call.c b/src/call.c index 63f744733e..d9838ffce2 100644 --- a/src/call.c +++ b/src/call.c @@ -141,75 +141,12 @@ static const struct sdp_format *sdp_media_rcodec(const struct sdp_media *m) } -static int start_audio(struct call *call) +static void call_timer_start(struct call *call) { - const struct sdp_format *sc; - const struct sdp_media *m = stream_sdpmedia(audio_strm(call->audio)); - struct aucodec *ac; - enum sdp_dir dir = sdp_media_dir(m); - int err = 0; - - /* Audio Stream */ - sc = sdp_media_rcodec(m); - if (!sc) { - info("call: audio stream is disabled\n"); - return 0; - } - - ac = sc->data; - if (dir & SDP_SENDONLY) - err |= audio_encoder_set(call->audio, ac, - sc->pt, sc->params); - - if (dir & SDP_RECVONLY) - err |= audio_decoder_set(call->audio, ac, - sc->pt, sc->params); - if (err) { - warning("call: start:" - " audio codec setup error (%m)\n", err); - return err; - } - - err = audio_start(call->audio); - if (err) - return err; - - return 0; -} - - -static void call_stream_start(struct call *call, bool active) -{ - int err; - struct le *le; - - debug("call: stream start (active=%d)\n", active); - - if (stream_is_ready(audio_strm(call->audio))) { - err = start_audio(call); - if (err) { - warning("call: could not start audio: %m\n", err); - } - } - - if (stream_is_ready(video_strm(call->video))) { - err = video_update(call->video, call->peer_uri); - if (err) { - warning("call: could not start video: %m\n", err); - } - } - - if (active) { - - tmr_cancel(&call->tmr_inv); - call->time_start = time(NULL); - - stream_flush(audio_strm(call->audio)); - } + debug("call: timer started\n"); - FOREACH_STREAM { - stream_enable(le->data, true); - } + tmr_cancel(&call->tmr_inv); + call->time_start = time(NULL); } @@ -309,34 +246,6 @@ static void mnat_handler(int err, uint16_t scode, const char *reason, } -static int update_audio(struct call *call) -{ - const struct sdp_format *sc; - int err = 0; - - debug("audio: update\n"); - - sc = sdp_media_rcodec(stream_sdpmedia(audio_strm(call->audio))); - if (sc) { - struct aucodec *ac = sc->data; - - err = audio_decoder_set(call->audio, ac, - sc->pt, sc->params); - if (err) { - warning("call: update:" - " audio_decoder_set error: %m\n", err); - } - err |= audio_encoder_set(call->audio, ac, - sc->pt, sc->params); - } - else { - info("audio stream is disabled..\n"); - } - - return err; -} - - static int call_apply_sdp(struct call *call) { struct le *le; @@ -377,7 +286,7 @@ static int update_streams(struct call *call) return EINVAL; if (stream_is_ready(audio_strm(call->audio))) - err |= update_audio(call); + err |= audio_update(call->audio); else audio_stop(call->audio); @@ -528,7 +437,7 @@ static void menc_event_handler(enum menc_event event, if (strstr(prm, "audio")) { stream_set_secure(audio_strm(call->audio), true); stream_start_rtcp(audio_strm(call->audio)); - err = start_audio(call); + err = audio_update(call->audio); if (err) { warning("call: secure: could not" " start audio: %m\n", err); @@ -593,7 +502,7 @@ static void stream_mnatconn_handler(struct stream *strm, void *arg) switch (stream_type(strm)) { case MEDIA_AUDIO: - err = start_audio(call); + err = audio_update(call->audio); if (err) { warning("call: mnatconn: could not" " start audio: %m\n", err); @@ -1325,8 +1234,6 @@ int call_progress_dir(struct call *call, enum sdp_dir adir, enum sdp_dir vdir) if (err) goto out; - call_stream_start(call, false); - out: mem_deref(desc); @@ -1954,7 +1861,7 @@ static void sipsess_estab_handler(const struct sip_msg *msg, void *arg) if (call->got_offer) (void)update_streams(call); - call_stream_start(call, true); + call_timer_start(call); if (call->rtp_timeout_ms) { @@ -2412,7 +2319,6 @@ static void sipsess_progr_handler(const struct sip_msg *msg, void *arg) mem_ref(call); call_event_handler(call, CALL_EVENT_PROGRESS, "%s", call->peer_uri); - call_stream_start(call, false); mem_deref(call); } else {