#include <iostream>
using namespace std;
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include <stdio.h>
}
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
static void decode(AVCodecContext *dec_ctx,AVPacket *pkt,AVFrame *frame,FILE *outfile)
{
int ret=avcodec_send_packet(dec_ctx,pkt); //发送给解码器
while(ret>=0)
{
ret=avcodec_receive_frame(dec_ctx,frame); //接收解码后的帧
if(ret==AVERROR(EAGAIN)||ret==AVERROR_EOF)
return;
int data_size=av_get_bytes_per_sample(dec_ctx->sample_fmt); //获取单个sample占用的字节
for(int i=0;i<frame->nb_samples;i++)
{
for(int ch=0;ch<dec_ctx->channels;ch++) //交错的方式写入,大部分float的格式输出
fwrite(frame->data[ch]+data_size*i,1,data_size,outfile);
}
}
}
int main()
{
const char *outfilename="out1.pcm";
const char *filename="out1.aac";
const AVCodec *codec;
AVCodecContext *codec_ctx=NULL;
AVCodecParserContext *parser=NULL;
int len=0;
int ret=0;
FILE *infile=NULL;
FILE *outfile=NULL;
uint8_t inbuf[AUDIO_INBUF_SIZE+AV_INPUT_BUFFER_PADDING_SIZE];
uint8_t *data=NULL;
size_t data_size=0;
AVPacket *pkt=NULL;
AVFrame *decoded_frame=NULL;
pkt=av_packet_alloc();
enum AVCodecID audio_codec_id=AV_CODEC_ID_AAC;
if(strstr(filename,"aac")!=NULL){ // 根据文件后缀名给audio_codec_id赋值
audio_codec_id=AV_CODEC_ID_AAC; //char *strstr( const char *str1, const char *str2 );
} // strstr函数是在字符串str1中查找是否含有字符串str2,如果存在,返回str2在str1中第一次出现的地址;否则返回NULL。
else if(strstr(filename,"mp3")!=NULL){
audio_codec_id=AV_CODEC_ID_MP3;
}
else{
printf("default codec id:%d\n",audio_codec_id);
}
codec=avcodec_find_decoder(audio_codec_id); //查找解码器
parser=av_parser_init(codec->id); //获取裸流的解析器AVCodecParserContext(数据)+AVCodecParser(方法)
codec_ctx=avcodec_alloc_context3(codec); //分配codec上下文
avcodec_open2(codec_ctx,codec,NULL); //将解码器和解码器上下文进行关联
infile=fopen(filename,"rb"); //打开输入文件
outfile=fopen(outfilename,"wb"); //打开输出文件
data=inbuf;
data_size=fread(inbuf,1,AUDIO_INBUF_SIZE,infile); 读取文件进行解码
while(data_size>0)
{
decoded_frame=av_frame_alloc();
ret=av_parser_parse2(parser,codec_ctx,&pkt->data,&pkt->size,
data,data_size,AV_NOPTS_VALUE,AV_NOPTS_VALUE,0);
data+=ret; //跳过已经解析的数据
data_size-=ret; //对应的缓存大小也做相应减小
if(pkt->size)
{
decode(codec_ctx,pkt,decoded_frame,outfile);
}
if(data_size<AUDIO_REFILL_THRESH) //如果数据少了则再次读取
{
memmove(inbuf,data,data_size); //把之前剩的数据拷贝到buffer的起始位置
data=inbuf;
//读取数据长度:AUDIO_INBUF_SIZE-data_size
len=fread(data+data_size,1,AUDIO_INBUF_SIZE-data_size,infile);
if(len>0)
data_size+=len;
}
}
/*冲刷解码器*/
pkt->data=NULL;
pkt->size=0;
decode(codec_ctx,pkt,decoded_frame,outfile);
fclose(outfile);
fclose(infile);
avcodec_free_context(&codec_ctx);
av_parser_close(parser);
av_frame_free(&decoded_frame);
av_packet_free(&pkt);
printf("main finish,please enter Enter and exit\n");
return 0;
}
FFmpeg-out1.aac文件解码成out1.pcm文件(代码实现)
最新推荐文章于 2024-06-03 19:48:40 发布
该代码示例展示了如何使用ffmpeg库解码AAC音频文件,并将其输出为PCM格式。程序首先根据文件后缀确定音频编码类型,然后找到相应的解码器,进行解码上下文初始化,读取文件数据,解析并解码音频帧,最后将解码后的数据写入新的PCM文件。
摘要由CSDN通过智能技术生成