mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-14 02:37:46 +08:00
1526 lines
47 KiB
C++
1526 lines
47 KiB
C++
// AVSVideoFramePainter.h
|
|
|
|
#pragma once
|
|
#include "resource.h" // main symbols
|
|
#include "ASCUncompressedVideoFrame.h"
|
|
#include "ASCVideoFrameTransform.h"
|
|
#include <math.h>
|
|
|
|
|
|
// IAVSVideoFrameDrawing
|
|
[ object, uuid("AE1D7D3F-ED9D-4159-922A-024F1F45B274"), dual, pointer_default(unique)]
|
|
__interface IAVSVideoFramePainter : IDispatch
|
|
{
|
|
//â pMask îäíà áàéòîâàÿ ïëîñêîñòü ñ àëüôî êàíàëîì
|
|
[id(209000 + 10)] HRESULT DrawMasked([in] IAVSUncompressedVideoFrame* pFrame, [in] long Left, [in] long Top, [in] IAVSUncompressedVideoFrame* pPicture, [in] IAVSUncompressedVideoFrame* pMask);
|
|
[id(209000 + 20)] HRESULT DrawMaskedUnknown([in] IUnknown* pFrame, [in] long Left, [in] long Top, [in] IUnknown* pPicture, [in] IUnknown* pMask);
|
|
|
|
|
|
//Äëÿ CSP_BGRA è CSP_BGR ColorKey ïåðåäàåòñÿ êàê 0x00RRGGBB
|
|
//Äëÿ CSP_I420 è CSP_YV12 ColorKey ïåðåäàåòñÿ êàê 0x00YYUUVV
|
|
//Äëÿ CSP_YUY2 ColorKey ïåðåäàåòñÿ êàê 0x00YYUUVV
|
|
[id(209000 + 30)] HRESULT DrawColorKey([in] IAVSUncompressedVideoFrame* pFrame, [in] long Left, [in] long Top, [in] IAVSUncompressedVideoFrame* pPicture, [in] long ColorKey);
|
|
[id(209000 + 40)] HRESULT DrawColorKeyUnknown([in] IUnknown* pFrame, [in] long Left, [in] long Top, [in] IUnknown* pPicture, [in] long ColorKey);
|
|
|
|
[id(209000 + 100)] HRESULT ConvetColorKey([in] long SrcColorSpace, [in] long DstColorSpace, [in] long SrcColorKey, [out, retval] long *pDstColorKey);
|
|
};
|
|
|
|
|
|
|
|
// CAVSVideoFrameColorTransform
|
|
[ coclass, threading(apartment), vi_progid("AVSMediaCore3.IAVSVideoFramePainter"), progid("AVSMediaCore3.IAVSVideoFramePainter.1"), version(1.0), uuid("DFACD890-DDCB-4432-921E-E46BDA97DE02")]
|
|
class ATL_NO_VTABLE CAVSVideoFramePainter :
|
|
public IAVSVideoFramePainter
|
|
{
|
|
public:
|
|
CAVSVideoFramePainter()
|
|
{
|
|
}
|
|
public:
|
|
STDMETHOD(DrawMasked)(IAVSUncompressedVideoFrame* pFrame, long Left, long Top, IAVSUncompressedVideoFrame* pPicture, IAVSUncompressedVideoFrame* pMask)
|
|
{
|
|
SFrameSetting oFrameSetting;
|
|
if (!GetFrameProperties(pFrame, oFrameSetting, TRUE))
|
|
return S_FALSE;
|
|
SFrameSetting oPictureSetting;
|
|
if (!GetFrameProperties(pPicture, oPictureSetting, TRUE))
|
|
return S_FALSE;
|
|
|
|
if (0!=(CSP_VFLIP & oFrameSetting.m_lColorSpace))
|
|
Top = oFrameSetting.m_lHeight - (Top + oPictureSetting.m_lHeight - 1);
|
|
|
|
if ((0==oPictureSetting.m_lWidth)||(0==oPictureSetting.m_lHeight)||
|
|
(0==oFrameSetting.m_lWidth)||(0==oFrameSetting.m_lHeight))
|
|
return S_FALSE;
|
|
if ((oFrameSetting.m_lWidth<=Left)||(oFrameSetting.m_lHeight<=Top))
|
|
return S_OK;
|
|
|
|
if ((Left<0) && (oPictureSetting.m_lWidth + Left<=0))
|
|
return S_OK;
|
|
if ((Top<0) && (oPictureSetting.m_lHeight + Top<=0))
|
|
return S_OK;
|
|
|
|
if (NULL!=pMask)
|
|
{
|
|
SFrameSetting oMaskSetting;
|
|
if (!GetFrameProperties(pMask, oMaskSetting))
|
|
return S_FALSE;
|
|
if ((oPictureSetting.m_lWidth != oMaskSetting.m_lWidth)||
|
|
(oPictureSetting.m_lHeight != oMaskSetting.m_lHeight))
|
|
return S_FALSE;
|
|
if ((CSP_YV12 != (CSP_COLOR_MASK & oMaskSetting.m_lColorSpace))&&
|
|
(CSP_I420 != (CSP_COLOR_MASK & oMaskSetting.m_lColorSpace)))
|
|
return S_FALSE;
|
|
}
|
|
|
|
pPicture->AddRef();
|
|
if (oFrameSetting.m_lColorSpace!=oPictureSetting.m_lColorSpace)
|
|
{
|
|
IAVSVideoFrameTransform *pTransform = NULL;
|
|
CoCreateInstance(__uuidof(CAVSVideoFrameTransform), NULL, CLSCTX_ALL, __uuidof(IAVSVideoFrameTransform), (void**)&pTransform);
|
|
if (NULL==pTransform)
|
|
return S_FALSE;
|
|
MediaFormat::IAVSVideoFormat *pFormat = NULL;
|
|
CoCreateInstance(MediaFormat::CLSID_CAVSVideoFormat, NULL, CLSCTX_ALL, MediaFormat::IID_IAVSVideoFormat, (void**)&pFormat);
|
|
if (NULL==pFormat)
|
|
{
|
|
pTransform->Release();
|
|
return S_FALSE;
|
|
}
|
|
pTransform->put_DeinterlaceEnabled(FALSE);
|
|
pTransform->put_CropScale(0);
|
|
|
|
pFormat->put_ColorSpace(oFrameSetting.m_lColorSpace);
|
|
pFormat->put_Width(oPictureSetting.m_lWidth);
|
|
pFormat->put_Height(oPictureSetting.m_lHeight);
|
|
long lTemp = 0;
|
|
pPicture->get_AspectRatioX(&lTemp);
|
|
pFormat->put_AspectRatioX(lTemp);
|
|
pPicture->get_AspectRatioY(&lTemp);
|
|
pFormat->put_AspectRatioY(lTemp);
|
|
pTransform->SetVideoFormat(pFormat);
|
|
RELEASEINTERFACE(pFormat);
|
|
IUnknown* punkPicture = NULL;
|
|
pTransform->TransformFrame(pPicture, &punkPicture);
|
|
RELEASEINTERFACE(pTransform);
|
|
RELEASEINTERFACE(pPicture);
|
|
if (NULL==punkPicture)
|
|
return S_FALSE;
|
|
punkPicture->QueryInterface(__uuidof(IAVSUncompressedVideoFrame), (void**)&pPicture);
|
|
punkPicture->Release();
|
|
}
|
|
|
|
if (NULL!=pMask)
|
|
DrawInner(pFrame, Left, Top, pPicture, pMask);
|
|
else
|
|
DrawInner(pFrame, Left, Top, pPicture);
|
|
|
|
RELEASEINTERFACE(pPicture);
|
|
return S_OK;
|
|
}
|
|
STDMETHOD(DrawMaskedUnknown)(IUnknown* punkFrame, long Left, long Top, IUnknown* punkPicture, IUnknown* punkMask)
|
|
{
|
|
IAVSUncompressedVideoFrame* pFrame = NULL;
|
|
IAVSUncompressedVideoFrame* pPicture = NULL;
|
|
IAVSUncompressedVideoFrame* pMask = NULL;
|
|
if ((NULL==punkFrame)||(NULL==punkPicture))
|
|
return S_FALSE;
|
|
punkFrame->QueryInterface(__uuidof(IAVSUncompressedVideoFrame), (void**)&pFrame);
|
|
punkPicture->QueryInterface(__uuidof(IAVSUncompressedVideoFrame), (void**)&pPicture);
|
|
if (NULL!=punkMask)
|
|
punkMask->QueryInterface(__uuidof(IAVSUncompressedVideoFrame), (void**)&pMask);
|
|
HRESULT hr = DrawMasked(pFrame, Left, Top, pPicture, pMask);
|
|
RELEASEINTERFACE(pFrame);
|
|
RELEASEINTERFACE(pPicture);
|
|
RELEASEINTERFACE(pMask);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHOD(DrawColorKey)(IAVSUncompressedVideoFrame* pFrame, long Left, long Top, IAVSUncompressedVideoFrame* pPicture, long ColorKey)
|
|
{
|
|
SFrameSetting oFrameSetting;
|
|
if (!GetFrameProperties(pFrame, oFrameSetting, TRUE))
|
|
return S_FALSE;
|
|
SFrameSetting oPictureSetting;
|
|
if (!GetFrameProperties(pPicture, oPictureSetting, TRUE))
|
|
return S_FALSE;
|
|
|
|
if (0!=(CSP_VFLIP & oFrameSetting.m_lColorSpace))
|
|
Top = oFrameSetting.m_lHeight - (Top + oPictureSetting.m_lHeight - 1);
|
|
if ((Left<0)||(Top<0))
|
|
return FALSE;
|
|
if ((0==oPictureSetting.m_lWidth)||(0==oPictureSetting.m_lHeight)||
|
|
(0==oFrameSetting.m_lWidth)||(0==oFrameSetting.m_lHeight))
|
|
return S_FALSE;
|
|
if ((oFrameSetting.m_lWidth<=Left)||(oFrameSetting.m_lHeight<=Top))
|
|
return S_OK;
|
|
|
|
pPicture->AddRef();
|
|
if (oFrameSetting.m_lColorSpace!=oPictureSetting.m_lColorSpace)
|
|
{
|
|
IAVSVideoFrameTransform *pTransform = NULL;
|
|
CoCreateInstance(__uuidof(CAVSVideoFrameTransform), NULL, CLSCTX_ALL, __uuidof(IAVSVideoFrameTransform), (void**)&pTransform);
|
|
if (NULL==pTransform)
|
|
return S_FALSE;
|
|
MediaFormat::IAVSVideoFormat *pFormat = NULL;
|
|
CoCreateInstance(MediaFormat::CLSID_CAVSVideoFormat, NULL, CLSCTX_ALL, MediaFormat::IID_IAVSVideoFormat, (void**)&pFormat);
|
|
if (NULL==pFormat)
|
|
{
|
|
pTransform->Release();
|
|
return S_FALSE;
|
|
}
|
|
pTransform->put_DeinterlaceEnabled(FALSE);
|
|
pTransform->put_CropScale(0);
|
|
|
|
pFormat->put_ColorSpace(oFrameSetting.m_lColorSpace);
|
|
pFormat->put_Width(oPictureSetting.m_lWidth);
|
|
pFormat->put_Height(oPictureSetting.m_lHeight);
|
|
long lTemp = 0;
|
|
pPicture->get_AspectRatioX(&lTemp);
|
|
pFormat->put_AspectRatioX(lTemp);
|
|
pPicture->get_AspectRatioY(&lTemp);
|
|
pFormat->put_AspectRatioY(lTemp);
|
|
pTransform->SetVideoFormat(pFormat);
|
|
RELEASEINTERFACE(pFormat);
|
|
IUnknown* punkPicture = NULL;
|
|
pTransform->TransformFrame(pPicture, &punkPicture);
|
|
RELEASEINTERFACE(pTransform);
|
|
RELEASEINTERFACE(pPicture);
|
|
if (NULL==punkPicture)
|
|
return S_FALSE;
|
|
punkPicture->QueryInterface(__uuidof(IAVSUncompressedVideoFrame), (void**)&pPicture);
|
|
punkPicture->Release();
|
|
}
|
|
DrawSimpleInner(pFrame, Left, Top, pPicture, ConvertColorKey(ColorKey, oPictureSetting.m_lColorSpace, oFrameSetting.m_lColorSpace));
|
|
RELEASEINTERFACE(pPicture);
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHOD(DrawColorKeyUnknown)(IUnknown* punkFrame, long Left, long Top, IUnknown* punkPicture, long ColorKey)
|
|
{
|
|
IAVSUncompressedVideoFrame* pFrame = NULL;
|
|
IAVSUncompressedVideoFrame* pPicture = NULL;
|
|
if ((NULL==punkFrame)||(NULL==punkPicture))
|
|
return S_FALSE;
|
|
punkFrame->QueryInterface(__uuidof(IAVSUncompressedVideoFrame), (void**)&pFrame);
|
|
punkPicture->QueryInterface(__uuidof(IAVSUncompressedVideoFrame), (void**)&pPicture);
|
|
HRESULT hr = DrawColorKey(pFrame, Left, Top, pPicture, ColorKey);
|
|
RELEASEINTERFACE(pFrame);
|
|
RELEASEINTERFACE(pPicture);
|
|
return hr;
|
|
}
|
|
STDMETHOD(ConvetColorKey)(long SrcColorSpace, long DstColorSpace, long SrcColorKey, long *pDstColorKey)
|
|
{
|
|
*pDstColorKey = ConvertColorKey(SrcColorKey, SrcColorSpace, DstColorSpace);
|
|
return S_OK;
|
|
}
|
|
protected:
|
|
struct SFrameSetting
|
|
{
|
|
SFrameSetting()
|
|
: m_lColorSpace(0)
|
|
, m_lHeight(0)
|
|
, m_lWidth(0)
|
|
{
|
|
}
|
|
long m_lColorSpace;
|
|
long m_lHeight;
|
|
long m_lWidth;
|
|
};
|
|
static inline BOOL GetFrameProperties(IAVSUncompressedVideoFrame* pFrame, SFrameSetting &oFrameSetting, BOOL bCheckBuffer = FALSE)
|
|
{
|
|
if (NULL==pFrame)
|
|
return FALSE;
|
|
pFrame->get_ColorSpace(&oFrameSetting.m_lColorSpace);
|
|
pFrame->get_Width(&oFrameSetting.m_lWidth);
|
|
pFrame->get_Height(&oFrameSetting.m_lHeight);
|
|
if (!bCheckBuffer)
|
|
return TRUE;
|
|
switch (oFrameSetting.m_lColorSpace & CSP_COLOR_MASK)
|
|
{
|
|
case CSP_I420:
|
|
case CSP_YV12:
|
|
{
|
|
LPBYTE pTemp = NULL;
|
|
pFrame->get_Plane(0, &pTemp);
|
|
if (NULL==pTemp)
|
|
return FALSE;
|
|
pTemp = NULL;
|
|
pFrame->get_Plane(1, &pTemp);
|
|
if (NULL==pTemp)
|
|
return FALSE;
|
|
pTemp = NULL;
|
|
pFrame->get_Plane(2, &pTemp);
|
|
if (NULL==pTemp)
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case CSP_YUY2:
|
|
case CSP_BGRA:
|
|
case CSP_BGR:
|
|
{
|
|
LPBYTE pTemp = NULL;
|
|
pFrame->get_Plane(0, &pTemp);
|
|
if (NULL==pTemp)
|
|
return FALSE;
|
|
}
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
static void DrawInner(IAVSUncompressedVideoFrame* pFrame, long lLeft, long lTop, IAVSUncompressedVideoFrame* pPicture, IAVSUncompressedVideoFrame* pMask)
|
|
{
|
|
SFrameSetting oFrameSetting;
|
|
GetFrameProperties(pFrame, oFrameSetting);
|
|
SFrameSetting oPictureSetting;
|
|
GetFrameProperties(pPicture, oPictureSetting);
|
|
|
|
long lMaskColorSpace;
|
|
pMask->get_ColorSpace(&lMaskColorSpace);
|
|
|
|
switch (oFrameSetting.m_lColorSpace & CSP_COLOR_MASK)
|
|
{
|
|
case CSP_I420:
|
|
case CSP_YV12:
|
|
{
|
|
if (lLeft<0)
|
|
lLeft = -(abs(lLeft)>>1)<<1;
|
|
else
|
|
lLeft = (lLeft>>1)<<1;
|
|
if (lTop<0)
|
|
lTop = -(abs(lTop)>>1)<<1;
|
|
else
|
|
lTop = (lTop>>1)<<1;
|
|
|
|
long lPictureWidth = (min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft)>>1)<<1;
|
|
if (lLeft<0)
|
|
lPictureWidth += lLeft;
|
|
long lPictureHeight = (min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop)>>1)<<1;
|
|
if (lTop<0)
|
|
lPictureHeight += lTop;
|
|
|
|
LPBYTE pMaskPlane = NULL;
|
|
pMask->get_Plane(0, &pMaskPlane);
|
|
|
|
|
|
long lMaskStride;
|
|
pMask->get_Stride(0, &lMaskStride);
|
|
{//YPlane
|
|
LPBYTE pFrameY = NULL;
|
|
pFrame->get_Plane(0, &pFrameY);
|
|
long lFrameStrideY;
|
|
pFrame->get_Stride(0, &lFrameStrideY);
|
|
|
|
LPBYTE pPictureY = NULL;
|
|
pPicture->get_Plane(0, &pPictureY);
|
|
long lPictureStrideY;
|
|
pPicture->get_Stride(0, &lPictureStrideY);
|
|
|
|
LPBYTE pMaskPtr = pMaskPlane;
|
|
long lFramePitch = lFrameStrideY - lPictureWidth;
|
|
long lPicturePitch = lPictureStrideY - lPictureWidth;
|
|
long lMaskPitch = lMaskStride - lPictureWidth;
|
|
|
|
if (lLeft<0)
|
|
{
|
|
pMaskPtr -= lLeft;
|
|
pPictureY -= lLeft;
|
|
}
|
|
else
|
|
pFrameY += lLeft;
|
|
|
|
if (0!=(oFrameSetting.m_lColorSpace & CSP_VFLIP))
|
|
{
|
|
lFramePitch -= 2*lFrameStrideY;
|
|
lPicturePitch -= 2*lPictureStrideY;
|
|
pPictureY += (oPictureSetting.m_lHeight - 1)*lPictureStrideY;
|
|
pFrameY += (oFrameSetting.m_lHeight - 1)*lFrameStrideY;
|
|
if (lTop<0)
|
|
pPictureY += lTop*lPictureStrideY;
|
|
else
|
|
pFrameY -= lTop*lFrameStrideY;
|
|
}
|
|
else
|
|
{
|
|
if (lTop<0)
|
|
pPictureY -= lTop*lPictureStrideY;
|
|
else
|
|
pFrameY += lTop*lFrameStrideY;
|
|
}
|
|
|
|
if (0!=(lMaskColorSpace & CSP_VFLIP))
|
|
{
|
|
lMaskPitch -= 2*lMaskStride;
|
|
pMaskPtr += (oPictureSetting.m_lHeight-1)*lMaskStride;
|
|
if (lTop<0)
|
|
pMaskPtr += lTop*lMaskStride;
|
|
}
|
|
else
|
|
{
|
|
if (lTop<0)
|
|
pMaskPtr -= lTop*lMaskStride;
|
|
}
|
|
|
|
for (long lRow = 0; lRow<lPictureHeight; lRow++)
|
|
{
|
|
for (long lCol = 0; lCol<lPictureWidth; lCol++, pFrameY++, pPictureY++, pMaskPtr++)
|
|
{
|
|
*pFrameY = ((255-(*pMaskPtr))*(*pFrameY) + (*pMaskPtr)*(*pPictureY))/255;
|
|
}
|
|
pFrameY += lFramePitch;
|
|
pPictureY += lPicturePitch;
|
|
pMaskPtr += lMaskPitch;
|
|
}
|
|
}
|
|
|
|
{//UVPlane
|
|
LPBYTE pFrameU = NULL;
|
|
LPBYTE pFrameV = NULL;
|
|
pFrame->get_Plane(1, &pFrameU);
|
|
pFrame->get_Plane(2, &pFrameV);
|
|
long lFrameStrideU;
|
|
long lFrameStrideV;
|
|
pFrame->get_Stride(1, &lFrameStrideU);
|
|
pFrame->get_Stride(2, &lFrameStrideV);
|
|
|
|
|
|
LPBYTE pPictureU = NULL;
|
|
LPBYTE pPictureV = NULL;
|
|
pPicture->get_Plane(1, &pPictureU);
|
|
pPicture->get_Plane(2, &pPictureV);
|
|
|
|
long lPictureStrideU;
|
|
long lPictureStrideV;
|
|
pPicture->get_Stride(1, &lPictureStrideU);
|
|
pPicture->get_Stride(2, &lPictureStrideV);
|
|
|
|
LPBYTE pMaskPtr = pMaskPlane;
|
|
long lFramePitchU = lFrameStrideU - lPictureWidth/2;
|
|
long lFramePitchV = lFrameStrideV - lPictureWidth/2;
|
|
long lPicturePitchU = lPictureStrideU - lPictureWidth/2;
|
|
long lPicturePitchV = lPictureStrideV - lPictureWidth/2;
|
|
long lMaskPitch = 2*lMaskStride - lPictureWidth;
|
|
if (lLeft<0)
|
|
{
|
|
pMaskPtr -= lLeft;
|
|
pPictureU -= lLeft/2;
|
|
pPictureV -= lLeft/2;
|
|
}
|
|
else
|
|
{
|
|
pFrameU += lLeft/2;
|
|
pFrameV += lLeft/2;
|
|
}
|
|
if (0!=(oFrameSetting.m_lColorSpace & CSP_VFLIP))
|
|
{
|
|
lFramePitchU -= 2*lFrameStrideU;
|
|
lFramePitchV -= 2*lFrameStrideV;
|
|
lPicturePitchU -= 2*lPictureStrideU;
|
|
lPicturePitchV -= 2*lPictureStrideV;
|
|
|
|
pFrameU += lFrameStrideU*(oFrameSetting.m_lHeight/2 - 1);
|
|
pFrameV += lFrameStrideV*(oFrameSetting.m_lHeight/2 - 1);
|
|
|
|
pPictureU += (oPictureSetting.m_lHeight/2 - 1)*lPictureStrideU;
|
|
pPictureV += (oPictureSetting.m_lHeight/2 - 1)*lPictureStrideV;
|
|
|
|
if (lTop<0)
|
|
{
|
|
pPictureU += lTop/2*lPictureStrideU;
|
|
pPictureV += lTop/2*lPictureStrideV;
|
|
}
|
|
else
|
|
{
|
|
pFrameU -= lTop/2*lFrameStrideU;
|
|
pFrameV -= lTop/2*lFrameStrideV;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (lTop<0)
|
|
{
|
|
pPictureU -= lTop/2*lPictureStrideU;
|
|
pPictureV -= lTop/2*lPictureStrideV;
|
|
}
|
|
else
|
|
{
|
|
pFrameU += lTop/2*lFrameStrideU;
|
|
pFrameV += lTop/2*lFrameStrideV;
|
|
}
|
|
}
|
|
if (0!=(lMaskColorSpace & CSP_VFLIP))
|
|
{
|
|
lMaskPitch -= 4*lMaskStride;
|
|
pMaskPtr += (oPictureSetting.m_lHeight-1)*lMaskStride;
|
|
if (lTop<0)
|
|
pMaskPtr += lTop*lMaskStride;
|
|
}
|
|
else
|
|
{
|
|
if (lTop<0)
|
|
pMaskPtr -= lTop*lMaskStride;
|
|
}
|
|
|
|
//long lPictureTempWidth = lPictureWidth/2;
|
|
//if (lLeft<0)
|
|
// lPictureTempWidth += lLeft/2;
|
|
//long lPictureTempHeight = lPictureHeight/2;
|
|
//if (lTop<0)
|
|
// lPictureTempHeight += lTop/2;
|
|
for (long lRow = 0; lRow<lPictureHeight/2; lRow++)
|
|
{
|
|
for (long lCol = 0; lCol<lPictureWidth/2; lCol++, pFrameU++, pFrameV++, pPictureU++, pPictureV++, pMaskPtr+=2)
|
|
{
|
|
*pFrameU = ((255-(*pMaskPtr))*(*pFrameU) + (*pMaskPtr)*(*pPictureU))/255;
|
|
*pFrameV = ((255-(*pMaskPtr))*(*pFrameV) + (*pMaskPtr)*(*pPictureV))/255;
|
|
}
|
|
pFrameU += lFramePitchU;
|
|
pFrameV += lFramePitchV;
|
|
pPictureU += lPicturePitchU;
|
|
pPictureV += lPicturePitchV;
|
|
pMaskPtr += lMaskPitch;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CSP_YUY2:
|
|
{
|
|
if (lLeft<0)
|
|
lLeft = -(abs(lLeft)>>1)<<1;
|
|
else
|
|
lLeft = (lLeft>>1)<<1;
|
|
if (lTop<0)
|
|
lTop = -(abs(lTop)>>1)<<1;
|
|
else
|
|
lTop = (lTop>>1)<<1;
|
|
|
|
long lPictureWidth = (min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft)>>1)<<1;
|
|
if (lLeft<0)
|
|
lPictureWidth += lLeft;
|
|
long lPictureHeight = (min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop)>>1)<<1;
|
|
if (lTop<0)
|
|
lPictureHeight += lTop;
|
|
|
|
LPBYTE pMaskPlane = NULL;
|
|
pMask->get_Plane(0, &pMaskPlane);
|
|
long lMaskStride;
|
|
pMask->get_Stride(0, &lMaskStride);
|
|
|
|
LPBYTE pFramePtr = NULL;
|
|
pFrame->get_Plane(0, &pFramePtr);
|
|
long lFrameStride;
|
|
pFrame->get_Stride(0, &lFrameStride);
|
|
|
|
LPBYTE pPicturePtr = NULL;
|
|
pPicture->get_Plane(0, &pPicturePtr);
|
|
long lPictureStride;
|
|
pPicture->get_Stride(0, &lPictureStride);
|
|
|
|
LPBYTE pMaskPtr = pMaskPlane;
|
|
long lFramePitch = lFrameStride - 2*lPictureWidth;
|
|
long lPicturePitch = lPictureStride - 2*lPictureWidth;
|
|
long lMaskPitch = lMaskStride - lPictureWidth;
|
|
if (lLeft>=0)
|
|
pFramePtr += 2*lLeft;
|
|
else
|
|
{
|
|
pPicturePtr -= 2*lLeft;
|
|
pMaskPtr -= 2*lLeft;
|
|
}
|
|
|
|
if (0!=oFrameSetting.m_lColorSpace & CSP_VFLIP)
|
|
{
|
|
lFramePitch -= 2*lFrameStride;
|
|
lPicturePitch -= 2*lPictureStride;
|
|
pFramePtr += (oFrameSetting.m_lHeight - 1)*lFrameStride;
|
|
pPicturePtr += (oPictureSetting.m_lHeight - 1)*lPictureStride;
|
|
if (lTop>=0)
|
|
pFramePtr -= lTop * lFrameStride;
|
|
else
|
|
pPicturePtr += lTop * lPictureStride;
|
|
}
|
|
else
|
|
{
|
|
if (lTop>=0)
|
|
pFramePtr += lTop * lFrameStride;
|
|
else
|
|
pPicturePtr -= lTop * lPictureStride;
|
|
}
|
|
if (0!=lMaskColorSpace & CSP_VFLIP)
|
|
{
|
|
lMaskPitch -= 2*lMaskStride;
|
|
pMaskPtr += (oFrameSetting.m_lHeight-1)*lMaskStride;
|
|
if (lTop<0)
|
|
pMaskPtr += lTop*lMaskStride;
|
|
}
|
|
else
|
|
{
|
|
if (lTop<0)
|
|
pMaskPtr -= lTop*lMaskStride;
|
|
}
|
|
|
|
for (long lRow = 0; lRow<lPictureHeight; lRow++)
|
|
{
|
|
for (long lCol = 0; lCol<lPictureWidth; lCol++, pMaskPtr++)
|
|
{
|
|
*pFramePtr = ((255-(*pMaskPtr))*(*pFramePtr) + (*pMaskPtr)*(*pPicturePtr))/255;
|
|
pFramePtr++; pPicturePtr++;
|
|
*pFramePtr = ((255-(*pMaskPtr))*(*pFramePtr) + (*pMaskPtr)*(*pPicturePtr))/255;
|
|
pFramePtr++; pPicturePtr++;
|
|
}
|
|
pFramePtr += lFramePitch;
|
|
pPicturePtr += lPicturePitch;
|
|
pMaskPtr += lMaskPitch;
|
|
}
|
|
}
|
|
break;
|
|
case CSP_BGRA:
|
|
{
|
|
long lPictureWidth = min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft);
|
|
if (lLeft<0)
|
|
lPictureWidth += lLeft;
|
|
long lPictureHeight = min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop);
|
|
if (lTop<0)
|
|
lPictureHeight += lTop;
|
|
|
|
LPBYTE pMaskPlane = NULL;
|
|
pMask->get_Plane(0, &pMaskPlane);
|
|
long lMaskStride;
|
|
pMask->get_Stride(0, &lMaskStride);
|
|
|
|
LPBYTE pFramePtr = NULL;
|
|
pFrame->get_Plane(0, &pFramePtr);
|
|
long lFrameStride;
|
|
pFrame->get_Stride(0, &lFrameStride);
|
|
|
|
LPBYTE pPicturePtr = NULL;
|
|
pPicture->get_Plane(0, &pPicturePtr);
|
|
long lPictureStride;
|
|
pPicture->get_Stride(0, &lPictureStride);
|
|
|
|
LPBYTE pMaskPtr = pMaskPlane;
|
|
long lFramePitch = lFrameStride - 4*lPictureWidth;
|
|
long lPicturePitch = lPictureStride - 4*lPictureWidth;
|
|
long lMaskPitch = lMaskStride - lPictureWidth;
|
|
if (lLeft>=0)
|
|
pFramePtr += 4*lLeft;
|
|
else
|
|
{
|
|
pPicturePtr -= 4*lLeft;
|
|
pMaskPtr -= lLeft;
|
|
}
|
|
|
|
if (0!=oFrameSetting.m_lColorSpace & CSP_VFLIP)
|
|
{
|
|
lFramePitch -= 2*lFrameStride;
|
|
lPicturePitch -= 2*lPictureStride;
|
|
pFramePtr += (oFrameSetting.m_lHeight - 1)*lFrameStride;
|
|
pPicturePtr += (oPictureSetting.m_lHeight - 1)*lPictureStride;
|
|
if (lTop>=0)
|
|
pFramePtr -= lTop*lFrameStride;
|
|
else
|
|
pPicturePtr += lTop*lPictureStride;
|
|
}
|
|
else
|
|
{
|
|
if (lTop>=0)
|
|
pFramePtr += lTop*lFrameStride;
|
|
else
|
|
pPicturePtr -= lTop*lPictureStride;
|
|
}
|
|
if (0!=lMaskColorSpace & CSP_VFLIP)
|
|
{
|
|
lMaskPitch -= 2*lMaskStride;
|
|
pMaskPtr += (oFrameSetting.m_lHeight-1)*lMaskStride;
|
|
if (lTop<0)
|
|
pMaskPtr += lTop*lMaskStride;
|
|
}
|
|
else
|
|
{
|
|
if (lTop<0)
|
|
pMaskPtr -= lTop*lMaskStride;
|
|
}
|
|
|
|
for (long lRow = 0; lRow<lPictureHeight; lRow++)
|
|
{
|
|
for (long lCol = 0; lCol<lPictureWidth; lCol++, pMaskPtr++)
|
|
{
|
|
*pFramePtr = ((255-(*pMaskPtr))*(*pFramePtr) + (*pMaskPtr)*(*pPicturePtr))/255;
|
|
pFramePtr++; pPicturePtr++;
|
|
*pFramePtr = ((255-(*pMaskPtr))*(*pFramePtr) + (*pMaskPtr)*(*pPicturePtr))/255;
|
|
pFramePtr++; pPicturePtr++;
|
|
*pFramePtr = ((255-(*pMaskPtr))*(*pFramePtr) + (*pMaskPtr)*(*pPicturePtr))/255;
|
|
pFramePtr++; pPicturePtr++;
|
|
pFramePtr++; pPicturePtr++;
|
|
}
|
|
pFramePtr += lFramePitch;
|
|
pPicturePtr += lPicturePitch;
|
|
pMaskPtr += lMaskPitch;
|
|
}
|
|
}
|
|
break;
|
|
case CSP_BGR:
|
|
{
|
|
long lPictureWidth = min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft);
|
|
if (lLeft<0)
|
|
lPictureWidth += lLeft;
|
|
long lPictureHeight = min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop);
|
|
if (lTop<0)
|
|
lPictureHeight += lTop;
|
|
|
|
LPBYTE pMaskPlane = NULL;
|
|
pMask->get_Plane(0, &pMaskPlane);
|
|
long lMaskStride;
|
|
pMask->get_Stride(0, &lMaskStride);
|
|
|
|
LPBYTE pFramePtr = NULL;
|
|
pFrame->get_Plane(0, &pFramePtr);
|
|
long lFrameStride;
|
|
pFrame->get_Stride(0, &lFrameStride);
|
|
|
|
LPBYTE pPicturePtr = NULL;
|
|
pPicture->get_Plane(0, &pPicturePtr);
|
|
long lPictureStride;
|
|
pPicture->get_Stride(0, &lPictureStride);
|
|
|
|
LPBYTE pMaskPtr = pMaskPlane;
|
|
long lFramePitch = lFrameStride - 3*lPictureWidth;
|
|
long lPicturePitch = lPictureStride - 3*lPictureWidth;
|
|
long lMaskPitch = lMaskStride - lPictureWidth;
|
|
if (lLeft>=0)
|
|
pFramePtr += 3*lLeft;
|
|
else
|
|
{
|
|
pPicturePtr -= 3*lLeft;
|
|
pMaskPtr -= lLeft;
|
|
}
|
|
|
|
if (0!=oFrameSetting.m_lColorSpace & CSP_VFLIP)
|
|
{
|
|
lFramePitch -= 2*lFrameStride;
|
|
lPicturePitch -= 2*lPictureStride;
|
|
pFramePtr += (oFrameSetting.m_lHeight - 1)*lFrameStride;
|
|
pPicturePtr += (oPictureSetting.m_lHeight - 1)*lPictureStride;
|
|
if (lTop>=0)
|
|
pFramePtr -= lTop*lFrameStride;
|
|
else
|
|
pPicturePtr += lTop*lPictureStride;
|
|
}
|
|
else
|
|
{
|
|
if (lTop>=0)
|
|
pFramePtr += lTop*lFrameStride;
|
|
else
|
|
pPicturePtr -= lTop*lPictureStride;
|
|
}
|
|
if (0!=lMaskColorSpace & CSP_VFLIP)
|
|
{
|
|
lMaskPitch -= 2*lMaskStride;
|
|
pMaskPtr += (oFrameSetting.m_lHeight-1)*lMaskStride;
|
|
if (lTop<0)
|
|
pMaskPtr += lTop*lMaskStride;
|
|
}
|
|
else
|
|
{
|
|
if (lTop<0)
|
|
pMaskPtr -= lTop*lMaskStride;
|
|
}
|
|
|
|
for (long lRow = 0; lRow<lPictureHeight; lRow++)
|
|
{
|
|
for (long lCol = 0; lCol<lPictureWidth; lCol++, pMaskPtr++)
|
|
{
|
|
*pFramePtr = ((255-(*pMaskPtr))*(*pFramePtr) + (*pMaskPtr)*(*pPicturePtr))/255;
|
|
pFramePtr++; pPicturePtr++;
|
|
*pFramePtr = ((255-(*pMaskPtr))*(*pFramePtr) + (*pMaskPtr)*(*pPicturePtr))/255;
|
|
pFramePtr++; pPicturePtr++;
|
|
*pFramePtr = ((255-(*pMaskPtr))*(*pFramePtr) + (*pMaskPtr)*(*pPicturePtr))/255;
|
|
pFramePtr++; pPicturePtr++;
|
|
}
|
|
pFramePtr += lFramePitch;
|
|
pPicturePtr += lPicturePitch;
|
|
pMaskPtr += lMaskPitch;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
static void DrawInner(IAVSUncompressedVideoFrame* pFrame, long lLeft, long lTop, IAVSUncompressedVideoFrame* pPicture)
|
|
{
|
|
SFrameSetting oFrameSetting;
|
|
GetFrameProperties(pFrame, oFrameSetting);
|
|
SFrameSetting oPictureSetting;
|
|
GetFrameProperties(pPicture, oPictureSetting);
|
|
|
|
switch (oFrameSetting.m_lColorSpace & CSP_COLOR_MASK)
|
|
{
|
|
case CSP_I420:
|
|
case CSP_YV12:
|
|
{
|
|
if (lLeft<0)
|
|
lLeft = -(abs(lLeft)>>1)<<1;
|
|
else
|
|
lLeft = (lLeft>>1)<<1;
|
|
if (lTop<0)
|
|
lTop = -(abs(lTop)>>1)<<1;
|
|
else
|
|
lTop = (lTop>>1)<<1;
|
|
|
|
long lPictureWidth = (min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft)>>1)<<1;
|
|
if (lLeft<0)
|
|
lPictureWidth += lLeft;
|
|
long lPictureHeight = (min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop)>>1)<<1;
|
|
if (lTop<0)
|
|
lPictureHeight += lTop;
|
|
|
|
{//YPlane
|
|
LPBYTE pFrameY = NULL;
|
|
pFrame->get_Plane(0, &pFrameY);
|
|
long lFrameStrideY;
|
|
pFrame->get_Stride(0, &lFrameStrideY);
|
|
|
|
LPBYTE pPictureY = NULL;
|
|
pPicture->get_Plane(0, &pPictureY);
|
|
long lPictureStrideY;
|
|
pPicture->get_Stride(0, &lPictureStrideY);
|
|
|
|
long lFramePitch = lFrameStrideY;
|
|
long lPicturePitch = lPictureStrideY;
|
|
|
|
if (lLeft<0)
|
|
pPictureY -= lLeft;
|
|
else
|
|
pFrameY += lLeft;
|
|
|
|
if (0!=(oFrameSetting.m_lColorSpace & CSP_VFLIP))
|
|
{
|
|
lFramePitch -= 2*lFrameStrideY;
|
|
lPicturePitch -= 2*lPictureStrideY;
|
|
pPictureY += (oPictureSetting.m_lHeight - 1)*lPictureStrideY;
|
|
pFrameY += (oFrameSetting.m_lHeight - 1)*lFrameStrideY;
|
|
if (lTop<0)
|
|
pPictureY += lTop*lPictureStrideY;
|
|
else
|
|
pFrameY -= lTop*lFrameStrideY;
|
|
}
|
|
else
|
|
{
|
|
if (lTop<0)
|
|
pPictureY -= lTop*lPictureStrideY;
|
|
else
|
|
pFrameY += lTop*lFrameStrideY;
|
|
}
|
|
|
|
|
|
for (long lRow = 0; lRow<lPictureHeight; lRow++)
|
|
{
|
|
memcpy(pFrameY, pPictureY, lPictureWidth);
|
|
pFrameY += lFramePitch;
|
|
pPictureY += lPicturePitch;
|
|
}
|
|
}
|
|
|
|
{//UVPlane
|
|
LPBYTE pFrameU = NULL;
|
|
LPBYTE pFrameV = NULL;
|
|
pFrame->get_Plane(1, &pFrameU);
|
|
pFrame->get_Plane(2, &pFrameV);
|
|
long lFrameStrideU;
|
|
long lFrameStrideV;
|
|
pFrame->get_Stride(1, &lFrameStrideU);
|
|
pFrame->get_Stride(2, &lFrameStrideV);
|
|
|
|
|
|
LPBYTE pPictureU = NULL;
|
|
LPBYTE pPictureV = NULL;
|
|
pPicture->get_Plane(1, &pPictureU);
|
|
pPicture->get_Plane(2, &pPictureV);
|
|
|
|
long lPictureStrideU;
|
|
long lPictureStrideV;
|
|
pPicture->get_Stride(1, &lPictureStrideU);
|
|
pPicture->get_Stride(2, &lPictureStrideV);
|
|
|
|
long lFramePitchU = lFrameStrideU;
|
|
long lFramePitchV = lFrameStrideV;
|
|
long lPicturePitchU = lPictureStrideU;
|
|
long lPicturePitchV = lPictureStrideV;
|
|
if (lLeft<0)
|
|
{
|
|
pPictureU -= lLeft/2;
|
|
pPictureV -= lLeft/2;
|
|
}
|
|
else
|
|
{
|
|
pFrameU += lLeft/2;
|
|
pFrameV += lLeft/2;
|
|
}
|
|
if (0!=(oFrameSetting.m_lColorSpace & CSP_VFLIP))
|
|
{
|
|
lFramePitchU -= 2*lFrameStrideU;
|
|
lFramePitchV -= 2*lFrameStrideV;
|
|
lPicturePitchU -= 2*lPictureStrideU;
|
|
lPicturePitchV -= 2*lPictureStrideV;
|
|
|
|
pFrameU += lFrameStrideU*(oFrameSetting.m_lHeight/2 - 1);
|
|
pFrameV += lFrameStrideV*(oFrameSetting.m_lHeight/2 - 1);
|
|
|
|
pPictureU += (oPictureSetting.m_lHeight/2 - 1)*lPictureStrideU;
|
|
pPictureV += (oPictureSetting.m_lHeight/2 - 1)*lPictureStrideV;
|
|
|
|
if (lTop<0)
|
|
{
|
|
pPictureU += lTop/2*lPictureStrideU;
|
|
pPictureV += lTop/2*lPictureStrideV;
|
|
}
|
|
else
|
|
{
|
|
pFrameU -= lTop/2*lFrameStrideU;
|
|
pFrameV -= lTop/2*lFrameStrideV;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (lTop<0)
|
|
{
|
|
pPictureU -= lTop/2*lPictureStrideU;
|
|
pPictureV -= lTop/2*lPictureStrideV;
|
|
}
|
|
else
|
|
{
|
|
pFrameU += lTop/2*lFrameStrideU;
|
|
pFrameV += lTop/2*lFrameStrideV;
|
|
}
|
|
}
|
|
for (long lRow = 0; lRow<lPictureHeight/2; lRow++)
|
|
{
|
|
memcpy(pFrameU, pPictureU, lPictureWidth/2);
|
|
memcpy(pFrameV, pPictureV, lPictureWidth/2);
|
|
pFrameU += lFramePitchU;
|
|
pFrameV += lFramePitchV;
|
|
pPictureU += lPicturePitchU;
|
|
pPictureV += lPicturePitchV;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CSP_YUY2:
|
|
{
|
|
if (lLeft<0)
|
|
lLeft = -(abs(lLeft)>>1)<<1;
|
|
else
|
|
lLeft = (lLeft>>1)<<1;
|
|
if (lTop<0)
|
|
lTop = -(abs(lTop)>>1)<<1;
|
|
else
|
|
lTop = (lTop>>1)<<1;
|
|
|
|
long lPictureWidth = (min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft)>>1)<<1;
|
|
if (lLeft<0)
|
|
lPictureWidth += lLeft;
|
|
long lPictureHeight = (min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop)>>1)<<1;
|
|
if (lTop<0)
|
|
lPictureHeight += lTop;
|
|
|
|
LPBYTE pFramePtr = NULL;
|
|
pFrame->get_Plane(0, &pFramePtr);
|
|
long lFrameStride;
|
|
pFrame->get_Stride(0, &lFrameStride);
|
|
|
|
LPBYTE pPicturePtr = NULL;
|
|
pPicture->get_Plane(0, &pPicturePtr);
|
|
long lPictureStride;
|
|
pPicture->get_Stride(0, &lPictureStride);
|
|
|
|
long lFramePitch = lFrameStride;
|
|
long lPicturePitch = lPictureStride;
|
|
if (lLeft>=0)
|
|
pFramePtr += 2*lLeft;
|
|
else
|
|
pPicturePtr -= 2*lLeft;
|
|
|
|
if (0!=oFrameSetting.m_lColorSpace & CSP_VFLIP)
|
|
{
|
|
lFramePitch -= 2*lFrameStride;
|
|
lPicturePitch -= 2*lPictureStride;
|
|
pFramePtr += (oFrameSetting.m_lHeight - 1)*lFrameStride;
|
|
pPicturePtr += (oPictureSetting.m_lHeight - 1)*lPictureStride;
|
|
if (lTop>=0)
|
|
pFramePtr -= lTop * lFrameStride;
|
|
else
|
|
pPicturePtr += lTop * lPictureStride;
|
|
}
|
|
else
|
|
{
|
|
if (lTop>=0)
|
|
pFramePtr += lTop * lFrameStride;
|
|
else
|
|
pPicturePtr -= lTop * lPictureStride;
|
|
}
|
|
for (long lRow = 0; lRow<lPictureHeight; lRow++)
|
|
{
|
|
memcpy(pFramePtr, pPicturePtr, 2*lPictureWidth);
|
|
pFramePtr += lFramePitch;
|
|
pPicturePtr += lPicturePitch;
|
|
}
|
|
}
|
|
break;
|
|
case CSP_BGRA:
|
|
{
|
|
long lPictureWidth = min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft);
|
|
if (lLeft<0)
|
|
lPictureWidth += lLeft;
|
|
long lPictureHeight = min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop);
|
|
if (lTop<0)
|
|
lPictureHeight += lTop;
|
|
|
|
|
|
LPBYTE pFramePtr = NULL;
|
|
pFrame->get_Plane(0, &pFramePtr);
|
|
long lFrameStride;
|
|
pFrame->get_Stride(0, &lFrameStride);
|
|
|
|
LPBYTE pPicturePtr = NULL;
|
|
pPicture->get_Plane(0, &pPicturePtr);
|
|
long lPictureStride;
|
|
pPicture->get_Stride(0, &lPictureStride);
|
|
|
|
long lFramePitch = lFrameStride;
|
|
long lPicturePitch = lPictureStride;
|
|
if (lLeft>=0)
|
|
pFramePtr += 4*lLeft;
|
|
else
|
|
pPicturePtr -= 4*lLeft;
|
|
|
|
if (0!=oFrameSetting.m_lColorSpace & CSP_VFLIP)
|
|
{
|
|
lFramePitch -= 2*lFrameStride;
|
|
lPicturePitch -= 2*lPictureStride;
|
|
pFramePtr += (oFrameSetting.m_lHeight - 1)*lFrameStride;
|
|
pPicturePtr += (oPictureSetting.m_lHeight - 1)*lPictureStride;
|
|
if (lTop>=0)
|
|
pFramePtr -= lTop*lFrameStride;
|
|
else
|
|
pPicturePtr += lTop*lPictureStride;
|
|
}
|
|
else
|
|
{
|
|
if (lTop>=0)
|
|
pFramePtr += lTop*lFrameStride;
|
|
else
|
|
pPicturePtr -= lTop*lPictureStride;
|
|
}
|
|
for (long lRow = 0; lRow<lPictureHeight; lRow++)
|
|
{
|
|
memcpy(pFramePtr, pPicturePtr, 4*lPictureWidth);
|
|
pFramePtr += lFramePitch;
|
|
pPicturePtr += lPicturePitch;
|
|
}
|
|
}
|
|
break;
|
|
case CSP_BGR:
|
|
{
|
|
long lPictureWidth = min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft);
|
|
if (lLeft<0)
|
|
lPictureWidth += lLeft;
|
|
long lPictureHeight = min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop);
|
|
if (lTop<0)
|
|
lPictureHeight += lTop;
|
|
|
|
LPBYTE pFramePtr = NULL;
|
|
pFrame->get_Plane(0, &pFramePtr);
|
|
long lFrameStride;
|
|
pFrame->get_Stride(0, &lFrameStride);
|
|
|
|
LPBYTE pPicturePtr = NULL;
|
|
pPicture->get_Plane(0, &pPicturePtr);
|
|
long lPictureStride;
|
|
pPicture->get_Stride(0, &lPictureStride);
|
|
|
|
long lFramePitch = lFrameStride;
|
|
long lPicturePitch = lPictureStride;
|
|
if (lLeft>=0)
|
|
pFramePtr += 3*lLeft;
|
|
else
|
|
pPicturePtr -= 3*lLeft;
|
|
|
|
if (0!=oFrameSetting.m_lColorSpace & CSP_VFLIP)
|
|
{
|
|
lFramePitch -= 2*lFrameStride;
|
|
lPicturePitch -= 2*lPictureStride;
|
|
pFramePtr += (oFrameSetting.m_lHeight - 1)*lFrameStride;
|
|
pPicturePtr += (oPictureSetting.m_lHeight - 1)*lPictureStride;
|
|
if (lTop>=0)
|
|
pFramePtr -= lTop*lFrameStride;
|
|
else
|
|
pPicturePtr += lTop*lPictureStride;
|
|
}
|
|
else
|
|
{
|
|
if (lTop>=0)
|
|
pFramePtr += lTop*lFrameStride;
|
|
else
|
|
pPicturePtr -= lTop*lPictureStride;
|
|
}
|
|
for (long lRow = 0; lRow<lPictureHeight; lRow++)
|
|
{
|
|
memcpy(pFramePtr, pPicturePtr, 3*lPictureWidth);
|
|
pFramePtr += lFramePitch;
|
|
pPicturePtr += lPicturePitch;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
static void DrawSimpleInner(IAVSUncompressedVideoFrame* pFrame, long lLeft, long lTop, IAVSUncompressedVideoFrame* pPicture, long lColorKey)
|
|
{
|
|
SFrameSetting oFrameSetting;
|
|
GetFrameProperties(pFrame, oFrameSetting);
|
|
SFrameSetting oPictureSetting;
|
|
GetFrameProperties(pPicture, oPictureSetting);
|
|
|
|
switch (oFrameSetting.m_lColorSpace & CSP_COLOR_MASK)
|
|
{
|
|
case CSP_I420:
|
|
case CSP_YV12:
|
|
{
|
|
BYTE nYColorKey = (lColorKey>>16)&0xFF;
|
|
BYTE nUColorKey = (lColorKey>>8)&0xFF;
|
|
BYTE nVColorKey = (lColorKey)&0xFF;
|
|
if (CSP_YV12 == (oFrameSetting.m_lColorSpace & CSP_COLOR_MASK))
|
|
{
|
|
BYTE nTemp = nUColorKey;
|
|
nUColorKey = nVColorKey;
|
|
nVColorKey = nTemp;
|
|
}
|
|
lLeft = (lLeft>>1)<<1;
|
|
lTop = (lTop>>1)<<1;
|
|
|
|
long lPictureWidth = (min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft)>>1)<<1;
|
|
long lPictureHeight = (min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop)>>1)<<1;
|
|
|
|
LPBYTE pFrameYFirst = NULL;
|
|
pFrame->get_Plane(0, &pFrameYFirst);
|
|
long lFrameStrideY;
|
|
pFrame->get_Stride(0, &lFrameStrideY);
|
|
LPBYTE pFrameYSecond = NULL;
|
|
|
|
LPBYTE pFrameU = NULL;
|
|
LPBYTE pFrameV = NULL;
|
|
pFrame->get_Plane(1, &pFrameU);
|
|
pFrame->get_Plane(2, &pFrameV);
|
|
long lFrameStrideU;
|
|
long lFrameStrideV;
|
|
pFrame->get_Stride(1, &lFrameStrideU);
|
|
pFrame->get_Stride(2, &lFrameStrideV);
|
|
|
|
LPBYTE pPictureYFirst = NULL;
|
|
pPicture->get_Plane(0, &pPictureYFirst);
|
|
long lPictureStrideY;
|
|
pPicture->get_Stride(0, &lPictureStrideY);
|
|
LPBYTE pPictureU = NULL;
|
|
LPBYTE pPictureV = NULL;
|
|
pPicture->get_Plane(1, &pPictureU);
|
|
pPicture->get_Plane(2, &pPictureV);
|
|
long lPictureStrideU;
|
|
long lPictureStrideV;
|
|
pPicture->get_Stride(1, &lPictureStrideU);
|
|
pPicture->get_Stride(2, &lPictureStrideV);
|
|
LPBYTE pPictureYSecond = pPictureYFirst + lPictureStrideY;
|
|
|
|
|
|
long lFramePitchY = 2*lFrameStrideY - lPictureWidth;
|
|
long lFramePitchU = lFrameStrideU - lPictureWidth/2;
|
|
long lFramePitchV = lFrameStrideV - lPictureWidth/2;
|
|
|
|
long lPicturePitchY = 2*lPictureStrideY - lPictureWidth;
|
|
long lPicturePitchU = lPictureStrideU - lPictureWidth/2;
|
|
long lPicturePitchV = lPictureStrideV - lPictureWidth/2;
|
|
if (0!=oFrameSetting.m_lColorSpace & CSP_VFLIP)
|
|
{
|
|
lFramePitchY -= 4*lFrameStrideY;
|
|
lFramePitchU -= 2*lFrameStrideU;
|
|
lFramePitchV -= 2*lFrameStrideV;
|
|
|
|
lPicturePitchY -= 4*lPictureStrideY;
|
|
lPicturePitchU -= 2*lPictureStrideU;
|
|
lPicturePitchV -= 2*lPictureStrideV;
|
|
|
|
pFrameYFirst += lLeft + (oFrameSetting.m_lHeight - 1 - lTop)*lFrameStrideY;
|
|
pFrameYSecond = pFrameYFirst - lFrameStrideY;
|
|
pFrameU += lLeft/2 + lFrameStrideU*(oFrameSetting.m_lHeight/2 - 1 - lTop/2);
|
|
pFrameV += lLeft/2 + lFrameStrideV*(oFrameSetting.m_lHeight/2 - 1 - lTop/2);
|
|
|
|
pPictureYFirst += (oPictureSetting.m_lHeight - 1)*lPictureStrideY;
|
|
pPictureYSecond = pPictureYFirst - lPictureStrideY;
|
|
pPictureU += (oPictureSetting.m_lHeight/2 - 1)*lPictureStrideU;
|
|
pPictureV += (oPictureSetting.m_lHeight/2 - 1)*lPictureStrideV;
|
|
}
|
|
else
|
|
{
|
|
pFrameYFirst += lLeft + lTop*lFrameStrideY;
|
|
pFrameYSecond = pFrameYFirst + lFrameStrideY;
|
|
pFrameU += lLeft/2 + lFrameStrideU*lTop/2;
|
|
pFrameV += lLeft/2 + lFrameStrideV*lTop/2;
|
|
}
|
|
|
|
for (long lRow = 0; lRow<lPictureHeight/2; lRow++)
|
|
{
|
|
for (long lCol = 0; lCol<lPictureWidth/2; lCol++)
|
|
{
|
|
if ((nUColorKey!=(*pPictureU))||(nVColorKey!=(*pPictureV))||
|
|
( (nYColorKey!=(*pPictureYFirst))&&(nYColorKey!=(*(pPictureYFirst+1)))&&
|
|
(nYColorKey!=(*pPictureYSecond))&&(nYColorKey!=(*(pPictureYSecond+1)))))
|
|
{
|
|
*pFrameYFirst = *pPictureYFirst;
|
|
pFrameYFirst++; pPictureYFirst++;
|
|
*pFrameYFirst = *pPictureYFirst;
|
|
pFrameYFirst++; pPictureYFirst++;
|
|
|
|
*pFrameYSecond = *pPictureYSecond;
|
|
pFrameYSecond++; pPictureYSecond++;
|
|
*pFrameYSecond = *pPictureYSecond;
|
|
pFrameYSecond++; pPictureYSecond++;
|
|
|
|
*pFrameU = *pPictureU;
|
|
pFrameU++; pPictureU++;
|
|
*pFrameV = *pPictureV;
|
|
pFrameV++; pPictureV++;
|
|
}
|
|
else
|
|
{
|
|
pFrameYFirst+=2; pPictureYFirst+=2;
|
|
pFrameYSecond+=2; pPictureYSecond+=2;
|
|
pFrameU++; pPictureU++;
|
|
pFrameV++; pPictureV++;
|
|
}
|
|
}
|
|
pFrameYFirst += lFramePitchY;
|
|
pFrameYSecond += lFramePitchY;
|
|
pFrameU += lFramePitchU;
|
|
pFrameV += lFramePitchV;
|
|
pPictureYFirst += lPicturePitchY;
|
|
pPictureYSecond += lPicturePitchY;
|
|
pPictureU += lPicturePitchU;
|
|
pPictureV += lPicturePitchV;
|
|
}
|
|
}
|
|
break;
|
|
case CSP_YUY2:
|
|
{
|
|
lLeft = (lLeft>>1)<<1;
|
|
lTop = (lTop>>1)<<1;
|
|
|
|
long lPictureWidth = (min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft)>>1)<<1;
|
|
long lPictureHeight = (min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop)>>1)<<1;
|
|
|
|
LPBYTE pFramePtr = NULL;
|
|
pFrame->get_Plane(0, &pFramePtr);
|
|
long lFrameStride;
|
|
pFrame->get_Stride(0, &lFrameStride);
|
|
|
|
LPBYTE pPicturePtr = NULL;
|
|
pPicture->get_Plane(0, &pPicturePtr);
|
|
long lPictureStride;
|
|
pPicture->get_Stride(0, &lPictureStride);
|
|
|
|
long lFramePitch = lFrameStride - 2*lPictureWidth;
|
|
long lPicturePitch = lPictureStride - 2*lPictureWidth;
|
|
if (0!=oFrameSetting.m_lColorSpace & CSP_VFLIP)
|
|
{
|
|
lFramePitch -= 2*lFrameStride;
|
|
lPicturePitch -= 2*lPictureStride;
|
|
pFramePtr += 2*lLeft + (oFrameSetting.m_lHeight - 1 - lTop)*lFrameStride;
|
|
pPicturePtr += (oPictureSetting.m_lHeight - 1)*lPictureStride;
|
|
}
|
|
else
|
|
{
|
|
pFramePtr += 2*lLeft + lTop*lFrameStride;
|
|
}
|
|
for (long lRow = 0; lRow<lPictureHeight; lRow++)
|
|
{
|
|
for (long lCol = 0; lCol<lPictureWidth; lCol++)
|
|
{
|
|
*pFramePtr = *pPicturePtr;
|
|
pFramePtr++; pPicturePtr++;
|
|
*pFramePtr = *pPicturePtr;
|
|
pFramePtr++; pPicturePtr++;
|
|
}
|
|
pFramePtr += lFramePitch;
|
|
pPicturePtr += lPicturePitch;
|
|
}
|
|
}
|
|
break;
|
|
case CSP_BGRA:
|
|
{
|
|
long lPictureWidth = min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft);
|
|
long lPictureHeight = min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop);
|
|
|
|
LPBYTE pFramePtr = NULL;
|
|
pFrame->get_Plane(0, &pFramePtr);
|
|
long lFrameStride;
|
|
pFrame->get_Stride(0, &lFrameStride);
|
|
|
|
LPBYTE pPicturePtr = NULL;
|
|
pPicture->get_Plane(0, &pPicturePtr);
|
|
long lPictureStride;
|
|
pPicture->get_Stride(0, &lPictureStride);
|
|
|
|
long lFramePitch = lFrameStride - 4*lPictureWidth;
|
|
long lPicturePitch = lPictureStride - 4*lPictureWidth;
|
|
if (0!=oFrameSetting.m_lColorSpace & CSP_VFLIP)
|
|
{
|
|
lFramePitch -= 2*lFrameStride;
|
|
lPicturePitch -= 2*lPictureStride;
|
|
pFramePtr += 4*lLeft + (oFrameSetting.m_lHeight - 1 - lTop)*lFrameStride;
|
|
pPicturePtr += (oPictureSetting.m_lHeight - 1)*lPictureStride;
|
|
}
|
|
else
|
|
{
|
|
pFramePtr += 4*lLeft + lTop*lFrameStride;
|
|
}
|
|
for (long lRow = 0; lRow<lPictureHeight; lRow++)
|
|
{
|
|
for (long lCol = 0; lCol<lPictureWidth; lCol++, pFramePtr+=4, pPicturePtr+=4)
|
|
{
|
|
if (((*(LPDWORD)pPicturePtr)&0xFFFFFF)!=lColorKey)
|
|
memcpy(pFramePtr, pPicturePtr, 3);
|
|
}
|
|
pFramePtr += lFramePitch;
|
|
pPicturePtr += lPicturePitch;
|
|
}
|
|
}
|
|
break;
|
|
case CSP_BGR:
|
|
{
|
|
long lPictureWidth = min(oPictureSetting.m_lWidth, oFrameSetting.m_lWidth - lLeft);
|
|
long lPictureHeight = min(oPictureSetting.m_lHeight, oFrameSetting.m_lHeight - lTop);
|
|
|
|
LPBYTE pFramePtr = NULL;
|
|
pFrame->get_Plane(0, &pFramePtr);
|
|
long lFrameStride;
|
|
pFrame->get_Stride(0, &lFrameStride);
|
|
|
|
LPBYTE pPicturePtr = NULL;
|
|
pPicture->get_Plane(0, &pPicturePtr);
|
|
long lPictureStride;
|
|
pPicture->get_Stride(0, &lPictureStride);
|
|
|
|
long lFramePitch = lFrameStride - 3*lPictureWidth;
|
|
long lPicturePitch = lPictureStride - 3*lPictureWidth;
|
|
if (0!=oFrameSetting.m_lColorSpace & CSP_VFLIP)
|
|
{
|
|
lFramePitch -= 2*lFrameStride;
|
|
lPicturePitch -= 2*lPictureStride;
|
|
pFramePtr += 3*lLeft + (oFrameSetting.m_lHeight - 1 - lTop)*lFrameStride;
|
|
pPicturePtr += (oPictureSetting.m_lHeight - 1)*lPictureStride;
|
|
}
|
|
else
|
|
{
|
|
pFramePtr += 3*lLeft + lTop*lFrameStride;
|
|
}
|
|
for (long lRow = 0; lRow<lPictureHeight; lRow++)
|
|
{
|
|
for (long lCol = 0; lCol<lPictureWidth; lCol++, pFramePtr+=3, pPicturePtr+=3)
|
|
{
|
|
if (((*(LPDWORD)pPicturePtr)&0xFFFFFF)!=lColorKey)
|
|
memcpy(pFramePtr, pPicturePtr, 3);
|
|
}
|
|
pFramePtr += lFramePitch;
|
|
pPicturePtr += lPicturePitch;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static BOOL IsEqualColorSpace(long lColorSpace1, long lColorSpace2)
|
|
{
|
|
lColorSpace1 &= CSP_COLOR_MASK;
|
|
lColorSpace2 &= CSP_COLOR_MASK;
|
|
if (((CSP_BGRA==lColorSpace1)||(CSP_BGR==lColorSpace1))&&
|
|
((CSP_BGRA==lColorSpace2)||(CSP_BGR==lColorSpace2)))
|
|
return TRUE;
|
|
|
|
if (((CSP_I420==lColorSpace1)||(CSP_YV12==lColorSpace1)||(CSP_YUY2==lColorSpace1))&&
|
|
((CSP_I420==lColorSpace2)||(CSP_YV12==lColorSpace2)||(CSP_YUY2==lColorSpace2)))
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
static BOOL IsYUVColorSpace(long lColorSpace)
|
|
{
|
|
lColorSpace &= CSP_COLOR_MASK;
|
|
return ((CSP_I420==lColorSpace)||(CSP_YV12==lColorSpace)||(CSP_YUY2==lColorSpace));
|
|
}
|
|
static BOOL IsRGBColorSpace(long lColorSpace)
|
|
{
|
|
lColorSpace &= CSP_COLOR_MASK;
|
|
return ((CSP_BGRA==lColorSpace)||(CSP_BGR==lColorSpace));
|
|
}
|
|
|
|
long ConvertColorKey(long lColorKey, long lSrcColorSpace, long lDstColorSpace)
|
|
{
|
|
if (IsEqualColorSpace(lSrcColorSpace, lDstColorSpace))
|
|
return lColorKey;
|
|
if (IsYUVColorSpace(lSrcColorSpace))
|
|
{
|
|
IAVSVideoFrameTransform *pTransform = NULL;
|
|
CoCreateInstance(__uuidof(CAVSVideoFrameTransform), NULL, CLSCTX_ALL, __uuidof(IAVSVideoFrameTransform), (void**)&pTransform);
|
|
if (NULL==pTransform)
|
|
return S_FALSE;
|
|
MediaFormat::IAVSVideoFormat *pFormat = NULL;
|
|
CoCreateInstance(MediaFormat::CLSID_CAVSVideoFormat, NULL, CLSCTX_ALL, MediaFormat::IID_IAVSVideoFormat, (void**)&pFormat);
|
|
if (NULL==pFormat)
|
|
{
|
|
pTransform->Release();
|
|
return S_FALSE;
|
|
}
|
|
pTransform->put_DeinterlaceEnabled(FALSE);
|
|
pTransform->put_CropScale(0);
|
|
|
|
pFormat->put_ColorSpace(CSP_BGRA);
|
|
pFormat->put_Width(2);
|
|
pFormat->put_Height(2);
|
|
pFormat->put_AspectRatioX(0);
|
|
pFormat->put_AspectRatioY(0);
|
|
pTransform->SetVideoFormat(pFormat);
|
|
RELEASEINTERFACE(pFormat);
|
|
|
|
IAVSUncompressedVideoFrame *pTestFrameSrc = NULL;
|
|
CoCreateInstance(__uuidof(CAVSUncompressedVideoFrame), NULL, CLSCTX_ALL, __uuidof(IAVSUncompressedVideoFrame), (void**)&pTestFrameSrc);
|
|
pTestFrameSrc->put_ColorSpace(CSP_I420);
|
|
pTestFrameSrc->put_Width(2);
|
|
pTestFrameSrc->put_Height(2);
|
|
pTestFrameSrc->put_AspectRatioX(0);
|
|
pTestFrameSrc->put_AspectRatioY(0);
|
|
pTestFrameSrc->SetDefaultStrides();
|
|
pTestFrameSrc->AllocateBuffer(-1);
|
|
BYTE nYColor = (lColorKey>>16) & 0xFF;
|
|
BYTE nUColor = (lColorKey>>8) & 0xFF;
|
|
BYTE nVColor = lColorKey & 0xFF;
|
|
|
|
LPBYTE pBuffer = NULL;
|
|
pTestFrameSrc->get_Plane(0, &pBuffer);
|
|
*pBuffer = nYColor; pBuffer++;
|
|
*pBuffer = nYColor; pBuffer++;
|
|
*pBuffer = nYColor; pBuffer++;
|
|
*pBuffer = nYColor; pBuffer++;
|
|
pTestFrameSrc->get_Plane(1, &pBuffer);
|
|
*pBuffer = nUColor; pBuffer++;
|
|
*pBuffer = nUColor; pBuffer++;
|
|
pTestFrameSrc->get_Plane(2, &pBuffer);
|
|
*pBuffer = nVColor; pBuffer++;
|
|
*pBuffer = nVColor; pBuffer++;
|
|
IUnknown *punkTestFrameSrc = NULL;
|
|
pTestFrameSrc->QueryInterface(__uuidof(IUnknown), (void**)&punkTestFrameSrc);
|
|
pTestFrameSrc->Release();
|
|
|
|
IUnknown* punkTestFrameDst = NULL;
|
|
pTransform->TransformFrame(punkTestFrameSrc, &punkTestFrameDst);
|
|
RELEASEINTERFACE(pTransform);
|
|
RELEASEINTERFACE(punkTestFrameSrc);
|
|
if (NULL==punkTestFrameDst)
|
|
return lColorKey;
|
|
IAVSUncompressedVideoFrame *pTestFrameDst = NULL;
|
|
punkTestFrameDst->QueryInterface(__uuidof(IAVSUncompressedVideoFrame), (void**)&pTestFrameDst);
|
|
punkTestFrameDst->Release();
|
|
|
|
pTestFrameDst->get_Plane(0,&pBuffer);
|
|
lColorKey = (*pBuffer)<<16; pBuffer++;
|
|
lColorKey |= (*pBuffer)<<8; pBuffer++;
|
|
lColorKey |= *pBuffer;
|
|
pTestFrameDst->Release();
|
|
return lColorKey;
|
|
}
|
|
else
|
|
{
|
|
IAVSVideoFrameTransform *pTransform = NULL;
|
|
CoCreateInstance(__uuidof(CAVSVideoFrameTransform), NULL, CLSCTX_ALL, __uuidof(IAVSVideoFrameTransform), (void**)&pTransform);
|
|
if (NULL==pTransform)
|
|
return S_FALSE;
|
|
MediaFormat::IAVSVideoFormat *pFormat = NULL;
|
|
CoCreateInstance(MediaFormat::CLSID_CAVSVideoFormat, NULL, CLSCTX_ALL, MediaFormat::IID_IAVSVideoFormat, (void**)&pFormat);
|
|
if (NULL==pFormat)
|
|
{
|
|
pTransform->Release();
|
|
return lColorKey;
|
|
}
|
|
pTransform->put_DeinterlaceEnabled(FALSE);
|
|
pTransform->put_CropScale(0);
|
|
|
|
pFormat->put_ColorSpace(CSP_YUY2);
|
|
pFormat->put_Width(2);
|
|
pFormat->put_Height(2);
|
|
pFormat->put_AspectRatioX(0);
|
|
pFormat->put_AspectRatioY(0);
|
|
pTransform->SetVideoFormat(pFormat);
|
|
RELEASEINTERFACE(pFormat);
|
|
|
|
IAVSUncompressedVideoFrame *pTestFrameSrc = NULL;
|
|
CoCreateInstance(__uuidof(CAVSUncompressedVideoFrame), NULL, CLSCTX_ALL, __uuidof(IAVSUncompressedVideoFrame), (void**)&pTestFrameSrc);
|
|
if (NULL==pTestFrameSrc)
|
|
{
|
|
pTransform->Release();
|
|
return lColorKey;
|
|
}
|
|
pTestFrameSrc->put_ColorSpace(CSP_BGR);
|
|
pTestFrameSrc->put_Width(2);
|
|
pTestFrameSrc->put_Height(2);
|
|
pTestFrameSrc->put_AspectRatioX(0);
|
|
pTestFrameSrc->put_AspectRatioY(0);
|
|
pTestFrameSrc->SetDefaultStrides();
|
|
pTestFrameSrc->AllocateBuffer(-1);
|
|
BYTE nRColor = (lColorKey>>16) & 0xFF;
|
|
BYTE nGColor = (lColorKey>>8) & 0xFF;
|
|
BYTE nBColor = lColorKey & 0xFF;
|
|
|
|
LPBYTE pBuffer = NULL;
|
|
pTestFrameSrc->get_Plane(0, &pBuffer);
|
|
*pBuffer = nBColor; pBuffer++;
|
|
*pBuffer = nGColor; pBuffer++;
|
|
*pBuffer = nRColor; pBuffer++;
|
|
|
|
*pBuffer = nBColor; pBuffer++;
|
|
*pBuffer = nGColor; pBuffer++;
|
|
*pBuffer = nRColor; pBuffer++;
|
|
|
|
*pBuffer = nBColor; pBuffer++;
|
|
*pBuffer = nGColor; pBuffer++;
|
|
*pBuffer = nRColor; pBuffer++;
|
|
|
|
*pBuffer = nBColor; pBuffer++;
|
|
*pBuffer = nGColor; pBuffer++;
|
|
*pBuffer = nRColor; pBuffer++;
|
|
IUnknown *punkTestFrameSrc = NULL;
|
|
pTestFrameSrc->QueryInterface(__uuidof(IUnknown), (void**)&punkTestFrameSrc);
|
|
pTestFrameSrc->Release();
|
|
|
|
IUnknown* punkTestFrameDst = NULL;
|
|
pTransform->TransformFrame(punkTestFrameSrc, &punkTestFrameDst);
|
|
RELEASEINTERFACE(pTransform);
|
|
RELEASEINTERFACE(punkTestFrameSrc);
|
|
if (NULL==punkTestFrameDst)
|
|
return lColorKey;
|
|
IAVSUncompressedVideoFrame *pTestFrameDst = NULL;
|
|
punkTestFrameDst->QueryInterface(__uuidof(IAVSUncompressedVideoFrame), (void**)&pTestFrameDst);
|
|
punkTestFrameDst->Release();
|
|
|
|
pTestFrameDst->get_Plane(0,&pBuffer);
|
|
lColorKey = (*pBuffer)<<16; pBuffer++;
|
|
lColorKey |= (*pBuffer)<<8; pBuffer++; pBuffer++;
|
|
lColorKey |= *pBuffer;
|
|
pTestFrameDst->Release();
|
|
}
|
|
return lColorKey;
|
|
}
|
|
};
|
|
|