【问题标题】:Opus Decoder does not produce a good outputOpus 解码器不会产生良好的输出
【发布时间】:2020-04-15 23:26:16
【问题描述】:

我使用 Opus 解码器从 RTP 数据包中解码获得的 Opus 数据包。 RTP 数据包解析器工作正常,但 Opus 解码器生成错误输出。

输出每秒钟都有非常小的脉冲,它们之间没有信号,但它的持续时间是正确的。

这是我的代码。


#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);
}

【问题讨论】:

  • Opus 数据包是原始的还是封装在 Ogg 或其他容器中?
  • 我认为是纯作品包,但是如何检查呢?
  • 如果一个包不是纯opus包,为什么opus解码器可以提取包参数?我认为它们没有封装在任何容器中。

标签: audio voip codec decoder opus


【解决方案1】:

请检查以下编解码器的基本步骤:

  1. Opus 解码器对于任何样本 Opus 转储文件(没有 RTP)都可以正常工作。

  2. 在发送到 RTP 打包之前和 RTP 解包之后转储并比较二进制数据。进行十六进制比较以验证数据是否正确。

  3. 分别检查单声道和立体声

也添加您的代码日志。

【讨论】:

  • 我使用this RTP opus pcap 文件。您可以使用wireshark 查看有效负载数据。我编辑代码并检查输入数据包。这些和我使用wireshark看到的一样。
  • 您可以尝试使用 ffmpeg cmd 来生成 pcap 并测试不同的场景。
猜你喜欢
  • 2016-10-25
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
  • 2012-11-19
  • 2020-12-26
  • 2011-12-17
  • 2014-08-04
相关资源
最近更新 更多