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

📄 drawyuv.cpp

📁 DRAWYUV程序是用于摄像头的数据回放,用了directshow,可以用在VC和wince都可
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				vfDest.vfBitCount = 32;
				break;

			default: 
				vfDest.vfBitCount = 0; // No support
				break;
			}			
			
			if (vfDest.vfBitCount == 0) break;

			m_dwBitCount  = vfDest.vfBitCount;

			// Create a converter
			vfSource.vfWidth = vfDest.vfWidth = nWidth;
			vfSource.vfHeight = vfDest.vfHeight = nHeight;
			vfSource.vfBitCount = SOURCE_BIT_COUNT;
			vfSource.vfFourCC = SOURCE_COLOR_SPACE;
			vfDest.vfFourCC = BI_RGB;

			m_pConverter = new Converter;
			if (!m_pConverter) break;
			
			if (!m_pConverter->Create(&vfSource, &vfDest)) break;			
		}

		/***********************************/
		/* Create a clipper for our window */
		/***********************************/
		ddrval = IDirectDraw_CreateClipper(m_lpDD, 0, &m_lpDDClipper, NULL);
		if( ddrval != DD_OK ) break;

		m_pDisplayWindow = new DisplayWindow;
		if (!m_pDisplayWindow) break;

		bRtn = m_pDisplayWindow->Create(lpszWindowName, dwStyle, x, y, nWidth, nHeight, hwndParent, fOverlay, m_lpDDSPrimary, m_lpDDClipper);
        if (!bRtn) break;
		
		ddrval = IDirectDrawClipper_SetHWnd(m_lpDDClipper, 0, m_pDisplayWindow->GetHwnd());
		if( ddrval != DD_OK ) break;

		if (!fOverlay)
		{
			ddrval = IDirectDrawSurface_SetClipper(m_lpDDSPrimary, m_lpDDClipper);
			if (ddrval != DD_OK) break;
		}

		bSuccess = TRUE;
		m_dwWidth = nWidth;
		m_dwHeight = nHeight;
		
	} while(0);
	
	if (!bSuccess)
	{
		this->Close();		
	}
	
	return bSuccess;
}

BOOL DrawYUV::Close()
{
	if (m_pDisplayWindow)
	{		
		m_bClosed = m_pDisplayWindow->Close();
		delete m_pDisplayWindow;
		m_pDisplayWindow = NULL;
	}

	if (m_pConverter)
	{
		delete m_pConverter;
		m_pConverter = NULL;
	}

	SAFE_RELEASE(m_lpDDSOverlay);
	SAFE_RELEASE(m_lpDDSBack);
	SAFE_RELEASE(m_lpDDClipper);
	SAFE_RELEASE(m_lpDDSPrimary);
	SAFE_RELEASE(m_lpDD);

	return TRUE;
}

BOOL DrawYUV::IsClose()
{
	return m_bClosed;
}

BOOL DrawYUV::SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags)
{
	if (m_pDisplayWindow)
	{
		return ::SetWindowPos(m_pDisplayWindow->GetHwnd(), hWndInsertAfter, x, y, cx, cy, uFlags);
	}
	
	return FALSE;
}

BOOL DrawYUV::Draw(LPBYTE lpBuffer, DWORD dwSize)
{
	if (!lpBuffer || dwSize == 0) return FALSE;

	LPBYTE lpOutput = NULL;
	HRESULT ddrval;
	RECT rectClient;// Window size and position 	
	RECT  rectDest;
	DDOVERLAYFX  ddofx;// Effects used in displaying the overlay 
	DWORD  dwFlags; 
	int nTemp = 0;
	POINT point;
	point.x = 0;
	point.y = 0;

	if (m_pConverter)
	{
		if (!m_pConverter->Convert(lpBuffer, &lpOutput)) return FALSE;
	}
	
		
	SetRect(&rectDest, 0, 0, m_dwWidth, m_dwHeight);
	
	DDSURFACEDESC  ddsd;
	ZeroMemory(&ddsd, sizeof(ddsd));
	ddsd.dwSize     = sizeof(ddsd);	

	if (m_bIsOverlay)
	{		
		ddrval = m_lpDDSOverlay->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
		if (ddrval != DD_OK) return FALSE;
		
		memcpy_MMX(ddsd.lpSurface, lpOutput == NULL ? lpBuffer : lpOutput, \
			lpOutput == NULL ? dwSize : ((m_dwWidth * m_dwHeight * m_dwBitCount) >> 3));
		
		m_lpDDSOverlay->Unlock(NULL);		
		
		/*************************/
		/* Where is the window ? */
		/*************************/
		GetWindowRect(m_pDisplayWindow->GetHwnd(), &rectClient);

		ddofx.dwSize = sizeof(DDOVERLAYFX);
		ddofx.dckSrcColorkey.dwColorSpaceLowValue  = DD_OVERLAY_COLORKEY_16BPP;
		ddofx.dckSrcColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_16BPP;
		
		ddofx.dckDestColorkey.dwColorSpaceLowValue  = DD_OVERLAY_COLORKEY_16BPP;
		ddofx.dckDestColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_16BPP;		
		
		dwFlags = DDOVER_SHOW | DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE;
		
		ddrval = IDirectDrawSurface_UpdateOverlay (m_lpDDSOverlay,
												   &rectDest,
												   m_lpDDSPrimary,
												   &rectClient,
												   dwFlags,
												   &ddofx);

		
	}
	else
	{
		ddrval = m_lpDDSBack->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
		if (ddrval != DD_OK) return FALSE;
		
		memcpy_MMX(ddsd.lpSurface, lpOutput, ((m_dwWidth * m_dwHeight * m_dwBitCount) >> 3));
		
		m_lpDDSBack->Unlock(NULL);

		::GetClientRect(m_pDisplayWindow->GetHwnd(), &rectClient);
		::ClientToScreen(m_pDisplayWindow->GetHwnd(), &point);
		nTemp = rectClient.right - rectClient.left;
		rectClient.left = point.x;
		rectClient.right = point.x + nTemp;
		
		nTemp = rectClient.bottom - rectClient.top;
		rectClient.top = point.y;
		rectClient.bottom = point.y + nTemp;

		ddrval = m_lpDDSPrimary->Blt(&rectClient, m_lpDDSBack, &rectDest, DDBLT_WAIT, NULL);		
	}

	return ddrval == DD_OK;
}

BOOL DrawYUV::ShowWindow(int nCmdShow)
{
	if (m_pDisplayWindow)
	{
		return ::ShowWindow(m_pDisplayWindow->GetHwnd(), nCmdShow);
	}

	return FALSE;
}

BOOL DrawYUV::AreOverlaysSupported()
{
	DDCAPS  capsDrv;
    HRESULT ddrval;
	
	memset (&capsDrv, 0, sizeof(capsDrv));
    capsDrv.dwSize = sizeof(capsDrv);
	
	ddrval = this->m_lpDD->GetCaps(&capsDrv, NULL);
	if (ddrval != DD_OK)
	{
		return FALSE;
	}
	
	if (!(capsDrv.dwCaps & DDCAPS_OVERLAY))
	{
		return FALSE;
	}
	
	return TRUE;
}

void DrawYUV::memcpy_MMX( void *dest, const void *src, unsigned int nbytes )
{
	__asm
	{
		MOV ESI, src         ;; pointer to src, DWORD aligned
			MOV EDI, dest        ;; pointer to dst, DWORD aligned
			MOV ECX, nbytes      ;; number of bytes to copy
			MOV EDX, ECX         ;; backup number of bytes
			CMP ECX, 4           ;; less than one DWORD to copy ?
			JB $copybyte2_cc     ;; yes, must be no DWORDs to copy, maybe bytes
			SHR ECX, 2           ;; number of DWORDs to copy
			TEST EDI,7           ;; dst QWORD aligned?
			JZ $dstqaligned2_cc  ;; yes
			MOVD MM0,[ ESI ]     ;; read one DWORD from src
			MOVD [EDI ] ,MM0     ;; store one DWORD to dst
			ADD ESI,4            ;; src++
			ADD EDI,4            ;; dst++
			DEC ECX              ;; number of DWORDs to copy
$dstqaligned2_cc:
		MOV EBX,ECX          ;; number of DWORDs to copy
			SHR ECX,4            ;; number of cache lines to copy
			JZ $copyqwords2_cc   ;; no whole cache lines to copy, maybe QWORDs
			
			ALIGN 16             ;; align loop for optimal performance
$cloop2_cc:
		MOVQ MM0,[ ESI ]     ;; load first QWORD in cache line from src
			ADD EDI,64           ;; src++
			MOVQ MM1,[ ESI+8 ]   ;; load second QWORD in cache line from src
			ADD ESI,64           ;; dst++
			MOVQ MM2,[ ESI-48 ]  ;; load third QWORD in cache line from src
			MOVQ [EDI-64 ] ,MM0  ;; store first DWORD in cache line to dst
			MOVQ MM0,[ ESI-40 ]  ;; load fourth QWORD in cache line from src
			MOVQ [EDI-56 ] ,MM1  ;; store second DWORD in cache line to dst
			MOVQ MM1,[ ESI-32 ]  ;; load fifth QWORD in cache line from src
			MOVQ [EDI-48 ] ,MM2  ;; store third DWORD in cache line to dst
			MOVQ MM2,[ ESI-24 ]  ;; load sixth QWORD in cache line from src
			MOVQ [EDI-40 ] ,MM0  ;; store fourth DWORD in cache line to dst
			MOVQ MM0,[ ESI-16 ]  ;; load seventh QWORD in cache line from src
			MOVQ [EDI-32 ] ,MM1  ;; store fifth DWORD in cache line to dst
			MOVQ MM1,[ ESI-8 ]   ;; load eight QWORD in cache line from src
			MOVQ [EDI-24 ] ,MM2  ;; store sixth DWORD in cache line to dst
			MOVQ [EDI-16 ] ,MM0  ;; store seventh DWORD in cache line to dst
			DEC ECX              ;; count--
			MOVQ [EDI-8 ] ,MM1   ;; store eighth DWORD in cache line to dst
			JNZ $cloop2_cc       ;; until no more cache lines to copy
			
$copyqwords2_cc:
		MOV ECX,EBX          ;; number of DWORDs to copy
			AND EBX,0xE          ;; number of QWORDS left to copy *2
			SHR EBX, 1           ;; number of QWORDS left to copy
			JZ $copydword2_cc    ;; no QWORDs left, maybe DWORD left
			
			ALIGN 16             ;; align loop for optimal performance
			
$qloop2_cc:
		MOVQ MM0, [ESI]      ;; read QWORD from src
			MOVQ [EDI], MM0      ;; store QWORD to dst
			ADD ESI,8            ;; src++
			ADD EDI,8            ;; dst++
			SUB EBX,1            ;; count--
			JNZ $qloop2_cc       ;; until no more QWORDs left to copy
			
$copydword2_cc:
		TEST ECX, 1          ;; DWORD left to copy ?
			JZ $copybyte2_cc     ;; nope, but maybe bytes left
			MOVD MM0, [ESI]      ;; read last DWORD from src
			MOVD [EDI], MM0      ;; store last DWORD to dst
			ADD  ESI, 4          ;; 4 bytes read
			ADD  EDI, 4          ;; 4 bytes written
			
$copybyte2_cc:
		AND EDX, 0x3         ;; number of bytes left to copy
			JZ $copydone2_cc     ;; no bytes left, we're done
			
$bloop2_cc:
		MOV AH,BYTE PTR [ESI]
			MOV BYTE PTR [EDI],AH
			ADD ESI,1            ;; src++
			ADD EDI,1            ;; dst++
			SUB EDX,1            ;; count--
			JNZ $bloop2_cc       ;; until no more bytes left to copy
			
$copydone2_cc:
		EMMS                 ;; clear MMX state
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -