求教为什么小弟我用directshow采集的视频预览时不能正常显示
求教为什么我用directshow采集的视频预览时不能正常显示
我用directshow采集视频, 中间用了一个CTransformFilter来旋转90度视频, 取出来的是RBG565,然后我再把它转成YUV420保存, 但现在出现一个问题, 那个保存下来的视频是正常的, 但是在预览的时候就画面不正确了, 应该显示出来的图象变成了一杠一杠的宽斜杠, 中间的间隔全部是黑色的.
这个代码我在其它的型号手机上是完全正常的.
我不用CTransformFilter预览画面是正常的, 我现在有点想不明白, 如果我CTransformFilter旋转90度的数据出错, 那我最终保存下来的视频也应该是宽斜杠和黑色的呀, 但现在从保存下来的视频是正常的, 那我用CTransformFilter旋转90度的数据也就是正确了,但为什么预览时会不正常呢
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_CAPTURE, &MEDIATYPE_Video, m_pCap, NULL, m_pRenderP);
// IAMStreamConfig *pConfig = NULL;
// hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
// m_pRenderP, IID_IAMStreamConfig, (void**)&pConfig);
// if (SUCCEEDED(hr))
// {
// int iCount=0,iSize=0;
// hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);
// AM_MEDIA_TYPE *pmt = NULL;
// hr = pConfig->GetFormat(&pmt);
// if (SUCCEEDED(hr))
// {
// pConfig-> SetFormat(pmt);
// }
// DeleteMediaType(pmt);
// pConfig-> Release();
// }
//////////////////////////////////////////////////////////////////////////
// 添加自定义Filter
CCRotateFilter *pRollTranc = new CCRotateFilter(NULL, &hr);
pRollTranc->SetCallback(&CallbackVideo);
IBaseFilter *pTrancFilter;
hr = pRollTranc->QueryInterface(__uuidof(IBaseFilter), (void**)&pTrancFilter);
if (FAILED(hr))
{
return S_FALSE;
}
hr = m_pGraph->AddFilter(pTrancFilter, L"My Filter");
if (FAILED(hr))
{
return S_FALSE;
}
IEnumFilters* pEnum;
hr = m_pGraph->EnumFilters(&pEnum);
if (FAILED(hr))
{
return S_FALSE;
}
// 查找Renderer Filter 输入pin
IPin* pPinIn = InputPinOf(m_pRenderP);
if (!pPinIn)
{
return S_FALSE;
}
// 查找连接在Renderer Filter输入pin上的输出pin
IPin* pPinOut = NULL;
hr = pPinIn->ConnectedTo(&pPinOut);
if (FAILED(hr))
{
return S_FALSE;
}
// 断开当前pin连接
hr = m_pGraph->Disconnect(pPinOut);
if (SUCCEEDED(hr))
{
hr = m_pGraph->Disconnect(pPinIn);
}
// 通过连接输入pin和输出pin连接我们自定的filter
if (SUCCEEDED(hr))
{
IPin* pPinInXfm = InputPinOf(pTrancFilter);
hr = m_pGraph->Connect(pPinOut, pPinInXfm);
pPinInXfm->Release();
}
if (SUCCEEDED(hr))
{
IPin* pPinOutXfm = OutputPinOf(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);
我用directshow采集视频, 中间用了一个CTransformFilter来旋转90度视频, 取出来的是RBG565,然后我再把它转成YUV420保存, 但现在出现一个问题, 那个保存下来的视频是正常的, 但是在预览的时候就画面不正确了, 应该显示出来的图象变成了一杠一杠的宽斜杠, 中间的间隔全部是黑色的.
这个代码我在其它的型号手机上是完全正常的.
我不用CTransformFilter预览画面是正常的, 我现在有点想不明白, 如果我CTransformFilter旋转90度的数据出错, 那我最终保存下来的视频也应该是宽斜杠和黑色的呀, 但现在从保存下来的视频是正常的, 那我用CTransformFilter旋转90度的数据也就是正确了,但为什么预览时会不正常呢
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_CAPTURE, &MEDIATYPE_Video, m_pCap, NULL, m_pRenderP);
// IAMStreamConfig *pConfig = NULL;
// hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
// m_pRenderP, IID_IAMStreamConfig, (void**)&pConfig);
// if (SUCCEEDED(hr))
// {
// int iCount=0,iSize=0;
// hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);
// AM_MEDIA_TYPE *pmt = NULL;
// hr = pConfig->GetFormat(&pmt);
// if (SUCCEEDED(hr))
// {
// pConfig-> SetFormat(pmt);
// }
// DeleteMediaType(pmt);
// pConfig-> Release();
// }
//////////////////////////////////////////////////////////////////////////
// 添加自定义Filter
CCRotateFilter *pRollTranc = new CCRotateFilter(NULL, &hr);
pRollTranc->SetCallback(&CallbackVideo);
IBaseFilter *pTrancFilter;
hr = pRollTranc->QueryInterface(__uuidof(IBaseFilter), (void**)&pTrancFilter);
if (FAILED(hr))
{
return S_FALSE;
}
hr = m_pGraph->AddFilter(pTrancFilter, L"My Filter");
if (FAILED(hr))
{
return S_FALSE;
}
IEnumFilters* pEnum;
hr = m_pGraph->EnumFilters(&pEnum);
if (FAILED(hr))
{
return S_FALSE;
}
// 查找Renderer Filter 输入pin
IPin* pPinIn = InputPinOf(m_pRenderP);
if (!pPinIn)
{
return S_FALSE;
}
// 查找连接在Renderer Filter输入pin上的输出pin
IPin* pPinOut = NULL;
hr = pPinIn->ConnectedTo(&pPinOut);
if (FAILED(hr))
{
return S_FALSE;
}
// 断开当前pin连接
hr = m_pGraph->Disconnect(pPinOut);
if (SUCCEEDED(hr))
{
hr = m_pGraph->Disconnect(pPinIn);
}
// 通过连接输入pin和输出pin连接我们自定的filter
if (SUCCEEDED(hr))
{
IPin* pPinInXfm = InputPinOf(pTrancFilter);
hr = m_pGraph->Connect(pPinOut, pPinInXfm);
pPinInXfm->Release();
}
if (SUCCEEDED(hr))
{
IPin* pPinOutXfm = OutputPinOf(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);