[opus] How to enable OPUS inband FEC
Dmitry Danilov
Dmitry at liveu.tv
Mon Jul 15 08:17:13 UTC 2019
Hi all,
I try to enable FEC in the encoder using the macro OPUS_SET_INBAND_FEC and I set the packet loss percentage to a constant value of 30%, using the macro OPUS_SET_PACKET_LOSS_PERC.
Please find my encoder settings below:
opus: encoder fmtp (maxplaybackrate=8000;maxaveragebitrate=24000;sprop-stereo=1;cbr=1;useinbandfec=1;usedtx=1)
opus: encode bw=narrow bitrate=24000 fch=auto vbr=0 fec=1 expected loss=30 dtx=1 complex=10
At the decoder side when a packet is lost I call the decoder with the next params:
opus_decode(ads->dec, NULL, 0, sampv, (int)(*sampc/ads->ch), 0);
and set the flag packet_lost=true;
When I receive the next packet, I'm trying to decode the packet with decode_fec = 1 and then the same packet with decode_fec = 0:
In the code below, suggest to replace ‘ads->ch’ with ‘numChannels’ to make it more clear to what you refer to.)
if(packet_lost ) {
if(opus_packet_has_fec(buf, (opus_int32)len, sample_rate)) {
fec_samples = opus_packet_get_samples_per_frame(buf, sample_rate);
info("opus: there is fec packets=%d\n", fec_samples);
n = opus_decode(
ads->dec,
buf,
(opus_int32)len,
sampv,
fec_samples,
1);
if (n < 0) {
warning("opus: decode error: %s\n", opus_strerror(n));
return EPROTO;
}
n2 = opus_decode(
ads->dec,
buf,
(opus_int32)len,
(opus_int16*)sampv + ( n * numChannels ),
(int)(*sampc/numChannels),
0);
if (n2 < 0) {
warning("opus: decode error: %s\n", opus_strerror(n));
return EPROTO;
}
n = n + n2;
}
But I feel no difference in audio results with and without FEC.
This is the way I'm trying to understand whether there is FEC inside the packet:
bool opus_packet_has_fec(const uint8_t* payload, size_t len, const int sample_rate)
{
int frames, channels, payload_length_ms;
int n;
opus_int16 frame_sizes[48];
const unsigned char *frame_data[48];
if (payload == NULL || len == 0) {
info("Empty payload!!\n");
return false;
}
/* In CELT_ONLY mode, packets should not have FEC. */
if (payload[0] & 0x80) {
info("CELT payload type!!\n");
return false;
}
payload_length_ms = opus_packet_get_samples_per_frame(payload, sample_rate) / 8;
//payload_length_ms = opus_packet_get_samples_per_frame(payload, 48000) / 48;
if (10 > payload_length_ms)
payload_length_ms = 10;
channels = opus_packet_get_nb_channels(payload);
switch (payload_length_ms) {
case 10:
case 20: {
frames = 1;
break;
}
case 40: {
frames = 2;
break;
}
case 60: {
frames = 3;
break;
}
default: {
return false; // It is actually even an invalid packet.
}
}
/* The following is to parse the LBRR flags. */
if (opus_packet_parse(payload, (opus_int32)len, NULL,
frame_data, frame_sizes, NULL) < 0) {
return false;
}
if (frame_sizes[0] <= 1) {
return false;
}
for (n = 0; n < channels; n++) {
if (frame_data[0][0] & (0x80 >> ((n + 1) * (frames + 1) - 1)))
return true;
}
return false;
}
The problem is that I feel no difference in audio quality.
Regardless of the actual packet loss rate (whether it is low - below 1% or high ~20%).
We test by streaming a wav file that plays a constant ton and can hear audio ticks with and without FEC enabled.
Any ideas?
Best regards,
Dmitry Danilov
Senior Software Engineer
LiveU Ltd.
Email: dmitry at liveu.tv<mailto:dmitry at liveu.tv>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.xiph.org/pipermail/opus/attachments/20190715/a9532fab/attachment-0001.html>
More information about the opus
mailing list