avformat_write_header() 在将数据写入内存而不是文件时不起作用

avformat_write_header() doesn't work when writing data to memory instead of file

我想将给定的输入格式从内存重新采样到内存,到目前为止一切都很好。

但是当试图从 ffmpeg 获取输出 header 时它不起作用。

我在这里分配上下文并传递 write_buffer 函数指针,这样它就不会写入文件,而是会使用所需数据调用我的函数

unsigned char * aviobuffer = (unsigned char *) av_malloc (32768);
AVIOContext * avio = avio_alloc_context (aviobuffer, 32768,1, NULL, NULL, write_buffer, NULL);

AVFormatContext* containerContext;
avformat_alloc_output_context2(&containerContext, NULL, "s16le", NULL);
containerContext->pb = avio;

这是我的 write_buffer 函数

std::vector<char>* data;
int write_buffer(void *opaque, uint8_t *buf, int buf_size)
{
    std::vector<char> tmp;
    tmp.assign(buf, buf + buf_size);
    data->insert(data->end(), tmp.begin(), tmp.end());
    return buf_size;
}

现在当我调用 avformat_write_header() 时它不会调用我的 write_buffer() 函数 + 它 returns 0 这意味着成功。

int ret = avformat_write_header(containerContext, NULL);

之后我调用适当的函数来获取数据 body 本身,我的 write_buffer() 被正常调用所以我现在只剩下数据 body 没有 header !!

无论如何我怎样才能得到输出header?

好吧,经过大量调试后我发现了 ffmpeg 写入格式 headers 的方式。

长话短说,某些格式与编写其 header 的特殊函数相关联。

ffmpeg 中的 "s16le" 格式与其中之一无关。但令人惊讶的是,正如我在问题中所述,ffmpeg 可以写入其数据 body 但不能写入 header!! 所以我搜索了一种接近我想要的格式并支持编写它的header。我找到了 "wav" 格式,试了一下,效果很好。幸运的是 wav 的默认是 s16le 这正是我想要的。

所以最后我更改了这行代码

avformat_alloc_output_context2(&containerContext, NULL, "s16le", NULL);

avformat_alloc_output_context2(&containerContext, NULL, "wav", NULL);