[ffmpeg]如何使用libfdk_aac将pcm编码为恒定比特率

问题描述 投票:0回答:1

我尝试了 libfdk_aac 和 aac,但编码的 PCM 音频始终具有可变的比特率。为什么会发生这种情况?我怎样才能让它以恒定的比特率进行编码 代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
#include <libavfilter/avfilter.h>
#include <libavfilter/buffersrc.h>
#include <libavfilter/buffersink.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libavutil/imgutils.h>
#include <libavutil/opt.h>
#include <libavutil/channel_layout.h>   
#include <libswresample/swresample.h>
#include <libswscale/swscale.h>
}

int main(int argc, char** argv) {
    AVCodecContext* codec_context = NULL;
    const AVCodec* codec = NULL;
    AVFrame* frame = NULL;
    AVPacket* pkt = NULL;
    FILE* input_file = NULL;
    FILE* output_file = NULL;
    int ret;

    // Open input file
    const char* input_filename = "D:\\audio\\b.pcm";
    const char* output_filename = "D:\\audio\\input.aac";
    input_file = fopen(input_filename, "rb");
    output_file = fopen(output_filename, "wb");
    if (!input_file || !output_file) {
        fprintf(stderr, "Could not open input or output file\n");
        exit(1);
    }

    // Find the AAC encoder
    codec = avcodec_find_encoder_by_name("libfdk_aac");
    if (!codec) {
        fprintf(stderr, "Codec not found\n");
        exit(1);
    }

    codec_context = avcodec_alloc_context3(codec);
    if (!codec_context) {
        fprintf(stderr, "Could not allocate audio codec context\n");
        exit(1);
    }

    // Set codec parameters
    codec_context->sample_fmt = AV_SAMPLE_FMT_S16;
    codec_context->sample_rate = 44100;
    codec_context->bit_rate = 256000;
    codec_context->rc_buffer_size = codec_context->bit_rate; 
    codec_context->rc_min_rate = codec_context->bit_rate;   
    codec_context->rc_max_rate = codec_context->bit_rate;  
    av_channel_layout_default(&codec_context->ch_layout, 2);
    // Open codec
    if (avcodec_open2(codec_context, codec, &opts) < 0) {
        fprintf(stderr, "Could not open codec\n");
        exit(1);
    }

    // Initialize packet
    pkt = av_packet_alloc();
    if (!pkt) {
        fprintf(stderr, "Could not allocate AVPacket\n");
        exit(1);
    }

    // Initialize frame
    frame = av_frame_alloc();
    frame->nb_samples = codec_context->frame_size;
    frame->format = codec_context->sample_fmt;
    frame->ch_layout.nb_channels = 2;

    // Allocate the data buffers
    ret = av_frame_get_buffer(frame, 0);
    if (ret < 0) {
        fprintf(stderr, "Could not allocate audio data buffers\n");
        exit(1);
    }

    // Main loop: read from the input file, encode, write to the output file
    while (fread(frame->data[0], 1, frame->linesize[0], input_file) == frame->linesize[0]) {
        // Send the frame to the encoder
        if (avcodec_send_frame(codec_context, frame) < 0) {
            fprintf(stderr, "Error sending frame to codec\n");
            exit(1);
        }

        // Get the encoded packet
        while (avcodec_receive_packet(codec_context, pkt) == 0) {
            fwrite(pkt->data, 1, pkt->size, output_file);
            av_packet_unref(pkt);
        }
    }

    // Flush the encoder
    avcodec_send_frame(codec_context, NULL);
    while (avcodec_receive_packet(codec_context, pkt) == 0) {
        fwrite(pkt->data, 1, pkt->size, output_file);
        av_packet_unref(pkt);
    }

    // Clean up
    fclose(input_file);
    fclose(output_file);
    av_frame_free(&frame);
    av_packet_free(&pkt);
    avcodec_free_context(&codec_context);

    return 0;
}

我对AAC进行编码,然后使用FFmpeg将其写入MP4文件:./ffmpeg -i input.aac -c copy output.mp4,并使用MediaInfo检查它

PCM文件为S16,2通道,44100 Hz

c++ c audio ffmpeg aac
1个回答
0
投票

这是 Mediainfo 及其如何识别比特率模式的问题。

如果您使用具有相同参数的 FDK 编码器复用到 MP4 容器,则结果输出将在 Mediainfo 中显示为恒定比特率。

© www.soinside.com 2019 - 2024. All rights reserved.