Search code examples
audiovoipcodecdecoderopus

Opus Decoder does not produce a good output


I use Opus decoder to decode obtained Opus packets from RTP packets. RTP packet parser works properly, but Opus decoder generate bad output.

The output has very small pulses at every seconds and between them has no signal, but its duration is correct.

Here is my code.


#define FRAME_SIZE 960
#define SAMPLE_RATE 16000
#define CHANNELS 2
#define MAX_PACKET_SIZE (3*1276)
//#define MAX_FRAME_SIZE 6*960
#define MAX_FRAME_SIZE 2880

ELA::OpusDecoder::OpusDecoder(const opus_int32 sampling_rate, const int number_of_channels)
{
    decoder = opus_decoder_create(sampling_rate, number_of_channels, &err);
    if (err<0)
    {
        fprintf(stderr, "failed to create decoder: %s\n", opus_strerror(err));
        exit(EXIT_FAILURE);
    }
}

ELA::OpusDecoder::~OpusDecoder()
{
    opus_decoder_destroy(decoder);
}

void ELA::OpusDecoder::decode(const AudioBuffer& input, AudioBufferRef& output, char* scratch)
{
    const AudioBufferDetails& details = input.details;
    char* in_buff_ptr = input.buffer;
    int bytes_remaining = details.bytes_count;
    char*  out_buff_ptr = scratch;
    uint32_t out_buff_size = 0;
    unsigned char cbits[MAX_FRAME_SIZE];

    memcpy(cbits, in_buff_ptr, bytes_remaining);

    int number_of_samples_in_packet = opus_decoder_get_nb_samples(decoder,cbits, MAX_FRAME_SIZE);
    int packet_channels = opus_packet_get_nb_channels(cbits);
    int packet_frame_count = opus_packet_get_nb_frames(cbits, MAX_FRAME_SIZE);
    int packet_samples = opus_packet_get_nb_samples(cbits, MAX_FRAME_SIZE, SAMPLE_RATE);
    int packet_bandwidth= opus_packet_get_bandwidth(cbits);
    int packet_sample_per_frame = opus_packet_get_samples_per_frame(cbits, SAMPLE_RATE);

    printf("\n %d  number_of_samples_in_packet", number_of_samples_in_packet);
    printf("\n %d  packet_channels", packet_channels);
    printf("\n %d  packet_frame_count", packet_frame_count);
    printf("\n %d  packet_samples", packet_samples);
    printf("\n %d  packet_bandwidth", packet_bandwidth);
    printf("\n %d  packet_sample_per_frame", packet_sample_per_frame);

    frame_size = opus_decode(decoder, cbits, bytes_remaining, (opus_int16*)out_buff_ptr, MAX_FRAME_SIZE, 0);

    if (err<0)
    {
        fprintf(stderr, "\ndecoder failed: %s\n", opus_strerror(err));
        exit(EXIT_FAILURE);
    }
    else
    {
        out_buff_ptr += bytes_remaining;
        out_buff_size += bytes_remaining;
    }

    save_output_audio_buffer(out_buff_size, scratch);
}

Solution

  • Please check these following basic steps for codec :

    1. Opus decoder is working properly for the any sample opus dump file (without RTP).

    2. dump and compare the binary data before sending to RTP packing and after RTP unpacking. do a hex compare to verify the data is correct.

    3. check mono and stereo separately

    add the logs of your code too.