我尝试了 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
这是 Mediainfo 及其如何识别比特率模式的问题。
如果您使用具有相同参数的 FDK 编码器复用到 MP4 容器,则结果输出将在 Mediainfo 中显示为恒定比特率。