欢迎来到学术参考网

FFmpeg MP3解码器的研究与优化

发布时间:2015-06-17 10:07

  FFmpeg是如今多媒体领域用途非常广泛的一个开源免费跨平台的视频和音频流方案,MP3格式是一种常用的音频格式。但是ffmpeg对MP3v2.5规格的MP3音频文件解码支持不是很好,在播放时会有明显失真,而MP3v2.5规格的MP3多应用与低码率、低采样率的语音通信。本文介绍了MP3文件格式,以及其解码流程,主要讨论了改进ffmpeg MP3解码器的方法,对ffmpeg MP3解码器进行优化。

  中图分类号:TP801 文献标识码:A 文章编号:

  介绍

  FFmpeg是一个自由软件,可以执行音讯和视讯多种格式的录影、转档、串流功能,包含了libavcodec ---这是一个用于多个专案中音讯和视讯的解码器函式库,以及 libavformat ---一个音讯与视讯格式转换函式库[1]。这个项目最初是由Fabrice Bellard发起的,而现在是由Michael Niedermayer在进行维护。许多FFmpeg的开发者同时也是MPlayer项目的成员,FFmpeg在MPlayer项目中是FFmpeg包含了大部分主流格式的音视频编解码,以及格式间转换,而且具有很好的可移植性,其主要由以下元件组成:

  (1)ffmpeg是一个命令列工具,用来对视讯档案转换格式,也支援对电视卡即时编码;

  (2) ffserver是一个 HTTP 多媒体即时广播串流服务器,支援时光平移;

  (3) ffplay是一个简单的播放器,基于 SDL 与 FFmpeg 函式库;

  (4) 4libavcodec包含了全部 FFmpeg 音讯/视讯 编解码函式库;

  (5) libavformat包含 demuxers 和 muxer 函式库;

  (6) libavutil包含一些工具函式库;

  (7) libpostproc对于视讯做前处理的函式库;

  (8)libswscale对于影像作缩放的函式库;

  FFmpeg结构主要是muxer/demuxer负责文件的组成/解析,decoder/encoder负责文件的编解码,device负责音视频的输出,其解码结构图如下:

  图1 FFmpeg解码结构图

  2. MP3文件格式解析及解码流程

  2.1 MP3文件格式解析

  Moving Picture Experts Group Audio Layer III(MPEG-1 Audio Layer 3,动态图像专家压缩标准音频层面3),经常称为MP3,是当今较流行的一种数字音频编码和有损压缩格式,它设计用来大幅度地降低音频数据量,而对于大多数用户的听觉感受来说,重放的音质与最初的不压缩音频相比没有明显的下降。它是在1991年,由位于德国埃尔朗根的研究组织Fraunhofer-Gesellschaft的一组工程师发明和标准化的[2]。

  声音是一个模拟信号,对声音进行采样,量化,编码就会得到PCM数据,PCM数据也就是脉冲编码调制音频数据,是电脑可以直接播放的原始数据。但是在PCM数据中含有很多对人类听觉不重要的数据,为了节省存储空间同时还能保证很好的音效,MP3利用心理声学技术将PCM音频数据中人类不敏感的部分除去并压缩形成MP3音频文件。所以说MP3是一种有损压缩格式[3]。

  MP3文件是由帧(Frame)构成,帧是MP3文件的组成单位,其中每帧都有一个帧头,长4个字节,包含了MP3文件的版本,采样率,比特率等属性信息。MP3文件的版本及其对应的采样率如表格1所示:

  表1 mp3文件版本及其对应采样率

  由上表可以看出,MPv2.5对应的采样率较低,虽然其不是MPEG的标准规范,但是此版本的MP3文件在语音通话领域应用较为广泛,MP3解码器有必要做好对应的解码。

  2.2 MP3解码流程

  MP3的解码总体上可分为9个过程[4]:比特流分解,哈夫曼解码,逆量化处理,立体声处理,频谱重排列,抗锯齿处理,IMDCT变换,子带合成,PCM输出。

  比特流分解也就是将MP3文件以二进制方式打开,根据MP3格式的定义,依次从MP3文件中读取头信息,边信息,比例因子等信息,这也就是demuxer所要做的工作。

  哈夫曼编码是一种无损压缩编码,其解码属于decoder很重要的一部分。

  MP3音频文件的详细解码流程如下图二所示:

  图2 MP3解码流程图

  3.改进ffmpeg对MPv2.5的支持

  3.1 准备工作

  MPv2.5虽然不属于MPEG标准,但是广泛应用于低采样率的语音通信中,ffmpeg中的MP3解码器,并没有针对MPv2.5版本的decoder,本文在此另外添加一个decoder来解决失真的问题。谷歌的Android系统中的MP3解码库对MPv2.5有很好的支持,本文参考android的MP3解码器新构建一个MP3解码器到ffmpeg中。

  3.1 准备工作

  (1)FFmpeg中MP3解码器格式:

  按照struct AVCodec的定义,本文添加的MP3解码器格式如下:

  AVCodec mpv2.5_mp3_decoder =

  {

  "mpv2.5_mp3",

  CODEC_TYPE_AUDIO,

  CODEC_ID_MP3v2.5,

  sizeof(MPADecodeContext),

  Decode_init_mp3,

  NULL,

  Decode_close_mp3,

  Decode_frame_mp3,

  CODEC_CAP_PARSE_ONLY,

  .flush= flush,

  .long_name= NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),

  };

  其中各部分含义[5]:

   "mpv2.5_mp3":MP3解码器的名称,注意要与解码器注册函数中相应参数保持一致;

  CODEC_TYPE_AUDIO:说明解码器解码文件的类型,此处为MP3音频文件;

  CODEC_ID_MP3v2.5:对应MP3解码器的唯一ID,是解码器的身份标识;

    Decode_init_mp3:对应MP3解码器的初始化接口;

  Decode_frame_mp3:对应MP3解码器的解码数据接口;

  Decode_close_mp3:对应MP3解码器的析构接口。

  (2)MP3解码库的接口API:

  Android中的MP3解码库函数接口主要有以下接口:

  void pvmp3_InitDecoder(tPVMP3DecoderExternal *pExt, void *pMem);

  MP3解码库的初始化接口,负责解码库基本参数的初始化以及分配解码需要的buffer;

   ERROR_CODE pvmp3_framedecoder(tPVMP3DecoderExternal *pExt, void *pMem);

  MP3解码库的解码接口,负责解码输入的MP3数据,输出PCM数据;

  3.2 主要步骤

  (1)注册解码器:

  在文件allcodecs.c中,实现所有ffmpeg支持格式的编解码器的注册,因此首先在此文件中实现添加MP3解码器的注册。

  解码器注册函数为:

  REGISTER_DECODER(MPV2.5_MP3,mpv2.5mp3);

  此函数是一个宏定义,实际会调用函数:

  void avcodec_register(AVCodec *codec);

  (2)添加解码器的ID:

  编解码器的ID为编解码器的身份标识,具有唯一性,在ffmpeg中,会根据ID来寻找对应的编解码器。

  在文件avcodec.h中的enum CodecID中实现注册:

  enum CodecID {

  CODEC_ID_NONE,

  /* video codecs */

  CODEC_ID_MPEG1VIDEO,

  CODEC_ID_MPEG2VIDEO,

  …………

  …………

  /* audio codecs */

  CODEC_ID_MP2= 0x15000,

  CODEC_ID_MP3,

  CODEC_ID_MP3v2.5,

  …………

  };

  (3)实现解码器到解码库的接口对应:

  为新添加的MP3解码库实现一个封装,封装后接口为:

  void* Decodeinit_mp3v2.5(void);

  void Decoder_exit_mp3v2.5(void* state);

  int Decode_frame_mp3v2.5(void *s,

  signed short *samples,const uint8 *buf,

  int buf_size,int *data_size) ;

  其中state是一个封装层的结构体实现MP3解码器与解码库的数据交互,内容如下:

  struct state_mp3{

  tPVMP3DecoderExternal *mp3decoderdata;

  unsigned char* pMem;

  };

  4.优化结果对比

  为了较为直观的显示ffmpegMP3解码器优化前后的不同,本文中找到MPv2.5b版本的不同采样率的多个MP3文件测试,用变量信噪比(Signal to Noise Ratio)显示优化前后区别,如表1:

  通过表格1我们可以看出,优化后ffmpeg解码MPv2.5版本的MP3文件信噪比明显提升,达到预期效果。

  5.总结

  本文介绍了多媒体编解码库ffmpeg,以及MP3文件格式,主要讨论了改进ffmpeg对mpv2.5 MP3音频文件的支持,实现对ffmpeg中MP3解码器的优化。优化后的ffmpeg MP3解码器可以清楚、流畅、无失真播放mpv2.5 MP3音频文件。

  参考文献:

  [1] Wikipedia: wiki/Ffmpeg

  [2] Cervera ,Teresa ,The effect of MPEG audio compression on multidimensional set of voice parameters ,Logopedics Phoniatrics Vocology ,2001.8 ,Vol.26,P.124.

  [3] 林福宗. 多媒体技术基础[M],北京:清华大学出版社,2001.

  [4] 张波. 嵌入式MP3解码研究与优化,上海:上海交通大学,2009.

  [5] 吴张顺. 基于ffmpeg的视频编码存储研究与实现,浙江:杭州电子科技大学,2006.

上一篇:如何设计EZ-USB FX2高像素镜头成像质量检测软件?

下一篇:Flash补间动画中的旋转走样分析