我正在使用libav将原始RGB24帧编码为h264并将其复用到flv。这有效 一切都很好,我已经流了超过48小时没有任何问题!我的下一步 是为流添加音频。我将捕获现场音频,我想对其进行编码 实时使用speex,mp3或nelly moser。
背景信息
我是数字音频的新手,因此我可能做错了。但基本上我的应用程序获得了一个带有交错音频的“浮动”缓冲区。这个“audioIn”函数由我正在使用的应用程序框架调用。缓冲区每个通道包含256个样本, 我有2个频道。因为我可能会混合术语,这就是我使用的方法 数据:
// input = array with audio samples
// bufferSize = 256
// nChannels = 2
void audioIn(float * input, int bufferSize, int nChannels) {
// convert from float to S16
short* buf = new signed short[bufferSize * 2];
for(int i = 0; i < bufferSize; ++i) { // loop over all samples
int dx = i * 2;
buf[dx + 0] = (float)input[dx + 0] * numeric_limits<short>::max(); // convert frame of the first channel
buf[dx + 1] = (float)input[dx + 1] * numeric_limits<short>::max(); // convert frame of the second channel
}
// add this to the libav wrapper.
av.addAudioFrame((unsigned char*)buf, bufferSize, nChannels);
delete[] buf;
}
现在我有一个缓冲区,每个样本都是16位,我把这个short* buffer
传递给我
包装器av.addAudioFrame()
功能。在这个函数中,我在编码之前创建了一个缓冲区
音频。根据我的阅读,音频编码器的AVCodecContext
设置frame_size
。调用avcodec_encode_audio2()
时,此frame_size必须与缓冲区中的样本数匹配。为什么我认为这是因为documented here。
然后,尤其是这条线:
如果没有设置,frame->nb_samples
必须等于avctx->frame_size
除了最后一个以外的所有帧。*(如果我错了,请在此处更正)。
编码后我调用av_interleaved_write_frame()
来实际写入帧。
当我使用mp3作为编解码器时,我的应用程序运行大约1-2分钟,然后我的服务器(正在接收视频/音频流(flv,tcp))与消息“Frame too large: 14485504
”断开连接。生成此消息是因为rtmp-server正在获取一个大的框架。这可能是因为我没有正确地与libav交错。
问题:
有一些我不确定的内容,即使是通过libav的源代码,因此我希望如果有人有一个编码音频的工作示例来自一个来自“外部”的缓冲区“libav(即您自己的应用程序)。即如何为编码器创建足够大的缓冲区?当您需要等待此缓冲区填满时,如何使“实时”流式传输工作?
正如我上面所写,我需要在编码之前跟踪缓冲区。其他人是否有一些代码可以做到这一点?我现在正在使用AVAudioFifo。编码音频和填充/读取缓冲区的函数也在这里:https://gist.github.com/62f717bbaa69ac7196be
我使用--enable-debug = 3编译并禁用优化,但我没有看到任何优化 调试信息。如何让libav更加冗长?
谢谢!