首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > 多媒体 >

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

2012-03-20 
求教为什么我用directshow采集的视频预览时不能正常显示我用directshow采集视频, 中间用了一个CTransformF

求教为什么我用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);



//设置视频尺寸
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; 

}

[解决办法]
输出 Pin 的类型是不是 YUV420?
[解决办法]
应该是N或P制的原因吧,强制设置为N(320x240)试一下。
[解决办法]
GetMediaType中设置下面格式就是设置为YUV播放视频,

pvi->bmiHeader.biCompression = MAKEFOURCC('I','4','2','0'); 
pvi->bmiHeader.biBitCount = 16;

楼主试试

热点排行