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

📄 pyuvplayerdlg.cpp

📁 WinCE下显示YUV格式视频的源代码
💻 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 + -