www.pudn.com > GDIyuvplayer.rar > YUVPlayerDlg.cpp
// YUVPlayerDlg.cpp : implementation file
//
#include "stdafx.h"
#include "YUVPlayer.h"
#include "DisplayWin.h"
#include "YUVPlayerDlg.h"
#include "CirQueue.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CEvent eventStart, ReadKill, ConvertKill, freeBuffer;
UINT frameSize , FirstOpen=0,TotalNum=0, FrameNow=0;
UINT picWidth, picHeight, totalTime=0, pauseReserved=0;
volatile BOOL ThreadinUse=FALSE;
CFile m_pFile;
CSliderCtrl *pSlide;
CCirQueue *FrameQueue;
HANDLE m_hTestEvent;
DWORD playStart,playTime;
char pathName[100];
extern UINT fileLength, SetQueueSize;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CYUVPlayerDlg dialog
CYUVPlayerDlg::CYUVPlayerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CYUVPlayerDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CYUVPlayerDlg)
m_nHeight = 288;
m_nWidth = 352;
m_nFSize = 1;
m_nFRate = _T("30");
m_nFnow = 0;
m_nFileLen = 0;
m_nSeekNum = 1;
m_nSeek = -1;
m_nChange = 1.0f;
m_nSlider = 0;
m_nBufferNum = 3;
m_nCurrentTime = _T(" 0: 0: 0");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CYUVPlayerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CYUVPlayerDlg)
DDX_Text(pDX, IDC_EDIT_HEIGHT, m_nHeight);
DDX_Text(pDX, IDC_EDIT_WIDTH, m_nWidth);
DDX_Radio(pDX, IDC_RADIO_QCIF, m_nFSize);
DDX_CBString(pDX, IDC_COMBO_FRATE, m_nFRate);
DDX_Text(pDX, IDC_EDIT_FRAMENOW, m_nFnow);
DDX_Text(pDX, IDC_EDIT2, m_nFileLen);
DDX_Text(pDX, IDC_EDIT5, m_nSeekNum);
DDX_Radio(pDX, IDC_RADIO_SEEK, m_nSeek);
DDX_Text(pDX, IDC_EDIT_SLOW, m_nChange);
DDX_Slider(pDX, IDC_SLIDER_PLAY, m_nSlider);
DDX_Text(pDX, IDC_EDIT_BUFFER, m_nBufferNum);
DDX_Text(pDX, IDC_EDIT_SHOWTIME, m_nCurrentTime);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CYUVPlayerDlg, CDialog)
//{{AFX_MSG_MAP(CYUVPlayerDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_OPEN, OnButtonOpen)
ON_BN_CLICKED(IDC_RADIO_QCIF, OnSizeQcif)
ON_BN_CLICKED(IDC_RADIO_CIF, OnSizeCif)
ON_BN_CLICKED(IDC_RADIO_4CIF, OnSize4cif)
ON_BN_CLICKED(IDC_RADIO_OTHERS, OnSizeOthers)
ON_BN_CLICKED(IDC_BUTTON_FULLSCREEN, OnFullscreen)
ON_BN_CLICKED(IDC_CANCEL, OnClickedCancel)
ON_BN_CLICKED(IDC_BUTTON_PLAY, OnPlay)
ON_BN_CLICKED(IDC_BUTTON_PAUSE, OnPause)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON_CLOSE, OnButtonClose)
ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
ON_BN_CLICKED(IDC_RADIO_SEEK, OnRadioSeek)
ON_BN_CLICKED(IDC_BUTTON_SLOW, OnButtonSlow)
ON_BN_CLICKED(IDC_BUTTON_ACCELERATE, OnButtonAccelerate)
ON_BN_CLICKED(IDC_BUTTON_NEXT, OnButtonNext)
ON_BN_CLICKED(IDC_BUTTON_GO, OnButtonSeek)
ON_WM_HSCROLL()
ON_BN_CLICKED(IDC_BUTTON_PREVIOUS, OnButtonPrevious)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CYUVPlayerDlg message handlers
BOOL CYUVPlayerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
RECT reWindow;
GetWindowRect(&reWindow);
SetWindowPos(&wndTop,250,440,reWindow.right-reWindow.left,reWindow.bottom-reWindow.top,SWP_NOACTIVATE);
// button initial
m_pDisp=NULL;
Disable(IDC_EDIT5);
Disable(IDC_BUTTON_GO);
Disable(IDC_BUTTON_CLOSE);
Disable(IDC_BUTTON_PLAY);
Disable(IDC_BUTTON_PAUSE);
Disable(IDC_BUTTON_STOP);
Disable(IDC_BUTTON_NEXT);
Disable(IDC_BUTTON_PREVIOUS);
Disable(IDC_BUTTON_ACCELERATE);
Disable(IDC_BUTTON_SLOW);
Disable(IDC_BUTTON_FULLSCREEN);
Disable(IDC_EDIT_WIDTH);
Disable(IDC_EDIT_HEIGHT);
Disable(IDC_EDIT2);
Disable(IDC_EDIT_FRAMENOW);
Disable(IDC_EDIT_SLOW);
Disable(IDC_RADIO_SEEK);
Disable(IDC_EDIT_SHOWTIME);
Disable(IDC_SLIDER_PLAY);
//////////// slider //////////////////////////////
pSlide = (CSliderCtrl *) GetDlgItem(IDC_SLIDER_PLAY);
return TRUE; // return TRUE unless you set the focus to a control
}
void CYUVPlayerDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CYUVPlayerDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CYUVPlayerDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
int CYUVPlayerDlg::OnButtonOpen()
{
UpdateData(TRUE);
KillTimer(1); //再次打开文件时,不会直接播放;
if (m_nBufferNum <= 0 || m_nBufferNum > 10)
{
AfxMessageBox("You must put a buffer number in 1 ~ 9") ;
return 0;
}
CFileDialog mFileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,"All Files (*.*)|*.*||");
if(mFileDlg.DoModal() != IDOK)
return 0;
sprintf( pathName, "%s", mFileDlg.GetPathName());
if (FirstOpen)
{
KillTimer(2);
pauseReserved = 0; //see OnPause();
totalTime = 0; //initialize totalTime once open;
m_nCurrentTime = _T(" 0: 0: 0");
if (m_pDisp != NULL)
{
m_pDisp -> SendMessage(WM_CLOSE);
}
}
m_pDisp = new DisplayWin((CFrameWnd*)this, m_nWidth, m_nHeight);
m_pDisp -> m_pPointToMe = &m_pDisp; // see a paper in csdn
if (FirstOpen)
{
m_pFile.Close();
}
if (!(m_pFile.Open(pathName,CFile::modeRead)))
{
AfxMessageBox("Can't open input file");
return 0;
}
// parameter initialize
fileLength = m_pFile.GetLength();
picWidth = m_nWidth;
picHeight = m_nHeight;
frameSize = picWidth*picHeight;
m_nFileLen = fileLength/(frameSize*1.5);
TotalNum = m_nFileLen;
m_nChange = 1 ;
m_nFnow = FrameNow = 1;
m_nSeekNum = 1;
SetQueueSize = m_nBufferNum; //Set the queue
/////pSlider///////////////////
pSlide -> SetRange(1,m_nFileLen);
m_nSlider = 1;
pSlide -> SetPos(m_nSlider);
///////////////////////////////
UpdateData(FALSE);
// thread start
m_hTestEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
SetEvent(m_hTestEvent);
AfxBeginThread(ReadtoBuffer,m_pDisp);
AfxBeginThread(ConvertPicture,m_pDisp);
// show the first frame when open
m_pDisp -> CenterWindow(picWidth,picHeight);
m_pDisp -> ShowWindow(SW_SHOW);
eventStart.SetEvent();
////////////////// button setting /////////////
Enable(IDC_BUTTON_PLAY);
Enable(IDC_BUTTON_CLOSE);
Enable(IDC_BUTTON_NEXT);
Enable(IDC_BUTTON_PREVIOUS);
Enable(IDC_BUTTON_FULLSCREEN);
Enable(IDC_RADIO_SEEK);
Enable(IDC_COMBO_FRATE);
Disable(IDC_EDIT_BUFFER);
Enable(IDC_SLIDER_PLAY);
FirstOpen++;
return TRUE;
}
void CYUVPlayerDlg::OnButtonClose()
{
if (m_pDisp != NULL)
{
KillTimer(1);
ReadKill.SetEvent();
ConvertKill.SetEvent();
m_pDisp = NULL;
OnCloseAll();
}
}
void CYUVPlayerDlg::OnCloseAll()
{
KillTimer(2);
pauseReserved = 0;
m_nCurrentTime.Format(_T(" 0: 0: 0"));
m_nChange = 1;
m_nFileLen = 0;
m_nFnow=FrameNow = 0;
m_nSeek = -1;
m_nSeekNum = 1;
m_nSlider = 1;
pSlide -> SetPos(m_nSlider);
Disable(IDC_BUTTON_CLOSE);
Enable(IDC_EDIT_BUFFER);
Enable(IDC_COMBO_FRATE);
Disable(IDC_BUTTON_PLAY);
Disable(IDC_BUTTON_PAUSE);
Disable(IDC_BUTTON_STOP);
Disable(IDC_BUTTON_NEXT);
Disable(IDC_BUTTON_PREVIOUS);
Disable(IDC_BUTTON_ACCELERATE);
Disable(IDC_BUTTON_SLOW);
Disable(IDC_BUTTON_FULLSCREEN);
Disable(IDC_RADIO_SEEK);
Disable(IDC_EDIT5);
Disable(IDC_BUTTON_GO);
UpdateData(FALSE);
}
void CYUVPlayerDlg::OnButtonStop()
{
unsigned char* temp;
KillTimer(1);
KillTimer(2);
pauseReserved = 0;
totalTime = 0;
m_nCurrentTime.Format(_T(" 0: 0: 0"));
if (m_pDisp != NULL)
{
ResetEvent(m_hTestEvent);
while (FrameQueue -> QEmpty() == FALSE)
{
temp = FrameQueue -> QOut();
free(temp);
}
FrameQueue -> ClearQueue();
m_pFile.SeekToBegin();
SetEvent(m_hTestEvent);
eventStart.SetEvent();
m_nFnow = 1;
m_nSlider = m_nFnow;
pSlide -> SetPos(m_nSlider);
m_nChange = 1;
}
Disable(IDC_BUTTON_STOP);
Enable(IDC_BUTTON_PLAY);
Disable(IDC_BUTTON_ACCELERATE);
Disable(IDC_BUTTON_SLOW);
Enable(IDC_COMBO_FRATE);
UpdateData(FALSE);
}
void CYUVPlayerDlg::OnPlay()
{
float interTime;
CButton *pbutton = (CButton *)GetDlgItem(IDC_BUTTON_GO);
m_nSeek = -1;
if (m_pDisp != NULL && m_nFnow != m_nFileLen)
{
UpdateData(TRUE);
interTime = 1000/atoi(m_nFRate);
SetTimer(1,interTime,NULL);
SetTimer(2,1000,NULL);
playStart = GetTickCount();
}
m_nSeek = -1;
m_nChange = 1;
pbutton->SetButtonStyle(BS_PUSHBUTTON);
Disable(IDC_BUTTON_PLAY);
Enable(IDC_BUTTON_STOP);
Enable(IDC_BUTTON_PAUSE);
Enable(IDC_BUTTON_ACCELERATE);
Enable(IDC_BUTTON_SLOW);
Disable(IDC_COMBO_FRATE);
Disable(IDC_EDIT5);
Disable(IDC_BUTTON_GO);
UpdateData(FALSE);
}
void CYUVPlayerDlg::OnPause()
{
KillTimer(1);
KillTimer(2);
pauseReserved = totalTime;
m_nChange = 1;
Enable(IDC_BUTTON_PLAY);
Disable(IDC_BUTTON_ACCELERATE);
Disable(IDC_BUTTON_SLOW);
Disable(IDC_BUTTON_PAUSE);
UpdateData(FALSE);
}
void CYUVPlayerDlg::OnTimer(UINT nIDEvent)
{
int playHR,playMin,playSec;
UpdateData(TRUE);
switch(nIDEvent)
{
case 1:
if (m_nFnow != m_nFileLen)
{
eventStart.SetEvent();
m_nFnow++;
FrameNow = m_nFnow;
m_nSlider = m_nFnow;
pSlide -> SetPos(m_nSlider);
}
else
{
OnButtonStop();
}
break;
case 2:
playTime = GetTickCount() - playStart;
totalTime = playTime + pauseReserved; //pauseReserved is set in OnPause();
playSec = (totalTime / 1000) % 60;
playMin = ((totalTime / 1000) / 60) % 60;
playHR = (totalTime / 1000) / 3600;
m_nCurrentTime.Format(_T("%2d:%2d:%2d"),playHR,playMin,playSec);
break;
}
UpdateData(FALSE);
}
void CYUVPlayerDlg::OnButtonSlow()
{
UpdateData(TRUE);
float interTime;
if (m_pDisp != NULL && m_nChange >= 0.2 && m_nFnow!=m_nFileLen)
{
m_nChange -= 0.1;
KillTimer(1);
interTime = 1000 / ((atoi(m_nFRate)) * m_nChange);
SetTimer(1,(UINT)interTime,NULL);
}
UpdateData(FALSE);
}
void CYUVPlayerDlg::OnButtonAccelerate()
{
UpdateData(TRUE);
float interTime;
if (m_pDisp != NULL && m_nChange < 5.0 && m_nFnow != m_nFileLen)
{
m_nChange += 0.1;
KillTimer(1);
interTime = 1000 / ((atoi(m_nFRate)) * m_nChange);
SetTimer(1,interTime,NULL);
}
UpdateData(FALSE);
}
void CYUVPlayerDlg::OnButtonNext()
{
if(m_pDisp != NULL && m_nFnow != m_nFileLen)
{
OnPause();
eventStart.SetEvent();
m_nFnow++;
m_nSlider = m_nFnow;
pSlide -> SetPos(m_nSlider);
UpdateData(FALSE);
}
}
void CYUVPlayerDlg::OnButtonPrevious()
{
unsigned char* temp;
if(m_pDisp != NULL && m_nFnow != 1)
{
OnPause();
ResetEvent(m_hTestEvent);
while (FrameQueue -> QEmpty() == FALSE)
{
temp = FrameQueue -> QOut();
free(temp);
}
FrameQueue -> ClearQueue();
m_pFile.Seek((m_nFnow - 2) * frameSize * 1.5, CFile::begin);
SetEvent(m_hTestEvent);
eventStart.SetEvent();
m_nFnow--;
m_nSlider = m_nFnow;
pSlide -> SetPos(m_nSlider);
UpdateData(FALSE);
}
}
void CYUVPlayerDlg::OnRadioSeek()
{
CButton *pbutton = (CButton *)GetDlgItem(IDC_BUTTON_GO);
if(m_nSeek == -1)
{
Enable(IDC_EDIT5);
Enable(IDC_BUTTON_GO);
m_nSeek = 0;
OnPause();
pbutton->SetButtonStyle(BS_DEFPUSHBUTTON);
}
else
{
m_nSeek = -1;
pbutton->SetButtonStyle(BS_PUSHBUTTON);
Disable(IDC_EDIT5);
Disable(IDC_BUTTON_GO);
}
UpdateData(FALSE);
}
void CYUVPlayerDlg::OnButtonSeek()
{
unsigned char * temp;
if(m_pDisp != NULL)
{
UpdateData(TRUE);
if ( m_nSeekNum <= 0 || m_nSeekNum > m_nFileLen)
{
AfxMessageBox(" out of range! ");
return;
}
else
{
ResetEvent(m_hTestEvent);
while (FrameQueue -> QEmpty() == FALSE)
{
temp=FrameQueue -> QOut();
free(temp);
}
FrameQueue -> ClearQueue();
m_pFile.Seek((m_nSeekNum - 1) * frameSize * 1.5, CFile::begin);
SetEvent(m_hTestEvent);
eventStart.SetEvent();
m_nFnow = m_nSeekNum;
m_nSlider = m_nFnow;
pSlide -> SetPos(m_nSlider);
UpdateData(FALSE);
}
}
}
void CYUVPlayerDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
unsigned char *temp;
if(m_pDisp != NULL)
{
pSlide = (CSliderCtrl *) pScrollBar;
m_nSlider = pSlide->GetPos();
m_nFnow = m_nSlider;
ResetEvent(m_hTestEvent);
while (FrameQueue -> QEmpty() == FALSE)
{
temp = FrameQueue -> QOut();
free(temp);
}
FrameQueue -> ClearQueue();
m_pFile.Seek((m_nSlider - 1) * frameSize * 1.5, CFile::begin);
SetEvent(m_hTestEvent);
eventStart.SetEvent();
UpdateData(FALSE);
}
}
void CYUVPlayerDlg::OnFullscreen()
{
if (m_pDisp != NULL)
{ if (m_pDisp -> m_FullScreen == FALSE)
m_pDisp -> FullScreen();
else
m_pDisp -> Endfullscreen();
}
}
void CYUVPlayerDlg::OnCancel()
{
if (m_pDisp != NULL && m_pDisp -> m_FullScreen == TRUE)
{
m_pDisp -> Endfullscreen();
}
else
if (m_pDisp == NULL)
CDialog::OnCancel();
}
void CYUVPlayerDlg::OnClickedCancel()
{
CDialog::OnCancel();
}
void CYUVPlayerDlg::OnSizeQcif()
{
UpdateData(TRUE);
m_nWidth = 176;
m_nHeight = 144;
Disable(IDC_EDIT_WIDTH);
Disable(IDC_EDIT_HEIGHT);
Disable(IDC_STATIC_H);
Disable(IDC_STATIC_W);
UpdateData(FALSE);
}
void CYUVPlayerDlg::OnSizeCif()
{
UpdateData(TRUE);
m_nWidth = 352;
m_nHeight = 288;
Disable(IDC_EDIT_WIDTH);
Disable(IDC_EDIT_HEIGHT);
Disable(IDC_STATIC_H);
Disable(IDC_STATIC_W);
UpdateData(FALSE);
}
void CYUVPlayerDlg::OnSize4cif()
{
UpdateData(TRUE);
m_nWidth = 704;
m_nHeight = 576;
Disable(IDC_EDIT_WIDTH);
Disable(IDC_EDIT_HEIGHT);
Disable(IDC_STATIC_H);
Disable(IDC_STATIC_W);
UpdateData(FALSE);
}
void CYUVPlayerDlg::Disable(int nID)
{
CWnd *pObject1;
pObject1 = GetDlgItem(nID);
pObject1 -> EnableWindow(FALSE);
}
void CYUVPlayerDlg::Enable(int nID)
{
CWnd *pObject1;
pObject1 = GetDlgItem(nID);
pObject1 -> EnableWindow(TRUE);
}
void CYUVPlayerDlg::OnSizeOthers()
{
Enable(IDC_EDIT_WIDTH);
Enable(IDC_EDIT_HEIGHT);
Enable(IDC_STATIC_H);
Enable(IDC_STATIC_W);
}