自己写filter完成视频图象旋转,遇到问题
如题,我自己写了个CRleFilter(继承TransformFilter),打算完成图象旋转,但是CRleFilter却无法完成连接,麻烦各位帮忙看下
我在CRleFilter里只重写了以下4个函数
virtual HRESULT Transform(IMediaSample * pIn, IMediaSample *pOut);
virtual HRESULT CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut);
virtual HRESULT DecideBufferSize(
IMemAllocator * pAllocator,
ALLOCATOR_PROPERTIES *pprop);
virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);
分别实现如下:
HRESULT CRleFilter::CheckInputType(const CMediaType *remtIn)
{
if ((remtIn-> majortype != MEDIATYPE_Video)||
(remtIn-> subtype != MEDIASUBTYPE_RGB565) ||
(remtIn-> formattype != FORMAT_VideoInfo) ||
(remtIn-> cbFormat < sizeof(VIDEOINFOHEADER)))
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
VIDEOINFOHEADER *pVih =
reinterpret_cast <VIDEOINFOHEADER*> (remtIn-> pbFormat);
m_biBitCount = pVih-> bmiHeader.biBitCount;
m_biCompression = pVih-> bmiHeader.biCompression;
m_inwidth = pVih-> bmiHeader.biWidth;
m_inheigth = pVih-> bmiHeader.biHeight;
// Everything is good.
return S_OK;
}
HRESULT CRleFilter::GetMediaType(int iPosition, CMediaType *pMediaType)
{
ASSERT(m_pInput-> IsConnected());
if (iPosition < 0)
{
return E_INVALIDARG;
}
if (iPosition > = 0)
{
HRESULT hr = m_pInput-> ConnectionMediaType(pMediaType);
if (FAILED(hr))
{
return hr;
}
//FOURCCMap fccMap(FCC( 'MRLE '));
pMediaType-> subtype = MEDIASUBTYPE_RGB565;//static_cast <GUID> (fccMap);//MEDIASUBTYPE_RGB565;
pMediaType-> SetVariableSize();
pMediaType-> SetTemporalCompression(FALSE);
ASSERT(pMediaType-> formattype == FORMAT_VideoInfo);
VIDEOINFOHEADER *pVih =
reinterpret_cast <VIDEOINFOHEADER*> (pMediaType-> pbFormat);
if(m_biBitCount != NULL)
{
pVih-> bmiHeader.biCompression = m_biCompression;
}
pVih-> bmiHeader.biSizeImage = DIBSIZE(pVih-> bmiHeader);
return S_OK;
}
// else
return VFW_S_NO_MORE_ITEMS;
}
HRESULT CRleFilter::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
{
// Check the major type.
if (mtOut-> majortype != MEDIATYPE_Video)
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
// Check the subtype and format type.
//FOURCCMap fccMap = FCC( 'MRLE ');
if (mtOut-> subtype != MEDIASUBTYPE_RGB565/*static_cast <GUID> (fccMap)*/)
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
if ((mtOut-> formattype != FORMAT_VideoInfo) ||
(mtOut-> cbFormat < sizeof(VIDEOINFOHEADER)))
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
// Compare the bitmap information against the input type.
ASSERT(mtIn-> formattype == FORMAT_VideoInfo);
BITMAPINFOHEADER *pBmiOut = HEADER(mtOut-> pbFormat);
BITMAPINFOHEADER *pBmiIn = HEADER(mtIn-> pbFormat);
if ((pBmiOut-> biPlanes != 1) ||
(pBmiOut-> biBitCount != m_biBitCount) ||
(pBmiOut-> biCompression != m_biCompression) ||
(pBmiOut-> biWidth != pBmiIn-> biHeight) ||//change 旋转
(pBmiOut-> biHeight != pBmiIn-> biWidth))
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
// Compare source and target rectangles.
//RECT rcImg;
//SetRect(&rcImg, 0, 0, pBmiIn-> biHeight,pBmiIn-> biWidth);//change
RECT *prcSrc = &((VIDEOINFOHEADER*)(mtIn-> pbFormat))-> rcSource;
RECT *prcTarget = &((VIDEOINFOHEADER*)(mtOut-> pbFormat))-> rcTarget;
if (!IsRectEmpty(prcSrc) /*&& !EqualRect(prcSrc, &rcImg)*/)
{
return VFW_E_INVALIDMEDIATYPE;
}
if (!IsRectEmpty(prcTarget)/* && !EqualRect(prcTarget, &rcImg)*/)
{
return VFW_E_INVALIDMEDIATYPE;
}
// Check the palette table.
if (pBmiOut-> biClrUsed != pBmiIn-> biClrUsed)
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
DWORD cbPalette = pBmiOut-> biClrUsed * sizeof(RGBQUAD);
if (mtOut-> cbFormat < sizeof(VIDEOINFOHEADER) + cbPalette)
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
if (0 != memcmp(pBmiOut + 1, pBmiIn + 1, cbPalette))
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
// Everything is good.
return S_OK;
}
HRESULT CRleFilter::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp)
{
AM_MEDIA_TYPE mt;
HRESULT hr = m_pOutput-> ConnectionMediaType(&mt);
if (FAILED(hr))
{
return hr;
}
ASSERT(mt.formattype == FORMAT_VideoInfo);
BITMAPINFOHEADER *pbmi = HEADER(mt.pbFormat);
pProp-> cbBuffer = DIBSIZE(*pbmi) * 2;
if (pProp-> cbAlign == 0)
{
pProp-> cbAlign = 1;
}
if (pProp-> cBuffers == 0)
{
pProp-> cBuffers = 1;
}
// Release the format block.
FreeMediaType(mt);
// Set allocator properties.
ALLOCATOR_PROPERTIES Actual;
hr = pAlloc-> SetProperties(pProp, &Actual);
if (FAILED(hr))
{
return hr;
}
// Even when it succeeds, check the actual result.
if (pProp-> cbBuffer > Actual.cbBuffer)
{
return E_FAIL;
}
return S_OK;
}
HRESULT CRleFilter::Transform(IMediaSample *pSource, IMediaSample *pDest)
{
// Get pointers to the underlying buffers.
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;
}
// Process the data.
/*DWORD cbDest = EncodeFrame(pBufferIn, pBufferOut);
KASSERT((long)cbDest <= pDest-> GetSize());
pDest-> SetActualDataLength(cbDest);
pDest-> SetSyncPoint(TRUE);*/
int k = 0;
for(int i = m_inwidth-1; i> =0 ;i--)
{
for(int j = 0; j < m_inheigth;j++)
{
pDest[k] = pSource[2*i + j*m_inwidth];//16bits
k++;
pDest[k] = pSource[2*i + j*m_inwidth +1];
k++;
}
}
return S_OK;
}
[解决办法]
你的链路是什么样的?
[解决办法]
你要旋转多少度?