📄 pyuvplayerdlg.cpp
字号:
// PYuvPlayerDlg.cpp : implementation file
//
#include "stdafx.h"
#include "PYuvPlayer.h"
#include "PYuvPlayerDlg.h"
#include "SetupDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//进行YUV->RGB转换的函数
unsigned char *clp = NULL;
unsigned char *clp1;
long int crv_tab[256];
long int cbu_tab[256];
long int cgu_tab[256];
long int cgv_tab[256];
long int tab_76309[256];
void init_dither_tab ()
{
long int crv, cbu, cgu, cgv;
int i;
crv = 104597;
cbu = 132201; /* fra matrise i global.h */
cgu = 25675;
cgv = 53279;
for (i = 0; i < 256; i++)
{
crv_tab[i] = (i - 128) * crv;
cbu_tab[i] = (i - 128) * cbu;
cgu_tab[i] = (i - 128) * cgu;
cgv_tab[i] = (i - 128) * cgv;
tab_76309[i] = 76309 * (i - 16);
}
if (!(clp = (unsigned char *)malloc(sizeof(unsigned char)*1024)))
{
AfxMessageBox(L"安排解码码表内存失败!");
}
clp1 = clp;
clp += 384;
for (i = -384; i < 640; i++)
clp[i] = (i < 0) ? 0 : ((i > 255) ? 255 : i);
}
void ConvertYUVtoRGB (unsigned char *src0, unsigned char *src1, unsigned char *src2,
unsigned char *dst_ori,int width,int height)
{
int y11, y21;
int y12, y22;
int y13, y23;
int y14, y24;
int u, v;
int i, j;
int c11, c21, c31, c41;
int c12, c22, c32, c42;
unsigned int DW;
unsigned int *id1, *id2;
unsigned char *py1, *py2, *pu, *pv;
unsigned char *d1, *d2;
d1 = dst_ori;
d1 += width * height * 3 - width * 3;
d2 = d1 - width * 3;
py1 = src0;
pu = src1;
pv = src2;
py2 = py1 + width;
id1 = (unsigned int *) d1;
id2 = (unsigned int *) d2;
for (j = 0; j < height; j += 2)
{
/* line j + 0 */
for (i = 0; i < width; i += 4)
{
u = *pu++;
v = *pv++;
c11 = crv_tab[v];
c21 = cgu_tab[u];
c31 = cgv_tab[v];
c41 = cbu_tab[u];
u = *pu++;
v = *pv++;
c12 = crv_tab[v];
c22 = cgu_tab[u];
c32 = cgv_tab[v];
c42 = cbu_tab[u];
y11 = tab_76309[*py1++]; /* (255/219)*65536 */
y12 = tab_76309[*py1++];
y13 = tab_76309[*py1++]; /* (255/219)*65536 */
y14 = tab_76309[*py1++];
y21 = tab_76309[*py2++];
y22 = tab_76309[*py2++];
y23 = tab_76309[*py2++];
y24 = tab_76309[*py2++];
/* RGBR */
DW = ((clp[(y11 + c41) >> 16])) |
((clp[(y11 - c21 - c31) >> 16]) << 8) |
((clp[(y11 + c11) >> 16]) << 16) |
((clp[(y12 + c41) >> 16]) << 24);
*id1++ = DW;
/* GBRG */
DW = ((clp[(y12 - c21 - c31) >> 16])) |
((clp[(y12 + c11) >> 16]) << 8) |
((clp[(y13 + c42) >> 16]) << 16) |
((clp[(y13 - c22 - c32) >> 16]) << 24);
*id1++ = DW;
/* BRGB */
DW = ((clp[(y13 + c12) >> 16])) |
((clp[(y14 + c42) >> 16]) << 8) |
((clp[(y14 - c22 - c32) >> 16]) << 16) |
((clp[(y14 + c12) >> 16]) << 24);
*id1++ = DW;
/* RGBR */
DW = ((clp[(y21 + c41) >> 16])) |
((clp[(y21 - c21 - c31) >> 16]) << 8) |
((clp[(y21 + c11) >> 16]) << 16) |
((clp[(y22 + c41) >> 16]) << 24);
*id2++ = DW;
/* GBRG */
DW = ((clp[(y22 - c21 - c31) >> 16])) |
((clp[(y22 + c11) >> 16]) << 8) |
((clp[(y23 + c42) >> 16]) << 16) |
((clp[(y23 - c22 - c32) >> 16]) << 24);
*id2++ = DW;
/* BRGB */
DW = ((clp[(y23 + c12) >> 16])) |
((clp[(y24 + c42) >> 16]) << 8) |
((clp[(y24 - c22 - c32) >> 16]) << 16) |
((clp[(y24 + c12) >> 16]) << 24);
*id2++ = DW;
}
id1 -= (9 * width) >> 2;
id2 -= (9 * width) >> 2;
py1 += width;
py2 += width;
}
}
/////////////////////////////////////////////////////////////////////////////
// CPYuvPlayerDlg dialog
CPYuvPlayerDlg::CPYuvPlayerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CPYuvPlayerDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CPYuvPlayerDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CPYuvPlayerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CPYuvPlayerDlg)
DDX_Control(pDX, IDC_SLIDER_POS, m_ctrlSliderPos);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CPYuvPlayerDlg, CDialog)
//{{AFX_MSG_MAP(CPYuvPlayerDlg)
ON_BN_CLICKED(IDC_BUTTON_OPEN, OnButtonOpen)
ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON_SEEKTOBEGIN, OnButtonSeektobegin)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_POS, OnCustomdrawSliderPos)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_BUTTON_SET, OnButtonSet)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPYuvPlayerDlg message handlers
BOOL CPYuvPlayerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 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
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// Adjust display windows
CWnd *wnd,*bwnd;
CRect rect,brect;
// TODO: Add extra initialization here
// For remote video display window
wnd=this->GetDlgItem(IDC_REMOTEVIDEO); // Video display window
bwnd=this->GetDlgItem(IDC_REMOTEBORDER); // Border window...
bwnd->GetWindowRect(brect);
ScreenToClient(brect);
remote_wnd_x=brect.TopLeft().x+(brect.Width()-IMAGE_WIDTH)/2;
remote_wnd_y=brect.TopLeft().y+(brect.Height()-IMAGE_HEIGHT)/2;
// Centre the remote video window
wnd->SetWindowPos(&wndTop,remote_wnd_x-4,remote_wnd_y-4,IMAGE_WIDTH+9,IMAGE_HEIGHT+9,SWP_SHOWWINDOW | SWP_DRAWFRAME);
Width=176;
Height=144;
TotalFrames=0;
CurrentFrame=0;
m_hFile=NULL;
buffer=new unsigned char[Width*Height*1.5];
BMPbuffer=new unsigned char[Width*Height*3];
Swapbuffer=new unsigned char[Width*Height*3];
init_dither_tab();
m_bPlaying=FALSE;
CString inf;
inf.Format(L"宽度:%d 高度:%d 总帧数:%d 当前:%d",Width,Height,TotalFrames,CurrentFrame);
SetDlgItemText(IDC_INF,inf);
m_ctrlSliderPos.SetRange(0,100);
m_ctrlSliderPos.SetPos(0);
return TRUE; // return TRUE unless you set the focus to a control
}
void CPYuvPlayerDlg::OnButtonOpen()
{
//static short szFilter[]="YUV Files(*.YUV)|*.YUV||";
CFileDialog FileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,_T("YUV Files(*.YUV)|*.YUV||"));//Filter);
if(FileDlg.DoModal()==IDCANCEL)
{
return;
}
//打开文件
if(m_hFile)
{
CloseHandle(m_hFile);
m_hFile=NULL;
}
m_hFile=CreateFile(FileDlg.GetPathName(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE==m_hFile)
{
AfxMessageBox(L"打开文件失败");
m_hFile=NULL;
return;
}
DWORD length;
TotalFrames=GetFileSize(m_hFile,&length);
TotalFrames/=(Width*Height*1.5);
CurrentFrame=0;
CString inf;
inf.Format(L"宽度:%d 高度:%d 总帧数:%d 当前:%d",Width,Height,TotalFrames,CurrentFrame);
SetDlgItemText(IDC_INF,inf);
m_ctrlSliderPos.SetRange(0,TotalFrames,TRUE);
m_ctrlSliderPos.SetPos(0);
DisplayFrame(CurrentFrame);
}
void CPYuvPlayerDlg::DisplayFrame(int frame)
{
if(CurrentFrame>TotalFrames)
{
CurrentFrame=TotalFrames;
}
DWORD dwRead;
SetFilePointer(m_hFile,frame*(Width*Height*1.5),NULL,FILE_BEGIN);
ReadFile(m_hFile,buffer,Width*Height*1.5,&dwRead,NULL);
CString inf;
inf.Format(L"宽度:%d 高度:%d 总帧数:%d 当前:%d",Width,Height,TotalFrames,CurrentFrame);
SetDlgItemText(IDC_INF,inf);
m_ctrlSliderPos.SetPos(CurrentFrame);
//YUV转RGB
ConvertYUVtoRGB((unsigned char*)buffer,(unsigned char*)(buffer+(Width*Height)),(unsigned char*)(buffer+(int)(Width*Height*1.25)),Swapbuffer,Width,Height);
for(int y=0;y<Height;y++)
{
memcpy(BMPbuffer+y*Width*3,Swapbuffer+(Height-y)*Width*3,3*Width);
}
//绘画
CBitmap bitmap;
//ZeroMemory(BMPbuffer,Width*Height*3);
bitmap.CreateBitmap(Width,Height,1,24,BMPbuffer);
CWnd* pWnd=GetDlgItem(IDC_REMOTEVIDEO);
pWnd->UpdateWindow();
CDC* pDC=pWnd->GetDC();
CDC bitmapDC;
bitmapDC.CreateCompatibleDC(pDC);
CBitmap* pOldBitmap = bitmapDC.SelectObject(&bitmap);
pDC->StretchBlt(0,0,176,144,&bitmapDC,0,0,Width,Height,SRCCOPY);
//pDC->BitBlt(0,0,176,144,&bitmapDC,0,0,SRCCOPY);
bitmapDC.SelectObject(pOldBitmap);
bitmapDC.DeleteDC();
bitmap.DeleteObject();
}
void CPYuvPlayerDlg::OnButtonPlay()
{
if(!m_bPlaying)
{
SetTimer(123,66,NULL);
m_bPlaying=TRUE;
SetDlgItemText(IDC_BUTTON_PLAY,L"停止");
}
else
{
KillTimer(123);
m_bPlaying=FALSE;
SetDlgItemText(IDC_BUTTON_PLAY,L"播放");
}
}
void CPYuvPlayerDlg::OnTimer(UINT nIDEvent)
{
if(nIDEvent==123)
{
if(CurrentFrame>=TotalFrames)
{
KillTimer(123);
m_bPlaying=FALSE;
SetDlgItemText(IDC_BUTTON_PLAY,L"播放");
CurrentFrame=0;
return;
}
CurrentFrame++;
DisplayFrame(CurrentFrame);
}
CDialog::OnTimer(nIDEvent);
}
void CPYuvPlayerDlg::OnButtonSeektobegin()
{
CurrentFrame=0;
DisplayFrame(CurrentFrame);
}
void CPYuvPlayerDlg::OnCustomdrawSliderPos(NMHDR* pNMHDR, LRESULT* pResult)
{
CurrentFrame=m_ctrlSliderPos.GetPos();
if(!m_bPlaying)
{
DisplayFrame(CurrentFrame);
}
*pResult = 0;
}
void CPYuvPlayerDlg::OnDestroy()
{
CDialog::OnDestroy();
KillTimer(123);
if(buffer)
{
delete buffer;
}
if(BMPbuffer)
{
delete BMPbuffer;
}
if(Swapbuffer)
{
delete Swapbuffer;
}
}
void CPYuvPlayerDlg::OnButtonSet()
{
CSetupDlg Dialog1;
Dialog1.m_iHeight=Height;
Dialog1.m_iWidth=Width;
if(Dialog1.DoModal()==IDOK)
{
if(!((Dialog1.m_iWidth==176&&Dialog1.m_iHeight==144)||
(Dialog1.m_iWidth==160&&Dialog1.m_iHeight==120)||
(Dialog1.m_iWidth==320&&Dialog1.m_iHeight==240)||
(Dialog1.m_iWidth==352&&Dialog1.m_iHeight==288)||
(Dialog1.m_iWidth==640&&Dialog1.m_iHeight==480)))
{
AfxMessageBox(L"参数错误!");
return;
}
Width=Dialog1.m_iWidth;
Height=Dialog1.m_iHeight;
KillTimer(123);
m_bPlaying=FALSE;
SetDlgItemText(IDC_BUTTON_PLAY,L"播放");
CurrentFrame=0;
TotalFrames=0;
CloseHandle(m_hFile);
m_hFile=NULL;
if(buffer)
{
delete buffer;
}
if(BMPbuffer)
{
delete BMPbuffer;
}
if(Swapbuffer)
{
delete Swapbuffer;
}
buffer=new unsigned char[Width*Height*1.5];
BMPbuffer=new unsigned char[Width*Height*3];
Swapbuffer=new unsigned char[Width*Height*3];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -