zoukankan      html  css  js  c++  java
  • libav杂碎

    音频输出的每个采样(Sample)数据类型和布局
      libav音频输出格式为原始波形数据,即PCM(模拟脉冲信号)或者Wave数据。每一个Sample的数据类型可能为uint8, int16, int32, float, double, 见枚举类型AVSampleFormat:
    enum AVSampleFormat
    {
        AV_SAMPLE_FMT_NONE = -1,
        AV_SAMPLE_FMT_U8,          ///< unsigned 8 bits
        AV_SAMPLE_FMT_S16,         ///< signed 16 bits
        AV_SAMPLE_FMT_S32,         ///< signed 32 bits
        AV_SAMPLE_FMT_FLT,         ///< float
        AV_SAMPLE_FMT_DBL,         ///< double
    
        AV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planar
        AV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planar
        AV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planar
        AV_SAMPLE_FMT_FLTP,        ///< float, planar
        AV_SAMPLE_FMT_DBLP,        ///< double, planar
    
        AV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
    };

    整形Sample的取值范围就是该整数类型的理论取值范围,比如AV_SAMPLE_FMT_U8的取值范围是从0到255,AV_SAMPLE_FMT_S16的取值范围是从-32768到32767.而浮点数有点不太一样,取值范围从-1.0到1.0。 数据类型越大,表示可以用于表示声音的范围越大,听起来也就越“高大上”

    AVCodecContext有这几个成员request_channel(过时), request_channel_layout, request_sample_fmt. 通过在解码之前设定这几个成员,libav允许你指定解码后的Sample数据类型。

    如果你真这么测试的话,你会发现解码后的Sample类型可能与你指定的不一致。这是因为,每个编码解码器都有支持的类型,比如说AAC编码只支持AV_SAMPLE_FMT_FLTP(在以前的版本上为AV_SAMPLE_FMT_S16),所以你需要在编码解码器支持的类型之上进行指定。

    那么怎么才能知道某个编码解码器支持哪些音频采样格式(或者图像格式)呢,还暂时不是很清楚。不过应该有某种机制可以知道。

    注意到AVSampleFormat里面还有几种格式以P(Planar,平面)结尾,那它们与不带P的有什么区别呢?当有多个Channel的时候,就有区别了。不带P的只有一个buffer,buffer里面Sample的分布是像这样A1B1A2B2A3B3......其中大写字母代表一个Channel,数字代表每个采样在该Channel里的编号。可以看出所有采样被放到一起(即一个buffer),不同的Channel被均匀的分布在其中。而带P的是像这样A1A2A3......B1B2B3......不同Channel各占一个buffer,且每个buffer长度一样。

    音频解码之后,需要发送到第三方的音频输出库进行播放。可是这些播放库不一定支持libav的所有格式,前面说过AAC编码只会输出float planar类型的采样,那要怎样在不支持float planar的音频输出设备(比如Windows的WaveOut)上输出呢?有两种方法(其实是一种,两种方法原理一样),一个是采用libav的resample API(我试了半天,程序老是会crash),另外一种就是自己根据上面说到的布局来手动解决了。

  • 相关阅读:
    JavaIO流(四) File文件对象
    Java IO流(三) 字符流Reader和Writer
    Java IO流(二) 字节流InputStream和OutputStream
    Java IO流(一)入门
    Decorator(装饰者)模式
    Listener(监听器)
    Filter(过滤器)
    Java开发入门
    啊哈哈,写博客的第一天
    MySQL变量
  • 原文地址:https://www.cnblogs.com/jianqifeihong/p/3477935.html
Copyright © 2011-2022 走看看