大神们,一开始使用getcurrentimage用来抓图,结果抓图太慢而且有闪烁现象,考虑在链路中加入一个Sample grabber filter来抓图,这是我自己拉的一个图,
但是结果话,我使用网络数据包接收,却显示如下的图除非我在addfilterbyID之前加入了获取媒体类型就会显示如下的图片但是如果我在connect之前加入的话,就会在运行的时候报错,内存读取错误。这是我的代码建立graph过程,
bool CFilterGraph::BuildGraph(void)
{
m_bInit = false; //初始化COM 组件
HRESULT hr = CoInitialize(NULL);
if(FAILED(hr))
{
::MessageBox(NULL,_T("CoInitialize error"),NULL,MB_OK);
return m_bInit;
}
//Create filter graph
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void**)&m_pGraph);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **) &m_pCapture);
if (SUCCEEDED(hr))
{
m_pCapture->SetFiltergraph (m_pGraph);
m_bInit = true;
}
}
#ifdef _DEBUG
hr = AddToRot(m_pGraph, &dwRegister);//在用GraphEdit显示应用程序中构建的Filter Graph之前,应用程序必须把它创建的Filter Graph进行注册,可以在应用程序成功创建了一个Filter Graph之后调用AddToRot进行注册
#endif
if (m_bInit)
{
// Media control interface
hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl);
if (FAILED(hr))
{
m_bInit = false;
}
} if (m_bInit)
{
// Media event interface
hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **)&m_pMediaEvent);
if (FAILED(hr))
{
m_bInit = false;
}
}
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&m_pInterface); if (m_bInit)
{
// Media video window interface
hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&m_pVideoWindow);
if (FAILED(hr))
{
m_bInit = false;
}
} //add filters
hr = AddFilterByCLSID(PushSource264, L"source", &m_pSource);
if (FAILED(hr))
{
::MessageBox(NULL,_T("PushSource264 error"),NULL,MB_OK);
m_bInit = false;
}
hr = AddFilterByCLSID(ffdshow_video_decoder, L"decoder", &m_pDecoder);
if (FAILED(hr))
{
m_bInit = false;
}
hr = AddFilterByCLSID(video_renderer, L"video", &m_pVideo);
if (FAILED(hr))
{
m_bInit = false;
}
hr = AddFilterByCLSID(samplegrabber, L"grapper", &m_psample);
if (FAILED(hr))
{
m_bInit = false;
}
/*hr = AddSoundDeviceByCLSID(default_directsound_device,L"audiorender",&m_pAudio);
if (FAILED(hr))
{
m_bInit = false;
}*/
hr = FindFilterInterface(m_pGraph,IID_IPushSource,(void**)&m_pPushSource);
if (FAILED(hr))
{
::MessageBox(NULL,_T("IID_IPushSource error"),NULL,MB_OK);
m_bInit = false;
}
if(m_pPushSource != NULL)
{
m_pPushSource->SetDecoder(m_resolution,m_framerate);
}
IVMRFilterConfig *pFilterConfig;
hr=m_pVideo->QueryInterface(IID_IVMRFilterConfig,(void **)&pFilterConfig);
hr=pFilterConfig->SetNumberOfStreams(2);
if(pFilterConfig != NULL)
{
pFilterConfig->Release();
pFilterConfig = NULL;
}
//connect filters
/*hr = ConnectAudioFilters(m_pSource, m_pAudio);
if (FAILED(hr))
{
::MessageBox(NULL,_T("ConnectAudioFilters error"),NULL,MB_OK);
m_bInit = false;
}*/ hr = ConnectVideoFilters(m_pSource,m_pDecoder);
if (FAILED(hr))
{
::MessageBox(NULL,_T("ConnectVideoFilters error"),NULL,MB_OK);
m_bInit = false;
}
hr = ConnectFilters(m_pDecoder,m_psample);
if (FAILED(hr))
{
::MessageBox(NULL,_T("ConnectFilters error"),NULL,MB_OK);
m_bInit = false;
}
hr = ConnectFilters(m_psample, m_pVideo);
if (FAILED(hr))
{
::MessageBox(NULL,_T("ConnectFilters error"),NULL,MB_OK);
m_bInit = false;
}
return m_bInit;求大神指教,其中的connect函数就是枚举找到为连接的pin然后把输入输出connect就可以了,求大神指导
FilterIsamplegrabber,抓图,
但是结果话,我使用网络数据包接收,却显示如下的图除非我在addfilterbyID之前加入了获取媒体类型就会显示如下的图片但是如果我在connect之前加入的话,就会在运行的时候报错,内存读取错误。这是我的代码建立graph过程,
bool CFilterGraph::BuildGraph(void)
{
m_bInit = false; //初始化COM 组件
HRESULT hr = CoInitialize(NULL);
if(FAILED(hr))
{
::MessageBox(NULL,_T("CoInitialize error"),NULL,MB_OK);
return m_bInit;
}
//Create filter graph
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void**)&m_pGraph);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **) &m_pCapture);
if (SUCCEEDED(hr))
{
m_pCapture->SetFiltergraph (m_pGraph);
m_bInit = true;
}
}
#ifdef _DEBUG
hr = AddToRot(m_pGraph, &dwRegister);//在用GraphEdit显示应用程序中构建的Filter Graph之前,应用程序必须把它创建的Filter Graph进行注册,可以在应用程序成功创建了一个Filter Graph之后调用AddToRot进行注册
#endif
if (m_bInit)
{
// Media control interface
hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl);
if (FAILED(hr))
{
m_bInit = false;
}
} if (m_bInit)
{
// Media event interface
hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **)&m_pMediaEvent);
if (FAILED(hr))
{
m_bInit = false;
}
}
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&m_pInterface); if (m_bInit)
{
// Media video window interface
hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&m_pVideoWindow);
if (FAILED(hr))
{
m_bInit = false;
}
} //add filters
hr = AddFilterByCLSID(PushSource264, L"source", &m_pSource);
if (FAILED(hr))
{
::MessageBox(NULL,_T("PushSource264 error"),NULL,MB_OK);
m_bInit = false;
}
hr = AddFilterByCLSID(ffdshow_video_decoder, L"decoder", &m_pDecoder);
if (FAILED(hr))
{
m_bInit = false;
}
hr = AddFilterByCLSID(video_renderer, L"video", &m_pVideo);
if (FAILED(hr))
{
m_bInit = false;
}
hr = AddFilterByCLSID(samplegrabber, L"grapper", &m_psample);
if (FAILED(hr))
{
m_bInit = false;
}
/*hr = AddSoundDeviceByCLSID(default_directsound_device,L"audiorender",&m_pAudio);
if (FAILED(hr))
{
m_bInit = false;
}*/
hr = FindFilterInterface(m_pGraph,IID_IPushSource,(void**)&m_pPushSource);
if (FAILED(hr))
{
::MessageBox(NULL,_T("IID_IPushSource error"),NULL,MB_OK);
m_bInit = false;
}
if(m_pPushSource != NULL)
{
m_pPushSource->SetDecoder(m_resolution,m_framerate);
}
IVMRFilterConfig *pFilterConfig;
hr=m_pVideo->QueryInterface(IID_IVMRFilterConfig,(void **)&pFilterConfig);
hr=pFilterConfig->SetNumberOfStreams(2);
if(pFilterConfig != NULL)
{
pFilterConfig->Release();
pFilterConfig = NULL;
}
//connect filters
/*hr = ConnectAudioFilters(m_pSource, m_pAudio);
if (FAILED(hr))
{
::MessageBox(NULL,_T("ConnectAudioFilters error"),NULL,MB_OK);
m_bInit = false;
}*/ hr = ConnectVideoFilters(m_pSource,m_pDecoder);
if (FAILED(hr))
{
::MessageBox(NULL,_T("ConnectVideoFilters error"),NULL,MB_OK);
m_bInit = false;
}
hr = ConnectFilters(m_pDecoder,m_psample);
if (FAILED(hr))
{
::MessageBox(NULL,_T("ConnectFilters error"),NULL,MB_OK);
m_bInit = false;
}
hr = ConnectFilters(m_psample, m_pVideo);
if (FAILED(hr))
{
::MessageBox(NULL,_T("ConnectFilters error"),NULL,MB_OK);
m_bInit = false;
}
return m_bInit;求大神指教,其中的connect函数就是枚举找到为连接的pin然后把输入输出connect就可以了,求大神指导
FilterIsamplegrabber,抓图,
{
if(!pGrabberF)
{
HRESULT hr=CoCreateInstance(CLSID_SampleGrabber,NULL,CLSCTX_INPROC_SERVER,
IID_IBaseFilter,reinterpret_cast<void**>(&pGrabberF));
if(!SUCCEEDED(hr))
{
return hr;
}
hr=mGraph->AddFilter(pGrabberF,L"Sample Grabber");
if(FAILED(hr))
{
return hr;
}
pGrabberF->QueryInterface(IID_ISampleGrabber,(void**)&pGrabber);
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = pGrabber->SetMediaType(&mt);
hr = pGrabber->SetOneShot(FALSE);
hr = pGrabber->SetBufferSamples(TRUE);
}
}HRESULT CompleteBuildGraph(const char *inFile) //这里连接filter
{
WCHAR szFilePath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, inFile, -1, szFilePath, MAX_PATH);
IBaseFilter *pSrc;
HRESULT hr=mGraph->AddSourceFilter(szFilePath,L"Source", &pSrc);
hr = CoCreateInstance(CLSID_Colour,NULL,CLSCTX_INPROC_SERVER,IID_IBaseFilter,reinterpret_cast<void**>(&pDecoder)); hr = CoCreateInstance(CLSID_Colour,NULL,CLSCTX_INPROC_SERVER,IID_IBaseFilter,reinterpret_cast<void**>(&pDecoder2)); hr = mGraph->AddFilter(pDecoder, L"Color Space Converter");
hr = mGraph->AddFilter(pDecoder2, L"Color Space Converter2");
hr = ConnectFilters(mGraph,pSrc,pDecoder);
hr = ConnectFilters(mGraph, pDecoder, pGrabberF); hr = ConnectFilters(mGraph, pGrabberF, pDecoder2); if(FAILED(hr))return hr;
IBaseFilter *pNull = NULL;
hr = CoCreateInstance(CLSID_VideoRenderer,NULL,CLSCTX_ALL,IID_IBaseFilter,reinterpret_cast<void**>(&pRender));
if(FAILED(hr))return hr;
hr = mGraph->AddFilter(pRender,L"Video Render");
if(FAILED(hr))return hr;
hr = ConnectFilters(mGraph, pDecoder2, pRender);
return hr;
}
{
IPin *pOut = NULL, *pIn = NULL;
HRESULT hr = GetPin(pFirst, PINDIR_OUTPUT, &pOut);
if (FAILED(hr)) return hr;
hr = GetPin(pSecond, PINDIR_INPUT, &pIn);
if (FAILED(hr))
{
pOut->Release();
return E_FAIL;
}
hr = pGraph->Connect(pOut, pIn);
pIn->Release();
pOut->Release();
return hr;
}和你的封装应该差不多,只不过我的是传递3个口相连,你的是两个
大神,根据你的程序我做了修改,然后
但是对graph进行run的时候返回错误值。。是什么原因呢??还有你怎么加入了两个colorcovert?
但是run的时候出现了一个错误是一个很大的负值,我查了以后是一个A product licensing error occurred..这是什么原因呢?
是这个错误原因
我拉了个和你给的graph差不多的,是没问题的,正常解码错误提示是没有足够的空间给你分配内存,一般导致这个错误的原因可能是你解码不对,你看下你的解码器是不是不能解码,或者你直接在Insert filtera 中拉一个directshow提供的简单解码器测试下看行不行
我反复检查了解码器,找不到任何原因啊还是出现run的错误原因郁闷啊,而且都是链路在edit显示是通的因为我是先判断是否能run起来后再接受数据,这就搞的很郁闷了。。我解码器用的是FFDSHOW的解码器直接加进去的。
就是这个就是调用了接口,反复试过了不行。
http://msdn.microsoft.com/en-us/library/ms679360(VS.85).aspx看下这里,然后错误信息对照这里
http://www.cnblogs.com/carekee/articles/2196518.html
返回错误信息对照http://www.cnblogs.com/carekee/articles/2196518.html
0x1643e180, 0x90f5, 0x11ce, 0x97, 0xd5, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a)
恩我今天把解码器和所有程序重头分析了一遍,单步跟踪了一遍所有步骤,没有使用getlasterrroe,但是我通过run返回的值是0x80040217,我通过MSDN查到是FW_E_CANNOT_CONNECT No combination of intermediate filters could be found to make the connection. 0x80040217
这样的说法,意为没有连接的找到能连接的filter,但是我通过edit看到remote connect的确实这样的:
因为我做的是个插件所以看以看到运行的链路,明明是通的。。但是为什么run不起来,您用过我发的那个解码器吗??我一直觉得是解码器的引脚没有引用对。就是ffdshow的解码器。。麻烦您了。。我必须使用getlasterror才能发现问题?今天比较忙也没怎么改程序。。
It does not support video types with top-down orientation (negative biHeight).
It does not support the VIDEOINFOHEADER2 format structure (format type equal to FORMAT_VideoInfo2).
It rejects any video type where the surface stride does not match the video width.
As a result, the Sample Grabber will not connect to the Video Mixing Renderer (VMR) for some video types所以,如果刚好在限制范围内,那么只能另谋他法了...
我在本地的视频播放和抓图中已经实现了功能,本地的视频和我从局域网拿到的数据包解包后是一样的,只是写在了本地。所以。现在这个问题太纠结了。那这样看来,网络的SOURCE和本地的SOURCE,在输出的OUTPUTPIN上的MEDIATYPE有不同,如果本地是好的,不妨把网络输出的MEDIATYPE改的和本地的一致?
我在本地的视频播放和抓图中已经实现了功能,本地的视频和我从局域网拿到的数据包解包后是一样的,只是写在了本地。所以。现在这个问题太纠结了。那这样看来,网络的SOURCE和本地的SOURCE,在输出的OUTPUTPIN上的MEDIATYPE有不同,如果本地是好的,不妨把网络输出的MEDIATYPE改的和本地的一致?
在samplegrabber前面我已经设置了MEDIATYPE的类型,您看下设置方法对吗?AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = pGrabber->SetMediaType(&mt);
hr = pGrabber->SetOneShot(FALSE);
hr = pGrabber->SetBufferSamples(TRUE);
我的意思是那个PushSource H264 Filter和source,这两个filter的outputpin的mediatype.
不是说SampleGrabber Filter
我的意思是那个PushSource H264 Filter和source,这两个filter的outputpin的mediatype.
不是说SampleGrabber Filter
源的mediatype是能够设置吗?不是我获取到的是什么,然后解码时才能决定更改媒体类型吗?关键在网路上帧是264的码流,本地也是264的码流。没什么区别。还是链路连接上没连接好
我的意思是那个PushSource H264 Filter和source,这两个filter的outputpin的mediatype.
不是说SampleGrabber Filter
源的mediatype是能够设置吗?不是我获取到的是什么,然后解码时才能决定更改媒体类型吗?关键在网路上帧是264的码流,本地也是264的码流。没什么区别。还是链路连接上没连接好这样看来,source你用的是第三方的了,所以源的mediatype就不能够自己设置了。
网络的source,应该是不区分数据类型的,所以其outputpin上的mediatype和本身就支持H264的PushSource H264 Filter的设置不同,这样就导致了后续的filter在连接时会有差异了。
这种情况下,我觉得你需要在网络的source后面加一个splitter,把数据处理为与PushSource H264 Filter输出相同的类型,也许这样可以解决问题。
sourece是这样的
看mediatype,估计你需要的是一个MPEG-2 Splitter
看mediatype,估计你需要的是一个MPEG-2 Splitter
我前面已经加了spaceconvert,非要加这个spilter?感觉解码器和render之间的问题太大了。。要连不上也是解码器和render之间连不上啊,因为我不加samplegrabber话,网络上的数据是完全可以接受的啊,而且播放正常,都已经要发布产品了,就是加了sample后就不行了。。我觉得还是在sample和render和decoder之间想办法,但是不知道为什么本地的就可以。设想的挺简单的没想到搞了这么几天都没有成功。
恩。。同时从sorce出来的源的数据也是mpeg2这个我都看过了。所以就太奇怪了。我奇怪的是mpeg2到底表示的是什么意思我百度也没找到,本地那个能使用的源里面设置的format是inforheader2,网络上的也是能设置,服务器发送来的数据时264的格式的,但是在接收的时候我对format进行了赋值是mpeg2(参考别人的)然后就能正常的播放了,改为和本地的一样的源和decoder都连接不上了。format我知道是描述流的具体信息的但是到底描述的是什么也不知道,所以根本找不出原因来。对filter理解的不深刻啊。感觉没把握到问题的关键。