目的:修改视频格式,使输出176x144的rgb24视频流
做法:
bool CCaptureVideo::SetCaptureSize(int width, int height)
{int iCount, iSize;
HRESULT hr;
VIDEO_STREAM_CONFIG_CAPS scc;
AM_MEDIA_TYPE *pmt;
IAMStreamConfig *pConfig = NULL;
hr = m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, // Any media type.
m_pBF, // Pointer to the capture filter.
IID_IAMStreamConfig, (void**)&pConfig);
if(FAILED(hr))
{
return hr;
}
hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);
if (sizeof(scc) != iSize)
{
// This is not the structure we were expecting.
return E_FAIL;
}
// Get the first format.
for(int mm=0; mm< iCount; mm++)
{
hr = pConfig->GetStreamCaps(mm, &pmt, reinterpret_cast
if (hr == S_OK)
{
if ((pmt->majortype==MEDIATYPE_Video && pmt->formattype == FORMAT_VideoInfo &&
pmt->subtype == MEDIASUBTYPE_RGB24))
{
// Find the smallest output size.
//LONG width = scc.MinOutputSize.cx;
//LONG height = scc.MinOutputSize.cy;
LONG cbPixel = 3; // Bytes per pixel in UYVY
// Modify the format block.
VIDEOINFOHEADER *pVih =
reinterpret_cast
pVih->bmiHeader.biWidth = width;
pVih->bmiHeader.biHeight = height;
// Set the sample size and image size.
// (Round the image width up to a DWORD boundary.)
pmt->lSampleSize = pVih->bmiHeader.biSizeImage = //176*144*3;
((width + 3) & ~3) * height * cbPixel;
// Now set the format.
hr = pConfig->SetFormat(pmt);
if (FAILED(hr))
{
//MessageBox(NULL, TEXT("SetFormat Failed\n"), NULL, MB_OK);
}
}
else{
}
DeleteMediaType(pmt);
}else
{
}
}
return true;
}
网上很多参考都是这样写的,代码应该是没问题的。但是调试后发现GetStreamCaps输出的AM_MEDIA_TYPE的subtype字段总是为 MEDIASUBTYPE_YUY2。而我又用另外一种方法去枚举采集filter的pin,发现每个pin的AM_MEDIA_TYPE的 subtype字段也是MEDIASUBTYPE_YUY2。
其方法如下:
IPin * CCaptureVideo::GetVideoPin(IBaseFilter * pFilter)
{
IEnumPins * m_EnumPins;
HRESULT hr = E_FAIL;
hr = pFilter->EnumPins(&m_EnumPins);
if(FAILED(hr))
{
return NULL;
}
IPin * pin = NULL;
bool b_getPin = false;
ULONG n_get = 0;
while(S_OK == m_EnumPins->Next(1, &pin, &n_get) && b_getPin==false)
{
PIN_DIRECTION pin_dir;
pin->QueryDirection(&pin_dir);
if(pin_dir == PINDIR_OUTPUT)
{
IEnumMediaTypes * p_Enum_MediaType;
hr = pin->EnumMediaTypes(&p_Enum_MediaType);
if(FAILED(hr))
{
continue;
}
AM_MEDIA_TYPE * p_am_type;
ULONG n_types = 0;
while(S_OK == p_Enum_MediaType->Next(1, &p_am_type, &n_types) && b_getPin==false)
{
if(p_am_type->majortype == MEDIATYPE_Video && p_am_type->subtype==MEDIASUBTYPE_RGB24)
{
b_getPin = true;
}
DeleteMediaType(p_am_type);
p_am_type = NULL;
}
p_Enum_MediaType->Release();
}
}
m_EnumPins->Release();
if(b_getPin == true)
re