?? delegatefilter.cpp
字號:
// AviDelegateWriter.cpp: implementation of the CDelegatorFilter class.
//
//////////////////////////////////////////////////////////////////////
#include <streams.h>
//#include <Vfw.h>
#include <direct.h>
#include <math.h>
//#include <Aviriff.h>
#include <stdio.h>
#include "IPsnr.h"
#include "SourcePin.h" // Added by ClassView
#include "CompedPin.h" // Added by ClassView
#include "AviPsnrFilter.h"
#include "DelegateFilter.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
double diff_y,diff_u,diff_v;
DWORD fccYV12 = MAKEFOURCC('Y','V','1','2');
DWORD fccYUY2 = MAKEFOURCC('Y','U','Y','2');
DWORD fccDTV1 = MAKEFOURCC('D','T','V','1');
CDelegatorFilter::CDelegatorFilter(LPUNKNOWN pUnk, HRESULT *phr):
CUnknown(NAME("CAviDelegator"), pUnk),
m_pFilter(NULL),
m_CompedPin(NULL),
m_SourcePin(NULL),
m_bCompedEnd(FALSE),
m_bSourceEnd(FALSE),
m_bStopped(FALSE),
m_nWidth(0),
m_nHeight(0),
m_nSrcCount(0),
m_nCompCount(0),
m_dwCompLen(0),
m_dwSrcLen(0),
m_pSrcData(NULL),
m_pCompData(NULL),
m_pDataYV12(NULL),
m_pPosition(NULL)
//m_fWriteError(0)
{
// ASSERT(phr);
m_pFilter = new CAviPsnrFilter(this, GetOwner(), &m_Lock, phr);
if (m_pFilter == NULL) {
if (phr)
*phr = E_OUTOFMEMORY;
return;
}
m_CompedPin = new CCompedPin(this,GetOwner(),
m_pFilter,
&m_Lock,
&m_ReceiveLock,
phr);
if (m_CompedPin == NULL) {
if (phr)
*phr = E_OUTOFMEMORY;
return;
}
m_SourcePin = new CSourcePin(this,GetOwner(),
m_pFilter,
&m_Lock,
&m_ReceiveLock,
phr);
if (m_SourcePin == NULL) {
if (phr)
*phr = E_OUTOFMEMORY;
return;
}
// m_CompedPin->m_pVpin = m_SourcePin;
// m_SourcePin->m_pApin = m_CompedPin;
memset(&m_PSNR, 0, sizeof(m_PSNR));
//AVIFileInit();
}
CDelegatorFilter::~CDelegatorFilter()
{
if(m_SourcePin)
delete m_SourcePin;
if(m_CompedPin)
delete m_CompedPin;
if(m_pFilter)
delete m_pFilter;
if(m_pPosition)
delete m_pPosition;
if(m_pDataYV12)
delete m_pDataYV12;
}
CUnknown * WINAPI CDelegatorFilter::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
{
// ASSERT(phr);
CDelegatorFilter *pNewObject = new CDelegatorFilter( punk, phr);
if (pNewObject == NULL) {
if (phr)
*phr = E_OUTOFMEMORY;
}
return pNewObject;
}
STDMETHODIMP CDelegatorFilter::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
{
CheckPointer(ppv,E_POINTER);
CAutoLock lock(&m_Lock);
// Do we have this interface
if(riid == IID_IPSNR) //提供IPsnr接口給外界
{
return GetInterface((IPsnr *) m_pFilter, ppv);
}
if (riid == IID_IBaseFilter || riid == IID_IMediaFilter || riid == IID_IPersist )
{
return m_pFilter->NonDelegatingQueryInterface(riid, ppv);
}
else if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking) {
if (m_pPosition == NULL)
{
HRESULT hr = S_OK;
m_pPosition = new CPosPassThru(NAME("Dump Pass Through"),
(IUnknown *) GetOwner(),
(HRESULT *) &hr, m_SourcePin);
if (m_pPosition == NULL)
return E_OUTOFMEMORY;
if (FAILED(hr))
{
delete m_pPosition;
m_pPosition = NULL;
return hr;
}
}
return m_pPosition->NonDelegatingQueryInterface(riid, ppv);
}
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
} // NonDelegatingQueryInterface
void CDelegatorFilter::ReleaseAviRs()
{
m_PSNR.dbSnr_y = m_PSNR.dbSnr_y_sums/m_nSrcCount;
m_PSNR.dbSnr_u = m_PSNR.dbSnr_u_sums/m_nSrcCount;
m_PSNR.dbSnr_v = m_PSNR.dbSnr_v_sums/m_nSrcCount;
/* FILE *stream;
char path[MAX_PATH+12];
getcwd(path, MAX_PATH);
int nLen=strlen(path);
if(*(path+nLen-1)=='\\')
strcat(path, "result.txt");
else
strcat(path, "\\result.txt");
stream = fopen(path, "w");
fprintf(stream, "PSNR_Y=%f6.2\nPSNR_U=%f6.2\nPSNR_V=%f6.2", m_PSNR.dbSnr_y, m_PSNR.dbSnr_u, m_PSNR.dbSnr_v);
fclose(stream);
*/
}
HRESULT CDelegatorFilter::GiveFrame(BYTE *pData, DWORD dwLen, BOOL bType)
{
CAutoLock lock(&m_Lock);
if(m_nSrcCount==m_nCompCount) //剛剛計算完一對兒,現(xiàn)在是新的一幀數(shù)據(jù)
{
if(bType==0) //源視頻
{
m_pSrcData = pData; //把數(shù)據(jù)先存起來,等壓縮數(shù)據(jù)到了與它進行計算
m_dwSrcLen = dwLen;
m_nSrcCount++;
}
if(bType==1) //壓縮視頻
{
// if(m_pCompData)
// delete m_pCompData;
// m_pCompData = new BYTE[dwLen];
// memcpy(m_pCompData, pData, dwLen);
m_pCompData = pData; //把數(shù)據(jù)先存起來,等壓縮數(shù)據(jù)到了與它進行計算
m_dwCompLen = dwLen;
m_nCompCount++;
}
}
else if(m_nSrcCount<m_nCompCount) //壓縮數(shù)據(jù)先到
{
if(bType==1) //不能再來一幀壓縮數(shù)據(jù)
return -1;
m_nSrcCount++;
if(m_nSrcCount!=m_nCompCount) //幀號必須是一致的
return -1;
if(!m_pCompData) //壓縮數(shù)據(jù)必須已經存儲
return -1;
CalPSNR(pData,m_pCompData, dwLen); //進行計算
m_pCompData = NULL; //不能delete,由dshow自動管理
}
else if(m_nSrcCount>m_nCompCount) //源數(shù)據(jù)先到
{
if(bType==0) //不能再來一幀源數(shù)據(jù)
return -1;
m_nCompCount++;
if(m_nSrcCount!=m_nCompCount) //幀號必須是一致的
return -1;
if(!m_pSrcData) //源數(shù)據(jù)必須已經存儲
return -1;
CalPSNR(m_pSrcData, pData, dwLen);//進行計算
m_pSrcData = NULL; //不能delete,由dshow自動管理
}
return S_OK;
}
HRESULT CDelegatorFilter::CalPSNR(BYTE *pSource, BYTE *pComped, DWORD dwLen)
{
if(m_CompedPin->m_FourCC==fccYUY2)
{
yuy22yv12(pComped,m_pDataYV12,m_nWidth, m_nHeight);
//顛倒
snr_cal_rev(pSource, m_pDataYV12, m_nWidth, m_nHeight);
}
else if(m_CompedPin->m_FourCC==fccYV12)
{
//不顛倒
snr_cal(pSource, pComped, m_nWidth, m_nHeight);
}
// m_PSNR.dbSnr_y_sums+=m_PSNR.dbSnr_y;
// m_PSNR.dbSnr_u_sums+=m_PSNR.dbSnr_u;
// m_PSNR.dbSnr_v_sums+=m_PSNR.dbSnr_v;
return S_OK;
}
void CDelegatorFilter::yuy22yv12(BYTE* puc_in, BYTE* puc_out, int width_y, int height_y)
{
int XY = width_y * height_y;
BYTE* puc_YUY2 = puc_in;
BYTE* puc_y = puc_out;
BYTE* puc_v = puc_out + XY;
BYTE* puc_u = puc_out + ((XY *5)>>2);
int nCtr, nOuterCtr;
int cx2 = width_y<<1;
//Y
for(nCtr=0; nCtr<XY; nCtr++)
{
*puc_y = *puc_YUY2;
puc_y++;
puc_YUY2 += 2;
}
puc_YUY2 = puc_in + 1;
//U and V
for(nOuterCtr=0; nOuterCtr < height_y>>1; nOuterCtr++)
{
for(nCtr=0; nCtr < width_y>>1; nCtr++)
{
//U
*puc_u = (unsigned char)(((int)(*puc_YUY2) + (int)(*(puc_YUY2 + cx2)))/2);
puc_u++;
puc_YUY2 += 2;
//V
*puc_v = (unsigned char)(((int)(*puc_YUY2) + (int)(*(puc_YUY2 + cx2)))/2);
puc_v++;
puc_YUY2 += 2;
}
puc_YUY2 += cx2;
}
}
void CDelegatorFilter::snr_cal_rev(unsigned char* origi_image, unsigned char * recon_image, int width, int height)
{
int height_cr=(height>>1);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -