DirectShow Теория Часть 1


    Начиная с этой статьи, я углублюсь в теорию и начну с технологии COM.

    Технология COM.


    COM основана на объектах. С точки зрения прикладного программиста это набор компонент (объектов) наследующих интерфейс IUnknown ( подробнее о нем ниже ). COM не зависит от языка программирования, но работает только на  Windows. COM представляет собой фундамент для таких технологий как OLE и ActiveX.  С точки зрения С++ программиста IUnknown просто интерфейс содержащий всего три чисто виртуальных метода:


struct IUnknown {
virtual ULONG __stdcall AddRef() = 0;
virtual ULONG __stdcall Release() = 0;
   virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv) = 0;
};

    Как я и сказал выше, COM не зависит от языка программирования, поэтому все функции вызываются по соглашению __stdcall для совместимости. Компонент COM как правило реализован в виде DLL, AddRef() и Release() позволяют управлять счетчиком ссылок на компонент, как только количество ссылок достигает нуля, компонент выгружается из памяти.
    AddRef() увеличивает количество ссылок, а Release() соответственно его уменьшает, забыв вызвать Release() и не обнулив счетчик ссылок компонента мы обрекаем его висеть у нас в памяти.
    QueryInterface не так прост. Это метод предназначенный для запроса интерфейсов у компонента. IID – идентификатор интерфейса, ppv – указатель в который следует передать этот интерфейс в том случае, если компонент его поддерживает.
    HRESULT это длинное целое сообщающее о результате выполнения функции. Первый бит указывает на успех \ провал операции, последние 16 битов содержат код возврата, остальные 15 содержат информацию о средстве, вернувшем результат.
    Для определения результата вызова функции нужно использовать специальные макросы, как показано ниже:



//……

IMyInterface* ptr = 0;
HRESULT hr = interface->QueryInterface(IID_IMyInterface,&ptr);

if (SUCCEEDED(hr))
    //использование ptr
else if (FAILED(hr))
    error();

//…….

    Так же можно получить сообщение об ошибке при помощи Windows API:


//…..
void showError(LPCTSTR str, HRESULT hr)
{
void* temp;
FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    0,
    hr,
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    (LPTSTR)&temp,
    0,
    0
    );

    cout << str << endl;
    cout << “Error (” << hex << hr << “): ” << (LPTSTR)temp << endl;
}

    Скопировать интерфейс можно так:


//….

IMyInterface *ptr;
ptr = myIfacePtr;
ptr->AddRef();

//….

    Для освобождения интерфейса нужно вызвать Release():


ptr->Release();

    Как устроен DirectShow.


    DirectShow полностью основан на COM.  По сути дела это набор объектно-ориентированных компонентов COM. Но об этом позже, сейчас давайте разберемся с общими принципами. Первое, что нужно сделать, для того, что бы комфортно программировать DirectShow нужно скачать Microsoft  SDK в состав которого входит приложение Graph Edit. И так, все по порядку.

    Программирование DirectShow основано на графах. Графы строятся из элементов, которыми являются кодеки, декомпрессоры и т.д. У каждого элемента есть каналы, входные и выходные, по которым элементы соединяются между собой. Несколько соединенных между собой элементов образуют граф. Например, давайте посмотрим, как будет выглядеть граф, воспроизводящий AVI видео файл в Graph Edit. Открываем Graph Edit, его окно вы можете видеть на рисунке ниже.

direct show first window

    Идем в меню и делаем следующее: File-&gt;Render Media File или просто нажимаем Ctrl+R. Открывается окно в котором предлагается выбрать файл для воспроизведения, я рекомендую вам так же как и я выбрать видео файл AVI.

direct show second window

    Это граф, который получился у меня. У вас он может выглядеть иначе, это зависит от установленных в системе кодеков. Для того, что бы проиграть файл, делаем следующее: Graph -&gt; Play или просто нажимаем Enter. Вот, что получилось у меня:

direct show third window

    Насмотревшись вдоволь, продолжим разбираться. Только что, мы увидели в принципе суть DirectShow – граф. Т.е. для программного воспроизведения файла мы должны программно, используя интерфейсы DirectShow построить такой же граф. Для начала построим такой же граф в Graph Edit. Что бы не усложнять себе задачу, откройте второй экземпляр программы. И так приступим. Для начала нам нужно добавить фильтр источник. Для этого идем в Graph -&gt; Insert Filters или нажимаем Ctrl + F. Перед вами появится окно как на картинке ниже:

direct show 4th window

    Раскрываем узел Direct Show Filters и выбираем там File Source (Async.). Выбираем файл, которому он будет соответствовать. Далее смотрим в первый экземпляр Grph Edit и во втором воссоздаем граф. Рекомендую все же поковыряться в Graph Edit и воссоздать таки граф. В следующей статье мы перейдем к обсуждению концепций Direct Show. А потом детально обсудим его интерфейсы.




Добавлена: 27-03-2009 | Изменена: 28-03-2009 | Пользователем: gnudimarik | Просмотров: 7412

Комментарии

De_Aztek 10-04-2009 18:55
Спасибо, Дмитрий!

Просто, понятно и самое главное, тема рассказывается с самого начала.
Пиши пожалуйста дальше.
jack 28-03-2010 19:26
YO! Брателло! Спасибо конечно, но где продолжение??


Оставить комментарий



Капча *

Captcha

Комментарий будет опубликован после проверки модератором

Для подсветки синтаксиса исходный код следует обрамлять следующими тэгами
<pre><code class="синтаксис" >код</code></pre>
Подерживаются следующие: cpp php javascript sql html-xml css ini