[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