AAC是一种常见的音频格式,今天尝试使用ffmpeg把pcm压缩成AAC编码。

第一步:初始化编码相关变量

寻找AAC的编码器

codec = avcodec_find_encoder(AV_CODEC_ID_AAC);

初始化编码器上下文,主要通道数,采样率,采样格式

 c = avcodec_alloc_context3(codec);if (!c) {fprintf(stderr, "Could not allocate audio codec context\n");return false;}c->channels = m_PcmChannel;c->channel_layout = av_get_default_channel_layout(m_PcmChannel);c->sample_rate = m_PcmSampleRate;c->sample_fmt = AV_SAMPLE_FMT_FLTP;//AV_SAMPLE_FMT_FLTP;c->bit_rate = 64000;/* Allow the use of the experimental AAC encoder. */c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;

打开编码器

 if (avcodec_open2(c, codec, NULL) < 0) {fprintf(stderr, "Could not open codec\n");return false;}

设置格式转换,主要是AAC需要的采样格式位AV_SAMPLE_FMT_FLTP,而PCM格式位AV_SAMPLE_FMT_S16,所以需要进行格式的转换。

 resample_context = swr_alloc_set_opts(NULL, c->channel_layout, c->sample_fmt,c->sample_rate, c->channel_layout, m_PcmFormat, c->sample_rate, 0, NULL);
if (swr_init(resample_context) < 0){fprintf(stderr, "Could not open resample context\n");return false;}

第二步:初始化相关工作做完之后,可以进行转码工作,首先丢进。

对PCM进行重新采样,转换成AAC需要的PCM格式

if (swr_convert(resample_context, frame->extended_data, frame->nb_samples, (const uint8_t**)m_PcmPointer, 1024)<0){fprintf(stderr, "Could not convert input samples (error )\n");if (NULL != frame){av_frame_free(&frame);}return ;}

放进编码器

ret = avcodec_send_frame(c, frame);

第三步:从编码器取出编码完的数据

int  ret = avcodec_receive_packet(c, packet);

第四步:由于编码后的AAC文件没有头,导致写成文件无法识别,所以需要手动写入AAC头

 // fill in ADTS data  m_pOutData[0] = 0xFF;m_pOutData[1] = 0xF1;m_pOutData[2] = ((profile) << 6) + (freqIdx << 2) + (chanCfg >> 2);m_pOutData[3] = (((chanCfg & 3) << 6) + (packetLen >> 11));m_pOutData[4] = ((packetLen & 0x7FF) >> 3);m_pOutData[5] = (((packetLen & 7) << 5) + 0x1F);m_pOutData[6] = 0xFC;

至此,PCM转成AAC的格式流程结束。

这里对AVSampleFormat格式进行一下介绍,

如果是以下格式:

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

只能保存再AVFrame的uint8_t *data[0];

音频保持格式如下:

LRLRLR。。。。

如果是以下格式

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

plane 0: LLLLLLLLLLLLLLLLLLLLLLLLLL...
plane 1: RRRRRRRRRRRRRRRRRRRR....

plane 0对于uint8_t *data[0];

plane 1对于uint8_t *data[1];

为了便于大家学习和研究, 工程采用VS2017开发,地址如下:

https://download.csdn.net/download/g0415shenw/10599101

ffmpeg之PCM转AAC相关推荐

  1. FFmpeg音频编码 ---- pcm转aac(使用新版ffmpeg API,亲测可用)

    /** * @projectName 08-01-encode_audio * @brief 音频编码 * 从本地读取PCM数据进行AAC编码 * 1. 输入PCM格式问题,通过AVCodec的sam ...

  2. ffmpeg 解码音频(aac、mp3)输出pcm文件

    ffmpeg 解码音频(aac.mp3)输出pcm文件 播放pcm可以参考: ffplay -ar 48000 -ac 2 -f f32le out.pcm main.c #include <s ...

  3. 在Linux环境下使用ffmpeg将PCM音频数据编码成aac数据

    在Linux环境下使用ffmpeg将PCM音频数据编码成aac数据 程序框图 代码演示 程序框图 将pcm数据经过aac编码器编码成aac数据,我是将从设备上采集的数据经过重采样送入aac编码器进行编 ...

  4. FFmpeg简单使用:音频编码 ---- pcm转aac

    基本流程  函数说明 avcodec_find_encoder:根据指定的AVCodecID查找注册的编码器. avcodec_alloc_context3:为AVCodecContext分配内存. ...

  5. 【FFmpeg】PCM编码成AAC

    使用FFmpeg把PCM裸数据编码成AAC音频流,具体步骤跟YUV编码成H264差不多. 1.命令行 ffmpeg -f s16le -ar 44100 -ac 2 -i bb1.pcm output ...

  6. ffmpeg pcm编码aac

    本博文参考自雷神博客 https://blog.csdn.net/leixiaohua1020/article/details/25430449 这是ffmpeg加上libfdk-aac 将pcm转a ...

  7. FFMPEG实现PCM编码(采用封装格式实现)

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 原文:https://blog.csdn.net/hiwubihe/article/details/81260882 [音频编解码系列文章] 音 ...

  8. 【Android FFMPEG 开发】Android 中使用 FFMPEG 将 PCM 音频采样转为 MP3 格式

    文章目录 一.前置操作 ( 移植 FFMPEG ) 二.FFMPEG 将 PCM 采样转为 MP3 格式的命令 三.Android FFMPEG 混音源代码完整示例 四.博客源码 一.前置操作 ( 移 ...

  9. 【开源项目】基于FFmpeg的PCM数据编码为AAC

    /* * 一笑奈何 * cn-yixiaonaihe.blog.csdn.net */#include <iostream> #include <thread> extern ...

最新文章

  1. Linux shell条件判断if中的-a到-z的意思
  2. java大量的print影响性能吗_printStackTrace()造成的性能瓶颈
  3. PHP培训教程 PHP里10个鲜为人知但却非常有用的函数
  4. 你的项目应该如何正确分层?
  5. mysql中的逻辑类型如何定义_MYSQL存储过程即常用逻辑知识点总结
  6. win 卸载mysql5.6_mysql5.6 win 安装 卸载总结
  7. Bootstrap HTML 编码规范之语言属性
  8. JQuery EasyUI DataGrid
  9. ip tcp udp mpeg4头结构的定义
  10. nohup命令的用法
  11. gluster安装完全指南
  12. oauth2+JWT实现oauth2服务
  13. your system does not seem to be set up to build kernel modules
  14. 凛冬至,这一杯互联网咖啡能热多久?
  15. Android 蓝牙开发——蓝牙连接(六)
  16. Java|Java中int的取值范围是多少
  17. 积累的VC编程小技巧之打印相关
  18. cpu设计和实现(流水线暂停)
  19. Java 8 新特性之 Stream 流(五)映射
  20. 【附源码】计算机毕业设计java员工工资管理系统设计与实现

热门文章

  1. [...]ubuntu rvm rails 安装完之后消失的解决方法
  2. Red Hat EnterPrise Linux 5.4下web服务器的综合使用(普通站点、虚拟主机、安全性、...
  3. oracle asm 错误集
  4. SQL2K数据库开发七之表操作添加删除和修改列
  5. msql查询姓名不带r的员工姓名_《MySQL数据库》关联查询
  6. c语言数据结构用矩阵存储图,数据结构之---C语言实现图的数组(邻接矩阵)存储表示...
  7. java中什么是继承,和继承的接口的关系?
  8. P2424 约数和 真丶除法分块
  9. [Java] 读写字符串数据
  10. 商业模式匹配乃同质化产品竞争终极大杀器