LibAV - 实时音频和视频捕获采用什么方法?

时间:2012-07-26 15:37:28

标签: audio encoding streaming libav

我正在使用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更加冗长?

谢谢!

0 个答案:

没有答案