MY NOTE 2010/10 N2

///////////////////////////////////

*.DirectShow编程

1.Source Filter

2.Transform Filter 

3.Renderer Filter 

4.Splitter Filter

5.Mux Filter

 


 

/////////////////

pin Categories

 [categories]preview pin and a capture pin

*.  The preview pin is used to render video to the screen, 

*.  while the capture pin is used to write video to a file.

 

preview pin 按需要会掉帧,这是为了持续产生

每个来自于capture pin的帧是时间标识结构,而preview pin没有事件标识(尽量避免掉帧)

 

 

视频端口 总是覆盖上一帧在捕获期间;

如果一个捕获设备调用视频端口(video port),那么捕获过滤器就有一个video port pin代替了preview pin . (PIN_CATEGORY_VIDEOPORT)

 

TV Tuner Filter. Controls tuning for analog TV tuners.

TV Audio Filter. Controls audio settings for analog TV tuners.

Analog Video Crossbar Filter. Routes video and audio signals through the hardware device. For example, a device might have multiple inputs, such as S-Video and composite video. The crossbar filter enables the application to select the input.

 

 

////////////////////////////////////////////////////////

 

 

/////////////////////////////////////////////////////////

*.创建DirectShow Capture Filter给设备,调用IMoniker::BindToObject来获得IBaseFilter指针,然后调用IFilterGraph::AddFilter添加过滤器到过滤图像上

[CODE]

 

IBaseFilter *pCap = NULL;

hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);

if (SUCCEEDED(hr))

{

    hr = m_pGraph->AddFilter(pCap, L"Capture Filter");

}

 

 

 

 

///////////////////////////////////////////////////////////

*.读取设备名的属性

step1:  Call IMoniker::BindToStorage to get a pointer to the IPropertyBag interface.

        IPropertyBag *pPropBag;

        HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));

 

step2:   Call IPropertyBag::Read to read the property.

        VARIANT var;

        VariantInit(&var);

        // Get description or friendly name.

        hr = pPropBag->Read(L"Description", &var, 0);

 

 

 

/////////////////////////////////////////////////////////

*.调用系统设备模拟器steps

step1:  Call CoCreateInstance to create an instance of the System Device Enumerator.

[code]

    // Create the System Device Enumerator.

    ICreateDevEnum *pDevEnum;

    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,  

        CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));

 

step2:  Call ICreateDevEnum::CreateClassEnumerator and specify the device category as a GUID.

[code]

         REFGUID category;

         IEnumMoniker **ppEnum; 

        // Create an enumerator for the category.

        hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0);

 

step3: The CreateClassEnumerator method returns a pointer to the IEnumMoniker interface. To enumerate the monikers, call IEnumMoniker::Next.

 

 

 

 

 

/////////////////////////////////////////////////////////////

OpenFile之步骤1-加载一个新filter graph(就是IGraphBuilder,当然然还有其初始化)

【注】初始化图像

[started here]

[FIRST] 先释放older 图像

m_pEvent->SetNotifyWindow((OAHWND)NULL,NULL,NULL);

SafeRelease(&m_pGraph);

SafeRelease(&m_pControl);

SafeRelease(&m_pEvent);

 

1.创建Filter Graph Manager

IGraphBuilder *m_pGraph;

HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, 

        CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pGraph));

 hr = m_pGraph->QueryInterface(IID_PPV_ARGS(&m_pControl));

 hr = m_pGraph->QueryInterface(IID_PPV_ARGS(&m_pEvent));

 

2.建立事件通知 体制

hr = m_pEvent->SetNotifyWindow((OAHWND)m_hwnd, WM_GRAPH_EVENT, NULL);

 

 

 

////////////////////////////////////////////

OpenFile之步骤2-加载Source Filter到Graph(暨刚刚IGraphBuilder定义了的)

[started here]

IBaseFilter *pSource = NULL;

初始化pSource,其中包含了视频体资源

m_pGraph->AddSourceFilter( 源文件件绝对地址, NULL, &pSource);

 

 

 

 

///////////////////////////////////

OpenFile之步骤3-渲染流

started here:

1.实例化接口 

 IFilterGraph2 pGraph2

 hr = m_pGraph->QueryInterface(IID_IFilterGraph2, (void**)&pGraph2);

2.添加视频渲染器到Graph

 【转】下面小标题 001

 

3.添加DSound Renderer到Graph

 IBaseFilter *pAudioRenderer = NULL;

 hr = AddFilterByCLSID(m_pGraph, CLSID_DSoundRender, 

        &pAudioRenderer, L"Audio Renderer");

 

4.枚举Source Filter上的pins,将pins集合保存在结构【IEnumPins】中

 IEnumPins *pEnum;

   hr = pSource->EnumPins(&pEnum);

5.循环渲染各个pin,注意每渲染一个Pin后马上释放用来保存pin的结构IPin; 

 IPin *pPin;

 HRESULT hr2 = pGraph2->RenderEx(pPin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL);

 pPin->Release();

  -判断是否遍历完pins集合的条件:  S_OK == pEnum->Next(1, &pPin, NULL)

 

 

6.移除未用到的renderer:

 SAFE_RELEASE(pEnum);

 //SAFE_RELEASE(pVMR);

 SAFE_RELEASE(pAudioRenderer);

 SAFE_RELEASE(pGraph2);

 

~~~~~

【小标题 001】

构建渲染类(CEVR,CVMR7,CVMR9)

-----类的成员方法:AddToGraph (貌似是添加渲染器到图像上)

[in]IGraphBuilder *pGraph 传入待加载渲染器的图像

[in]hwnd

1.构建一个EVR渲染器,绑定该渲染器(pEVR)到图像(pGraph)

 IBaseFilter *pEVR = NULL;

 HRESULT hr = AddFilterByCLSID(pGraph, CLSID_EnhancedVideoRenderer, 

        &pEVR, L"EVR"); // 此时先绑定渲染器到图像,即使渲染器目前仍然为空

 

2.初始化刚定义的渲染器(pEVR),

 Step1:  询问(Queries)渲染器为得到IMFGetService 接口

 IMFGetService *pGS = NULL;

 HRESULT hr = pEVR->QueryInterface(IID_PPV_ARGS(&pGS)); 

 

Step2:  调用IMFGetService::GetService 为了得到 一个指向IMFVideoDisplayControl接口指针

 IMFVideoDisplayControl **ppDisplay = NULL;

 hr = pGS->GetService(MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&pDisplay));

 

Step3: 调用IMFVideoDisplayControl::SetVideoWindow 设置视频窗口

 hr = pDisplay->SetVideoWindow(hwnd);

 

Step4:  调用IMFVideoDisplayControl::SetAspectRatioMode来认证视频的比特率

 hr = pDisplay->SetAspectRatioMode(MFVideoARMode_PreservePicture);

 

 

 

 

posted @ 2010-10-15 18:33  hungryMan  阅读(667)  评论(0编辑  收藏  举报