FFmpeg开发条记(十四)FFmpeg音频重采样的缓存

打印 上一主题 下一主题

主题 850|帖子 850|积分 2560

​FFmpeg在许多地方都运用了缓存机制,好比《FFmpeg开发实战:从零基础到短视频上线》一书的“3.3.2  对视频流重新编码”介绍了编解码的数据缓存,不单是视频编码过程和视频解码过程有缓存,乃至连音频重采样都用到了缓存。 也就是说,重采样函数swr_convert一次只会输出指定长度的音频数据,超出这个长度的数据被留在重采样的缓存当中。那么在对一个音频文件转换格式之时,有大概所有音频帧都遍历完了,重采样缓存里面还生存着剩余未取走的音频数据。此时要像对待视频编码缓存那样,想办法把剩下的音频数据冲出来。
具体到代码实现上,在调用swr_convert函数之时,倒数第二个参数填NULL,表示输入的数据内容为空;倒数第一个参数填0,表示输入的数据大小为0。这便告诉采样器,已经没有要转换的音频了,请把缓存中剩余的数据冲出来吧。那么swr_convert函数的返回值就是本次冲走的输出数据大小,当返回值为0时,表示重采样缓存已经冲光了,再也没有剩余的数据了,此时才能竣事音频的格式转换操作。
当然,对于常见的mp3和aac格式,它们每帧的长度是固定的,正常情况调用一次swr_convert函数即可输出完整的音频数据,无需另外处置惩罚重采样缓存。只有ogg、amr、wma等格式的每帧音频长度不固定,才需要额外处置惩罚音频的重采样缓存,于是对《FFmpeg开发实战:从零基础到短视频上线》一书第五章的重采样代码改动如下。
打开chapter05/swrmp3.c,把下面这行
  1. swr_frame->nb_samples = audio_decode_ctx->frame_size;
复制代码
改为下面几行(由于ogg、amr和wma的frame_size为0,以是需要另外赋值):
  1. swr_frame->nb_samples = audio_decode_ctx->frame_size;
  2. if (swr_frame->nb_samples <= 0) {
  3.     swr_frame->nb_samples = 512;
  4. }
复制代码
另外在轮询数据包的循环竣事之后,补充下面的重采样缓存冲刷代码,如许新天生的音频文件才是完整的:
  1. while (1) { // 冲走重采样的缓存(兼容对ogg、amr等格式的重采样)
  2.     // 重采样。也就是把输入的音频数据根据指定的采样规格转换为新的音频数据输出
  3.     ret = swr_convert(swr_ctx, // 音频采样器的实例
  4.                     // 输出的数据内容和数据大小
  5.                     swr_frame->data, swr_frame->nb_samples,
  6.                     // 输入内容填NULL、输入大小填0表示冲走缓存
  7.                     NULL, 0);
  8.     if (ret < 0) {
  9.         av_log(NULL, AV_LOG_ERROR, "swr_convert frame occur error %d.\n", ret);
  10.         return -1;
  11.     } else if (ret == 0) { // 到末尾了
  12.         break;
  13.     }
  14.     save_mp3_file(fp_out, swr_frame); // 把音频帧保存到MP3文件
  15. }
复制代码
接着执行下面的编译命令。
  1. gcc swrmp3.c -o swrmp3 -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -lavformat -lavdevice -lavfilter -lavcodec -lavutil -lswscale -lswresample -lpostproc -lm
复制代码
编译完成后执行以下命令启动测试程序,期望把ring.ogg重采样后生存为MP3文件。
  1. ./swrmp3 ../ring.ogg
复制代码
程序运行完毕,发现控制台输出以下的日记信息,说明完成了对ogg文件重采样mp3音频的操作。
  1. Success open input_file ring.ogg.
  2. audio_decode_ctx frame_size=0, sample_fmt=8, sample_rate=11025, nb_channels=1
  3. audio_encode_ctx frame_size=1152, sample_fmt=6, sample_rate=44100, nb_channels=1
  4. target audio file is output_swrmp3.mp3
  5. Success resample audio frame as mp3 file.
复制代码
然后打开影音播放器可以正常播放output_swrmp3.mp3,表示上述代码正确实现了将ogg音频数据重采样再转存MP3文件的功能。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

来自云龙湖轮廓分明的月亮

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表