yuvviewerdlg.cpp

来自「《Visual C++小波变换技术与工程实践》作者:靳济芳。书上的代码。第11章」· C++ 代码 · 共 871 行 · 第 1/2 页

CPP
871
字号

/************************************************************************
 *
 *  Ye-Kui Wang       wyk@ieee.org
 *  Juan-Juan Jiang   juanjuan_j@hotmail.com
 *  
 *  March 14, 2002
 *
 ************************************************************************/

/*
 * Disclaimer of Warranty
 *
 * These software programs are available to the user without any
 * license fee or royalty on an "as is" basis.  The developers disclaim 
 * any and all warranties, whether express, implied, or statuary, including 
 * any implied warranties or merchantability or of fitness for a particular 
 * purpose.  In no event shall the copyright-holder be liable for any incidental,
 * punitive, or consequential damages of any kind whatsoever arising from 
 * the use of these programs.
 *
 * This disclaimer of warranty extends to the user of these programs
 * and user's customers, employees, agents, transferees, successors,
 * and assigns.
 *
 * The developers does not represent or warrant that the programs furnished 
 * hereunder are free of infringement of any third-party patents.
 *
 * */


// YUVviewerDlg.cpp : implementation file
//

#include "stdafx.h"
#include "YUVviewer.h"
#include "ChildWindow.h"
#include "YUVviewerDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

BOOL g_bPlay;
int g_nFrameNumber = 0;
int g_nOldFrameNumber = -1000; 
BOOL g_Play = true;

int g_nStartFrame = 0;
int g_nEndFrame = 10000;
int g_nCurrentFrame = 0; 
BOOL g_bReversePlay = FALSE;

void getSeqName(char *inseqpath, char *seqname);

//int nImgWidth, nImgHeight;
UINT PlayVideo( LPVOID pParam )
{
	int i;
	//播放标志
	BOOL bPlay = g_bPlay;
	BOOL bEof = FALSE;
	//视频播放窗口
	CYUVviewerDlg *pWin = (CYUVviewerDlg *)pParam;
	UINT picsize = pWin->m_nWidth*pWin->m_nHeight;
	int timespan = 1000/atoi(pWin->m_sFrameRate);
	//播放的起止帧
	if(g_nCurrentFrame < g_nStartFrame) g_nCurrentFrame = g_nStartFrame;
	if(g_nCurrentFrame > g_nEndFrame) g_nCurrentFrame = g_nEndFrame;
	//多路处理
	for(i=0; i<pWin->m_iCount; i++)
	{
		pWin->m_pFile[i]->Seek(g_nCurrentFrame*picsize*3/2, SEEK_SET);
		pWin->m_pWnd[i]->nPicShowOrder = g_nCurrentFrame;
	}
	
	HANDLE hPlayTemp1 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"播    放");
	
	while(g_nCurrentFrame >= g_nStartFrame && g_nCurrentFrame <= g_nEndFrame && !bEof)
	{
		DWORD t2=GetTickCount();
		g_nFrameNumber = g_nCurrentFrame;
 
		if ( WAIT_OBJECT_0 == WaitForSingleObject(hPlayTemp1,INFINITE) )
			ReleaseMutex( hPlayTemp1 );
		
		for(i=0; i<pWin->m_iCount; i++)
		{
			pWin->m_pFile[i]->Seek(g_nCurrentFrame*picsize*3/2, SEEK_SET);
			//如果参数不匹配,则将视频尾置真值
			if(picsize != pWin->m_pFile[i]->Read(pWin->m_pWnd[i]->Y,picsize))
			{
				pWin->m_buttonPausePlay.SetWindowText("播    放");
				pWin->m_bEOF = TRUE;
				pWin->m_bPlay = FALSE;
				//达到视频尾,停止播放
				bEof = TRUE;
				break;
			}
			//彩色图象的视频
			if(1) 
			{
				if(picsize/4 != pWin->m_pFile[i]->Read(pWin->m_pWnd[i]->Cb,picsize/4))
				{
					bEof = TRUE;
					break;
				}
				if(picsize/4 != pWin->m_pFile[i]->Read(pWin->m_pWnd[i]->Cr,picsize/4))
				{
					bEof = TRUE;
					break;
				}
			}

			pWin->m_pWnd[i]->InvalidateRect (NULL,FALSE);
			pWin->m_pWnd[i]->UpdateWindow ();
			pWin->m_pWnd[i]->nPicShowOrder=g_nCurrentFrame;
		}

		if(g_bReversePlay == FALSE)
			g_nCurrentFrame++;
		else 
			g_nCurrentFrame--;
		int t1=GetTickCount()-t2;
		if(t1 < timespan) 
			Sleep(timespan - t1); 
	}
	
	pWin->m_pWinThread = NULL;
	AfxEndThread(0);

	return 1;

}


void CYUVviewerDlg::OnOrder() 
{
	if(g_bReversePlay == FALSE)
	{
		m_buttonOrder.SetWindowText("==>");
		g_bReversePlay = TRUE;
	}
	else
	{
		m_buttonOrder.SetWindowText("<==");
		g_bReversePlay = FALSE;
	}
}

void CYUVviewerDlg::OnPauseplay() 
{

	UpdateData(TRUE);
	//播放帧的基本参数
	g_nStartFrame = m_nFrameFrom;
	if(m_nFrameTo != 0) g_nEndFrame = m_nFrameTo;
	else g_nEndFrame = 10000;

	// 创建一个新的线程,播放
	if (m_bPlay)
	{
		m_buttonPausePlay.SetWindowText("暂	停");
		m_bPlay = false;
		g_Play = true;
	}
	else
	{
		//如果达到视频尾端,播放停止
		if(m_bEOF)
		{
			m_buttonPausePlay.SetWindowText("暂	停");
			m_bEOF = FALSE;
			//视频复位
			OnTransfer();
		}
		else
		{
			m_buttonPausePlay.SetWindowText("播	放");
		}
		
		m_bPlay = true; 
	}

	char chTitle[15];
	m_buttonPausePlay.GetWindowText(chTitle,15);
	hPlayTemp = NULL;
	hPlayTemp=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"播	放");
	if ( strcmp( chTitle,"播	放" ) == 0 )
	{
		WaitForSingleObject( hPlayTemp,0);
		
	}
	else
		ReleaseMutex(hPlayTemp);

	if ( m_pWinThread == NULL)
		m_pWinThread = AfxBeginThread( (AFX_THREADPROC)PlayVideo , (void*)this);

}


void CYUVviewerDlg::OnCloseall() 
{
	int i;
	//多路
	for(i=0; i<m_iCount; i++)
	{
		if(m_pFile[i])
			m_pFile[i]->Close();
		if(m_pWnd[i])
			m_pWnd[i]->DestroyWindow();
	}
	m_iCount = 0;
	//播放参数复位
	g_nFrameNumber = 0;
	g_nOldFrameNumber = -1000; 
	g_Play = true;

	g_nStartFrame = 0;
	g_nEndFrame = 10000;
	g_nCurrentFrame = 0; 
	g_bReversePlay = FALSE;
}


void CYUVviewerDlg::OnCancel() 
{
	int i;

	for(i=0; i<m_iCount; i++)
	{
		if(m_pFile[i])
			m_pFile[i]->Close();
		if(m_pWnd[i])
			m_pWnd[i]->DestroyWindow();
	}
	
	CDialog::OnCancel();
}

void CYUVviewerDlg::OnOpenfile() 
{
	UpdateData(TRUE);
	//视频窗口的尺寸
	UINT picsize = m_nWidth*m_nHeight;
	//多路视频文件
	m_pFile[m_iCount] = new CFile();
	//打开视频文件
	char BASED_CODE szFilter[] = "YUV Files (*.yuv)|*.yuv|All Files (*.*)|*.*||";
	CFileDialog dlg( TRUE, "yuv", NULL, OFN_HIDEREADONLY,szFilter);
	if(dlg.DoModal()!=IDOK) return; 

	sprintf( inSeqence[m_iCount], "%s", dlg.GetPathName() );
	getSeqName(inSeqence[m_iCount], inSeqName[m_iCount]);
	//如果重复打开同一个视频文件,报错!
	if(!m_pFile[m_iCount]->Open(inSeqence[m_iCount], CFile::modeRead )) 
	{
		AfxMessageBox("不能打开输入的视频");
		return;
	}
	//为每一路视频信号创建一个视频窗口
	m_pWnd[m_iCount]=new CChildWindow((CFrameWnd*)this, m_nWidth, m_nHeight,1);
	//如果图象尺寸不符合,播放复位
	if(picsize != m_pFile[m_iCount]->Read(m_pWnd[m_iCount]->Y,picsize))
	{
		OnTransfer();
		return;
	}
	//彩色视频(系统认为这是恒为真值的)
	if(1) 
	{
		if(picsize/4 != m_pFile[m_iCount]->Read(m_pWnd[m_iCount]->Cb,picsize/4))
		{
			OnTransfer();
			return;
		}
		if(picsize/4 != m_pFile[m_iCount]->Read(m_pWnd[m_iCount]->Cr,picsize/4))
		{
			OnTransfer();
			return;
		}
	}
	//ShowWindow
	m_pWnd[m_iCount]->ShowWindow(SW_SHOW);
	//视频窗口的缩放
	if(m_nZoom == -1) m_pWnd[m_iCount]->CenterWindow(m_nWidth,m_nHeight);
	else if(m_nZoom == 0) m_pWnd[m_iCount]->CenterWindow(m_nWidth*2,m_nHeight*2);
	//多路视频信号计数
	m_iCount++;
	
	return;

}


void CYUVviewerDlg::OnNext() 
{
	int i;
	UINT picsize = m_nWidth*m_nHeight;

	UpdateData(TRUE);
	//起始播放帧
	g_nStartFrame = m_nFrameFrom;
	if(m_nFrameTo != 0) g_nEndFrame = m_nFrameTo;
	else g_nEndFrame = 10000;
	//多路视频
	for(i=0; i<m_iCount; i++)
	{
		m_pFile[i]->Seek(g_nCurrentFrame*picsize*3/2, SEEK_SET);
		m_pWnd[i]->nPicShowOrder = g_nCurrentFrame;
	}
	//如果没有达到播放的终止帧,则定位下一帧
	if(g_nCurrentFrame < g_nEndFrame)
	{
		g_nFrameNumber = g_nCurrentFrame;
		//多路同步
		for(i=0; i<m_iCount; i++)
		{
			//如果参数不匹配,播放复位
			if(picsize != m_pFile[i]->Read(m_pWnd[i]->Y,picsize))
			{
				OnTransfer();
				return;
			}
			if(1) 
			{
				if(picsize/4 != m_pFile[i]->Read(m_pWnd[i]->Cb,picsize/4))
				{
					OnTransfer();
					return;
				}
				if(picsize/4 != m_pFile[i]->Read(m_pWnd[i]->Cr,picsize/4))
				{
					OnTransfer();
					return;
				}
			}
			m_pWnd[i]->InvalidateRect (NULL,FALSE);
			m_pWnd[i]->UpdateWindow ();
			m_pWnd[i]->nPicShowOrder ++;
		}
		g_nCurrentFrame++;
	}

}


void CYUVviewerDlg::OnNext5() 
{
	int i;
	UINT picsize = m_nWidth*m_nHeight;

	UpdateData(TRUE);
	//起始帧
	g_nStartFrame = m_nFrameFrom;
	if(m_nFrameTo != 0) g_nEndFrame = m_nFrameTo;
	else g_nEndFrame = 10000;
	//前向跳过4帧
	g_nCurrentFrame += 4;
	if(g_nCurrentFrame > g_nEndFrame) g_nCurrentFrame = g_nEndFrame;
	//多路视频
	for(i=0; i<m_iCount; i++)
	{
		m_pFile[i]->Seek(g_nCurrentFrame*picsize*3/2, SEEK_SET);
		m_pWnd[i]->nPicShowOrder = g_nCurrentFrame;
	}
	
	if(g_nCurrentFrame < g_nEndFrame) 
	{
		g_nFrameNumber = g_nCurrentFrame;
		for(i=0; i<m_iCount; i++)
		{
			if(picsize != m_pFile[i]->Read(m_pWnd[i]->Y,picsize))
			{
				OnTransfer();
				return;
			}
			if(1) 
			{
				if(picsize/4 != m_pFile[i]->Read(m_pWnd[i]->Cb,picsize/4))
				{
					OnTransfer();
					return;
				}
				if(picsize/4 != m_pFile[i]->Read(m_pWnd[i]->Cr,picsize/4))
				{
					OnTransfer();
					return;
				}
			}
			m_pWnd[i]->InvalidateRect (NULL,FALSE);
			m_pWnd[i]->UpdateWindow ();
			m_pWnd[i]->nPicShowOrder ++;
		}
		g_nCurrentFrame++;
	}

}


void CYUVviewerDlg::OnPrevious() 
{
	int i;
	int picsize = m_nWidth*m_nHeight;

	UpdateData(TRUE);
	//起始帧
	g_nStartFrame = m_nFrameFrom;
	if(m_nFrameTo != 0) g_nEndFrame = m_nFrameTo;
	else g_nEndFrame = 10000;
	//后退一帧
	g_nCurrentFrame -= 2;
	if(g_nCurrentFrame<0) g_nCurrentFrame = 0;
	//多路视频处理
	for(i=0; i<m_iCount; i++)
	{
		m_pFile[i]->Seek(g_nCurrentFrame*picsize*3/2, SEEK_SET);
		m_pWnd[i]->nPicShowOrder = g_nCurrentFrame;
	}
	
	if(g_nCurrentFrame < g_nEndFrame) // && !bEof)
	{
		g_nFrameNumber = g_nCurrentFrame;//j;
 
		for(i=0; i<m_iCount; i++)
		{
			m_pFile[i]->Read(m_pWnd[i]->Y,picsize);
			if(1) 
			{
				m_pFile[i]->Read(m_pWnd[i]->Cb,picsize/4);
				m_pFile[i]->Read(m_pWnd[i]->Cr,picsize/4);
			}
			m_pWnd[i]->InvalidateRect (NULL,FALSE);

⌨️ 快捷键说明

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