filter链接connect失败,返回错误代码0x80040217

时间:2021-04-05 10:48:28
播放程序需要用到CoreAVC和CoreAAC这2个解码器
如果选择智能链接的话,播放时会选择其它解码器(如ffdshow),导致程序出错
所以我选择手动链接,指定解码器。
但是在手动链接过程中,发现2个问题,请知道的达人帮帮忙。
我的链路是这样的:
下面这个是用GraphEdit生成的链路图
filter链接connect失败,返回错误代码0x80040217

下面是我程序手动链接生成的链路图
filter链接connect失败,返回错误代码0x80040217

我的问题是:
1. CoreAVC在Debug模式下LoadLibrary(CoreAVC.ax)失败,但是在执行模式下又是成功的(通过打印输出记录),
   请问下这个是什么原因,其它几个Filter都是可以的
2. 就是如上图所示,播放同一个文件,我程序手动链接时,音频链路连不上,返回代码就是0x80040217,
   该代码表示:两个pin连接不上,并且没有可用的中间filter。

请问下这个该怎么解决,也查询了网上不少同样的问题,但是还是不会解决,初学Directshow,时间又紧,还请谅解。
下面我帖下这个相关代码,能帮忙的兄弟们,谢谢了!

9 个解决方案

#1



HRESULT CDXGraph::GetUnconnectedPin(
  IBaseFilter *pFilter,   // Pointer to the filter.
  PIN_DIRECTION PinDir,   // Direction of the pin to find.
  IPin **ppPin)           // Receives a pointer to the pin.
{
    *ppPin = 0;
    IEnumPins *pEnum = 0;
    IPin *pPin = 0;
    HRESULT hr = pFilter->EnumPins(&pEnum);
    if (FAILED(hr))
    {
        return hr;
    }
    while (pEnum->Next(1, &pPin, NULL) == S_OK)
    {
        PIN_DIRECTION ThisPinDir;
        pPin->QueryDirection(&ThisPinDir);
        if (ThisPinDir == PinDir)
        {
            IPin *pTmp = 0;
            hr = pPin->ConnectedTo(&pTmp);
            if (SUCCEEDED(hr))  // Already connected, not the pin we want.
            {
                pTmp->Release();
            }
            else  // Unconnected, this is the pin we want.
            {
                pEnum->Release();
                *ppPin = pPin;
                return S_OK;
            }
        }
        pPin->Release();
    }
    pEnum->Release();
    // Did not find a matching pin.
    return E_FAIL;
}

// Connect filter from the upstream output pin to the downstream input pin
bool CDXGraph::ConnectFilters(IPin * inOutputPin, IPin * inInputPin, 
  const AM_MEDIA_TYPE * inMediaType)
{
if (mGraph && inOutputPin && inInputPin)
{
HRESULT hr = mGraph->ConnectDirect(inOutputPin, inInputPin, inMediaType);
return SUCCEEDED(hr) ? true : false;
}
return false;
}

HRESULT CDXGraph::ConnectFilters(IPin *pOut,            // Output pin on the upstream filter.
 IBaseFilter *pDest)    // Downstream filter.
{
    if ((mGraph == NULL) || (pOut == NULL) || (pDest == NULL))
    {
        return E_POINTER;
    }
#ifdef debug
PIN_DIRECTION PinDir;
pOut->QueryDirection(&PinDir);
_ASSERTE(PinDir == PINDIR_OUTPUT);
#endif

    // Find an input pin on the downstream filter.
    IPin *pIn = 0;
    HRESULT hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);
    if (FAILED(hr))
    {
        return hr;
    }
    // Try to connect them.
    hr = mGraph->Connect(pOut, pIn);
    pIn->Release();
    return hr;
}

//建立mp4音频解码链路
HRESULT CDXGraph::BuildMp4AudioChain(IBaseFilter* pSpliterFilter)
{
USES_CONVERSION;
HRESULT hr=S_OK;
IBaseFilter* pAudioDecFilter=NULL;
//从CoreAAC.ax加载 coreaac音频解码器
CreateInstanceFromDll(mRegistrDll[1].mName, mRegistrDll[1].mClsid, IID_IBaseFilter, (void**)&pAudioDecFilter);
if (pAudioDecFilter==NULL)
{
hr=-1;
//HR_FAIL(hr,L"CreateInstanceFromDll CoreAAC.ax");
return -1;
}
//将音频解码器加入到过滤表中
hr=mGraph->AddFilter(pAudioDecFilter,A2W("CoreAAC Audio Decoder"));
//HR_FAIL(hr,A2W("add AudioDecFilter to graph"));
//接下来获取分离器的音频输出
CComPtr<IPin> pSpAudioOutPin = GetPin(pSpliterFilter,/*L"Audio",*/PINDIR_OUTPUT);
if(pSpAudioOutPin == NULL)
{
pSpAudioOutPin = GetPin(pSpliterFilter,/*L"Sound",*/PINDIR_OUTPUT);
}
if(pSpAudioOutPin == NULL) 
return -1;

//再得到解码器的音频输入
CComPtr<IPin> pAudioDecInPin = GetPin(pAudioDecFilter,/*A2W("In"),*/PINDIR_INPUT);
if(pAudioDecInPin == NULL) 
return -1;

//将分离器分离后的音频流与音频解码器输入端连接
//下面这2种方法都试了,第二种方法不知道是不是我的函数没写对// hr=mGraph->Connect(pSpAudioOutPin,pAudioDecInPin);
hr=ConnectFilters(pSpAudioOutPin,pAudioDecFilter);
//HR_FAIL(hr,L"connect pin pSpAudioOutPin pSpAudioDecInPin");

//如果连接成功,就可以获取音频解码器的输出端了,现在应该可以解码电影中的声音了
CComPtr<IPin> pAudioDecOutPin = GetPin(pAudioDecFilter,/*A2W("Out"),*/PINDIR_OUTPUT);
if(pAudioDecOutPin == NULL) 
return -1;
//最近一步,将音频解码器输出连接至系统声音设备
return ConnectToAudioRender(pAudioDecOutPin); //ConnectToAudioRender在后面实现
}

#2


1. debug模式下连接不上,应该是coreavc filter作了保护,防止调式运行
2. filter连接不上无非就是媒体类型不对,CoreAAC Audio Decoder 还是CoreAAC Video Decoder?

#3


楼上全中。

1。调试模式的限制,它不允许你调试。
2。加Audio decoder,图中显然你是加成了video啊

#4


引用 2 楼 zoulie 的回复:
1. debug模式下连接不上,应该是coreavc filter作了保护,防止调式运行
2. filter连接不上无非就是媒体类型不对,CoreAAC Audio Decoder 还是CoreAAC Video Decoder?


//将音频解码器加入到过滤表中
    hr=mGraph->AddFilter(pAudioDecFilter,A2W("CoreAAC Audio Decoder"));
这个是显示问题,我已经在代码里改过来了,图是之前截取的,所以显示还是不对
请问下 媒体类型不对  在哪里更改啊

#5


引用 3 楼 rageliu 的回复:
楼上全中。

1。调试模式的限制,它不允许你调试。
2。加Audio decoder,图中显然你是加成了video啊


这代码是从别处整过来的
GetPin(pSpliterFilter,/*L"Audio",*/PINDIR_OUTPUT);
这个GetPin函数有3个参数,但是我在SDK例子上的程序没有第二个参数
请问是不是因为这个没有指定类型引起的
请问这个函数该怎么写呢
谢谢  实在时间太紧 又刚开始接触

#6


该回复于2011-04-06 15:52:49被版主删除

#7


继续问~~

#8


音频链路还是没连上
请大虾们帮忙看看

#9


结贴: 详情见: http://topic.csdn.net/u/20110518/15/0590644f-5ceb-4df1-92cf-2dca19a06f1c.html?2096552732

#1



HRESULT CDXGraph::GetUnconnectedPin(
  IBaseFilter *pFilter,   // Pointer to the filter.
  PIN_DIRECTION PinDir,   // Direction of the pin to find.
  IPin **ppPin)           // Receives a pointer to the pin.
{
    *ppPin = 0;
    IEnumPins *pEnum = 0;
    IPin *pPin = 0;
    HRESULT hr = pFilter->EnumPins(&pEnum);
    if (FAILED(hr))
    {
        return hr;
    }
    while (pEnum->Next(1, &pPin, NULL) == S_OK)
    {
        PIN_DIRECTION ThisPinDir;
        pPin->QueryDirection(&ThisPinDir);
        if (ThisPinDir == PinDir)
        {
            IPin *pTmp = 0;
            hr = pPin->ConnectedTo(&pTmp);
            if (SUCCEEDED(hr))  // Already connected, not the pin we want.
            {
                pTmp->Release();
            }
            else  // Unconnected, this is the pin we want.
            {
                pEnum->Release();
                *ppPin = pPin;
                return S_OK;
            }
        }
        pPin->Release();
    }
    pEnum->Release();
    // Did not find a matching pin.
    return E_FAIL;
}

// Connect filter from the upstream output pin to the downstream input pin
bool CDXGraph::ConnectFilters(IPin * inOutputPin, IPin * inInputPin, 
  const AM_MEDIA_TYPE * inMediaType)
{
if (mGraph && inOutputPin && inInputPin)
{
HRESULT hr = mGraph->ConnectDirect(inOutputPin, inInputPin, inMediaType);
return SUCCEEDED(hr) ? true : false;
}
return false;
}

HRESULT CDXGraph::ConnectFilters(IPin *pOut,            // Output pin on the upstream filter.
 IBaseFilter *pDest)    // Downstream filter.
{
    if ((mGraph == NULL) || (pOut == NULL) || (pDest == NULL))
    {
        return E_POINTER;
    }
#ifdef debug
PIN_DIRECTION PinDir;
pOut->QueryDirection(&PinDir);
_ASSERTE(PinDir == PINDIR_OUTPUT);
#endif

    // Find an input pin on the downstream filter.
    IPin *pIn = 0;
    HRESULT hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);
    if (FAILED(hr))
    {
        return hr;
    }
    // Try to connect them.
    hr = mGraph->Connect(pOut, pIn);
    pIn->Release();
    return hr;
}

//建立mp4音频解码链路
HRESULT CDXGraph::BuildMp4AudioChain(IBaseFilter* pSpliterFilter)
{
USES_CONVERSION;
HRESULT hr=S_OK;
IBaseFilter* pAudioDecFilter=NULL;
//从CoreAAC.ax加载 coreaac音频解码器
CreateInstanceFromDll(mRegistrDll[1].mName, mRegistrDll[1].mClsid, IID_IBaseFilter, (void**)&pAudioDecFilter);
if (pAudioDecFilter==NULL)
{
hr=-1;
//HR_FAIL(hr,L"CreateInstanceFromDll CoreAAC.ax");
return -1;
}
//将音频解码器加入到过滤表中
hr=mGraph->AddFilter(pAudioDecFilter,A2W("CoreAAC Audio Decoder"));
//HR_FAIL(hr,A2W("add AudioDecFilter to graph"));
//接下来获取分离器的音频输出
CComPtr<IPin> pSpAudioOutPin = GetPin(pSpliterFilter,/*L"Audio",*/PINDIR_OUTPUT);
if(pSpAudioOutPin == NULL)
{
pSpAudioOutPin = GetPin(pSpliterFilter,/*L"Sound",*/PINDIR_OUTPUT);
}
if(pSpAudioOutPin == NULL) 
return -1;

//再得到解码器的音频输入
CComPtr<IPin> pAudioDecInPin = GetPin(pAudioDecFilter,/*A2W("In"),*/PINDIR_INPUT);
if(pAudioDecInPin == NULL) 
return -1;

//将分离器分离后的音频流与音频解码器输入端连接
//下面这2种方法都试了,第二种方法不知道是不是我的函数没写对// hr=mGraph->Connect(pSpAudioOutPin,pAudioDecInPin);
hr=ConnectFilters(pSpAudioOutPin,pAudioDecFilter);
//HR_FAIL(hr,L"connect pin pSpAudioOutPin pSpAudioDecInPin");

//如果连接成功,就可以获取音频解码器的输出端了,现在应该可以解码电影中的声音了
CComPtr<IPin> pAudioDecOutPin = GetPin(pAudioDecFilter,/*A2W("Out"),*/PINDIR_OUTPUT);
if(pAudioDecOutPin == NULL) 
return -1;
//最近一步,将音频解码器输出连接至系统声音设备
return ConnectToAudioRender(pAudioDecOutPin); //ConnectToAudioRender在后面实现
}

#2


1. debug模式下连接不上,应该是coreavc filter作了保护,防止调式运行
2. filter连接不上无非就是媒体类型不对,CoreAAC Audio Decoder 还是CoreAAC Video Decoder?

#3


楼上全中。

1。调试模式的限制,它不允许你调试。
2。加Audio decoder,图中显然你是加成了video啊

#4


引用 2 楼 zoulie 的回复:
1. debug模式下连接不上,应该是coreavc filter作了保护,防止调式运行
2. filter连接不上无非就是媒体类型不对,CoreAAC Audio Decoder 还是CoreAAC Video Decoder?


//将音频解码器加入到过滤表中
    hr=mGraph->AddFilter(pAudioDecFilter,A2W("CoreAAC Audio Decoder"));
这个是显示问题,我已经在代码里改过来了,图是之前截取的,所以显示还是不对
请问下 媒体类型不对  在哪里更改啊

#5


引用 3 楼 rageliu 的回复:
楼上全中。

1。调试模式的限制,它不允许你调试。
2。加Audio decoder,图中显然你是加成了video啊


这代码是从别处整过来的
GetPin(pSpliterFilter,/*L"Audio",*/PINDIR_OUTPUT);
这个GetPin函数有3个参数,但是我在SDK例子上的程序没有第二个参数
请问是不是因为这个没有指定类型引起的
请问这个函数该怎么写呢
谢谢  实在时间太紧 又刚开始接触

#6


该回复于2011-04-06 15:52:49被版主删除

#7


继续问~~

#8


音频链路还是没连上
请大虾们帮忙看看

#9


结贴: 详情见: http://topic.csdn.net/u/20110518/15/0590644f-5ceb-4df1-92cf-2dca19a06f1c.html?2096552732