Есть ли в .NET набор рабочих объявлений P / Invoke для FFMpeg, libavutil, libavformat и libavcodec? - PullRequest
7 голосов
/ 24 сентября 2010

В настоящее время я ищу доступ к libavutil, libavformat и libavcodec (все части FFMpeg) из .NET.

В настоящее время я получаю библиотеки из автоматизированных сборок общего пакета FFMpeg , выполняемых каждую ночь для 32-битной Windows.

Я также использую код из ffmpeg-sharp проекта . В этом проекте я удалил несколько классов, которые не компилировались (это классы-обертки, а не объявления P / Invoke).

Код компилируется нормально, но я сталкиваюсь с несколькими проблемами.

Во-первых, похоже, что сборка av * .dll использует соглашение о вызовах cdecl , поскольку я получал номер PInvokeStackImbalanceException при попытке вызвать av_open_input_file , Это было достаточно легко изменить, чтобы заставить его работать правильно. Структура AVFormatContext заполнена.

После этого я хочу позвонить av_find_stream_info, чтобы получить информацию о потоках в файле. Однако при вызове этого с AVFormatContext, полученным из вызова на av_open_input_file, выдается AccessViolationException, указывающее, что я пытаюсь читать или писать из защищенной памяти.

Кто-нибудь использовал P / Invoke для доступа к библиотекам dll libavutil, libavformat и libavcodec через P / Invoke и заставил его работать?

Я должен отметить, что работа с версией FFMpeg для командной строки, хотя и не является жизнеспособным решением, в этом случае доступ должен осуществляться через библиотеки. Причина этого в том, что мне придется слишком сильно разбивать диск, чтобы делать то, что мне нужно (я должен делать покадровый анализ некоторых видео очень высокой четкости), и я хочу избежать диска как можно больше.

Ответы [ 4 ]

2 голосов
/ 24 сентября 2010

Это то, что я понял - а именно, большое количество объявлений P / Invoke в проекте ffmpeg-sharp неверно.Есть много мест, где они используют структуры в объявлении, которые возвращаются обратно, но впоследствии должны быть переданы в подпрограммы освобождения позже.

Поскольку указатель был потерян в процессе маршалинга, именно это вызвало выброс AccessViolationException при попытке передать эту структуру другим методам, которые принимают действительныеуказатель (как дескриптор в Windows).Вместо того, чтобы рассматривать их как непрозрачные (как они должны делать, как это делают API-интерфейсы Windows), они возвращают структуры обратно и теряют указатель в процессе.

Решение состоит в том, чтобы изменить свои объявления API для получения / возврата IntPtr и выполнять маршалинг структур по мере необходимости, чтобы не включать их в объявления P / Invoke.

1 голос
/ 11 февраля 2014
0 голосов
/ 30 августа 2011

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);

Теперь вы можете отправить указатель на функцию.

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

Возможно, вам потребуется изменить некоторые неуправляемые структуры.Для этого вам необходимо скопировать структуру в управляемую память (метод Marshal.PtrToStructure), затем изменить ее и снова скопировать в неуправляемую память.
Меня очень мучила та же проблема.Я решил это, но все равно не могу декодировать видео)) Надеюсь, мое решение кому-нибудь поможет.

0 голосов
/ 24 сентября 2010

Я держался подальше от любой из этих библиотек / проектов. Вся информация, которую я нашел в то время, указывала на те, которые ломаются слишком легко с новыми версиями и / или просто устарели.

Что я сделал, так это запустил процесс ffmpeg напрямую, как я упоминал в этом ответе , изменив образец в сообщении в блоге, на которое я ссылаюсь. На сегодняшний день у нас не было проблем с этим:)

Если вышесказанное не работает для вашего сценария, удачи.

...