From 1db7678e2e804d982177277e3efda95c40f5d830 Mon Sep 17 00:00:00 2001
From: Philip-Dylan Gleonec <philip-dylan.gleonec@savoirfairelinux.com>
Date: Mon, 15 Feb 2021 17:44:03 +0100
Subject: [PATCH] ffmpeg: update fec patch to match recent ffmpeg

An AVOption has been added to ffmpeg in sept. 2020, making the patch in
contrib redundant. This change is integrated in the contrib ffmpeg
starting from commit 855019860, which updates the used version.

This patch adapts the patches to be applied to ffmpeg and the call to
enable FEC in libopus. Specifically it does the following changes:

- backport the mainline ffmpeg patch that add fec to libopusenc
- add packet_loss reload to adapt its value to network
- modify rules.mak to add patches to the correct platforms
- make media_encoder set the right AVOption to enable fec

Issue: #4857
Change-Id: I614fce2f0cf7fc387973b34323138b07c1767726
---
 ...opusenc-reload-packet-loss-at-encode.patch | 44 +++++++++++++++++++
 contrib/src/ffmpeg/package.json               |  2 +-
 contrib/src/ffmpeg/rules.mak                  |  6 +--
 src/media/media_encoder.cpp                   |  2 +-
 4 files changed, 48 insertions(+), 6 deletions(-)
 create mode 100644 contrib/src/ffmpeg/libopusenc-reload-packet-loss-at-encode.patch

diff --git a/contrib/src/ffmpeg/libopusenc-reload-packet-loss-at-encode.patch b/contrib/src/ffmpeg/libopusenc-reload-packet-loss-at-encode.patch
new file mode 100644
index 0000000000..5c4bd4d3eb
--- /dev/null
+++ b/contrib/src/ffmpeg/libopusenc-reload-packet-loss-at-encode.patch
@@ -0,0 +1,44 @@
+From dba13d03bc8e827fededc20b0ab1f574a1500f2a Mon Sep 17 00:00:00 2001
+From: Philip-Dylan Gleonec <philip-dylan.gleonec@savoirfairelinux.com>
+Date: Thu, 11 Feb 2021 12:25:14 +0100
+Subject: [PATCH 2/2] avcodec/libopusenc: reload packet loss at encode
+
+An estimation of packet loss is required by libopus to compute its FEC
+data. Currently, this estimation is constant, and can not be changed
+after configuration. This means an application using libopus through
+ffmpeg can not adapt the packet loss estimation when the network
+quality degrades.
+
+This patch makes the encoder reload the packet_loss AVOption before
+encoding samples, if fec is enabled. This way an application can modify
+the packet loss estimation by changing the AVOption. Typical use-case
+is a RTP stream, where packet loss can be estimated from RTCP packets.
+
+Signed-off-by: Philip-Dylan Gleonec <philip-dylan.gleonec@savoirfairelinux.com>
+---
+ libavcodec/libopusenc.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c
+index 70d17f802b..c18e8ae7fa 100644
+--- a/libavcodec/libopusenc.c
++++ b/libavcodec/libopusenc.c
+@@ -460,6 +460,15 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt,
+     int ret;
+     int discard_padding;
+ 
++    if (opus->opts.fec) {
++        ret = opus_multistream_encoder_ctl(opus->enc,
++                                           OPUS_SET_PACKET_LOSS_PERC(opus->opts.packet_loss));
++        if (ret != OPUS_OK)
++            av_log(avctx, AV_LOG_WARNING,
++                   "Unable to set expected packet loss percentage: %s\n",
++                   opus_strerror(ret));
++    }
++
+     if (frame) {
+         ret = ff_af_queue_add(&opus->afq, frame);
+         if (ret < 0)
+-- 
+2.25.1
+
diff --git a/contrib/src/ffmpeg/package.json b/contrib/src/ffmpeg/package.json
index ed715bdc3c..a5af29200f 100644
--- a/contrib/src/ffmpeg/package.json
+++ b/contrib/src/ffmpeg/package.json
@@ -12,7 +12,7 @@
     "patches": [
         "change-RTCP-ratio.patch",
         "rtp_ext_abs_send_time.patch",
-        "libopusenc-enable-FEC.patch",
+        "libopusenc-reload-packet-loss-at-encode.patch",
         "libopusdec-enable-FEC.patch"
     ],
     "win_patches": [
diff --git a/contrib/src/ffmpeg/rules.mak b/contrib/src/ffmpeg/rules.mak
index 980bde8a8a..e092f65781 100644
--- a/contrib/src/ffmpeg/rules.mak
+++ b/contrib/src/ffmpeg/rules.mak
@@ -363,11 +363,9 @@ ffmpeg: ffmpeg-$(FFMPEG_HASH).tar.gz
 	$(APPLY) $(SRC)/ffmpeg/change-RTCP-ratio.patch
 	$(APPLY) $(SRC)/ffmpeg/rtp_ext_abs_send_time.patch
 	$(APPLY) $(SRC)/ffmpeg/libopusdec-enable-FEC.patch
-	$(APPLY) $(SRC)/ffmpeg/libopusenc-enable-FEC.patch
-	$(APPLY) $(SRC)/ffmpeg/screen-sharing-x11-fix.patch
-ifdef HAVE_IOS
+	$(APPLY) $(SRC)/ffmpeg/libopusenc-reload-packet-loss-at-encode.patch
 	$(APPLY) $(SRC)/ffmpeg/ios-disable-b-frames.patch
-endif
+	$(APPLY) $(SRC)/ffmpeg/screen-sharing-x11-fix.patch
 	$(UPDATE_AUTOCONFIG)
 	$(MOVE)
 
diff --git a/src/media/media_encoder.cpp b/src/media/media_encoder.cpp
index 317435f562..43822c9ebb 100644
--- a/src/media/media_encoder.cpp
+++ b/src/media/media_encoder.cpp
@@ -1058,7 +1058,7 @@ void
 MediaEncoder::initOpus(AVCodecContext* encoderCtx)
 {
     // Enable FEC support by default with 10% packet loss
-    av_opt_set_int(encoderCtx, "enable_fec", fecEnabled_ ? 1 : 0, AV_OPT_SEARCH_CHILDREN);
+    av_opt_set_int(encoderCtx, "fec", fecEnabled_ ? 1 : 0, AV_OPT_SEARCH_CHILDREN);
     av_opt_set_int(encoderCtx, "packet_loss", 10, AV_OPT_SEARCH_CHILDREN);
 }
 
-- 
GitLab