ImageVerifierCode 换一换
格式:DOCX , 页数:9 ,大小:19.83KB ,
资源ID:6852806      下载积分:2 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6852806.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(FFmpeg音频格式转换.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

FFmpeg音频格式转换.docx

1、FFmpeg音频格式转换FFmpeg音频格式转换前段时间,在学习试用FFmpeg播放音频的时候总是有杂音,网上的很多教程是基于之前版本的FFmpeg的,而新的FFmepg3中audio增加了平面(planar)格式,而SDL播放音频是不支持平面格式的,所以通过FFmpeg解码出来的数据不能直接发送到SDL进行播放,需要进行一个格式转换。通过网上一些资料,也能够正确的播放音频了,但是对具体的音频转换过程不是很了解,这里就对FFmpeg的对音频的存储格式及格式转换做个总结。本文主要有以下几个方面的内容: , AVSampleFormat 音频sample的存储格式 , channel layout

2、 各个通道存储顺序 , 使用FFmpeg对音频数据进行格式转换 , 音频解码API avcodec_decode_audio4在新版中已废弃,替换为使用更为简单的avcodec_send_packet和avcodec_receive_frame。本文简单的介绍了该API的使用。 AVSampleFormat 在FFmpeg中使用枚举AVSampleFormat表示音频的采样格式,其声明如下: enum AVSampleFormat AV_SAMPLE_FMT_NONE = -1, AV_SAMPLE_FMT_U8, / unsigned 8 bits AV_SAMPLE_FMT_S16, /

3、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, / d

4、ouble, planar AV_SAMPLE_FMT_NB / Number of sample formats. DO NOT USE if linking dynamically ; 和图像的像素存储格式类似,可以使用8位无符号整数、16位有符号整数、32位有符号整数以及单精度浮点数,双精度浮点数表示一个采样。但是,没有使用 24位的有符号整数,这是因为这些不同的格式使用的是原生的C类型,而C中是没有24位的长度的类型的。 Sample value can be expressed by native C types,hence the lack of a signed 24-bit s

5、ample format even though it is a common raw audio data format. 对于浮点格式,其值在-1.0,1.0之间,任何在该区间之外的值都超过了最大音量的范围。 和YUV的图像格式格式,音频的采样格式分为平面(planar)和打包(packed)两种类型,在枚举值中上半部分是packed类型,后面(有P后缀的)是planar类型。 对于planar格式的,每一个通道的值都有一个单独的plane,所有的plane必须有相同的大小;对于packed类型,所有的数据在同一个数据平面中,不同通道的数据 交叉保存。 另外,在AVFrame中表示音频采样

6、格式的字段format是一个int型,在使用AVSampleFormat时候需要进行一个类型转换,将int转换为AVSampleFormat枚举值。 在头文件samplefmt.h提供了和音频采样格式相关的一些函数,现列举一些如下: , const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt) 根据枚举值获取其相应的格式名称(字符串) , enum AVSampleFormat av_get_sample_fmt(const char *name) 根据格式名字(字符串)获取相应的枚举值 , enum AVSample

7、Format av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt) 传入planar类型的采样格式,返回其可转换的packed类型的采样格式。例如传入 AV_SAMPLE_FMT_S32P,其返回值为 AV_SAMPLE_FMT_S32。 , enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt) 和上面函数类似,不同的是传入的是packed类型的格式。 , int av_sample_fmt_is_planar(enum AVSampl

8、eFormat sample_fmt 判断一个采样格式是不是planar类型的 , int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt) 每个采样值所占用的字节数 , int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,enum AVSampleFormat sample_fmt, int align) 根据输入的参数,计算其所占用空间的大小(字节数)。linesize可设为null,align是buff空间的对齐格式(0=d

9、efault,1 = no alignment) channel_layout 从上面可知,sample有两种类型的存储方式:平面(planar)和打包(packed),在planar中每一个通道独自占用一个存储平面;在packed中,所有通道的sample交织存储在同一个 平面。但是,对于planar格式不知道具体的某一通道所在的平面;对于packed格式各个通道的数据是以怎么样的顺序交织存储的。这就需要借助于channel_layout。 首先来看下FFmpeg对channel_layout的定义: channel_layout是一个64位整数,每个值为1的位对应一个通道。也就说,chan

10、nel_layout的位模式中值为1的个数等于其通道数量。 A channel_layout is a 64-bits interget with a bit set for every channel.The number of bits set must be equal to the number of channels. 在头文件channel_layout.h中为将每个通道定义了一个mask,其定义如下: #define AV_CH_FRONT_LEFT 0x00000001 #define AV_CH_FRONT_RIGHT 0x00000002 #define AV_CH_FRO

11、NT_CENTER 0x00000004 #define AV_CH_LOW_FREQUENCY 0x00000008 #define AV_CH_BACK_LEFT 0x00000010 #define AV_CH_BACK_RIGHT 0x00000020 #define AV_CH_FRONT_LEFT_OF_CENTER 0x00000040 #define AV_CH_FRONT_RIGHT_OF_CENTER 0x00000080 #define AV_CH_BACK_CENTER 0x00000100 #define AV_CH_SIDE_LEFT 0x00000200 #def

12、ine AV_CH_SIDE_RIGHT 0x00000400 #define AV_CH_TOP_CENTER 0x00000800 #define AV_CH_TOP_FRONT_LEFT 0x00001000 #define AV_CH_TOP_FRONT_CENTER 0x00002000 #define AV_CH_TOP_FRONT_RIGHT 0x00004000 #define AV_CH_TOP_BACK_LEFT 0x00008000 #define AV_CH_TOP_BACK_CENTER 0x00010000 #define AV_CH_TOP_BACK_RIGHT

13、0x00020000 #define AV_CH_STEREO_LEFT 0x20000000 / Stereo downmix. #define AV_CH_STEREO_RIGHT 0x40000000 /sample_rate) + frame-nb_samples, frame-sample_rate, frame-sample_rate, AVRounding(1); 函数av_rescale_rnd是按照指定的舍入方式计算a * b / c 。 函数swr_get_delay得到输入sample和输出sample之间的延迟,并且其返回值的根据传入的第二个参数不同而不同。如果是输入的

14、采样率,则返回值是输入sample个数;如果输入的是输出采样率,则返回值是输出sample个数。 2. 调用 swr_convert进行转换 int nb = swr_convert(swr_ctx, &audio_buf, dst_nb_samples, (const uint8_t*)frame-data, frame-nb_samples); 其返回值为转换的sample个数。 SDL播放音频时的格式转换 , 首先使用avcodec_send_packet和avcodec_receive_frame获取解码后的原始数据 , int ret = avcodec_send_packet(aC

15、odecCtx, &pkt); , if (ret 0 & ret != AVERROR(EAGAIN) & ret != AVERROR_EOF) , return -1; , , ret = avcodec_receive_frame(aCodecCtx, frame); , if (ret channels 0 & frame-channel_layout = 0) , frame-channel_layout = av_get_default_channel_layout(frame-channels); , else if (frame-channels = 0 & frame-ch

16、annel_layout 0) frame-channels = av_get_channel_layout_nb_channels(frame-channel_layout); 如果channel layout未知(channel_layout = 0),根据通道数量获取其默认的channel layout;如同通道的数量未知,则根据其channel layout得到其通道数量。 , 设置输出格式 由于SDL2的sample格式不支持浮点型(FFmpeg中是支持的浮点型的),这里简单的设置输出格式为AV_SAMPLE_FMT_S16(16位有符号整型),输出的channel layout也

17、根据通道数量设置为默认值 dst_layout = av_get_default_channel_layout(frame-channels)(SDL2不支持planar格式)。实例化SwrContext , swr_ctx = swr_alloc_set_opts(nullptr, dst_layout, dst_format,frame-sample_rate, , frame-channel_layout, (AVSampleFormat)frame-format, frame-sample_rate, 0, nullptr); , if (!swr_ctx | swr_init(swr_ctx) sample_rate) + frame-nb_samples, frame-sample_rate, frame-sample_rate, AVRounding(1); , / 转换,返回值为转换后的sample个数 , int nb = swr_convert(swr_ctx, &audio_buf, dst_nb_samples, (const uint8_t*)frame-data, frame-nb_samples); data_size = frame-channels * nb * av_get_bytes_per_sample(dst_fo

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1