avformat代码在相同参数下产生的输出与ffmpeg略有不同-为什么?
我希望通过代码实现与此ffmpeg命令行调用完全相同的结果:avformat代码在相同参数下产生的输出与ffmpeg略有不同-为什么?,ffmpeg,libavcodec,libavformat,Ffmpeg,Libavcodec,Libavformat,我希望通过代码实现与此ffmpeg命令行调用完全相同的结果: ffmpeg -i CAMERARTSPLINK -c:v copy -an -movflags +frag_keyframe+empty_moov -f mp4 当我运行上述命令时,它会给出以下二进制结果: got 36 bytes: 0, 0, 0, 36, 102, 116, 121, 112, ..., 111, 54, 109, 112, 52, 49, got 512 bytes: 0, 0, 3, 76, 109,
ffmpeg -i CAMERARTSPLINK -c:v copy -an -movflags +frag_keyframe+empty_moov -f mp4
当我运行上述命令时,它会给出以下二进制结果:
got 36 bytes: 0, 0, 0, 36, 102, 116, 121, 112, ..., 111, 54, 109, 112, 52, 49,
got 512 bytes: 0, 0, 3, 76, 109, 111, 111, 118, 0, 0, 0, ..., 132, 0, 0, 3, 0, 4, 0, 0, 3, 0, 202,
代码可以利用ffmpeg库和include,但我不想将ffmpeg用作程序调用(也就是说,exec*函数不是首选)
我已经为RTSP H264到MP4 remux创建了一个带有avformat
的小型演示代码示例。
代码高度重用horgh的nice库
我在pastebin.com(400 loc)上发布了这篇文章。它成功构建,但您需要将其链接到avformat
、avdevice
、avcodec
和avutil
我尽力达到同样的结果,但是当我运行这段代码时,字节#38后的前几个字节是不同的(可能不仅仅是这些,我没有比较字节#548后的任何内容):
您可以在我的代码输出的第二行中看到,以0
0
0
0
109
<
而ffmpeg给出了0
0
3
76
<109
其余的所有数据(即使字节没有粘贴在这里)都是完全相同的(至少前548个字节是如此)
我的代码有什么问题?这两个字节对于解码此流似乎非常重要。10211612112
在ascii中是ftyp
这是mp4格式类型框0,0,0,36是框的大小
ascii中的109111111118
是mdat
这是数据框0,0,0,0
是框的大小
在这种情况下,mdat
框的大小未知,因为我们还不知道所有视频和音频帧的大小。所以使用了一个零的占位符。当文件完成时,应该用正确的大小覆盖大小值这是ffmpeg有限的日志功能加上我在视频编解码器方面的有限知识的愚蠢错误
问题在于ffmpeg(使用h264输入)在将原子写入输出缓冲区时:
- 首先将原子的大小()
- 然后填充缓冲区的其余部分
- 然后在最后,它在缓冲区中查找回atom的大小,并更新大小()
这一切都很好,但在填充缓冲区的其余部分时,它会使用,如果到达缓冲区的末尾,avio_w8将刷新缓冲区
如果您在avio_alloc_context
中使用自定义IO,并且您没有定义足够大的缓冲区,也没有定义查找操作,并且正在写入的atom大于您的缓冲区大小,那么它将被清除,ffmpeg将无法查找回以更新atom的大小
这可能会导致视频输出文件或流损坏(且无法播放)
因此,解决方案是将缓冲区大小从512增加到4096。在这种情况下,moov原子甚至可以在不进行查找操作的情况下进行拟合
如果您知道moov atom的长度大于512字节,并且查看我的示例代码,那么这是非常简单的。谢谢。有道理。但ffmpeg命令并没有输出到文件,而是直接输出到标准输出。因此,它无法在打印到标准输出后改变盒子的大小。我需要的是:在不知道mdat框的大小之前,avformat不能打印mdat框。在我的自定义io回调中,没有定义seek函数。或者,为了扭转这个问题:ffmpeg如何知道mdat的大小(在打印到stdout时)而我的代码不知道?ffmpeg在写入mdat框之前无法知道mdat框的大小。将mp4写入标准输出是无效的操作。您必须使用碎片化mp4或其他可流化容器,如mkv。
writeOutput: writing 36 bytes: 0, 0, 0, 36, 102, 116, 121, 112, ..., 111, 54, 109, 112, 52, 49,
writeOutput: writing 512 bytes: 0, 0, 0, 0, 109, 111, 111, 118, 0, 0, 0, ..., 132, 0, 0, 3, 0, 4, 0, 0, 3, 0, 202,