diff --git a/src/media/audio/audio_receive_thread.cpp b/src/media/audio/audio_receive_thread.cpp index 754a2e5482bbbd214fd01b318fc432ff1b651018..41253d5340dd49d07e9fbcc7b1221b45263447a2 100644 --- a/src/media/audio/audio_receive_thread.cpp +++ b/src/media/audio/audio_receive_thread.cpp @@ -73,6 +73,7 @@ AudioReceiveThread::setup() } audioDecoder_->setIOContext(sdpContext_.get()); + audioDecoder_->setFEC(true); if (audioDecoder_->openInput(args_)) { JAMI_ERR("Could not open input \"%s\"", SDP_FILENAME); return false; diff --git a/src/media/audio/audio_rtp_session.cpp b/src/media/audio/audio_rtp_session.cpp index b86d1706e12c1e19e7e22644c818d2b44161ade3..743c30349ec8ee9a61ce10cebf9c21902803b0e5 100644 --- a/src/media/audio/audio_rtp_session.cpp +++ b/src/media/audio/audio_rtp_session.cpp @@ -99,6 +99,8 @@ AudioRtpSession::startSender() return; } + send_.fecEnabled = true; + // be sure to not send any packets before saving last RTP seq value socketPair_->stopSendOp(); if (sender_) diff --git a/src/media/media_codec.h b/src/media/media_codec.h index 56d78b4637e2014060cefc1f1adaf24350f0836c..01830b0b319a9236e9a36c3257417736854da566 100644 --- a/src/media/media_codec.h +++ b/src/media/media_codec.h @@ -278,6 +278,7 @@ struct MediaDescription /** Audio parameters */ unsigned frame_size {}; + bool fecEnabled {false}; /** Video parameters */ std::string parameters {}; diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp index 65fe1888823d45faf508d0b3d9c415308a1120bd..d593512c57e67701488c46898873db8912d56a9d 100644 --- a/src/media/media_decoder.cpp +++ b/src/media/media_decoder.cpp @@ -545,7 +545,7 @@ MediaDecoder::prepareDecoderContext() } if (avStream_->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { if (decoderCtx_->codec_id == AV_CODEC_ID_OPUS) { - av_opt_set_int(decoderCtx_, "decode_fec", 1, AV_OPT_SEARCH_CHILDREN); + av_opt_set_int(decoderCtx_, "decode_fec", fecEnabled_ ? 1 : 0, AV_OPT_SEARCH_CHILDREN); } } return 0; diff --git a/src/media/media_decoder.h b/src/media/media_decoder.h index 64c4047b7c41fdc0eff269e23ece0f048a17961d..a296d5397be51f886802730de10679450d32c472 100644 --- a/src/media/media_decoder.h +++ b/src/media/media_decoder.h @@ -178,7 +178,6 @@ public: rational<double> getFps() const; AVPixelFormat getPixelFormat() const; - void setOptions(const std::map<std::string, std::string>& options); void updateStartTime(int64_t startTime); @@ -193,6 +192,8 @@ public: void setResolutionChangedCallback(std::function<void(int, int)> cb) { resolutionChangedCallback_ = std::move(cb); } + void setFEC(bool enable) { fecEnabled_ = enable; } + private: NON_COPYABLE(MediaDecoder); @@ -230,6 +231,8 @@ private: int width_; int height_; + bool fecEnabled_ {false}; + protected: AVDictionary* options_ = nullptr; }; diff --git a/src/media/media_encoder.cpp b/src/media/media_encoder.cpp index 225efd05b9b67837c589d866b70444f8bd070721..805108eb686c846c877ad33eda6ab5cc9ecf9142 100644 --- a/src/media/media_encoder.cpp +++ b/src/media/media_encoder.cpp @@ -129,6 +129,7 @@ MediaEncoder::setOptions(const MediaDescription& args) mode_ = args.mode; linkableHW_ = args.linkableHW; + fecEnabled_ = args.fecEnabled; } void @@ -996,7 +997,7 @@ void MediaEncoder::initOpus(AVCodecContext* encoderCtx) { // Enable FEC support by default with 10% packet loss - av_opt_set_int(encoderCtx, "enable_fec", 1, AV_OPT_SEARCH_CHILDREN); + av_opt_set_int(encoderCtx, "enable_fec", fecEnabled_ ? 1 : 0, AV_OPT_SEARCH_CHILDREN); av_opt_set_int(encoderCtx, "packet_loss", 10, AV_OPT_SEARCH_CHILDREN); } diff --git a/src/media/media_encoder.h b/src/media/media_encoder.h index 2ce7963c6080abd55285ac6e89b260ad31dae0af..983ec23966558c2fc57c8f70cc2f9a63176bd0e2 100644 --- a/src/media/media_encoder.h +++ b/src/media/media_encoder.h @@ -155,6 +155,7 @@ private: std::mutex encMutex_; bool linkableHW_ {false}; RateMode mode_ {RateMode::CRF_CONSTRAINED}; + bool fecEnabled_ {false}; #ifdef ENABLE_VIDEO video::VideoScaler scaler_;