bookmark_border[Directshow] Introduction to DirectShow Application Programming

DirectShow 공부를 좀 해야겠다.
이제 하려는 Project가 DirectShow를 기반으로 동작하여 동영상 편집등등을 하는데 기본지식없이 하는건 무리같다.

DirectShow와 응용프로그램의 관계
사용자 삽입 이미지

DirectShow
에서 말하는 소프트웨어 컴포넌트들을Filter라고 부른다.
그 필터의 종류에는 여러가지가 있고 직접 만들수도 있다.

필터의 예 )

  • read files
  • get video from a video capture device
  • decode various stream formats, such as MPEG-1 video
  • pass data to the graphics or sound card

    AVI 파일을 열었을때의 모습이다.
    사용자 삽입 이미지

    File Source Filter는 하드디스크에서 파일을 읽어오고, AVI Splitter Filter는 두개의 Stream(Audio/Video)으로 나눈다. AVI Decompressor Filter는 Video stream을 해독하고 Video Render Filter는 Display해준다. DIrectSound Device는 Audio를 재생시켜준다.

    DirectShow is based on COM; the Filter Graph Manager and the filters are all COM objects. You should have a general understanding of COM client programming before you begin programming DirectShow. Many books about COM programming are available.
    COM프로그램을 먼저 이해하라네.. 또 COM에서 만나는구나…!!!


    출처 :http://msdn2.microsoft.com/en-us/library/ms786509.aspx

  • bookmark_border[DShow] 여러가지 주저리..

    [[[[ 이글은 제가 AVI파일을 DirectShow로 재생하면서 경험한 일을 그냥 두서없이 적은글입니다…. ]]]]

    AVI 를 재생하기위한 Source Filter들..
        1. AsyncReader와 FileSourceFilter + AVISplitter (CLSID_AsyncReader, CLSID_AviSplitter)
            Direct Show의 기본.. 단점은 불완전한 파일에 대해서 재생불가.. 열려있는 파일이 재생이 되었던가..?-_-

        2. AVIFile-based reader Filter (CLSID_AVIDoc)
            아래것의 기본이 되는 필터인듯하다.
            하지만, 임의의 AVI파일의 사운드가 들리지 않는 현상이 발생한다.
            그래프 에디터로 확인시 연결은 잘되어있지만.. 재생시에 에러리턴..
            추측이지만.. VFW를 기본으로 사용하고.. 오디오가 VBR인경우 인식을 못해 사운드 재생이 안되는 듯하다.        

        3. AVI Splliter Filter이용 (CLSID_AviSource) – AviSource 필터는 단순히 AviSplitter를 상속했을 뿐이다.
            위와 거의 동일하다. 
            가장 두드러지는 특징은 불완전한 파일도 처음 Open시 reindexing 과정을 거쳐 재생을 시켜준다.
            하지만 최초 로딩시에만 적용이 된다.. 흑..ㅠ_ㅠ

    AVI Audio Rendering..
        내 프로그램에서만 사운드를 조절하고 싶은데.. 어떤이유에서 인가.. 전체 Wave볼륨이 조절되었다.

        ///    볼륨조절부분 .. ////////////////////////////////////////////////////////////////////
        HRESULT hr;
        CComPtr<IBasicAudio> pVC;
        hr = m_pGraph->QueryInterface(IID_IBasicAudio,  (void **)&pVC);
        if(SUCCEEDED(hr))
        {
            pVC->put_Volume(lVolume);
        }
        ////////////////////////////////////////////////////////////////////////////////////////
        
        이코드면 분명 내 프로그램만 조절 되어야 한다… 근데 왜??
        결론 부터 말하자면 Audio Renderer 문제 였다.
        오디오 렌더러를 만들때 (CLSID_AudioRender – Waveout audio renderer) 를 사용했는데.. 이건 Wave볼륨값을 조절하는가보다.. 
        그래서 CLSID_DSoundRender – DSound audio renderer로 바꿔줬다.. 
        (근데 내가 왜 NULL렌더링을 안했지? NULL 렌더링하니.. 문제가 없네.. 삽질인가..-_-;;;;)

    bookmark_border[Dshow] 연결된 필터 이름 알아오기

    관련 Site에서 간단하게 도움을 받아서 작성한 Function입니다.

    * Wince에서 NullPlayer를 작성하여 OS에서 연결되는 Filter 정보를
    확인하고자 하여 아래 함수를 작성하였습니다.

    코드 :

    HRESULT GetConnectFiltersName( IGraphBuilder *pGraph )
    {
     IEnumFilters *pEnumFilter = NULL;
     HRESULT hr =  pGraph->EnumFilters( &pEnumFilter );
     IBaseFilter *pBaseFilter = NULL;
     FILTER_INFO stFilterInfo;

     while(  S_OK == pEnumFilter->Next( 1, &pBaseFilter, NULL ) )
     {
      pBaseFilter->QueryFilterInfo( &stFilterInfo );
      char sztmp[256];
      ::WideCharToMultiByte(CP_ACP, 0, stFilterInfo.achName, -1, sztmp, 256, NULL, NULL);
      ::printf( "%s\r\n", sztmp );
      pBaseFilter->Release();
     }

     pEnumFilter->Release();
     return S_OK;
    }


    그럼 고운하루 되세요

    bookmark_border[Dshow] DirectShow Filter Build시 발생하는 Link Error 해결방법

    Some of the DirectShow samples break if you install Visual Studio 2005 Beta 2. Most of the errors that I found fall into three categories:
    • C4430: Missing type specifier. To conform with C++, undeclared types do not default to int. All types must be declared. Fix: Declare the type, or suppress the warning with the "/wd4430" flag.
    • C4996: ‘ xxxx’ was declared deprecated. You may be including an older version of strsafe.h from the DirectX SDK or the Platform SDK. You should include the version installed with Visual Studio. (But it’s probably harmless to ignore this warning.) 
    • C2065: ‘xxx’: undeclared identifier. To conform with C++, the scope of a variable declared inside a "for" loop is restricted to the loop. Fixes: (a) Move the declaration outside the for loop. (b) Redeclare the variable in multiple scopes, if you don’t need it to persist outside the loop. (c)Set the /Zc:forScope flag.(You can find this under Project, Properties, Configuration Properties, C/C++, Language, Force Conformance In For Loop Scope. Set to "No".)

    Here are the specific fixes that I made. Warning: I have not thoroughly tested these, and I only tried them under the "Windows XP 32-bit Debug" environment in Platform SDK. You should use your own judgment before making any of these fixes.

    • BaseClasses\ctlutil.h (278)  
         (LONG) operator=(LONG);
    • BaseClasses\wxdebug.cpp (564)
         static DWORD g_dwLastRefresh = 0;
    • BaseClasses\winutil.cpp (2092)
         UINT Count;
         for (Count = 0;Count < Result;Count++) {
    •  BaseClasses\outputq.cpp (635)
         long iDone = 0;
         for (iDone = 0;
    • Capture\AmCap\amcap.cpp (691)
         for(int i = 0; i < NUMELMS(gcap.rgpmAudioMenu); i++)
    • Capture\AmCap\amcap (2795)
         for(int i = 0; i < NUMELMS(gcap.rgpmAudioMenu); i++)
    • DMODemo\dsutil.cpp (686)
          DWORD i = 0;
          for( i=0; i<m_dwNumBuffers; i++ )
    • dmoimpl.h (622)   [In the Platform SDK headers]
          for (DWORD dw = 0; dw < NUMBEROFOUTPUTS; dw++) {
    • DMO\GargleDMO\MedParamBase\param.cpp (91)
          for (DWORD dwIndex = 0; dwIndex < cParams; dwIndex++)
    • DMO\GargleDMO\MedParamBase\param.cpp (309)
          CCurveItem *pCurve = NULL;
          for (pCurve = pCurveHead;
    • DMO\GargleDMO\gargle.cpp (145)
          for (DWORD i = 0; i < cOutputStreams && SUCCEEDED(hr); ++i)
    • Filters\Dump\dump.cpp (426)
          for (int Loop = 0;Loop < (DataLength % BYTES_PER_LINE);Loop++)
    • Filters\Gargle\gargle.cpp (212)
          static int m_nInstanceCount; // total instances
    • Filters\RGBFilters\RateSource\ratesource.cpp (382)
          for( int y = 0 ; y < DEFAULT_HEIGHT ; y++ )
    • Filters\RGBFilters\RateSource\ratesource.cpp (387)
          for( int y = 0 ; y < DEFAULT_WIDTH ; y++ )
    • VMR\VMRXclBasic and VMR\Ticker: LNK1181: cannot open input file ‘dxguid.lib’. This was an error in the makefile. Change to read:
          DXLIB="$(DXSDK_DIR)\Lib\x86"  (currently says "x32")
    • VMR\VMRXcl and VMR\VMRMulti: C1083: Cannot open include file: ‘d3dxmath.h’: No such file or directory. This is an old DX header that is no longer included in DX or in Visual Studio. Unfortunately the only fix is to download an older version of the DirectX SDK.
    • VMR9\MultiVMR9\GamePlayer\character.cpp (383)
          DWORD i = 0;
          for (i = 0; i < pMeshContainer->NumInfl; ++i)
    • VMR9\MultiVMR9\DLL\MixerControl.h (28)
          static const DWORD MultiVMR9Mixer_DefaultFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;
    • VMR9\VMRAllocator: error LNK2019: unresolved external symbol "wchar_t * __stdcall _com_util::ConvertStringToBSTR(char const *)" (etc).  Add this to the makefile:

         comsuppw.lib \