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.
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.
See Auto Generated FFmpeg wrapper for C#/.NET and Mono.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With