ffmpeg avcodec_decode_audio4解码 swr_convert 转换为AV_SAMPLE_FMT_S16格式

本文介绍了一种使用FFmpeg库进行音频转换的方法,包括如何设置音频参数、申请缓冲区、初始化Swr上下文以及执行音频重采样等关键步骤。
	uint64_t out_channel_layout=AV_CH_LAYOUT_STEREO; //定义目标音频参数
	//nb_samples: AAC-1024 MP3-1152
	int out_nb_samples=pACodecCtx->frame_size;
	AVSampleFormat out_sample_fmt=AV_SAMPLE_FMT_S16;
	int out_sample_rate=44100;
	int out_channels=av_get_channel_layout_nb_channels(out_channel_layout);
	//Out Buffer Size
	int out_buffer_size=av_samples_get_buffer_size(NULL,out_channels ,out_nb_samples,out_sample_fmt, 1);//计算转换后数据大小
	uint8_t * audio_out_buffer=(uint8_t *)av_malloc(out_buffer_size);//申请输出缓冲区

	//FIX:Some Codec's Context Information is missing
	uint64_t in_channel_layout=av_get_default_channel_layout(pACodecCtx->channels);
	//Swr
	SwrContext *audio_convert_ctx = swr_alloc();
	audio_convert_ctx=swr_alloc_set_opts(audio_convert_ctx,out_channel_layout, out_sample_fmt, out_sample_rate,
	pACodecCtx->channel_layout ,pACodecCtx->sample_fmt , pACodecCtx->sample_rate,0, NULL);//配置源音频参数和目标音频参数
	swr_init(audio_convert_ctx);

	int len2=swr_convert(audio_convert_ctx,&audio_out_buffer, out_buffer_size,(const uint8_t **)audio_frame->data , audio_frame->nb_samples);
	int resampled_data_size = len2 * out_channels  * av_get_bytes_per_sample(out_sample_fmt);//每声道采样数 x 声道数 x 每个采样字节数 
	fwrite(audio_out_buffer,1,resampled_data_size,pcm);//pcm记录
        fflush(pcm);

</pre><pre name="code" class="html">



                
以下是使用FFmpeg新版本库实现音频解码为wav格式的代码: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <stdbool.h> #include <unistd.h> #include <libavutil/frame.h> #include <libavutil/mem.h> #include <libavutil/opt.h> #include <libavutil/samplefmt.h> #include <libavutil/channel_layout.h> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswresample/swresample.h> #define AUDIO_INBUF_SIZE 20480 #define AUDIO_REFILL_THRESH 4096 int main(int argc, char **argv) { AVCodec *codec; AVCodecContext *c = NULL; int len; FILE *f, *outfile; uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; AVPacket avpkt; AVFrame *decoded_frame = NULL; int got_frame; int ret; int16_t *samples; int sample_size; SwrContext *swr_ctx = NULL; int dst_nb_samples; int dst_linesize; uint8_t **dst_data; int dst_bufsize; int i; if (argc <= 2) { fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]); exit(0); } av_register_all(); if (avformat_open_input(&c, argv[1], NULL, NULL) < 0) { fprintf(stderr, "Could not open input file '%s'\n", argv[1]); exit(1); } if (avformat_find_stream_info(c, NULL) < 0) { fprintf(stderr, "Could not find stream information\n"); exit(1); } av_dump_format(c, 0, argv[1], 0); codec = avcodec_find_decoder(c->streams[0]->codecpar->codec_id); if (!codec) { fprintf(stderr, "Codec not found\n"); exit(1); } c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr, "Could not allocate codec context\n"); exit(1); } if (avcodec_parameters_to_context(c, c->streams[0]->codecpar) < 0) { fprintf(stderr, "Could not copy codec parameters to context\n"); exit(1); } if (avcodec_open2(c, codec, NULL) < 0) { fprintf(stderr, "Could not open codec\n"); exit(1); } f = fopen(argv[2], "wb"); if (!f) { fprintf(stderr, "Could not open output file '%s'\n", argv[2]); exit(1); } decoded_frame = av_frame_alloc(); if (!decoded_frame) { fprintf(stderr, "Could not allocate audio frame\n"); exit(1); } av_init_packet(&avpkt); while (av_read_frame(c, &avpkt) >= 0) { if (avpkt.stream_index == 0) { ret = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt); if (ret < 0) { fprintf(stderr, "Error decoding audio frame\n"); exit(1); } if (got_frame) { sample_size = av_get_bytes_per_sample(c->sample_fmt); if (sample_size < 0) { fprintf(stderr, "Failed to calculate sample size\n"); exit(1); } samples = (int16_t *)decoded_frame->data[0]; len = decoded_frame->nb_samples * c->channels * sample_size; if (swr_ctx) { av_freep(&dst_data[0]); swr_free(&swr_ctx); } swr_ctx = swr_alloc_set_opts(NULL, av_get_default_channel_layout(c->channels), AV_SAMPLE_FMT_S16, c->sample_rate, av_get_default_channel_layout(c->channels), c->sample_fmt, c->sample_rate, 0, NULL); if (!swr_ctx || swr_init(swr_ctx) < 0) { fprintf(stderr, "Failed to initialize the resampling context\n"); exit(1); } dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, c->sample_rate) + decoded_frame->nb_samples, c->sample_rate, c->sample_rate, AV_ROUND_UP); ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, c->channels, dst_nb_samples, AV_SAMPLE_FMT_S16, 0); if (ret < 0) { fprintf(stderr, "Could not allocate destination samples\n"); exit(1); } dst_bufsize = av_samples_get_buffer_size(NULL, c->channels, dst_nb_samples, AV_SAMPLE_FMT_S16, 0); if (dst_bufsize < 0) { fprintf(stderr, "Could not get sample buffer size\n"); exit(1); } ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)decoded_frame->data, decoded_frame->nb_samples); if (ret < 0) { fprintf(stderr, "Error while converting\n"); exit(1); } fwrite(dst_data[0], 1, dst_bufsize, f); } } av_packet_unref(&avpkt); } fclose(f); avcodec_free_context(&c); av_frame_free(&decoded_frame); av_free(samples); if (swr_ctx) { av_freep(&dst_data[0]); swr_free(&swr_ctx); } return 0; } ``` 这段代码使用了FFmpeg库来解码音频文件,并将其转换为WAV格式。它可以处理多种音频格式,包括MP3、AAC、FLAC等。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值