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

淺唱寂寞╮ 提交于 2019-11-30 13:54:27

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.

eglasius

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.

SharpFFmpeg imports c++ libraries. C++ code is an unmanaged code. It needs pointers to the unmanaged memory. "Marshal" class provides some method to allocate unmanaged memory. For example:

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

Also, if you want to send a managed variable (any C# variable) to the function, you have to marshal (copy) this variable to the unmanaged memory.

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

Now you can send a pointer to the function.

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

It's possible that you'll need to modify some unmanaged structures. To do this you have to copy structure to a managed memory (Marshal.PtrToStructure method), then modify it, and copy it to an unmanaged memory again.
I was tormented by the same problem a lot. I solved it, but I can't decode video anyway)) I hope my solution will help anybody.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!