]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-8161: mod_opus: Keep FEC enabled only if loss > 10 ( otherwise PLC is supposed...
authorDragos Oancea <droancea@yahoo.com>
Thu, 17 Sep 2015 16:52:55 +0000 (12:52 -0400)
committerDragos Oancea <droancea@yahoo.com>
Thu, 17 Sep 2015 17:29:38 +0000 (13:29 -0400)
src/mod/codecs/mod_opus/mod_opus.c

index 6f56727667cac90e26f910ee0935802e5270733c..74f797512ad108cdd74213b61cc236ecac7e7506 100644 (file)
@@ -309,6 +309,33 @@ static switch_bool_t switch_opus_has_fec(const uint8_t* payload,int payload_leng
        return  SWITCH_FALSE;
 }
 
+/* this is only useful for fs = 8000 hz, the map is only used
+ * at the beginning of the call. */
+static int switch_opus_get_fec_bitrate(int fs, int loss)
+{
+       int threshold_bitrates[25] = {
+               15600,15200,15200,15200,14800,
+               14800,14800,14800,14400,14400,
+               14400,14000,14000,14000,13600,
+               13600,13600,13600,13200,13200,
+               13200,12800,12800,12800,12400
+       };
+
+       if (loss <= 0){
+               return SWITCH_STATUS_FALSE;
+       } 
+
+       if (fs == 8000) {
+               if (loss >=25) { 
+                       return threshold_bitrates[24];
+               } else {
+                       return threshold_bitrates[loss-1];
+               }
+       }
+
+       return SWITCH_STATUS_FALSE ; 
+}
+
 static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint32_t samples_per_second, char *print_text)
 {
        int nb_samples;
@@ -493,7 +520,20 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
                }
 
                if (opus_codec_settings.useinbandfec) {
+                       /* FEC on the encoder: start the call with a preconfigured packet loss percentage */
+                       int fec_bitrate = opus_codec_settings.maxaveragebitrate;
+                       int loss_percent = opus_prefs.plpct ; 
                        opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC(opus_codec_settings.useinbandfec));
+                       opus_encoder_ctl(context->encoder_object, OPUS_SET_PACKET_LOSS_PERC(loss_percent));
+                       if (opus_prefs.keep_fec){  
+                               fec_bitrate = switch_opus_get_fec_bitrate(enc_samplerate,loss_percent); 
+                                /* keep a bitrate for which the encoder will always add FEC */
+                               if (fec_bitrate != SWITCH_STATUS_FALSE) {
+                                       opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(fec_bitrate)); 
+                                       /* will override the maxaveragebitrate set in opus.conf.xml  */ 
+                                       opus_codec_settings.maxaveragebitrate = fec_bitrate;
+                               }
+                       }
                }
 
                if (opus_codec_settings.usedtx) {
@@ -954,18 +994,21 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
                                plpct = 100;
                        }
 
-                       calc = plpct % 10;
-                       plpct = plpct - calc + ( calc ? 10 : 0);
-
-                       if (opus_prefs.plpct > 0 && plpct < opus_prefs.plpct) {
-                               plpct = opus_prefs.plpct;
+                       if (opus_prefs.keep_fec) {
+                               opus_encoder_ctl(context->encoder_object, OPUS_SET_PACKET_LOSS_PERC(plpct));
+                       } else {
+                               calc = plpct % 10;
+                               plpct = plpct - calc + ( calc ? 10 : 0);
                        }
-
                        if (plpct != context->old_plpct) {
-                               opus_encoder_ctl(context->encoder_object, OPUS_SET_PACKET_LOSS_PERC(plpct));
-
                                if (opus_prefs.keep_fec) {
-                                       switch_opus_keep_fec_enabled(codec);
+                                       if (plpct > 10) {
+                                       /* this will increase bitrate a little bit, just to keep FEC enabled */
+                                               switch_opus_keep_fec_enabled(codec);
+                                       }
+                               } else {
+                                       /* this can have no effect because FEC is F(bitrate,packetloss), let the codec decide if FEC is to be used or not */
+                                       opus_encoder_ctl(context->encoder_object, OPUS_SET_PACKET_LOSS_PERC(plpct));
                                }
 
                                if (globals.debug || context->debug) {