求教为什么我用directshow采集的视频预览时不能正常显示

ayiyi0910 2011-08-24 01:40:57
我用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);

//设置视频尺寸
m_pVideoWindow->SetWindowPosition(VIDEO_SRCCEN_LEFT, VIDEO_SRCCEN_TOP, VIDEO_SRCCEN_WIDTH, VIDEO_SRCCEN_HEIGHT);
m_pVideoWindow->put_Visible(OATRUE);

pEnum->Release();

pTrancFilter->Release();
pTrancFilter = NULL;

if (pRollTranc)
{
pRollTranc->Release();
}

return hr;
}

HRESULT CCRotateFilter::Transform(IMediaSample *pSource, IMediaSample *pDest)
{
HRESULT hr = S_OK;
BYTE *pBufferIn, *pBufferOut;
hr = pSource-> GetPointer(&pBufferIn);
if (FAILED(hr))
{
return hr;
}
hr = pDest-> GetPointer(&pBufferOut);
if (FAILED(hr))
{
return hr;
}

// 直接copy, 不做转换
// memcpy(pBufferOut, pBufferIn, 2*m_lHeight*m_lWidth);

// 图像数据旋转90°(不同的机器可能旋转的方向不同,请自行调整loop变量起始值)
// 这里只支持16bit的RGB颜色空间,如RGB565,RGB555
int k = 0;

for(int i = 0; i< m_lWidth; i++)
{
for(int j = 0; j < m_lHeight; j++)
{
pBufferOut[k] = pBufferIn[2*i + j*m_cbWidth];//16bits
k++;
pBufferOut[k] = pBufferIn[2*i + j*m_cbWidth + 1];
k++;
}
}

if (m_callback)
{
REFERENCE_TIME StartTime, StopTime;
pSource->GetTime( &StartTime, &StopTime);

// long lSize = pDest->GetActualDataLength();

HRESULT hr = m_callback(pBufferOut, &StartTime, &StopTime, m_lHeight, m_lWidth, k);

return hr;
}

return NOERROR;

}
...全文
151 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
ayiyi0910 2011-09-02
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 ayiyi0910 的回复:]
另外再求教一下, 如果我要设置取出来的视频分辩率的话是不是在我上面注释掉的代码那里修改

但是我用下面这个代码时 返回的hr = E_NOINTERFACE
IAMStreamConfig *pConfig = NULL;
hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
……
[/Quote]

这个问题解决了是参数错了,第三个参数不是用m_pRenderP

求教一下, 我在CTransformFilter传进去的是RBG565, 我在里面把数据转成了YUV420, 但是浏览的时候花屏了,是不是我要对输出IMediaSample的进行设置, 一般是要在那里设置? 请大家指教一下, 能有代码例子就更好了,谢谢
ayiyi0910 2011-08-24
  • 打赏
  • 举报
回复
另外再求教一下, 如果我要设置取出来的视频分辩率的话是不是在我上面注释掉的代码那里修改

但是我用下面这个代码时 返回的hr = E_NOINTERFACE
IAMStreamConfig *pConfig = NULL;
hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
m_pRenderP, IID_IAMStreamConfig, (void**)&pConfig);

7,660

社区成员

发帖
与我相关
我的任务
社区描述
Windows Phone是微软发布的一款手机操作系统,它将微软旗下的Xbox LIVE游戏、Zune音乐与独特的视频体验整合至手机中。
社区管理员
  • Windows客户端开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧