吉 安

简单粗暴

  • 主页
  • 认识
  • 编程
  • 问题
  • 工具
  • 想法
所有文章 友链 关于我

吉 安

简单粗暴

  • 主页
  • 认识
  • 编程
  • 问题
  • 工具
  • 想法

pcm与opus互转

2022-02-23

Opus简介

Opus是什么

Opus是一个有损声音编码的格式,由Xiph.Org基金会开发,之后由互联网工程任务(IETF)组进行标准化,目标是希望用单一格式包含声音和语音,取代Speex和Vorbis,且适用于网络上低延迟的实时语音频传输场景,标准格式定义于RFC 6716文件。

为什么用Opus

  • Opus格式是一个开放格式,使用上没有任何专利或限制。
  • Opus延时低。16位深16K采样率PCM一帧:1260bit,G711a :640bit,Opus才100左右,没有声音时才二三十。

怎么样用Opus

从官网获取源码:http://www.opus-codec.org/

1
2
3
4
5
wget https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz
tar -zxvf opus-1.3.1.tar.gz
cd opus-1.3.1
./configure --prefix=$your_install_dir
make; make install

就可以在$your_install_dir中获得lib文件和头文件了。我们摄像头用可以直接放工程里编(工程里已经有了)。

libopus使用

编码

创建编码器

1
2
3
4
5
6
7
8
9
10
11
/*
* OPUS_APPLICATION_VOIP 视频会议
* OPUS_APPLICATION_AUDIO 高保真
* OPUS_APPLICATION_RESTRICTED_LOWDELAY 低延迟,但是效果差
*/
encoder = opus_encoder_create(sampling_rate, channels, OPUS_APPLICATION_VOIP, &err);
if (err != OPUS_OK)
{
fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
return -1;
}

设置编码器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
* OPUS_SIGNAL_VOICE 语音
* OPUS_SIGNAL_MUSIC 音乐
*/
opus_encoder_ctl(encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
opus_encoder_ctl(encoder, OPUS_SET_BITRATE(OPUS_AUTO)); // 控制最大比特率,AUTO在不说话时减少带宽。
opus_encoder_ctl(encoder, OPUS_SET_BANDWIDTH(OPUS_AUTO));
opus_encoder_ctl(encoder, OPUS_SET_VBR(1)); // 0固定码率,1动态码率
opus_encoder_ctl(encoder, OPUS_SET_VBR_CONSTRAINT(1)); // 0不受约束,1受约束(默认)
opus_encoder_ctl(encoder, OPUS_SET_COMPLEXITY(0)); // 编码复杂度0~10
opus_encoder_ctl(encoder, OPUS_SET_INBAND_FEC(FEC_DISABLE)); // 算法修复丢失的数据包,0关,1开
opus_encoder_ctl(encoder, OPUS_SET_FORCE_CHANNELS(channels)); // 声道数
opus_encoder_ctl(encoder, OPUS_SET_DTX(0)); // 不连续传输,0关,1开
opus_encoder_ctl(encoder, OPUS_SET_LSB_DEPTH(bit_depth)); // 位深
opus_encoder_ctl(encoder, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration)); // 帧持续时间
opus_encoder_ctl(encoder, OPUS_SET_APPLICATION(OPUS_APPLICATION_VOIP)); //同编码器创建参数

编码

1
opus_data_len = opus_encode(encoder, pcm_data, frame_size, out_buf, out_len);

销毁编码器

1
opus_encoder_destroy(encoder);

解码

创建解码器

1
2
3
4
5
6
decoder = opus_decoder_create(sampling_rate, channels, &err);
if (err != OPUS_OK)
{
fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
return -1;
}

解码

1
pcm_data_len = opus_decode(decoder, frame_data, frame_len, out_buf, out_len, FEC_DISABLE);

销毁解码器

1
opus_decoder_destroy(decoder);

实际使用

注意1

为了减少带宽,所以每一帧的数据量都是不一样的,在编码的时候在每一帧前有四位的数据是记录的帧的长度。
并且此处还要注意PCM位深16位,所以一帧的数据量为采样率/FPS*2,PCM一帧的长度固定的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
while (running)
{
opus_buf_len = opus_encode_frame(read_buf + decode_offset,
AUDIO_SAMPLERATE / AUDIO_FPS * sizeof(opus_int16),
opus_buf, DATA_MAX_LEN);
fwrite(&opus_buf_len, sizeof(int), 1, fp);
fwrite(opus_buf, sizeof(uint8_t), opus_buf_len, fp);
decode_offset += AUDIO_SAMPLERATE / AUDIO_FPS * sizeof(opus_int16);

if (decode_offset >= read_size)
{
break;
}
}

注意2

1
opus_encoder_ctl(encoder, OPUS_SET_COMPLEXITY(0));                            // 编码复杂度0~10

编码器的编码复杂度,随着复杂度越高,编码耗时越长。简单测试如下:

1
2
3
4
5
6
7
8
9
10
11
Complexity=0. The run time is: 2.218s
Complexity=1. The run time is: 2.606s
Complexity=2. The run time is: 3.101s
Complexity=3. The run time is: 3.306s
Complexity=4. The run time is: 3.339s
Complexity=5. The run time is: 4.179s
Complexity=6. The run time is: 4.159s
Complexity=7. The run time is: 5.221s
Complexity=8. The run time is: 6.368s
Complexity=9. The run time is: 6.387s
Complexity=10. The run time is: 6.307s
赏

谢谢你请我吃糖果

支付宝
微信
  • 编码
  • 音视频

扫一扫,分享到微信

微信分享二维码
初识音视频
© 2022 吉 安
访客量:25753
  • 所有文章
  • 友链
  • 关于我

tag:

  • 问题
  • qt
  • 工具
  • 编码
  • 音视频
  • 一些认识
  • 进程
  • 想法
  • c-cpp
  • 内存

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • pcm与opus互转

    2022-02-23

    #编码#音视频

  • 初识音视频

    2021-10-09

    #音视频#一些认识

  • 认识GRUB

    2021-01-14

    #工具#一些认识

  • 关于IT女性

    2020-10-30

    #想法

  • 认识selinux

    2020-10-15

    #工具#一些认识

  • 认识firewalld

    2020-10-12

    #工具#一些认识

  • 认识audit

    2020-10-10

    #工具#一些认识

  • 简单讲讲deb打包

    2020-08-18

    #工具

  • debian系linux安装软件

    2020-08-17

    #工具

  • QWebEngineView最小化后缩略图显示空白

    2020-07-20

    #问题#qt

  • Hexo无法解析Markdown表格

    2020-07-02

    #问题

  • 认识chromuim

    2020-07-02

    #一些认识

  • 初识QtWebEngine

    2020-06-28

    #qt#编码#c-cpp

  • 内存的使用

    2020-06-04

    #编码#c-cpp#内存

  • 认识各种内存地址

    2020-06-02

    #一些认识#内存

  • 进程的限制之ulimit

    2020-05-07

    #工具#进程

  • 认识/proc/[pid]/

    2020-05-06

    #一些认识#进程

  • 进程的查看工具

    2020-05-06

    #工具#进程

  • 认识进程

    2020-04-29

    #一些认识#进程

  • 认识多处理器架构

    2020-04-17

    #一些认识

  • 认识x11

    2020-04-16

    #一些认识

  • 进程调试工具strace

    2020-04-15

    #工具#进程

  • 小黄同学
猛男!