бібліотека AviCap32.dll
- capGetDriverDescriptionA [AviCap32.dll]
- capCreateCaptureWindowA [AviCap32.dll]
Для отримання списку підтримуваних пристроїв і ітерації за доступними драйверампристроїв використовується метод capGetDriverDescriptionA. Функція повертає ім'я і версію драйвера пристрою за вказаною індексу. Далі, вибравши відповідний драйвер пристрою, необхідно створити вікно, в яке буде проводитися захоплення сигналу з пристрою. Так як окремої функції отримання одиничного кадру в AviCap32 не існує, то в якості альтернативи можна з потрібною періодичністю копіювати вміст створеного вікна в об'єкт Bitmap. Для визначення моменту доступності кадру є можливість скористатися функцією зворотного виклику (callback function), для цього необхідно надіслати повідомлення WM_CAP_SET_CALLBACK_FRAME в створене вікно. Після створення вікна виконується ініціалізація підключення до драйверу пристрою. Наступний метод виконує це завдання:
В даному методі Connect можна підкреслити декілька ключових моментів:
По завершенню роботи з пристроєм, необхідно виконати відключення вікна від драйвера, а також знищити вікно, що використовується для захоплення. Для цього в вікно передається повідомлення WM_CAP_DRIVER_DISCONNECT. в якості параметра вказується ідентифікатор драйвера пристрою, відключення від якого запитується за допомогою даного повідомлення. Потім викликається функція DestroyWindow.
фреймворк DirectShow
Останнім кроком ініціалізації є настройка вікна захоплення. У методі SetPreviewVisible це вікно прив'язується до батьківського вікна, на якому і буде відображатися сигнал. При бажанні вікно можна приховати.
Тепер розглянемо метод, в основі якого лежить використання спеціального фільтра, що реалізує інтерфейс ISampleGrabber. Отримання списку пристроїв виконується таким же чином, як і в способі, що використовує вікно захоплення. Для отримання кадру за допомогою фільтра SampleGrabber необхідно побудувати граф, що включає в себе три фільтра:
Метод ConnectFilterToFilter пов'язує контакти виведення одного фільтра з контактами введення іншого. Зв'язуються контакти повинні підтримувати переданий у вигляді параметра тип медіаінформації, ця умова перевіряється за допомогою методу PinHasMediaType. У методі ConnectFilterToFilter виконується ітерація по контактам фільтра-джерела, для контактів виведення виконується метод зв'язування з фільтром-приймачем ConnectPinToFilter. в якому виконується ітерація по всім контактам введення і встановлення зв'язку між контактами. Перейдемо до розгляду ініціалізації підключення до драйверу пристрою. Це виконує наступний метод:
Фреймворк Media Foundation
Media Foundation, так само як і DirectShow, спроектований на основі об'єктної моделі компонентів (COM) - що обумовлює необхідність використання COM Interop при програмуванні на мові C #. І знову, як спрощення ручної праці є можливість скористатися готовою бібліотекою MediaFoundation .Net [5]. Але варто зазначити, що деякі методи і інтерфейси бібліотеки знаходяться в стадії тестування, тому не включені в скомпільований варіант - так що для повноцінної роботи необхідно вручну скомпілювати код бібліотеки, вказавши прапор ALLOW_UNTESTED_INTERFACES.
Перед початком використання Media Foundation необхідно викликати метод MFStartup для ініціалізації фреймворка, а по завершенні роботи - MFShutdown.
По завершенні роботи з MediaFoundation необхідно звільнити все використовуються COM об'єкти за допомогою виклику методу Marshal.ReleaseComObject.
Мал. 1. Результати виміру продуктивності розглянутих методів
В якості критеріїв оцінки продуктивності були обрані два показника: корисне навантаження і середній час доступу до кадру. Значення корисного навантаження, виражене в умовних одиницях, відображає максимальний обсяг обчислень, вироблених над отриманим кадром. З графіка видно, що AviCap32 може забезпечити корисне навантаження в 2 рази менше, ніж інші способи - причиною цього зниження продуктивності під час оновлення кадру на формі з використанням методу Invoke. У той же час показник середнього часу доступу до кадру для AviCap32 порівняємо з часом доступу при використанні DirectShow. Це означає, що прибравши виклики Invoke. можна домогтися ідентичного значення корисного навантаження. У випадку з Media Foundation, навпаки, значення доступу до кадру вище за інших. Це пов'язано з тим, що кадри не кешуються на стороні Media Foundation і при запиті чергового кадру втрачається час на його очікування. Додавши додатковий потік для кешування кадрів, є можливість знизити значення доступу до кадру.