在.NET中是否有一组用于FFMpeg,libavutil,libavformat和libavcodec的工作P / Invoke声明?

时间:2010-09-24 18:53:22

标签: .net ffmpeg libavcodec libavformat

我目前正在寻求从.NET访问libavutil,libavformat和libavcodec(FFMpeg的所有部分)。

目前,我每晚都会为Windows 32位执行libraries from the automated builds of the shared FFMpeg package

我也在使用ffmpeg-sharp project中的代码。在该项目中,我删除了许多未编译的类(它们是包装类而不是P / Invoke声明)。

代码编译得很好,但我遇到了一些问题。

首先,av * .dll的构建似乎使用cdecl calling convention,因为我在尝试呼叫av_open_input_file时收到了一些PInvokeStackImbalanceException。这很容易改变以使其正常工作。填充了AVFormatContext结构。

之后,我想调用av_find_stream_info来获取有关文件中的流的信息。但是,当调用从AVFormatContext调用中检索到的av_open_input_file时,会抛出AccessViolationException,表示我正在尝试从受保护的内存中读取或写入。

是否有人使用P / Invoke通过P / Invoke访问libavutil,libavformat和libavcodec dll库并使其工作?

我应该提到使用FFMpeg的命令行版本,虽然解决方案在这种情况下不是可行的解决方案,但是需要通过库进行访问。这样做的原因是我不得不把磁盘方式过多地做我需要做的事情(我必须对一些非常高清晰度的视频进行逐帧分析)并且我想避免磁盘尽可能多。

4 个答案:

答案 0 :(得分:2)

这就是我想到的 - 即ffmpeg-sharp项目中的大量P / Invoke声明是不正确的。有很多地方他们在声明中使用结构,这些结构被编组回来,但随后必须传递给释放例程。

因为指针在编组过程中已经丢失了,所以当尝试将该结构传递给接受有效指针的其他方法(如Windows中的句柄)时,这会导致AccessViolationException被抛出)。它们不像将它们视为不透明(就像它们应该像Windows API一样),而是将结构编组回来并在过程中丢失指针。

解决方案是更改其API声明以获取/返回IntPtr并根据需要执行结构的编组,而不是将它们包含在P / Invoke声明中。

答案 1 :(得分:1)

答案 2 :(得分:0)

我已从任何这些图书馆/项目中明确指出。我当时发现的所有信息都指出那些新版本太容易破坏和/或过于过时。

我所做的是直接运行ffmpeg进程,就像我在this answer上提到的那样,通过修改我在那里链接的博客文章中的示例。到目前为止,我们没有遇到过麻烦:)

如果以上情况对您的情况不起作用,祝您好运。

答案 3 :(得分:0)

SharpFFmpeg导入c ++库。 C ++代码是一种非托管代码。它需要指向非托管内存的指针。 “Marshal”类提供了一些分配非托管内存的方法。例如:

    IntPtr buffer = Marshal.AllocHGlobal(buf.Length + FFmpeg.FF_INPUT_BUFFER_PADDING_SIZE); //buf is a byte array

此外,如果要向该函数发送托管变量(任何C#变量),则必须将此变量封送(复制)到非托管内存。

    for (int i = 0; i < buf.Length; i++)
        Marshal.StructureToPtr(buf[i], buffer + i, true);

现在你可以发送一个指向函数的指针。

    FFmpeg.avcodec_decode_video(codecContextUnmanaged, frame, ref success, buffer, buf.Length);

您可能需要修改一些非托管结构。为此,您必须将结构复制到托管内存(Marshal.PtrToStructure方法),然后修改它,并再次将其复制到非托管内存。 我被同样的问题折磨得很厉害。我解决了它,但无论如何我无法解码视频))我希望我的解决方案能帮助任何人。