Декодирование m4a и сброс данных PCM дают шум

Я использую приведенный ниже код (измененный из примеров, приведенных в 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);
}

Я пробовал файлы .mp3 и .m4a; Файлы .mp3 работают нормально, но не файлы .m4a. Любая помощь?


person L__    schedule 20.10.2013    source источник
comment
Очевидная вещь, которую нужно проверить в первую очередь - содержит ли используемая вами сборка FFmpeg необходимый синтаксический анализатор MPEG-4 и декодер AAC.   -  person Roman R.    schedule 20.10.2013
comment
@РоманР. Да, строит. Я улучшил свой код, и теперь он может правильно выводить один канал; однако другой канал по-прежнему представляет собой статический шум.   -  person L__    schedule 21.10.2013
comment
@линнард. У меня такая же проблема, и я все еще борюсь с ней. Может воспроизводить аудио в формате mp3, но не в формате aac. Я пересобрал ffmpeg со всеми кодеками и парсерами, но безуспешно. Нашли ли вы или какой-либо орган какое-либо решение для этого?   -  person Dnyanesh Gate    schedule 06.12.2013


Ответы (1)


Большинство файлов aac имеют формат FLOAT, то есть AV_SAMPLE_FMT_FLTP, в то время как библиотеки, такие как libao, могут воспроизводить звук только в целочисленном формате, то есть AV_SAMPLE_FORMAT_S16.

В результате вам нужно будет использовать libavresample для передискретизации музыки и преобразования формата соответствующим образом.

person L__    schedule 07.12.2013