C ++ и DirectShow - PullRequest
       48

C ++ и DirectShow

3 голосов
/ 15 декабря 2010

Я только начинаю программировать на DirectShow, и природа DirectShow API 'C' заставляет меня сканировать скин. Бесконечные коды возврата вместо исключений, повсеместно addref / release, функции, принимающие указатели на указатели ...

Существуют ли «дружественные к C ++» обертки для программирования DirectShow, которые скрывают все безобразие COM под ним .?

Ответы [ 4 ]

5 голосов
/ 16 декабря 2010

Для 98% кода DirectShow вы не должны никогда видеть вызов AddRef или Release.Всегда используйте CComPtr <>.Есть несколько незначительных исключений из этого правила.

Также важно понимать блокировку, как CCritSec и CAutoLock;еще раз, я бы избегал ручной блокировки экземпляров CCritSec, потому что это хороший способ заблокировать приложение.

Кроме того, этот код может быть очень удобен:

#include <dxerr9.h>

...

HRESULT hr = S_OK;

... something goes wrong ...

CString err(::DXGetErrorString9(hr));
err += ::DXGetErrorDescription9(hr);

Наконец, убедитесь, что вы используете событие DShow.Всякая полезная информация приходит по событиям из графика DShow, и удивительно, как много приложений не реализовали это (или неправильно).

Некоторое время назад, Я написал это, который я как бы собрал вместе в ловушку при работе с DShow.К сожалению, я знаю эти подводные камни, потому что я облажался почти всеми этими способами.

4 голосов
/ 15 декабря 2010

CComPtr довольно удобный,

Кроме того, вам просто нужно жить с такими вещами, как HRESULTS. Я предпочитаю их исключениям ... с ними гораздо проще работать ... каждый со своим.

2 голосов
/ 21 декабря 2010

Стоит знать, что DirectShow реализован в quartz.dll, а DirectShow Editing Services - в qedit.dll.

Вы можете использовать эти два с поддержкой Компилятор COM из Visual C ++ длянаписать клиентские приложения DirectShow.

Вот небольшой пример медиафайла воспроизведения (скомпилируйте с cl / D_UNICODE playfile.cpp):

#include <iostream> 

#import <quartz.dll> rename_namespace("dshow") 
#import <qedit.dll> rename_namespace("dshow")

// Required for CLSID_FilterGraph
#include <uuids.h> 
#pragma comment(lib, "strmiids.lib")

int wmain(int argc, wchar_t* argv[]) 
{  
    using namespace dshow;
    using namespace std;

    if (argc != 2)
    {
        wcout << "Usage: play media_file" << endl;
        return 1;
    }

    struct ComInitializer
    {
        ComInitializer() 
        { 
            ::CoInitialize(0);
        }

        ~ComInitializer()
        {
            ::CoUninitialize();
        }
    } comInit;

    try 
    { 
        IGraphBuilderPtr graphBuilder; 
        graphBuilder.CreateInstance(CLSID_FilterGraph); 

        graphBuilder->RenderFile(argv[1], 0);

        IMediaControlPtr mediaControl = graphBuilder;
        mediaControl->Run();

        wcout << "Press Return to stop playback." << endl;
        wcin.get();

        mediaControl->Stop();
    } 
    catch (const _com_error& err)
    {
        wcout << L"Error code: 0x" << hex << err.Error() << endl;
    }
} 

Я использовал этот метод при создании консоли DirectShow oggenc приложение.

0 голосов
/ 15 декабря 2010

Если вы не нашли обертку, вы можете воспользоваться шаблоном кодирования, описанным в моей записи в блоге. "B true или B throw! 1003 *

Пример из этой записи в блоге (это можно легко адаптировать для COM, и фактически я впервые «изобрел» его для использования COM):

std::ostream& operator<<( std::ostream& stream, wchar_t const s[] )
{
    Size const  nBytes      = wcstombs( 0, s, 0 );
    (nBytes >= 0)
        || throwX( "wcstombs failed to deduce buffer size" );

    Size const              bufSize     = nBytes + 1;
    std::vector< char >     buf( bufSize );

    // The count of bytes written does not include terminating nullbyte.
    wcstombs( &buf[0], s, bufSize )
        >> Accept< IsNonNegative >()
        || throwX( "wcstombs failed to convert string" );

    return (stream << &buf[0]);
}

В блоге обсуждается, очевидно, у каждого есть свои предпочтения в отношении подходящих операторов и т. Д., Поэтому я просто добавляю общий принцип здесь.

О, следует добавить, вместо вызовов AddRef и Release, просто использовать смарт-указатель COM. Их так много (например, в ATL / MFC и «встроенных» для Visual C ++), что их просто нужно выбрать. Или создайте свой собственный, например. на основании boost::intrusive_ptr.

Приветствия & hth.,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...