7.10.2022

Rtpengine. Opus. Ilbc.

I am using ilbc to make calls with mobile applications. As we know ilbc is old codec, all tests,table and pictures all over the net make us feel as ilbc most worse then opus. because opus is faster, more quality e.t.c.

Seems… my opinion is different, if you want good quality and minimum bandwidth out of box then use ilbc – it’s not problem, it will have 23kb bandwidth for one side. Audio bandwidth up to 4kHz so voice will be good enough for conversation. But there is no way to reduce bitrate and bandwidth with ilbc, so let’s try to implement opus.

also, converting 48kHz(sample rate) files with libopus is slowest then with ilbc in most of cases. Be noted that you can not use opus with 8kHz(sample rate) in default configuration by rtpengine only 48kHz is supported.

Components used for testing:

  • centos 7: iftop, tcpdump
  • custom ffmpeg 4.2.7,
  • opus 1.3.2,
  • opus-tools: opusenc, opusrtp
  • rtpengine 11.0.1.5,
  • microsip 3,
  • sipp 3.6.
  • clumsy ( simulate bad network on windows)

I will start from end, maybe it will be helpful for someone. What was my aim, i wanted to use packet loss, fec, speech mode, low bandwidth from opus codec.
Success:
* low bandwidth with 8kb\s bitrate (13kb\s actual) and 40ms frame duration.
Failed:
* packet_loss (no way to understand if it really works, real test does not show that it helps)
* fec, ( same as packet loss)
* speech mode, (take more cpu resources when encoding without real result)

How to add opus support into rtpengine.

For encoding\decoding opus rtpeginge using ffmpeg library. so you have to be sure that libopus is present with ffmpeg. you can do that with: “ffmpeg -h encoder=libopus” if you don’t see: “Codec ‘libopus’ is not recognized by FFmpeg.” then seems ffmpeg have opus with libopus encoder\decoder.

How to set parameters for opus codec:

when you do rtpengine_offer use this: as one of params:
codec-transcode-opus/48000/2/8000/40/maxaveragebitrate–8000;maxplaybackrate–12000;useinbandfec–1;ptime–40;maxptime–40/ar-48000,b–8000
where is :
48000 – sample rate in SDP
2 – channels (default for opus)
8000 (b\s) – bitrate for codec implement on encoder side
40 (ms) – frame duration (should affect on encoder side, but you have a=ptime 20 in SDP, codec will work on 20 ms)
“maxaveragebitrate–8000;maxplaybackrate–12000;useinbandfec–1;ptime–40;maxptime–40” there are a=fmtp parameters into SDP, you can check what it means in RFC.
“ar–48000,b–8000” – codec individual options you can take a look ffmpeg docs to check what you can use. For some reason individual options for opus codec like packet_loss can not be set by this logic, you have to set it inside codeclib.c in rtpengine source code . for example “

if (enc->ptime > 0 ) {
            codeclib_set_av_opt_int(enc, "frame_duration", enc->ptime);
            codeclib_set_av_opt_int(enc, "packet_loss", 5);
            codeclib_set_av_opt_int(enc, "fec", 1);
            codeclib_set_av_opt_int(enc, "application", 2048);
}


issues: when you set 40 ms frame_duration for opus and you have not any a=ptime 40 in SDP towards to destination peer, peer will not send stream with 40 ms frame_duration, maybe there is a bug into Microsip. Using ptime and maxptime into codec options – not helps.
so, to avoid this i did add ptime=40 as rtpengine_offer parameter and add little fix to codeclib.c to make 40ms default ptime for opus codec.

How to check speed of converting with libopus

you need any music input file, for example any.wav. then you may try to use
ffmpeg -i madonna-48k.wav -c libopus -ab 18000 madonna.opus
it will convert wav file to opus with bitrate 18k\s
as result you will see some data ended with
size= 82kB time=00:00:39.83 bitrate= 16.8kbits/s speed= 136x
also you can convert it with libilbc encoder:
ffmpeg -i madonna-48k.wav -c libilbc -ar 8000 -ab 18000 madonna.lbc
you will see:
size= 74kB time=00:00:39.84 bitrate= 15.2kbits/s speed= 170x

to be continued….