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

自己写filter完成视频图象旋转,遇到有关问题

2012-02-05 
自己写filter完成视频图象旋转,遇到问题如题,我自己写了个CRleFilter(继承TransformFilter),打算完成图象

自己写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;
}

[解决办法]
你的链路是什么样的?
[解决办法]
你要旋转多少度?

热点排行