【问题标题】:avcodec_encode_video2 crash on MinGW32 (but not on MinGW64)avcodec_encode_video2 在 MinGW32 上崩溃(但不在 MinGW64 上)
【发布时间】:2018-08-04 02:02:17
【问题描述】:

多年来,我一直在测试我正在开发的软件,该软件仅通过 Qt-MinGW64 为 64 位系统编译,没有遇到任何关于视频编码的问题(这是此类应用程序的功能之一)。最近一直在尝试用Qt-MingGW32编译来构建我的软件对应的x86版本。

但是,在构建相同的 ffmpeg 和 x264 库版本以创建 32 位版本并成功将它们链接到我的项目后,由于分段错误错误,在编码几帧后应用程序不断崩溃。这很奇怪,因为正如我之前指出的,它在为 64 位系统编译时可以完美运行。

我也浪费了相当多的时间来尝试结合大量不同版本的 ffmpeg 和 x264 库,但也没有运气。在为 x264 和 ffmpeg 库禁用线程时,它都不起作用,因此它似乎不是 win32 线程问题。因此,我得出的结论是,错误最有可能出现在我的代码中,这超出了我的理解范围,它告诉 ffmpeg 在 x64 版本中分配正确的内存量,但在 x86 版本中没有。

还必须指出的是,在调用avcodec_encode_video2 之前,我会执行以下调用等,以便分配与相应项目(AVFrame、AVCodec 等)关联的内存,例如

avcodec_open2( my_codec_context, my_codec, &opt );
my_av_frame=av_frame_alloc();

更准确地说,我正在使用的代码结构的详细信息可以在here找到。

因此,该错误似乎比有关未初始化内存的问题更微妙。

非常感谢。

更新:

我发现了问题的重点。出于某种原因,FFmpeg/x264 库在使用 Qt-MinGW32 编译的 Win32 GUI 应用程序中表现异常,而它们在同样使用 Qt-WinGW32 编译的 Win32 控制台应用程序中运行正常。我已经证明了这个声明执行了两个虚拟测试,其中完全相同的一段代码通过控制台应用程序和 GUI 应用程序运行,在第一种情况下成功,在后一种情况下失败。可以在下面找到此类测试的代码,以及我的项目中使用的 x264 和 FFmpeg 库,以及使用 MinGW32 在 msys2 中构建它们的说明:

https://takeafile.com/?f=hisusinivi

我不知道它是否可以通过简单地调整代码来解决,或者它是一个涉及不兼容问题的严重错误。如果是后者,是否应该将其作为重大bug报告给Qt/FFmpeg/x264工作人员?

【问题讨论】:

  • 一点也不奇怪 - 我希望几乎所有在编译为 64 位时编译、链接和工作的软件在切换到 32 位时都会失败。
  • 我做过很多 32 位和 64 位的交叉编译。 (和 16 位交叉编译,早在什么时候。)关于指针或数据类型大小的假设通常会导致问题。制作高度可移植的代码很困难——因为它需要大量的勤奋和纪律。如果代码在 GitHub 或其他任何地方,我可以看一下。
  • 另外,我的一个朋友将 AT&T Unix 移植到 64 位 Cray 计算机上。他在 Unix 代码中遇到了各种有趣的假设,他必须理顺这些假设。美好时光。
  • 感谢您的所有 cmets。至于代码,我只通过SVN使用本地控制版本。整个应用程序的代码太长了,但是如果你愿意,并且为了可读性,我可以将编码例程提取并上传到一个单独的项目中,这样你就可以分析产生问题的具体部分,无需无需处理其余代码,也不必编译代码其他部分中使用的更多第三方库依赖项。
  • 好吧,碰巧在我为您分离出失败的代码片段,生成虚拟帧并对其进行编码后,它并没有崩溃。进一步调查,我发现错误正在产生,因为正是我顽固地试图用 32 位版本编码其视频的项目使用了非常接近 2 GB 的 RAM,这似乎是程序的限制可以在 32 位操作系统中使用。因此,似乎在编码过程的中间它以某种方式达到了这样的 2 GB 限制,从而导致了崩溃。再次感谢您鼓舞人心的建议。

标签: c++ qt ffmpeg mingw x264


【解决方案1】:

看起来您正在耗尽内存(32 位应用程序可用的虚拟地址空间),至少您的 QT GUI 测试应用程序会发生这种情况。您对 YUV 4:4:4 FullHD 视频进行编码的设置需要大约 1.3 GB 的内存,并且默认情况下这应该可用于 64 位操作系统的 32 位应用程序(并且它用于您的控制台测试)。但由于某种原因,您的 QT GUI 测试在仅分配 1 GB 内存后开始失败。我不知道这个 1 GB 限制是由 QT 还是 Windows 用于任何 GUI 应用程序。如果您将视频分辨率设为 960x540 而不是 1920x1080,那么它应该可以工作(因为它需要少于 1 GB 的内存)。否则,您应该通过将-Wl,--large-address-aware 指定给链接器,在 PE 标头中设置 LARGE_ADDRESS_AWARE 标志,并且 64 位操作系统上的 32 位应用程序应该可以使用超过 4 GB 的内存。

更新

看起来 QT GUI-test 的内存比控制台测试少,因为它还链接到 Qt5Guid.dll 和 Qt5Widgetsd.dll,除了在控制台应用程序中链接的其他库之外,它还需要额外的 450 MB 地址空间,因此只有 1 个从 2 GB 可用的 GB 可用地址空间保留在内存堆中。

【讨论】:

  • 感谢您的回复。我还怀疑这是涉及 32 位应用程序的 2 GB 限制的问题,但是您已经确切指定了是什么使 GUI 版本占用更多的 RAM,所以我已将您的答案标记为已接受的答案。我想我应该在我的应用程序的 32 位版本的单独命令行进程中调用编码器。
猜你喜欢
  • 2013-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多