From b318b93fd3ca72c5d8650ebd4063a757cdd21400 Mon Sep 17 00:00:00 2001
From: Philip-Dylan Gleonec <philip-dylan.gleonec@savoirfairelinux.com>
Date: Thu, 14 Jan 2021 15:16:25 +0100
Subject: [PATCH] ffmpeg: add FEC support to libopusenc

Add option to enable FEC support in libopus encoder, and adds uses this
option to instanciate the opus encoder.
This option is disabled by default, in order to avoid changing default
ffmpeg behavior. If FEC support is enabled and packet loss is higher
than 0, the encoder adds ancilliary data to the packet so the decoder
can restore the previous packet, in case it is lost. As more data has
to be transmitted, this reduces the audio quality when using a fixed
bitrate.

Issue: #5156
Change-Id: Ic7d69ab122bd63c3ff880e46a0a0dcb316b00760
---
 .../src/ffmpeg/libopusenc-enable-FEC.patch    | 34 +++++++++++++++++++
 contrib/src/ffmpeg/rules.mak                  |  1 +
 2 files changed, 35 insertions(+)
 create mode 100644 contrib/src/ffmpeg/libopusenc-enable-FEC.patch

diff --git a/contrib/src/ffmpeg/libopusenc-enable-FEC.patch b/contrib/src/ffmpeg/libopusenc-enable-FEC.patch
new file mode 100644
index 0000000000..0aa68c3c69
--- /dev/null
+++ b/contrib/src/ffmpeg/libopusenc-enable-FEC.patch
@@ -0,0 +1,34 @@
+diff --git a/libavcodec/libopusencc.c b/libavcodec/libopusencc.c
+index 2a97811d18..40ee7b8fec 100644
+--- a/libavcodec/libopusenc.c
++++ b/libavcodec/libopusenc.c
+@@ -33,6 +33,7 @@
+ typedef struct LibopusEncOpts {
+     int vbr;
+     int application;
++    int enable_fec;
+     int packet_loss;
+     int complexity;
+     float frame_duration;
+@@ -143,6 +144,13 @@
+                "Unable to set constrained VBR: %s\n", opus_strerror(ret));
+
+     ret = opus_multistream_encoder_ctl(enc,
++                                       OPUS_SET_INBAND_FEC(opts->enable_fec));
++    if (ret != OPUS_OK)
++        av_log(avctx, AV_LOG_WARNING,
++               "Unable to set enable FEC flag percentage: %s\n",
++               opus_strerror(ret));
++
++    ret = opus_multistream_encoder_ctl(enc,
+                                        OPUS_SET_PACKET_LOSS_PERC(opts->packet_loss));
+     if (ret != OPUS_OK)
+         av_log(avctx, AV_LOG_WARNING,
+@@ -543,6 +551,7 @@
+         { "audio",          "Favor faithfulness to the input",         0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_AUDIO },               0, 0, FLAGS, "application" },
+         { "lowdelay",       "Restrict to only the lowest delay modes", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_RESTRICTED_LOWDELAY }, 0, 0, FLAGS, "application" },
+     { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 20.0 }, 2.5, 120.0, FLAGS },
++    { "enable_fec",     "Enable forward error correction",     OFFSET(enable_fec),     AV_OPT_TYPE_BOOL,  { .i64 = 0 },    0,   1,     FLAGS },
+     { "packet_loss",    "Expected packet loss percentage",     OFFSET(packet_loss),    AV_OPT_TYPE_INT,   { .i64 = 0 },    0,   100,  FLAGS },
+     { "vbr",            "Variable bit rate mode",              OFFSET(vbr),            AV_OPT_TYPE_INT,   { .i64 = 1 },    0,   2,    FLAGS, "vbr" },
+         { "off",            "Use constant bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "vbr" },
diff --git a/contrib/src/ffmpeg/rules.mak b/contrib/src/ffmpeg/rules.mak
index 5390094ecb..b138d35a16 100644
--- a/contrib/src/ffmpeg/rules.mak
+++ b/contrib/src/ffmpeg/rules.mak
@@ -352,6 +352,7 @@ 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
 	$(UPDATE_AUTOCONFIG)
 	$(MOVE)
 
-- 
GitLab