DirectShow组件开发入门级二

DirectShow组件开发入门级二

该节主要针对DirectShow开发环境的配置问题,当然网上现有这方面的资源比较多,小菜只是稍微坐下整理,以供有需要的人参考学习

一、            设置DirectShow开发的编译环境:

1、资源筹集工作:

描述了如何来编译DirectShow应用。可以使用命令行形式来编译一个工程,也可以在Microsoft Visual Studio集成环境下(包含VC++)实现。
    头文件:
    所有的DirectShow应用都需要Dshow.h这个头文件,某些DirectShow接口需要附加的头文件,参考接口的说明视具体情况定。
    库文件:
    DirectShow使用以下库文件:
    Strmiids.lib 输出类标识(CLSID)和接口标识(IID),所有DirectShow应用均需此库。
    Quartz.lib   输出AMGetErrorText函数,如果不调用此函数,此库不是必需的。
    有了以上这些头文件和库文件,你已经可以编写DirectShow应用了,但是微软建议使用DirectShow基类库来编写filter,这样可以大大减少程序编写的工作量。要使用DirectShow基类库,需要先编译它,由于该基类库是基于VS环境下的,因此应当通过Visual studio工具来进行编译才能生成相应Debug和Release版本的lib库,基类库位于SDK的Samples\Multimedia\DirectShow\BaseClasses文件夹下,包含两个版本的库:发布版(retail version)Strmbase.lib和调试版(debug version)Strmbasd.lib。

在编译生成该库时,会存在这样子的问题,由于工程内的编码风格参照了VC环境下的,因此变量的命名方式或者代码的数据处理风格和VS不一致,因此要进行两个地方的设置才能通过编译:

                打开project->BaseClassesproperties->configuration->C/C++->Language->Force Comformance inFor Loop Scrope设置为No

                打开project->BaseClasses properties->configuration->C/C++->Command Line,增加/wd4430选项

       通过以上两个地方的设置,便可以生成相应版本的lib库文件

2、配置操作环境

         当得到相应的资源后,我们需要对VS进行配置编译环境:

         D:\DIRECTSHOWX9.0\Include

         D:\DIRECTSHOWX9.0\Samples\C++\DirectShow\BaseClasses

如图,再添加库文件的引用。

             D:\directShowX9.0\Samples\C++\DirectShow\BaseClasses\Debug

             D:\directShowX9.0\Lib

             D:\directShowX 9.0\Samples\C++\DirectShow\BaseClasses\Release

 

3、配置环境路径

         建一个DLL工程,在建成后点击项目->属性->连接器->命令行,在附加选项中输入strmbasd.lib

在工程的CPP文件中添加#include <dshow.h>、#include <streams.h>

         一般使用_stdcall函数调用协议,即在VS的菜单中选择Project|Setting|C/C++,在弹出的对话框中的Category中选择Code generation,然后在Calling convention中选择_stdcall;

         使用多线程的C语言运行库时库,在VS下的菜单中选择Project|Setting|C/C++,在弹出的对话框中的Category中选择Code generation,然后在Use run-time library中,Debug版选择Debug Multithreaded,Release版选择Multithreaded;

         然后将配置必要的链接库文件,在VS的菜单中选择Project|Setting|Link,在弹出的对话框中的Category中选择General,然后在Object/library modules 中输入如下代码:

         Debug版本                             Strmbasd.lib, Msvcrtd.lib, Winmm.lib

         Release版本                           Strmbase.lib, Msvcrt.lib, Winmm.lib

并且选中Ignore all default Libraries。

定义一个.def文件用于到处dll函数,假设filter的文件名为TransInplace.ax,.def文件的格式一般如下:

LIBRARY     TransInplace.ax

EXPORTS

            DllMain               PRIVATE

            DllGetClassObject       PRIVATE

            DllCanUnloadNow      PRIVATE

            DllRegisterServer       PRIVATE

            DllUnregisterServer     PRIVATE

同时定义DLL入口函数,代码如下:

//

// DllEntryPoint

extern "C"BOOL WINAPI DllEntryPoint(HINSTANCE,ULONG,LPVOID);

BOOL APIENTRY DllMain(HANDLE hModule,

                       DWORD  ul_reason_for_call,

                       LPVOID lpReserved )

{

    return DllEntryPoint((HINSTANCE)(hModule),ul_reason_for_call,lpReserved);

}

二、            简单对于DirectShow应用下的工程代码显示学习:

配置完以上步骤之后,就可以形成一个DirectShow的开发环境,可以实现一个简单的应用端代码的开发.

   // Convert filename to wide character string

   wcsncpy(wFile,T2W(szFile),NUMELMS(wFile)-1);           //获取要进行播放的媒体文件路径

   wFile[MAX_PATH-1]= 0;

   // Get the interface for DirectShow'sGraphBuilder

   JIF(CoCreateInstance(CLSID_FilterGraph, NULL,CLSCTX_INPROC_SERVER,

                         IID_IGraphBuilder, (void**)&pGB));

     //ZZS:---------------------------------------------------------------------

IBaseFilter   *pIF_video= NULL;

ITransInplace *pITinplaceA = NULL;

     //创建一个GUID为CLSID_TransInplaceFilter的Filter对象,存放于pIF_video中

     JIF(CoCreateInstance(CLSID_TransInplaceFilter,NULL,CLSCTX_INPROC_SERVER,

                            IID_IBaseFilter,reinterpret_cast<void**>(&pIF_video)));

     //查询可以获得相应该Filter的接口

     JIF(pIF_video->QueryInterface(IID_ITransInplace,(void **)&pITinplaceA));

     if (pITinplaceA !=NULL)

     {

         //对该接口进行判空

     }

     JIF(pGB->AddFilter(pIF_video,L"In-place-Video"));      //将该Filter插入到FilterGraph中

   // Get the media event interface beforebuilding the graph

   JIF(pGB->QueryInterface(IID_IMediaEventEx,(void **)&pME));

   // Have the graph builder construct theappropriate graph automatically

   JIF(pGB->RenderFile(wFile,NULL));

/*对该FilterGraph进行枚举,获取到添加到filter链路中的所有Filter,并将其打印出来

     if (pGB != NULL)

     {

         IEnumFilters *pEnum= NULL;

         hr = pGB->EnumFilters(&pEnum);            //获得Filter的枚举器

         if (SUCCEEDED(hr))

         {

              ULONG cFetched;

              char szName[256] ={0};

              IBaseFilter *pFilter= NULL ;

              IEnumPins *ppEnum= NULL;

              while(S_OK == pEnum->Next(1,&pFilter,&cFetched))                          //枚举每一个Filter获取相应的资源

              {

                   FILTER_INFO info= {0};

                   pFilter->QueryFilterInfo(&info);

                   WideCharToMultiByte(CP_ACP,0,info.achName,256,szName,256,0,0);

                   OutputDebugStringA(szName);

                   info.pGraph->Release();

                   pFilter->Release();

              }

              pEnum->Release();

         }

     }

   if( SUCCEEDED(hr ) )

   {

       // QueryInterface for DirectShow interfaces

       JIF(pGB->QueryInterface(IID_IMediaControl,(void **)&pMC));

       JIF(pGB->QueryInterface(IID_IMediaSeeking,(void **)&pMS));

       // Query for video interfaces, which may notbe relevant for audio files

       JIF(pGB->QueryInterface(IID_IVideoWindow,(void **)&pVW));

       JIF(pGB->QueryInterface(IID_IBasicVideo, (void **)&pBV));

       // Query for audio interfaces, which may notbe relevant for video-only files

       JIF(pGB->QueryInterface(IID_IBasicAudio,(void **)&pBA));

       // Have the graph signal event via windowcallbacks for performance

       JIF(pME->SetNotifyWindow((OAHWND)ghApp, WM_GRAPHNOTIFY,0));

       // Is this an audio-only file (no videocomponent)?

       CheckVisibility();

       if (!g_bAudioOnly)

       {

            // Setupthe video window

            JIF(pVW->put_Owner((OAHWND)ghApp));

            JIF(pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS| WS_CLIPCHILDREN));

            JIF(InitVideoWindow(1, 1));

       }

       else

       {

            //Initialize the default player window and enable playback menu items

            // thatdon't involve manipulating video size

            JIF(InitPlayerWindow());

            EnablePlaybackMenu(TRUE, AUDIO);

       }

       // Complete window initialization

       CheckSizeMenu(ID_FILE_SIZE_NORMAL);

       ShowWindow(ghApp,SW_SHOWNORMAL);

       UpdateWindow(ghApp);

       SetForegroundWindow(ghApp);

       UpdateMainTitle();

       g_bFullscreen = FALSE;

       // Run the graph to play the media file

       JIF(pMC->Run());

       g_psCurrent = Running;

       SetFocus(ghApp);

   }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值