views:

42

answers:

2

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 PInvokeStackImbalanceExceptions 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, and 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.

A: 

I've steered clear from any of those libraries/projects. All info I found at the time pointed to those breaking too easily with new versions and/or just being too out of date.

What I did is was run the ffmpeg process directly, as I mentioned on this answer, by modifying a sample in a blog post I link there. To this date we've not had trouble with it :)

If the above doesn't work for your scenario, good luck.

eglasius
@eglasius: I modified the question, but I should mention that using the command-line is not an option. 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.
casperOne
I haven't done it, but you might be able to redirect the output to avoid having to go to the disk to grab it
eglasius
@eglasius: I figurd it out, see my answer below. It's more how ffmpeg-sharp handles P/Invoke. I'm able to get stream/codec information from files now in memory.
casperOne
eglasius
+1  A: 

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 AccessViolationExceptions 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 IntPtrs and perform marshaling of the structures as needed, not to include them in the P/Invoke declarations.

casperOne