⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 delegatefilter.cpp

📁 对比两个AVI文件的psnr值的VC源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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) //刚刚计算完一对儿,现在是新的一帧数据
	{
		if(bType==0)			 //源视频	
		{
			m_pSrcData = pData;	 //把数据先存起来,等压缩数据到了与它进行计算
			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; //把数据先存起来,等压缩数据到了与它进行计算
			m_dwCompLen = dwLen;
			m_nCompCount++;
		}

	}
	else if(m_nSrcCount<m_nCompCount)  //压缩数据先到
	{
		if(bType==1)					//不能再来一帧压缩数据
			return -1;
		m_nSrcCount++;				
		if(m_nSrcCount!=m_nCompCount)	//帧号必须是一致的
			return -1;
		if(!m_pCompData)				//压缩数据必须已经存储
			return -1;
		CalPSNR(pData,m_pCompData, dwLen);  //进行计算
		m_pCompData = NULL;				//不能delete,由dshow自动管理
	}

	else if(m_nSrcCount>m_nCompCount)	 //源数据先到
	{
		if(bType==0)					//不能再来一帧源数据
			return -1;
		m_nCompCount++;	
		if(m_nSrcCount!=m_nCompCount)	//帧号必须是一致的
			return -1;
		if(!m_pSrcData)					//源数据必须已经存储
			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 + -