OPUS的入门指导

https://blog.csdn.net/wirelessdisplay/article/details/77801825

  1. 基本介绍

     官网http://www.opus-codec.org/

     opus是一个有损声音编码的格式,由IETF开发,没有任何专利或限制,适用于网络上的实时声音传输,标准格式为RFC 6716,其技术来源于Skype的SILK及Xiph.Org的CELT编码

     主要特性如下:

  • 6 kb /秒到510 kb / s的比特率
  • 采样率从8 kHz(窄带)到48 kHz(全频)
  • 帧大小从2.5毫秒到60毫秒
  • 支持恒定比特率(CBR)和可变比特率(VBR)
  • 从窄带到全频段的音频带宽
  • 支持语音和音乐
  • 支持单声道和立体声
  • 支持多达255个频道(多数据流的帧)
  • 可动态调节比特率,音频带宽和帧大小
  • 良好的鲁棒性丢失率和数据包丢失隐藏(PLC)
  • 浮点和定点实现

 

     基于OPUS强大的PLC能力以及良好的VOIP音质, 我们决定在我们的视频会议中引入OPUS编码,用于Android/iOS/Windows视频会议客户端,以及视频会议媒体服务器中.

     本文主要介绍OPUS在服务器端的引入过程,内容涵盖下载编译/SIP SDP/RTP/编解码

 

  1. 下载编译介绍

     我司的会议服务器使用的CentOS7.2 64bit的开发环境, 以下就以此环境做例子说明

     使用当前最新的1.2.1版本下载编译:

     wget https://archive.mozilla.org/pub/opus/opus-1.2.1.tar.gz

     tar -zxf opus-1.2.1.tar.gz

     cd opus-1.2.1

     ./configure --prefix=$your_install_dir

     make; make install

 

     编译完之后, 在$your_install_dir目录下就有存在这三个文件夹,后续将此三个文件夹导入我们的服务器代码工程总:include  lib  share

     

  1. SDP介绍

     我司的会议系统支持IMS/SIP, 所以Android/iOS/Windows客户端都是基于IMS/SIP做信令呼叫协议, 所以需要在SIP/SDP中支持OPUS

     参考RFC7587, 

     其中 101是payload type值, 这个值没有保留值,可以在35-127之间随意取值, 只要和其他codec不冲突即可;48000是采样率, opus支持8k, 12k,16k,24k和48k, 2为双声道.useinbandfec为是否启用opus的内置的plc算法

 

  1. RTP接受发送

     RTP的封包可以参考RFC7587,没有什么特殊性,主要是ts的打包需要注意下

OPUS支持的包间隔从20ms到120ms, 视频会议对实时性要求比较高, 所以我们采用的20ms, 48k采样率的ts递增值为960

 

  1. 解码

     解码器初始化:

    pDecoder = opus_decoder_create(sample_rate_, channels_, &error);

    if (OPUS_OK != error || NULL == pDecoder)

    {

        TRACE_ERR("Could not open opus decoder codec %d", error);

        return false;

    }

 

     解码:

    if (NULL == data || 0 == size)

    {

        outputSamples = opus_decode(pDecoder,

                        NULL,

                        0,

                        pDecodedData,

                        frame_size_,

                        1);

    }

    else

    {

        outputSamples = opus_decode(pDecoder,

                    (const unsigned char*)data,

                    size,

                    pDecodedData,

                    frame_size_,

                    0);

    }

 

     输入的数据是RTP payload数据解码, 如果是丢包, 则输入的NULL指针. 由于我们采用的inbandfec,所有丢包情况下最后一个参数是1. frame_size_为48k/50=980

     输出的数据在data中,格式为PCM S16.

 

  1. 编码

     初始化:

     OpusEncoder* opusEncoder = (OpusEncoder*)opus_encoder_;

    int error;

 

    opusEncoder = opus_encoder_create (sample_rate_, channels_, OPUS_APPLICATION_VOIP, &error);

    if (error != OPUS_OK || opusEncoder == NULL)

    {

        TRACE_ERR("create opus encoder failed %d", error);

        return false;

    }

 

    opus_encoder_ctl(opusEncoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));

    opus_encoder_ctl(opusEncoder, OPUS_SET_BITRATE(OPUS_AUTO));     ///使用AUTO主要是应为视频会议过程中,大部分场景是不说话的,减少带宽占用

    opus_encoder_ctl(opusEncoder, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));

    opus_encoder_ctl(opusEncoder, OPUS_SET_VBR(1));//0:CBR, 1:VBR

    opus_encoder_ctl(opusEncoder, OPUS_SET_VBR_CONSTRAINT(0));//0:Unconstrained VBR., 1:Constrained VBR.

    opus_encoder_ctl(opusEncoder, OPUS_SET_COMPLEXITY(5));//range:0~10

    opus_encoder_ctl(opusEncoder, OPUS_SET_FORCE_CHANNELS(channels_)); //1:Forced mono, 2:Forced stereo

    opus_encoder_ctl(opusEncoder, OPUS_SET_APPLICATION(OPUS_APPLICATION_VOIP));//

    opus_encoder_ctl(opusEncoder, OPUS_SET_INBAND_FEC(1));//0:Disable, 1:Enable

    opus_encoder_ctl(opusEncoder, OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_20_MS));

 

     编码:

    outputLen = opus_encode(pEncoder, (const opus_int16*)data, frame_size_, pkt.data, MAX_DECODED_BUFFER_LENGTH);

    if (outputLen <= 0)

    {

        MEDIA_TRACE_ERR("opus encode failed %d", outputLen);

        return outputLen;

    }

 

     输入的是PCM S16数据,输出则为OPUS包, 一个RTP封包就够了

 

  1. 调试

     如果调试过程中,声音不正常, 这需要定位问题. 声音不正常, 主要需要确认: 终端发过来的流/RTP收包部分/解码部分/重采样/混音部分/编码部分/发包部分

     定位问题,需要在每个地方都打桩写文件来确认.

     文件写下来之后, PCM数据只是使用专业软件来听(我司使用的GoldWave); OPUS数据的话,可以使用opus_demo(在上面所述的libopus代码中)来解码再听,写opus文件的时候,需要注意格式(加8字节的头).

 

  1. 效果

     使用OPUS之后, 效果尤其是公网上传输的效果比较好, 30%以内的丢包, 都能够保证语音能够正常听清楚

 

 

     技术交流有兴趣请加:

     音视频技术交流群:308601278

     无线投屏技术交流群:582349005

     

     我司有成熟的视频会议/视频监控/视频调度/无线投屏盒子销售,也可做音视频相关产品和技术的定制化开发

     有需要可发邮件[email protected]

你可能感兴趣的:(算法)