From cbbf2f710beaba36dbc415cdcd4f8ae32c447003 Mon Sep 17 00:00:00 2001
From: Pierre Lespagnol <pierre.lespagnol@savoirfairelinux.com>
Date: Fri, 31 Jul 2020 12:15:16 -0400
Subject: [PATCH] autoadapt: use crf mode for the congestion control algo

Change-Id: I1c30102c406277c38605b73fec43debd153df1fc
---
 src/media/media_encoder.cpp           | 21 +++++++++------------
 src/media/video/video_rtp_session.cpp |  1 -
 2 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/src/media/media_encoder.cpp b/src/media/media_encoder.cpp
index fe1ea7e4b4..c9e632b6f3 100644
--- a/src/media/media_encoder.cpp
+++ b/src/media/media_encoder.cpp
@@ -819,16 +819,15 @@ MediaEncoder::initH264(AVCodecContext* encoderCtx, uint64_t br)
     if(mode_ == RateMode::CRF_CONSTRAINED) {
         uint64_t maxBitrate = 1000 * br;
         uint8_t crf = (uint8_t) std::round(LOGREG_PARAM_A + log(pow(maxBitrate, LOGREG_PARAM_B)));     // CRF = A + B*ln(maxBitrate)
-        uint64_t bufSize = maxBitrate * 2;
+        // bufsize parameter impact the variation of the bitrate, reduce to half the maxrate to limit peak and congestion
+        //https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
+        uint64_t bufSize = maxBitrate / 2;
 
         av_opt_set_int(encoderCtx, "crf", crf, AV_OPT_SEARCH_CHILDREN);
-        av_opt_set_int(encoderCtx, "b", maxBitrate, AV_OPT_SEARCH_CHILDREN);
         av_opt_set_int(encoderCtx, "maxrate", maxBitrate, AV_OPT_SEARCH_CHILDREN);
-        av_opt_set_int(encoderCtx, "minrate", -1, AV_OPT_SEARCH_CHILDREN);
         av_opt_set_int(encoderCtx, "bufsize", bufSize, AV_OPT_SEARCH_CHILDREN);
-        JAMI_DBG("H264 encoder setup: crf=%u, maxrate=%lu, bufsize=%lu", crf, maxBitrate, bufSize);
+        JAMI_DBG("H264 encoder setup: crf=%u, maxrate=%lu kbit/s, bufsize=%lu kbit", crf, maxBitrate/1000, bufSize/1000);
     }
-    // If auto quality enabled use CRB mode
     else if (mode_ == RateMode::CBR) {
         av_opt_set_int(encoderCtx, "b", br * 1000, AV_OPT_SEARCH_CHILDREN);
         av_opt_set_int(encoderCtx, "maxrate", br * 1000, AV_OPT_SEARCH_CHILDREN);
@@ -849,13 +848,11 @@ MediaEncoder::initH265(AVCodecContext* encoderCtx, uint64_t br)
         // H265 use 50% less bitrate compared to H264 (half bitrate is equivalent to a change 6 for CRF)
         // https://slhck.info/video/2017/02/24/crf-guide.html
         uint8_t crf = (uint8_t) std::round(LOGREG_PARAM_A + log(pow(maxBitrate, LOGREG_PARAM_B)) - 6);     // CRF = A + B*ln(maxBitrate)
-        uint64_t bufSize = maxBitrate * 2;
+        uint64_t bufSize = maxBitrate / 2;
         av_opt_set_int(encoderCtx, "crf", crf, AV_OPT_SEARCH_CHILDREN);
-        av_opt_set_int(encoderCtx, "b", maxBitrate, AV_OPT_SEARCH_CHILDREN);
         av_opt_set_int(encoderCtx, "maxrate", maxBitrate, AV_OPT_SEARCH_CHILDREN);
-        av_opt_set_int(encoderCtx, "minrate", -1, AV_OPT_SEARCH_CHILDREN);
         av_opt_set_int(encoderCtx, "bufsize", bufSize, AV_OPT_SEARCH_CHILDREN);
-        JAMI_DBG("H265 encoder setup: crf=%u, maxrate=%lu, bufsize=%lu", crf, maxBitrate, bufSize);
+        JAMI_DBG("H265 encoder setup: crf=%u, maxrate=%lu kbit/s, bufsize=%lu kbit", crf, maxBitrate/1000, bufSize/1000);
     }
     else if (mode_ == RateMode::CBR) {
         av_opt_set_int(encoderCtx, "b", br * 1000, AV_OPT_SEARCH_CHILDREN);
@@ -891,7 +888,7 @@ MediaEncoder::initVP8(AVCodecContext* encoderCtx, uint64_t br)
         // http://www.webmproject.org/docs/encoder-parameters/
         uint64_t maxBitrate = 1000 * br;
         uint8_t crf = (uint8_t) std::round(LOGREG_PARAM_A + log(pow(maxBitrate, LOGREG_PARAM_B)));     // CRF = A + B*ln(maxBitrate)
-        uint64_t bufSize = 2 * maxBitrate;
+        uint64_t bufSize = maxBitrate / 2;
 
         av_opt_set(encoderCtx, "quality", "realtime", AV_OPT_SEARCH_CHILDREN);
         av_opt_set_int(encoderCtx, "error-resilient", 1, AV_OPT_SEARCH_CHILDREN);
@@ -917,7 +914,7 @@ void
 MediaEncoder::initMPEG4(AVCodecContext* encoderCtx, uint64_t br)
 {
     uint64_t maxBitrate = 1000 * br;
-    uint64_t bufSize = 2 * maxBitrate;
+    uint64_t bufSize = maxBitrate / 2;
 
     // Use CBR (set bitrate)
     encoderCtx->rc_buffer_size = bufSize;
@@ -929,7 +926,7 @@ void
 MediaEncoder::initH263(AVCodecContext* encoderCtx, uint64_t br)
 {
     uint64_t maxBitrate = 1000 * br;
-    uint64_t bufSize = 2 * maxBitrate;
+    uint64_t bufSize = maxBitrate / 2;
 
     // Use CBR (set bitrate)
     encoderCtx->rc_buffer_size = bufSize;
diff --git a/src/media/video/video_rtp_session.cpp b/src/media/video/video_rtp_session.cpp
index c67371fbaf..8bdfddb4f7 100644
--- a/src/media/video/video_rtp_session.cpp
+++ b/src/media/video/video_rtp_session.cpp
@@ -136,7 +136,6 @@ void VideoRtpSession::startSender()
         auto codecVideo = std::static_pointer_cast<jami::AccountVideoCodecInfo>(send_.codec);
         auto autoQuality = codecVideo->isAutoQualityEnabled;
 
-        send_.mode = autoQuality ? RateMode::CBR : RateMode::CRF_CONSTRAINED;
         send_.linkableHW = conference_ == nullptr;
         send_.bitrate = videoBitrateInfo_.videoBitrateCurrent;
 
-- 
GitLab