C++ 解码m4a并转储PCM数据会返回噪声

C++ 解码m4a并转储PCM数据会返回噪声,c++,audio,ffmpeg,libavcodec,C++,Audio,Ffmpeg,Libavcodec,我正在使用下面的代码(根据libavcodec中给出的示例进行修改)对音频文件进行解码 int main(int argc, char **argv) { av_register_all(); avcodec_register_all(); char *filename = argv[1]; char *outfilename = argv[2]; FILE *outfile; AVCodec *codec; AVCodecConte

我正在使用下面的代码(根据libavcodec中给出的示例进行修改)对音频文件进行解码

int main(int argc, char **argv)
{
    av_register_all();
    avcodec_register_all();

    char *filename = argv[1];
    char *outfilename = argv[2];

    FILE *outfile;

    AVCodec *codec;
    AVCodecContext *c= NULL;
    AVPacket avpkt;
    AVFrame *frame = av_frame_alloc();

    printf("Decode audio file %s to %s\n", filename, outfilename);

    outfile = fopen(outfilename, "wb");
    if (!outfile) {
        fprintf(stderr, "Could not write to %s\n", outfilename);
        av_free(c);
        exit(1);
    }

    AVFormatContext *format_context = NULL;
    avformat_open_input(&format_context, filename, NULL, NULL);
    printf("Opened format input\n");

    int find_result = avformat_find_stream_info(format_context, NULL);
    if (find_result < 0) {
        fprintf(stderr, "Cannot find stream info\n");
        avformat_close_input(&format_context);
        exit(-1);
    }

    int audio_stream_idx = av_find_best_stream(format_context, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);

    if (audio_stream_idx < 0) {
        fprintf(stderr,"Couldn't find stream information\n");
        exit(-1);
    }

    // Get a pointer to the codec context for the audio stream
    c = format_context->streams[audio_stream_idx]->codec;
    av_opt_set_int(c, "refcounted_frames", 1, 0);

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

    // read the audio frames
    int ret, got_frame;
    while (1) {
        if ((ret = av_read_frame(format_context, &avpkt)) < 0)
            break;
        if (avpkt.stream_index == audio_stream_idx) {
            avcodec_get_frame_defaults(frame);
            got_frame = 0;
            ret = avcodec_decode_audio4(c, frame, &got_frame, &avpkt);
            if (ret < 0) {
                fprintf(stderr, "Error decoding audio\n");
                continue;
            }

            if (got_frame) {
                // write to disk
                fwrite(frame->extended_data[0], 1, frame->linesize[0], outfile);
            }
        }
        av_free_packet(&avpkt);
    }

    fclose(outfile);

    printf("Finished\n");
    if (c) 
        avcodec_close(c);
    avformat_close_input(&format_context);
    av_frame_free(&frame);
}
int main(int argc,char**argv)
{
av_寄存器_all();
avcodec_寄存器_all();
char*filename=argv[1];
char*outfilename=argv[2];
文件*输出文件;
AVCodec*编解码器;
AVCodecContext*c=NULL;
avpkt;
AVFrame*frame=av_frame_alloc();
printf(“将音频文件%s解码为%s\n”,文件名,输出文件名);
outfile=fopen(outfilename,“wb”);
如果(!outfile){
fprintf(stderr,“无法写入%s\n”,outfilename);
无AVU(c);
出口(1);
}
AVFormatContext*format_context=NULL;
avformat_open_输入(&format_上下文、文件名、NULL、NULL);
printf(“打开的格式输入\n”);
int find_result=avformat_find_stream_info(format_context,NULL);
如果(查找结果<0){
fprintf(stderr,“找不到流信息”);
avformat_close_输入(&format_上下文);
出口(-1);
}
int audio\u stream\u idx=av\u find\u best\u stream(格式上下文、AVMEDIA\u类型音频、-1、&codec,0);
中频(音频流idx<0){
fprintf(stderr,“找不到流信息”);
出口(-1);
}
//获取指向音频流的编解码器上下文的指针
c=格式\u上下文->流[音频\u流\u idx]->编解码器;
av_opt_set_int(c,“参考帧”,1,0);
if(avcodec_open2(c,codec,NULL)<0){
fprintf(stderr,“无法打开编解码器”\n);
出口(-1);
}
//阅读音频帧
int ret,得到了框架;
而(1){
if((ret=av_read_frame(format_context,&avpkt))<0)
打破
if(avpkt.stream\u index==音频\u流\u idx){
avcodec_获取_帧_默认值(帧);
got_frame=0;
ret=avcodec\U decode\U audio4(c、帧和got\U帧和avpkt);
如果(ret<0){
fprintf(stderr,“音频解码错误”);
继续;
}
如果(得到了框架){
//写入磁盘
fwrite(帧->扩展_数据[0],1,帧->线宽[0],输出文件);
}
}
av_免费_数据包(&avpkt);
}
fclose(输出文件);
printf(“完成的”\n);
如果(c)
avcodec_close(c);
avformat_close_输入(&format_上下文);
av_无帧(&帧);
}

我尝试了
.mp3
.m4a
文件
.mp3
文件工作正常,但不适用于
.m4a
文件。有什么帮助吗?

大多数
aac
文件都是浮点格式,即
AV\u SAMPLE\u FMT\u FLTP
,而像
libao
这样的库只能以整数格式播放音频,即
AV\u SAMPLE\u format\u S16


因此,您需要使用
libavresample
对音乐进行重新采样,并根据需要转换格式。

首先要检查的一件显而易见的事情是:您使用的FFmpeg构建是否包含所需的MPEG-4解析器和AAC解码器。@RomanR。是的,它可以建造。我改进了我的代码,现在它可以正确地输出一个通道;然而,另一个通道仍然是静态噪声。@lynnard。我也遇到了同样的问题,但仍在努力解决。能够播放mp3音频,但不能播放aac。我确实用所有编解码器和解析器重建了ffmpeg,但仍然没有成功。你或任何人找到解决办法了吗?