(转) 通过ffmpeg将aac格式转换成wav格式
(2013-02-06 10:25:34)分类: 音视频 |
http://blog.csdn.net/ajaxhe/article/details/6761678
这是一个很简单的小程序,但也让我这个初学者折腾了好几天,走算是入门了,总结下学习的过程,希望能够初学者能有所帮助。
看源代码,首先得让让它跑起来。看了ffmpeg提供源码api-example.c,很好的入门程序,虽然对视频编解码十分顺利,但是源码提供的音频解码是有问题的,mp2文件不能正常的解码,这是很让人沮丧,特别是对一个初学者来说。
在对源程序进行单步调试的过程中,问题定位在了这个语句上:
-
avcodec_decode_audio3(in_ast_cctx,
(int16_t *)outbuf, &out_size, &packet);
-
-
avpkt.data = inbuf; -
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
且看video_decode_example函数中这段话:
问题已经很明朗了,通过在填充avpkt.data之前,需要进行一个预处理,即通过AAC帧中的同步字(帧头的12bit--0xFFF)来找出完整的一帧。
那就写预处理程序吧,转念一想,ffmpeg这么多行代码,不提供AAC帧解析的API也没有天理了,继续google,找到了下面一篇文章:
http://hi.baidu.com/wg_wang/blog/item/8e7e321796063a0c4b90a770
http://hi.baidu.com/wg_wang/blog/item/f78216f35465655d342acc16
http://hi.baidu.com/wg_wang/blog/item/4d55bd23eb3e2d49ac34de17
文章的标题是:利用libavcodec和libavformat对音频转码。附上了很详细的代码解析,我写的源程序大部分基于该文章。
下面就是test.c文件中的源码
- #include
-
- #include
"libavformat/avformat.h" - #include
"libavcodec/avcodec.h" - #include
"audio.h" - #include
"neaacdec.h" -
- int
main( intargc, char**argv) -
{
-
AVFormatContext *in_fctx; -
AVCodecContext *in_ast_cctx; -
AVCodec *in_ast_codec; -
AVPacket packet; -
audio_file *aufile; -
char *outbuf char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);= ( -
int out_size; -
int samples; -
-
//char *filename = "C:\\Users\\ajaxhe\\Desktop\\AudioCodec\\ffmpeg\\MyProject\\output_example2\\Debug\\higher1.aac"; -
char *filename; -
char *wavfile "debug_test.wav";= -
//char *wavfile; -
int ret = 0; -
int ast_idx = -1; -
int i, first_time = 1; -
-
if (argc == 3){ -
filename = argv[1]; -
wavfile = argv[2]; -
} -
else{ -
printf("usage: output_example.exe );infile.aac outfile.aac\n" -
return -1; -
} -
-
av_register_all(); -
in_fctx = av_alloc_format_context(); -
-
ret = av_open_input_file(&in_fctx, filename, NULL, 0, NULL); -
if ( ret != 0 ){ -
printf("open input ,audio file[%s] fail" filename); -
return -1; -
} -
-
ret = av_find_stream_info(in_fctx); -
if ( ret < 0 ){ -
printf("find stream ,in audio file[%s] fail" filename); -
return -1; -
} -
-
//dump_format(in_fctx, 0, filename, 0); -
//这里我们假设,如果一个文件包含多个音频流, -
//只对第一个音频流做转码,而对于视频流则忽略 -
for (i=0; int)in_fctx->nb_streams;i<( ++i){ -
if (in_fctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO){ -
ast_idx=i; -
break; -
} -
} -
if (ast_idx == -1){ -
printf("there is ,not any audio stream in [%s]" filename); -
return 0; -
} -
else{ -
printf("find audio ,stream in [%s]\n" filename); -
} -
-
in_ast_cctx = in_fctx->streams[ast_idx]->codec; -
in_ast_codec = avcodec_find_decoder(in_ast_cctx->codec_id); -
if (!in_ast_codec){ -
printf("find decoder ,for codec_id[%d] fail, file[%s]" in_ast_cctx->codec_id, filename); -
return -1; -
} -
-
ret = avcodec_open(in_ast_cctx, in_ast_codec); -
if (ret >= 0){ -
printf("open codec[name:%s] ,for stream[idx:%d] of file[%s]\n" in_ast_codec->name, ast_idx, filename); -
} -
-
av_init_packet(&packet); -
while (av_read_frame(in_fctx, &packet) >= 0){ -
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; -
ret = avcodec_decode_audio3(in_ast_cctx, (int16_t *)outbuf, &out_size, &packet); -
if (first_time){ -
aufile = open_audio_file(wavfile, in_ast_cctx->sample_rate, in_ast_cctx->channels, FAAD_FMT_16BIT, OUTPUT_WAV, 0); -
first_time = 0; -
} -
samples = in_ast_cctx->frame_size * in_ast_cctx->channels; -
write_audio_file(aufile, outbuf, samples, 0); -
} -
-
if (!first_time) -
close_audio_file(aufile); -
-
avcodec_close(in_ast_cctx); -
av_free(in_ast_cctx); -
-
return 0; -
}
#include "audio.h"
#include "neaacdec.h"
这两个头文件是我从faad2源代码中弄过来,时间仓促,没有来得及自己整理下,需要的整个工程朋友就直接从下面这个链接下载吧