本文介绍了为VMR9手动创建DVD图时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为3D创建视频播放器,并且需要创建自己的渲染器.我在使用渲染器创建图形时遇到问题,因此我退后一步,只是尝试在无窗口模式下使用VMR9渲染器构建图形.如果我在窗口中使用VMR9构建图形 模式下一切正常.当我尝试以无窗口或无渲染模式构建图形时,尝试连接过滤器时得到0x80040217(找不到中间过滤器的组合来建立连接.)

I am creating a video player for 3D and need to create my own renderer. I had a problem creating the graph with my renderer so I stepped back and just tried to build the graph with the VMR9 renderer in Windowless mode. If I build the graph with VMR9 in windowed mode everything works fine. When I try to build the graph in windowless or renderless mode I get 0x80040217 (No combination of intermediate filters could be found to make the connection.) when I try to connect up the filters.

任何人都可以对此有所了解吗?

Can anyone shed some light on this?

 

源代码为:


    //手动构建图
    //创建图构建器
    hr = m_pGraph.CoCreateInstance(CLSID_FilterGraph,   NULL,    CLSCTX_INPROC_SERVER);
   如果(FAILED(hr)){
        err.NotifyError(L"IID_IGraphBuilder的CoCreateInstance失败",hr);
    }

    //创建DVD导航器并将其添加到图
    hr = m_pDVDNav.CoCreateInstance(CLSID_DVDNavigator,   NULL,    CLSCTX_INPROC_SERVER);
   如果(FAILED(hr)){
        err.NotifyError(L"CLSID_DVDNavigator的CoCreateInstance()失败",hr);
       返回hr;
    }
    hr = m_pGraph-> AddFilter(m_pDVDNav,L"DVD Navigator");
   如果(FAILED(hr)){
        err.NotifyError(L"DVD Navigator的AddFilter()失败",hr);
       返回hr;
    }
 
    //创建和配置视频渲染器
    hr = m_pVideoRenderer.CoCreateInstance(CLSID_VideoMixingRenderer9,NULL,CLSCTX_INPROC_SERVER);
    if(FAILED(hr)){
        //VMR9无法成功实例化
        err.NotifyError(L"CLSID_VideoMisingRenderer9的CoCreateInstance()失败",hr);
       返回hr;
    }

    hr = m_pGraph-> AddFilter(m_pVideoRenderer,L视频混合渲染器");
    if(FAILED(hr)){
        err.NotifyError(L"Video Mixing Renderer的AddFilter()失败",hr);
       返回hr;
    }

    //在VMR-9过滤器上为IVMRFilterConfig9接口调用QueryInterface.
    hr = m_pVideoRenderer-> QueryInterface(& m_pVMRConfig9);
   如果(FAILED(hr)){
        err.NotifyError(L"IVMRFilterConfig9的QueryInterface()失败",hr);
       返回hr;
    }

    //将VMR9模式设置为无窗口".
    hr = m_pVMRConfig9-> SetRenderingMode(VMR9Mode_Windowless);
    if(FAILED(hr)){
        err.NotifyError(L"VMR9Mode_Windowless的SetRenderingMode()失败",hr);
       返回hr;
    }

    hr = m_pVMRConfig9-> SetNumberOfStreams(2);
    if(FAILED(hr)){
        err.NotifyError(L"1IVMRFilterConfig9的SetNumberOfStreams()失败",hr);
       返回hr;
    }

    hr = m_pVideoRenderer-> QueryInterface(IID_IVMRWindowlessControl9,(LPVOID *)& m_pIWindowlessControl);
    if(FAILED(hr)){
        err.NotifyError(L"VMRWindowlessControl9的QueryInterface()失败",hr);
       返回hr;
    }

    //*在构建图形之前*查询IMediaEventEx,以便
    //我们捕获了所有初始化事件.
    hr = m_pGraph-> QueryInterface(IID_IMediaEventEx,reinterpret_cast< void **>(& m_pIME));
    if(FAILED(hr)){
        err.NotifyError(L"IID_IMediaEvents的QueryInterface失败",hr);
           返回hr;
    }

    //设置事件通知.
    hr = m_pIME-> SetNotifyWindow((OAHWND)m_hwndVideo,WM_DVD_EVENT,NULL);
   如果(FAILED(hr)){
        err.NotifyError(L"EM_DVD_EVENT的SetNotifyWindow()失败",hr);
       返回hr;
    }

    int i;
    IPin * outPin;

    //自动制作DVD图形
    //Render()在DVD导航器的所有输出引脚上.这应该会自动添加DVD解码器和
    //将视频从DVD导航器连接到DVD解码器上的视频输入.然后
    //将DVD解码器的视频输出连接到VMR9输入1.我们仍然需要制作Sub Picture
    //连接,但我们在下面手动进行操作.
    for(i = 0; i< 3; i ++){
        hr = GetPin(m_pDVDNav,PINDIR_OUTPUT,& outPin,i);
        if(hr!= S_OK){
            err.NotifyError(L"outPin上的GetPin失败",hr);
           返回E_FAIL;
        }
        hr = m_pGraph-> Render(outPin);
        if(hr!= S_OK){
            err.NotifyError(L在GraphBuilder上调用渲染失败",hr);
           返回hr;
        }
    }

    //至此,我们有了DVD导航器,DVD解码器和VMR9.我们需要连接
    //从DVD解码器输出的子图片到VMR9过滤器上的第二个视频输入.
    //现在将DVD解码器连接到VMR9 Renderer
    //引脚名称如下:
    //        DVD解码器子图片输入:    子图片输入
    //        DVD解码器子图片输出:     〜子图片输出
    //        VMR9视频2输入:                             VMR输入1
    //        VMR9视频1输入:                             VMR输入0
    //获取DVD解码器
    hr = GetNextFilter(m_pDVDNav,DOWNSTREAM,& m_pDVDDecoder);
    if(FAILED(hr)){
        err.NotifyError(TEXT("GetNextFilter"),hr,TEXT(无法从DVD Navigator获取下游过滤器"));
       返回hr;
    }
    //从DVD解码器获取Sub Picture输出.
    IPin * pDecSubPicOut;
    hr = FindPinByName(m_pDVDDecoder,L〜Subpicture Output",& pDecSubPicOut);
    if(FAILED(hr)){
        err.NotifyError(TEXT("FindPinByName"),hr,TEXT(无法从DVDDecoder获取子图片输出"));
       返回hr;
    }

    //获取输入到VMR9渲染器的2号视频.
    IPin * pRendSubPicIn;
    hr = FindPinByName(m_pVideoRenderer,L"VMR Input1",& pRendSubPicIn);
    if(FAILED(hr)){
        err.NotifyError(TEXT("FindPinByName"),hr,TEXT(无法在VMR9上获得VMR Input1"));
       返回hr;
    }

    //将DVD Decoder Sub Picture输出连接到VMR9视频输入2
    hr = m_pGraph-> Connect(pDecSubPicOut,pRendSubPicIn);
    if(FAILED(hr)){
        err.NotifyError(TEXT("Connect(pDecSubPicOut,pRendSubPicIn)")),hr,TEXT(无法将DVDDecoder子图片输出连接到VMR9"));
       返回hr;
    }


    // Build the graph manually
    // Create graph builder
    hr = m_pGraph.CoCreateInstance(CLSID_FilterGraph,    NULL,    CLSCTX_INPROC_SERVER);
    if (FAILED(hr)) {
        err.NotifyError(L"CoCreateInstance ofr IID_IGraphBuilder failed", hr);
    }

    // Create the DVD Navigator and add it to the Graph
    hr = m_pDVDNav.CoCreateInstance(CLSID_DVDNavigator,    NULL,    CLSCTX_INPROC_SERVER);
    if (FAILED(hr)) {
        err.NotifyError(L"CoCreateInstance() for CLSID_DVDNavigator failed", hr);
        return hr;
    }
    hr = m_pGraph->AddFilter(m_pDVDNav, L"DVD Navigator");
    if (FAILED(hr)) {
        err.NotifyError(L"AddFilter() for DVD Navigator failed", hr);
        return hr;
    }
 
    // Create and configure video renderer
    hr = m_pVideoRenderer.CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER);
    if(FAILED(hr)) {
        // VMR9 not successfully instantiated
        err.NotifyError(L"CoCreateInstance() for CLSID_VideoMisingRenderer9 failed", hr);
        return hr;
    }

    hr = m_pGraph->AddFilter(m_pVideoRenderer, L"Video Mixing Renderer");
    if(FAILED(hr)) {
        err.NotifyError(L"AddFilter() for Video Mixing Renderer failed", hr);
        return hr;
    }

    // Call QueryInterface on the VMR-9 filter for the IVMRFilterConfig9 interface.
    hr = m_pVideoRenderer->QueryInterface(&m_pVMRConfig9);
    if (FAILED(hr)) {
        err.NotifyError(L"QueryInterface() for IVMRFilterConfig9 failed", hr);
        return hr;
    }

    // Set the VMR9 mode to Windowless.
    hr = m_pVMRConfig9->SetRenderingMode(VMR9Mode_Windowless);
    if(FAILED(hr)) {
        err.NotifyError(L"SetRenderingMode() for VMR9Mode_Windowless failed", hr);
        return hr;
    }

    hr = m_pVMRConfig9->SetNumberOfStreams(2);
    if(FAILED(hr)) {
        err.NotifyError(L"SetNumberOfStreams() for 1IVMRFilterConfig9 failed", hr);
        return hr;
    }

    hr = m_pVideoRenderer->QueryInterface(IID_IVMRWindowlessControl9, (LPVOID *)&m_pIWindowlessControl);
    if(FAILED(hr)) {
        err.NotifyError(L"QueryInterface() for VMRWindowlessControl9 failed", hr);
        return hr;
    }

    // Query for IMediaEventEx *before* building the graph so that
    // we catch all of the initialization events.
    hr = m_pGraph->QueryInterface(IID_IMediaEventEx, reinterpret_cast<void**>(&m_pIME));
    if(FAILED(hr)) {
        err.NotifyError(L"QueryInterface for IID_IMediaEvents failed", hr);
            return hr ;
    }

    // Set up event notification.
    hr = m_pIME->SetNotifyWindow((OAHWND)m_hwndVideo, WM_DVD_EVENT, NULL);
    if (FAILED(hr)) {
        err.NotifyError(L"SetNotifyWindow() for EM_DVD_EVENT failed", hr);
        return hr;
    }

    int i;
    IPin * outPin;

    // AUTO BUILD THE DVD GRAPH
    // Render() on the all of the output pins of the DVD Navigator. This should automatically add the DVD Decoder and
    // connects the video out from the DVD Navigator to the video input on the DVD Decoder. It then
    // connects the video output from the DVD Decoder to VMR9 input 1. We still need to make the Sub Picture
    // connections but we do that manually below.
    for(i = 0; i < 3; i++) {
        hr = GetPin(m_pDVDNav, PINDIR_OUTPUT, &outPin, i);
        if(hr != S_OK) {
            err.NotifyError(L"GetPin on outPin failed", hr);
            return E_FAIL;
        }
        hr = m_pGraph->Render(outPin);
        if(hr != S_OK) {
            err.NotifyError(L"Call to Render on GraphBuilder failed", hr);
            return hr;
        }
    }

    // At this point we have the DVD Navigator, DVD Decoder and VMR9. We need to connect the
    // subpicture output from the DVD Decoder to the 2nd video input on the VMR9 filter.
    // Now connect the DVD Decoder to the VMR9 Renderer
    // The pin names are as follows:
    //        DVD Decoder Sub Picture Input:        SubpictureInput
    //        DVD Decoder Sub Picture Output:        ~SubpictureOutput
    //        VMR9 Video 2 Input:                                VMR Input1
    //        VMR9 Video 1 Input:                                VMR Input0
    // Get the DVD Decoder
    hr = GetNextFilter(m_pDVDNav, DOWNSTREAM, &m_pDVDDecoder);
    if(FAILED(hr)) {
        err.NotifyError(TEXT("GetNextFilter"), hr, TEXT("Could not get downstream filter from DVD Navigator"));
        return hr;
    }
    // Get the Sub Picture output from the DVD Decoder.
    IPin * pDecSubPicOut;
    hr = FindPinByName(m_pDVDDecoder, L"~Subpicture Output", &pDecSubPicOut);
    if(FAILED(hr)) {
        err.NotifyError(TEXT("FindPinByName"), hr, TEXT("Could not get Subpicture Output from DVDDecoder"));
        return hr;
    }

    // Get the number 2 video input to the VMR9 Renderer.
    IPin * pRendSubPicIn;
    hr = FindPinByName(m_pVideoRenderer, L"VMR Input1", &pRendSubPicIn);
    if(FAILED(hr)) {
        err.NotifyError(TEXT("FindPinByName"), hr, TEXT("Could not get VMR Input1 on VMR9"));
        return hr;
    }

    // Connect the DVD Decoder Sub Picture output to VMR9 video input 2
    hr = m_pGraph->Connect(pDecSubPicOut, pRendSubPicIn);
    if(FAILED(hr)) {
        err.NotifyError(TEXT("Connect(pDecSubPicOut, pRendSubPicIn)"), hr, TEXT("Could not connect DVDDecoder sub picture output to VMR9"));
        return hr;
    }

推荐答案

出于测试目的,我的建议不是使用智能连接,而是手动添加和连接过滤器.  使用GraphEdit识别所需的过滤器.

For testing purposes, my suggestion is not to use intelligent connect but rather to manually add and connect the filters.   Use GraphEdit to identify the filters that you need. 

在将所有过滤器添加到图形之前,将它们连接之前,我遇到了类似的问题.  就我而言,关键是在将过滤器添加到图表后立即连接过滤器.

I encountered a similar problem when adding all filters to the graph BEFORE connecting them.   In my case, the key was to connect a filter after immediatley after it was added to the graph. 

祝你好运

伊恩

 


这篇关于为VMR9手动创建DVD图时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-04 22:54