Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a set of working P/Invoke declarations for FFMpeg, libavutil, libavformat and libavcodec in .NET?

I'm currently looking to access libavutil, libavformat and libavcodec (all part of FFMpeg) from .NET.

Currently, I'm getting the libraries from the automated builds of the shared FFMpeg package performed every night for Windows 32-bit.

I am also using the code from the ffmpeg-sharp project. In that project, I have removed a number of classes that were not compiling (they are wrapper classes not the P/Invoke declarations).

The code compiles fine, but I am running into a few issues.

First, it appears that the build of av*.dll uses the cdecl calling convention, as I was receiving a number of PInvokeStackImbalanceException when trying to call av_open_input_file. This was easy enough to change to get it to work right. The AVFormatContext structure is populated.

After that, I want to call av_find_stream_info to get information about the streams in the file. However, when calling that with the AVFormatContext retrieved from the call to av_open_input_file, an AccessViolationException is thrown indicating that I am trying to read or write from protected memory.

Has anyone used P/Invoke to access the libavutil, libavformat and libavcodec dll libraries through P/Invoke and have gotten it to work?

I should mention that working with the command-line version of FFMpeg, while a solution, is not a viable solution in this case, access needs to occur through the libraries. The reason for this is that I'd have to thrash the disk way too much to do what I need to do (I have to do a frame-by-frame analysis of some very high definition video) and I want to avoid the disk as much as possible.

like image 626
casperOne Avatar asked Sep 24 '10 18:09

casperOne


2 Answers

This is what I figured out - namely, a good amount of the P/Invoke declarations in the ffmpeg-sharp project are incorrect. There are a good number of places where they use structures in the declaration which are marshaled back, but subsequently, have to be passed to deallocation routines later.

Because the pointer has been lost as part of the marshaling, this is what was causing the AccessViolationException to be thrown when trying to pass that stucture to other methods that are accepting a valid pointer (like a handle in Windows). Instead of treating them as opaque (as they should, like Windows APIs do) they marshal the structures back and lose the pointer in the process.

The solution is to change their API declarations to take/return an IntPtr and perform marshaling of the structures as needed, not to include them in the P/Invoke declarations.

like image 120
casperOne Avatar answered Nov 13 '22 11:11

casperOne


See Auto Generated FFmpeg wrapper for C#/.NET and Mono.

like image 39
superware Avatar answered Nov 13 '22 09:11

superware