文档章节

Opus 编解码遇到的怪事

UMU
 UMU
发布于 2017/07/01 17:23
字数 499
阅读 195
收藏 0

    最近参考 ffmpeg 的 transcoding_aac 示例代码,写了一个 transcoding_opus,并拿 MP3 测试转码,结果发现转完的 opus 文件的 SampleFormat 和指定的并不一样。UMU 的代码是把源文件解码出来的 sample 先 resample 成 AV_SAMPLE_FMT_S16 格式,然后再交给 opus encoder 去编码的,但是编完用 ffprobe 查看,发现 SampleFormat 变成 AV_SAMPLE_FMT_FLTP。

    那么第一个问题来了,为什么会这样?

    开始研究,首先 UMU 把 opus encoder 支持的 sample_fmt 打印出来,发现只有两种:AV_SAMPLE_FMT_S16、AV_SAMPLE_FMT_FLT,压根就没有 AV_SAMPLE_FMT_FLTP,强行指定 AV_SAMPLE_FMT_FLTP 之后,直接报错,不支持这种 sample_fmt。

    推测,真的被编码为 AV_SAMPLE_FMT_S16 了,是 ffprobe 的问题,于是自己写了个简化版的 ffprobe,流程几乎是一样的,出来的结果——果然一模一样……打印出 AV_SAMPLE_FMT_FLTP。

    接着怀疑 ffprobe 用的 decoder,于是去看了 avcodec_find_decoder 返回的 AVCodec,打印一下 name 和 long_name,和 transcoding_opus 的 avcodec_find_encoder 返回的一比,果然不一样……

    选用的编码器是这样的:

AVCodec ff_libopus_encoder = {
    .name            = "libopus",
    .long_name       = NULL_IF_CONFIG_SMALL("libopus Opus"),
    .type            = AVMEDIA_TYPE_AUDIO,
    .id              = AV_CODEC_ID_OPUS,
    .priv_data_size  = sizeof(LibopusEncContext),
    .init            = libopus_encode_init,
    .encode2         = libopus_encode,
    .close           = libopus_encode_close,
    .capabilities    = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SMALL_LAST_FRAME,
    .sample_fmts     = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_FLT,
                                                      AV_SAMPLE_FMT_NONE },
    .supported_samplerates = libopus_sample_rates,
    .priv_class      = &libopus_class,
    .defaults        = libopus_defaults,
};

    而选用的解码器是这样的:

AVCodec ff_opus_encoder = {
    .name           = "opus",
    .long_name      = NULL_IF_CONFIG_SMALL("Opus"),
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = AV_CODEC_ID_OPUS,
    .defaults       = opusenc_defaults,
    .priv_class     = &opusenc_class,
    .priv_data_size = sizeof(OpusEncContext),
    .init           = opus_encode_init,
    .encode2        = opus_encode_frame,
    .close          = opus_encode_end,
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
    .capabilities   = AV_CODEC_CAP_EXPERIMENTAL | AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
    .supported_samplerates = (const int []){ 48000, 0 },
    .channel_layouts = (const uint64_t []){ AV_CH_LAYOUT_MONO,
                                            AV_CH_LAYOUT_STEREO, 0 },
    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                     AV_SAMPLE_FMT_NONE },
};

    问题清楚了,看来用 ID 查找编解码器并不靠谱,因为这个 ID 是 Type ID,不是 Item ID,还是改为用 name 来找:

//AVCodec *output_codec = avcodec_find_encoder(AV_CODEC_ID_OPUS);
AVCodec *output_codec = avcodec_find_encoder_by_name("opus");

    那么,第二个问题顺势而来……哪个比较牛?

    用 AV_SAMPLE_FMT_FLTP 后 frame_size 是 120,用其它是 960,frame_size 小有小的好处,比如在做实时编码直播时,理论延迟会更小。

    经过测试,用 AV_SAMPLE_FMT_FLTP 的 opus 比 libopus 压缩率普遍略高一些,但它只支持 48000Hz 一种 sample_rate,libopus 支持的更多:48000, 24000, 16000, 12000, 8000。

© 著作权归作者所有

共有 人打赏支持
UMU

UMU

粉丝 118
博文 112
码字总数 44043
作品 0
厦门
程序员
加载中

评论(1)

sandmanhome
sandmanhome
居然还有这种坑:satisfied:
Baresip 0.4.9 发布,SIP 用户代理

Baresip 是一个可移植的模块化的 SIP 用户代理,支持音频和视频。 Baresip 0.4.9 发布,此版本支持 ZRTP media 加密(通过新模块 zrtp.so);支持 LLVM clang 编译;添加一个日志框架; OPUS...

oschina
2014/01/08
412
0
Microsoft Edge 将支持开源视频编解码器 VP9

今天微软宣布 Microsoft Edge 将会支持开源视频编解码器 WebM/VP9,现在正在开发过程中。VP9 是开源编码器,提供高效的流 HD 内容压缩,有更低的压缩比率,适用于 UHD 流。VP9 最初支持不久后...

oschina
2015/09/09
2.5K
8
Opus 1.1 发布,最高支持255个音频通道

Opus开源免专利费音频编解码器发布了1.1版, 改进了环绕声编码,支持最高255个音频通道。Opus合并了Xiph.org的CELT低延时音频编解码器和Skype的SILK语音编解码器,专为互联网音频设计,可用于...

oschina
2013/12/08
2.2K
2
Edge 支持 WebM ,VP9 和 Opus 视频编码格式

从 EdgeHTML 14.14291 版本开始, Microsoft Edge 浏览器已经完成了对开源 WebM 容器格式 VP9 视频及 Opus音频编解码器的支持。这让使用 Media Source Extensions 的网站将可以适应串流播放视...

oschina
2016/04/20
2.7K
14
iOS下 AAC 音频编码

编码结构图 前言 iOS下Apple为我们提供了非常方便的音频编解码工具AudioToolbox。该工具中包含了常见的编解码库,如AAC、iLBC、OPUS等。今天我们就介绍一下如何使用 AudioToolbox 进行AAC音频...

音视频直播技术专家
2017/10/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

day99-20180926-英语流利阅读-待学习

换汤不换药的美容大忽悠:从抗衰老到肌肤焕发新生 Lala 2018-09-26 1.今日导读 说到护肤品,一个个大牌广告就浮现在我们眼前:皮肤吹弹可破的女明星手捧功能各异的瓶瓶罐罐,暗示着消费者买买...

飞鱼说编程
32分钟前
3
0
FFmpeg Maintainer赵军:FFmpeg关键组件与硬件加速

大家好!我是赵军,现就职于英特尔的DCG从事基于FFmpeg的硬件优化工作,两年多前加入FFmpeg社区,2018年4月成为FFmpeg的其中的一个FFmpeg Maintainer,主要负责FFmpeg的硬件优化工作。 概览:...

yizhichao
今天
1
0
ehlib 修改 使行号字体颜色 与标题字体颜色 一致

对ehlib 显示效果不够满意,而做的调整 修改这个过程:procedure TCustomDBGridEh.DrawIndicatorCell(ACol, ARow: Longint; AreaCol, AreaRow: Longint; ARect: TRect; AState: TGri......

vga
今天
1
0
Bash重定向详解

Bash重定向详解 Bash的重定向指的是将命令的输入和输出导向不同地方,而不是默认的标准输入、标准输出和标准错误。Bash的重定向实际上是对标准输入、标准输出和标准错误的重置,进而将所需输...

小陶小陶
今天
3
0
EventBus原理深度解析

一、问题描述 在工作中,经常会遇见使用异步的方式来发送事件,或者触发另外一个动作:经常用到的框架是MQ(分布式方式通知)。如果是同一个jvm里面通知的话,就可以使用EventBus。由于Event...

yangjianzhou
今天
54
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部