继承CTransformFilter类的filter的断开问题
我写了一个CCRotateFilter来继承CTransformFilter, 用来浏览视频的时候旋转
下面是几个基本相关函数
HRESULT BuildGraph(HWND hWnd)
{
HRESULT hr;
hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGraph);
// Create the Capture Graph Builder.
hr = CoCreateInstance(CLSID_CaptureGraphBuilder, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
(void **)&m_pBuilder);
hr = m_pGraph->AddFilter(m_pCap, L"Video Capture Source");
m_pBuilder->SetFiltergraph(m_pGraph);
hr = CoCreateInstance(CLSID_VideoRenderer, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
(void **)&m_pRenderP);
hr = m_pGraph->AddFilter(m_pRenderP, L"Video Render");
hr = m_pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video, m_pCap, NULL, m_pRenderP);
//////////////////////////////////////////////////////////////////////////
// 添加自定义Filter
CCRotateFilter *pRollTranc = new CCRotateFilter(NULL, &hr);
pRollTranc->AddRef();
hr = pRollTranc->QueryInterface(__uuidof(IBaseFilter), (void**)&m_pTrancFilter);
if (FAILED(hr))
{
MessageBox(NULL,TEXT("QueryInterface1 失败"),L"",MB_OK);
}
hr = m_pGraph->AddFilter(m_pTrancFilter, L"My Filter");
if (FAILED(hr))
{
MessageBox(NULL,TEXT("AddFilter 失败"),L"",MB_OK);
}
IEnumFilters* pEnum;
hr = m_pGraph->EnumFilters(&pEnum);
if (FAILED(hr))
{
MessageBox(NULL,TEXT("EnumFilters 失败"),L"",MB_OK);
}
// IVideoWindow接口找到Renderer Filter
IBaseFilter* pVR = NULL;
hr = FindFilterByInterface(IID_IVideoWindow, &pVR);
if (FAILED(hr))
{
MessageBox(NULL,TEXT("FindFilterByInterface 失败"),L"",MB_OK);
}
// 查找Renderer Filter 输入pin
IPin* pPinIn = InputPinOf(pVR);
if (!pPinIn)
{
MessageBox(NULL,TEXT("失败"),L"",MB_OK);
}
// 查找连接在Renderer Filter输入pin上的输出pin
IPin* pPinOut = NULL;
hr = pPinIn->ConnectedTo(&pPinOut);
if (FAILED(hr))
{
MessageBox(NULL,TEXT("失败"),L"",MB_OK);
}
// 断开当前pin连接
hr = m_pGraph->Disconnect(pPinOut);
if (SUCCEEDED(hr))
{
hr = m_pGraph->Disconnect(pPinIn);
}
// 通过连接输入pin和输出pin连接我们自定的filter
if (SUCCEEDED(hr))
{
IPin* pPinInXfm = InputPinOf(m_pTrancFilter);
hr = m_pGraph->Connect(pPinOut, pPinInXfm);
pPinInXfm->Release();
}
if (SUCCEEDED(hr))
{
IPin* pPinOutXfm = OutputPinOf(m_pTrancFilter);
hr = m_pGraph->Connect(pPinOutXfm, pPinIn);
pPinOutXfm->Release();
}
pPinIn->Release();
pPinOut->Release();
//////////////////////////////////////////////////////////////////////////
// 用于调试,输出graph中所有的filter,以及各filter的所有pin及其连接
EnumFilters(m_pGraph);
hr = m_pRenderP->QueryInterface(IID_IVideoWindow, (void**)&m_pVideoWindow);
// 设置视频播放的WINDOWS窗口
m_pVideoWindow->put_MessageDrain((OAHWND)hWnd);
m_pVideoWindow->put_Owner((OAHWND)hWnd);
m_pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
//设置视频尺寸
m_pVideoWindow->SetWindowPosition(VIDEO_SRCCEN_LEFT, VIDEO_SRCCEN_TOP, VIDEO_SRCCEN_WIDTH, VIDEO_SRCCEN_HEIGHT);
m_pVideoWindow->put_Visible(OATRUE);
return hr;
}
HRESULT InitCapFilter()
{
HRESULT hr = S_OK;
GUID clsid = DEVCLASS_CAMERA_GUID;
IPersistPropertyBag *pPropertyBag = NULL;
// Create Capture Filter
CHK(hr = CoCreateInstance(CLSID_VideoCapture, NULL, CLSCTX_INPROC_SERVER,IID_IBaseFilter,
(void **)&m_pCap) );
DEVMGR_DEVICE_INFORMATION pdi;
HANDLE hand = FindFirstDevice(DeviceSearchByGuid,&clsid,&pdi);
RETAILMSG(1, (TEXT("CamTest: Find device: %x %x\r\n"),hand,pdi.szDeviceName));
CHK(hr = m_pCap->QueryInterface(IID_IPersistPropertyBag, (void **)&pPropertyBag));
if (!SUCCEEDED(hr))
{
return hr;
}
VARIANT varCamName;
IPropertyBag *propBag = NULL;
varCamName.byref = L"CAM1:" ;
CHK(hr = pPropertyBag->Load(propBag,NULL));
SAFE_RELEASE(pPropertyBag);
Cleanup:
if(FAILED(hr))
{
LPWSTR lpTemp;
wsprintf(lpTemp, _T("%d"), hr);
MessageBox(m_hWndDLG, lpTemp, _T("TEST"), MB_OK);
OutputDebugString(L"Initial Error!");
}
return hr;
}
BOOL StartPreview()
{
HRESULT hr;
IMediaControl *pMC = NULL;
hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC);
if(SUCCEEDED(hr))
{
hr = pMC->Run();
if(FAILED(hr))
{
// stop parts that ran
pMC->Stop();
}
else
{
m_bPreviewing = TRUE;
}
pMC->Release();
}
if(FAILED(hr))
{
return FALSE;
}
return TRUE;
}
BOOL StopPreview()
{
// way ahead of you
if(!m_bPreviewing)
{
return FALSE;
}
// stop the graph
IMediaControl *pMC = NULL;
HRESULT hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC);
if(SUCCEEDED(hr))
{
hr = pMC->Stop();
pMC->Release();
}
if(FAILED(hr))
{
return FALSE;
}
m_bPreviewing = FALSE;
return TRUE;
}
BOOL CloseCamera()
{
SAFE_RELEASE(m_pRenderP);
SAFE_RELEASE(m_pCap);
//释放IVideoWindow接口
if (m_pVideoWindow != NULL)
{
//隐藏视频窗口
m_pVideoWindow->put_Visible(OAFALSE);
//设置视频播放窗口句柄为空
m_pVideoWindow->put_Owner(NULL);
m_pVideoWindow->Release();
m_pVideoWindow = NULL;
}
SAFE_RELEASE(m_pTrancFilter);
SAFE_RELEASE(m_pGraph);
SAFE_RELEASE(m_pBuilder);
return TRUE;
}
然后有一个button来控制开启和关闭
hr = InitCapFilter();
if (SUCCEEDED(hr))
{
BuildGraph(m_hWndDLG);
StartPreview();
m_hBmpBtnVideo = GetBitmap(PNG_BTN_CAMERA_CLOSE);
if (m_hWBtnVideo)
{
InvalidateRect(m_hWBtnVideo, NULL, TRUE);
UpdateWindow(m_hWBtnVideo);
}
m_bVideoRun = TRUE;
m_bVideoState = TRUE;
}
关闭
if (m_bVideoRun)
{
StopPreview();
CloseCamera();
m_bVideoRun = FALSE;
}
第一次启动的时候很正常, 但我关闭后第二次启动的时候就出错了, 在InitCapFilter()里CHK(hr = pPropertyBag->Load(propBag,NULL));这个时候出错, 返回的hr = -2147024841(ERROR_DEV_NOT_EXIST)
如果我不在CCRotateFilter的时候一切都ok的, 请问我要怎么样在关闭的时候把CCRotateFilter停掉呀. 初学directshow,很多地方不懂请指教, 有代码示例就更好了,谢谢!
[解决办法]
这个不是你的filter的问题吧,采集设备是独占设备,在使用完后一定要释放,才能再次使用
[解决办法]
如果方便的话,可以把你的程序发给我,我给你看看~~
[解决办法]
加上下面的释放就可以了
pEnum->Release();
pTrancFilter->Release();
pTrancFilter = NULL;
if (pRollTranc)
{
pRollTranc->Release();
}