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

在.NET中是否有一组用于FFMpeg、libavutil、libavformat和libavcodec的有效P/Invoke声明?,.net,ffmpeg,libavcodec,libavformat,.net,Ffmpeg,Libavcodec,Libavformat,我目前正在寻找从.NET访问libavutil、libavformat和libavcodec(都是FFMpeg的一部分) 目前,我每天晚上都要在Windows 32位上执行这项任务 我也在使用来自的代码。在该项目中,我删除了许多没有编译的类(它们是包装类而不是P/Invoke声明) 代码编译得很好,但我遇到了一些问题 首先,av*.dll的构建似乎使用了,因为我在尝试调用时收到了大量的PInvokeStackImbalanceException。这很容易改变,让它正常工作。结构已填充 之后,我想

我目前正在寻找从.NET访问libavutil、libavformat和libavcodec(都是FFMpeg的一部分)

目前,我每天晚上都要在Windows 32位上执行这项任务

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

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

首先,av*.dll的构建似乎使用了,因为我在尝试调用时收到了大量的
PInvokeStackImbalanceException
。这很容易改变,让它正常工作。结构已填充

之后,我想打电话获取关于文件中流的信息。但是,当使用从调用
av_open_input_file
中检索到的
AVFormatContext
调用该文件时,将抛出一个提示,指示我正在尝试从受保护内存读取或写入

    for (int i = 0; i < buf.Length; i++)
        Marshal.StructureToPtr(buf[i], buffer + i, true);
是否有人使用p/Invoke通过p/Invoke访问libavutil、libavformat和libavcodec dll库并使其正常工作


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

我已经避开了这些库/项目中的任何一个。我当时发现的所有信息都指向那些太容易与新版本决裂和/或太过时的版本

我所做的是直接运行ffmpeg过程,正如我在前面提到的,通过修改我链接到那里的博客文章中的一个示例。到目前为止,我们还没有遇到任何问题:)


如果上述方法对您的场景不起作用,祝您好运。

这就是我发现的——也就是说,ffmpeg sharp项目中大量的p/Invoke声明是不正确的。在很多地方,它们使用声明中的结构,这些结构被封送回,但随后必须传递给释放例程

由于指针在封送处理过程中丢失,因此当尝试将该结构传递给其他接受有效指针(如Windows中的句柄)的方法时,会引发。它们没有将它们视为不透明的(它们应该像Windows API那样),而是将结构封送回去,并在过程中丢失指针


解决方案是改变API声明以获取/返回AN并根据需要对结构进行封送处理,而不将它们包含在P/Unjk声明中。

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

    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);
您可能需要修改一些非托管结构。为此,您必须将结构复制到托管内存(Marshal.PtrToStructure方法),然后对其进行修改,然后再次将其复制到非托管内存。

同样的问题让我很苦恼。我解决了这个问题,但无论如何我不能解码视频。)我希望我的解决方案能帮助任何人。

请看。

我修改了这个问题,但我应该提到,使用命令行不是一个选项。我必须对磁盘进行太多的反复操作才能完成我需要做的事情(我必须对一些非常高清晰度的视频进行逐帧分析),并且我希望尽可能避免使用磁盘。我没有这样做,但您可能能够重定向输出,以避免必须转到磁盘才能获取它。我想好了,请参阅下面的答案。更重要的是ffmpeg sharp如何处理P/Invoke。我现在可以从内存中的文件中获取流/编解码器信息。@CasperOne很高兴听到您的回答和您的问题+1。我现在正在寻找一个简单的.NET包装器,它应该公开一个全局转换方法并使用ffmpeg。我还需要它在每次进度更改时引发一个事件,这样我就可以异步运行它并以百分比通知用户。关于磁盘抖动问题,我刚刚通过标准输出管道捕获ffmpeg输出(是内容,不是元数据)取得了一些成功。如果这符合您的场景,那么就没有文件,也不会命中磁盘。