技术在于交流、沟通,转载请注明出处并保持作品的完整性。

原文:https://blog.csdn.net/hiwubihe/article/details/81261022

[音频编解码系列文章]

  1. 音频编解码基础
  2. FFMPEG实现音频重采样
  3. FFMPEG实现PCM编码(采用封装格式实现)
  4. FFMPEG实现PCM编码(不采用封装格式实现)
  5. FAAC库实现PCM编码
  6. FAAD库实现RAW格式AAC解码
  7. FAAD库实现RAW格式AAC封装成ADTS格式
  8. FAAD库实现ADTS格式解码
  9. FFMPEG实现对AAC解码(采用封装格式实现)
  10. FFMPEG实现对AAC解码(不采用封装格式实现)

本篇FFMEPG实现对AAC解码,解码结果保存wav格式。对AAC编码文件来说,编码根据音频参数编码,解码根据音频参数重新构建声波,FFMPEG构建的音频存储方式不一定支持播放, 所以需要重采样样本,如AAC解码的样本格式AV_SAMPLE_FMT_FLTP。AAC的解码器如果是外部解码器"aac",解码格式需要AV_SAMPLE_FMT_FLTP,如果是“libvo_aacenc”这个解码器需要格式AV_SAMPLE_FMT_S16。

DEMO源代码如下

/*******************************************************************************
Copyright (c) wubihe Tech. Co., Ltd. All rights reserved.
--------------------------------------------------------------------------------Date Created:   2014-10-25
Author:         wubihe QQ:1269122125 Email:1269122125@qq.com
Description:    音频格式AAC MP3的解码,结果保存WAV格式
--------------------------------------------------------------------------------
Modification History
DATE          AUTHOR          DESCRIPTION
--------------------------------------------------------------------------------********************************************************************************/#include <stdlib.h>
#include <string.h>
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"};#define INPUT_FILE_NAME       ("huangdun.aac")
#define OUTPUT_FILE_NAME     ("huangdun.wav")
#define  MAXWAVESIZE         (4294967040LU)//写WAV文件头
static int write_wav_header(int iBitPerSample,int iChans,unsigned char ucFormat,int iSampleRate,int iTotalSamples,FILE*pFile)
{unsigned char header[44];unsigned char* p = header;unsigned int bytes = (iBitPerSample + 7) / 8;float data_size = (float)bytes * iTotalSamples;unsigned long word32;*p++ = 'R'; *p++ = 'I'; *p++ = 'F'; *p++ = 'F';word32 = (data_size + (44 - 8) < (float)MAXWAVESIZE) ?(unsigned long)data_size + (44 - 8)  :  (unsigned long)MAXWAVESIZE;*p++ = (unsigned char)(word32 >>  0);*p++ = (unsigned char)(word32 >>  8);*p++ = (unsigned char)(word32 >> 16);*p++ = (unsigned char)(word32 >> 24);*p++ = 'W'; *p++ = 'A'; *p++ = 'V'; *p++ = 'E';*p++ = 'f'; *p++ = 'm'; *p++ = 't'; *p++ = ' ';*p++ = 0x10; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;if (ucFormat == AV_SAMPLE_FMT_FLT){*p++ = 0x03; *p++ = 0x00;} else {*p++ = 0x01; *p++ = 0x00;}*p++ = (unsigned char)(iChans >> 0);*p++ = (unsigned char)(iChans >> 8);word32 = (unsigned long)(iSampleRate + 0.5);*p++ = (unsigned char)(word32 >>  0);*p++ = (unsigned char)(word32 >>  8);*p++ = (unsigned char)(word32 >> 16);*p++ = (unsigned char)(word32 >> 24);word32 = iSampleRate * bytes * iChans;*p++ = (unsigned char)(word32 >>  0);*p++ = (unsigned char)(word32 >>  8);*p++ = (unsigned char)(word32 >> 16);*p++ = (unsigned char)(word32 >> 24);word32 = bytes * iChans;*p++ = (unsigned char)(word32 >>  0);*p++ = (unsigned char)(word32 >>  8);*p++ = (unsigned char)(iBitPerSample >> 0);*p++ = (unsigned char)(iBitPerSample >> 8);*p++ = 'd'; *p++ = 'a'; *p++ = 't'; *p++ = 'a';word32 = data_size < MAXWAVESIZE ?(unsigned long)data_size : (unsigned long)MAXWAVESIZE;*p++ = (unsigned char)(word32 >>  0);*p++ = (unsigned char)(word32 >>  8);*p++ = (unsigned char)(word32 >> 16);*p++ = (unsigned char)(word32 >> 24);return fwrite(header, sizeof(header), 1, pFile);
}int main()
{FILE *pOutFile=NULL;pOutFile = fopen(OUTPUT_FILE_NAME, "wb");if(pOutFile == NULL){return -1;}//注册解码器av_register_all();avformat_network_init();AVFormatContext  * pFormatCtx = avformat_alloc_context();//打开封装格式if(avformat_open_input(&pFormatCtx,INPUT_FILE_NAME,NULL,NULL)!=0){return -1;}//if(avformat_find_stream_info(pFormatCtx,NULL)<0){printf("封装格式查找流失败.\n");return -1;}// Dump valid information onto standard errorav_dump_format(pFormatCtx, 0, INPUT_FILE_NAME, false);// Find the first audio streamint audioStream = -1;for(int i=0; i < pFormatCtx->nb_streams; i++){if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){audioStream=i;break;}}if(audioStream==-1){printf("Didn't find a audio stream.\n");return -1;}// Get a pointer to the codec context for the audio streamAVCodecContext *pCodecCtx=pFormatCtx->streams[audioStream]->codec;// Find the decoder for the audio streamAVCodec            *pCodec=avcodec_find_decoder(pCodecCtx->codec_id);if(pCodec==NULL){printf("Codec not found.\n");return -1;}// Open codecif(avcodec_open2(pCodecCtx, pCodec,NULL)<0){printf("Could not open codec.\n");return -1;}//对AAC编码文件来说,编码根据音频参数编码,解码根据音频参数重新构建声波,FFMPEG构建的//音频存储方式不一定支持播放,所以需要重采样样本 如AAC解码的样本格式是AV_SAMPLE_FMT_FLTPuint64_t iInputLayout                = av_get_default_channel_layout(pCodecCtx->channels);int      iInputChans                = pCodecCtx->channels;AVSampleFormat eInputSampleFormat   = pCodecCtx->sample_fmt;int      iInputSampleRate           = pCodecCtx->sample_rate;uint64_t iOutputLayout              = av_get_default_channel_layout(pCodecCtx->channels);int      iOutputChans               = pCodecCtx->channels;AVSampleFormat eOutputSampleFormat  = AV_SAMPLE_FMT_S16;int         iOutputSampleRate          = pCodecCtx->sample_rate;SwrContext *pSwrCtx = swr_alloc_set_opts(NULL,iOutputLayout, eOutputSampleFormat, iOutputSampleRate,iInputLayout,eInputSampleFormat , iInputSampleRate,0, NULL);swr_init(pSwrCtx);//AVPacket读取原始解码前的数据AVPacket *packet=(AVPacket *)malloc(sizeof(AVPacket));av_init_packet(packet);//1帧数据样本数int iFrameSamples = pCodecCtx->frame_size;// 存储原始数据 int iRawLineSize = 0;int iRawBuffSize  = av_samples_get_buffer_size(&iRawLineSize, iInputChans, iFrameSamples, eInputSampleFormat, 0);uint8_t *pRawBuff = (uint8_t *)av_malloc(iRawBuffSize);//原始数据保存在AVFrame结构体中AVFrame* pRawframe = av_frame_alloc();pRawframe->nb_samples  = iFrameSamples;pRawframe->format        = eInputSampleFormat;pRawframe->channels     = iInputChans;int iReturn = avcodec_fill_audio_frame(pRawframe, iInputChans, eInputSampleFormat, (const uint8_t*)pRawBuff, iRawBuffSize, 0);if(iReturn<0){return -1;}// 存储转换后数据 int iConvertLineSize = 0;int iConvertBuffSize  = av_samples_get_buffer_size(&iConvertLineSize, iOutputChans, iFrameSamples, eOutputSampleFormat, 0);uint8_t *pConvertBuff = (uint8_t *)av_malloc(iConvertBuffSize);//转换后数据保存在AVFrame结构体中AVFrame* pConvertframe = av_frame_alloc();pConvertframe->nb_samples   = iFrameSamples;pConvertframe->format        = eOutputSampleFormat;pConvertframe->channels     = iOutputChans;iReturn = avcodec_fill_audio_frame(pConvertframe, iOutputChans, eOutputSampleFormat, (const uint8_t*)pConvertBuff, iConvertBuffSize, 0);if(iReturn<0){return -1;}int iGetPicture;int iDecodeRet;int iFrameNo = 0;write_wav_header(16,iOutputChans,eOutputSampleFormat,iOutputSampleRate,0,pOutFile);while(av_read_frame(pFormatCtx, packet)>=0){if(packet->stream_index==audioStream){iDecodeRet = avcodec_decode_audio4( pCodecCtx, pRawframe,&iGetPicture, packet);if ( iDecodeRet < 0 ) {printf("Error in decoding audio frame.\n");return -1;}if ( iGetPicture > 0 ){printf("FrameNo:%5d\n",iFrameNo);swr_convert(pSwrCtx, (uint8_t**)pConvertframe->data, iFrameSamples ,(const uint8_t**)pRawframe->data, iFrameSamples );fwrite(pConvertframe->data[0],pConvertframe->linesize[0],1,pOutFile);iFrameNo++;}}av_free_packet(packet);}av_free(pRawBuff);av_free(pConvertBuff);swr_free(&pSwrCtx);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);fclose(pOutFile);printf("Aac encode Success!!\n");getchar();return 0;
}

FFMPEG实现对AAC解码(采用封装格式实现)相关推荐

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

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

  2. 【FFmpeg杂记】音频解码输出PCM格式数据分析

      FFmpeg音频解码后输出的为PCM数据,PCM中的声音数据没有被压缩.   FFmpeg中音视频数据基本上都有Packed和Planar两种存储方式,对于双声道音频来说,Packed方式为两个声 ...

  3. ffmpeg音视频编解码的封装

    //导入头文件 //核心库 #include "libavcodec/avcodec.h" //封装格式处理库 #include "libavformat/avforma ...

  4. mongodb java条件查询_java实现对mongodb,泛型封装增删查改、条件查询等操作

    本文实现一个通用泛型封装实现类,需要给定一个集合对象,类似mysql中与java对应的表:思想就是把给定的对象解析出所有非空字段,保存到一个BasicDBObject中,这里一定要保证java对象与m ...

  5. C# Excel.Range类实现对Excel单元格文本格式的设置

    Excel.Range titleRange_A = newWorksheet.get_Range(newWorksheet.Cells[2, 2], newWorksheet.Cells[2, 2] ...

  6. ffmpeg之封装格式之aac

    简介 ACC(Advanced Audio Coding,高级音频编码)是杜比实验室为音乐社区提供的技术.,出现于1997年,基于MPEG-2的音频编码技术.2000年,MPEG-4标准出现后,AAC ...

  7. FFmpeg封装格式处理2-解复用例程

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10506642.html FFmpeg封装格式处理相关内容分为如下几篇文章: [1]. F ...

  8. 【Android RTMP】音频数据采集编码 ( FAAC 编码器编码 AAC 音频采样数据 | 封装 RTMP 音频数据头 | 设置 AAC 音频数据类型 | 封装 RTMP 数据包 )

    文章目录 安卓直播推流专栏博客总结 一. FAAC 编码器编码 AAC 音频采样数据 二. 封装 RTMP 音频数据头 三. 封装 RTMP 音频数据类型 四. 拷贝 AAC 音频数据到 RTMPPa ...

  9. FFmpeg之视频封装格式、流媒体协议、视频编解码协议和传输流格式、时间戳和时间基、视频像素数据

    通用视频分析工具:Mediainfo.Elecard StreamEye(视频编码分析工具); 视频封装格式: ********************MP4****************** MP ...

最新文章

  1. (Java)常用排序
  2. 仿ios便签软件_手机便签软件误删怎么恢复?
  3. SAP云平台,Netweaver,Kubernetes和C4C的用户和角色关系
  4. 小程序开发(11)-之支付封装
  5. Transformer组件很重要Attention is all you need
  6. 一串字字符中多个逗号转换为一个,既标准分隔符(正则表达式)
  7. puppet成长日记二 Package资源详细介绍及案例分析
  8. Hadoop集群的启动顺序
  9. JSP的优势与劣势浅析
  10. mybatis 多表插入_CRUD_Operator-Mybatis
  11. 计算机二级vb题库公众号,计算机二级vb题库
  12. 计算机常见故障有那些,电脑有哪些常见故障?如何排除?
  13. 《个人信息安全规范 (2019-6-21) 》征求意见稿的最新变化
  14. eplan p8详细安装步骤文库_EPLAN_P8_2.1.6 安装步骤
  15. css网站变灰色代码
  16. PX4从放弃到精通(二十七):固定翼姿态控制
  17. react上拉加载更多
  18. 初等矩阵及初等变换中的符号意义
  19. Java之每日经典一题:(1)珠穆朗玛峰
  20. 球的半径和体积:输入球的中心点和球上某一点的坐标,计算球的半径和体积

热门文章

  1. 腾讯资深架构师整理出来的Java高级开发需要的分布式技术,简直绝了
  2. ReactiveX 操作符
  3. 论文写作之常见错误总结
  4. 数据分析毕业设计 金融数据分析与可视化系统 - python 大数据
  5. 蓝桥 Python 大于等于n的最小完全平方数
  6. 重积分 | 二重积分中 dx x dy = ρ dρ x dθ
  7. Redis Sentinel判断主观下线和客观下线
  8. 大学物理---统计物理(热学部分)
  9. Python基础知识:输入输出函数(input和print)及格式化输出
  10. linux定时发信息到微信群聊,Wechat-Timed-Message