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

📄 h264playerdlg.cpp

📁 WinCE 2003上播放 H.264视频的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:

      /* 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;
  }
}


/////////////////////////////////////////////////////////////////////////////
// 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()

/////////////////////////////////////////////////////////////////////////////
// CH264PlayerDlg dialog

CH264PlayerDlg::CH264PlayerDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CH264PlayerDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CH264PlayerDlg)
		// 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 CH264PlayerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CH264PlayerDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CH264PlayerDlg, CDialog)
	//{{AFX_MSG_MAP(CH264PlayerDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_PLAY, OnPlay)
	ON_WM_DESTROY()
	ON_MESSAGE(WM_DISPLAY_FRAME,OnDisplayFrameMsg)	
	ON_MESSAGE(WM_DECODE_COMPLETE,OnDecodeCompleteMsg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CH264PlayerDlg message handlers

BOOL CH264PlayerDlg::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
	//初始化视频窗口
	// Adjust display windows	

	// 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);

	// Initialize DIB for drawing...
	// Setup bmpinfo structure yourself
	m_bmpinfo=new BITMAPINFO;
	m_bmpinfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
	m_bmpinfo->bmiHeader.biWidth=IMAGE_WIDTH;
	m_bmpinfo->bmiHeader.biHeight=IMAGE_HEIGHT;
	m_bmpinfo->bmiHeader.biPlanes=1;
	m_bmpinfo->bmiHeader.biBitCount=24;
	m_bmpinfo->bmiHeader.biCompression=0;
	m_bmpinfo->bmiHeader.biSizeImage=0;
	m_bmpinfo->bmiHeader.biXPelsPerMeter=0;
	m_bmpinfo->bmiHeader.biYPelsPerMeter=0;
	m_bmpinfo->bmiHeader.biClrUsed=0;
	m_bmpinfo->bmiHeader.biClrImportant=0;
	// Get Dialog DC
	m_hdc=this->GetDC()->m_hDC;
	hdib=::DrawDibOpen();
	if(hdib!=NULL)
	{
	 
		::DrawDibBegin(hdib,
					   m_hdc,
					   -1,				// don't stretch
					   -1,				// don't stretch
					   &m_bmpinfo->bmiHeader,
					   IMAGE_WIDTH,         // width of image
					   IMAGE_HEIGHT,        // height of image
					   0				
					   );
	
	}

	//初始化显示
	width=IMAGE_WIDTH;height=IMAGE_HEIGHT;
	//bufRGB = (unsigned char *)malloc(sizeof(unsigned char)*(3 * width * height));
	init_dither_tab();

	m_bDecoding=FALSE;
	hDecodeThread=NULL;

	FileName="";
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CH264PlayerDlg::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 CH264PlayerDlg::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 CH264PlayerDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CH264PlayerDlg::OnPlay() 
{
	if(!m_bDecoding)
	{
		//获取输入文件和输出文件名称
		CFileDialog FileDlg1(TRUE,NULL,NULL,OFN_HIDEREADONLY,TEXT("264 Files(*.264)|*.264||"));
		//FileDlg1.m_pOFN->lpstrTitle="请选择需要解码的文件";
		if(FileDlg1.DoModal()==IDOK)
		{
			FileName=FileDlg1.GetPathName();
		}
		else
		{
			return;
		}

		//如果有的话,停止解码线程
		if(hDecodeThread)
		{
			TerminateThread(hDecodeThread,0);
			CloseHandle(hDecodeThread);
			hDecodeThread=NULL;
		}

		//开始解码线程
		m_bDecoding=TRUE;
		SetDlgItemText(IDC_PLAY,_T("停止解码"));
		hDecodeThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DecodeThread,(void *)this,0,&dwThreadID);
	}
	else
	{
		SetDlgItemText(IDC_PLAY,_T("解码"));
		//停止编码线程
		if(hDecodeThread)
		{
			TerminateThread(hDecodeThread,0);
			CloseHandle(hDecodeThread);
			hDecodeThread=NULL;
		}
		m_bDecoding=FALSE;
	}
}

//解码线程
DWORD CH264PlayerDlg::DecodeThread(void *pDlg)
{
	CH264PlayerDlg* pDialog=(CH264PlayerDlg*)pDlg;

	FILE * inpf;
	//FILE * outf;
	int nWrite;
	int i,p;
	int nalLen;
	unsigned char* Buf;
	int  got_picture, consumed_bytes; 
	unsigned char *DisplayBuf;
	DisplayBuf=new unsigned char[60000];
	
	char outfile[] = "test.pgm";
	inpf = fopen(pDialog->FileName.GetBuffer(0), "rb");
	//outf = fopen("out.yuv", "wb");

	nalLen = 0;
	Buf = (unsigned char*)calloc ( 1000000, sizeof(char));


	avcodec_init(); 
	avcodec_register_all(); 
	codec = avcodec_find_decoder(CODEC_ID_H264);

	if (!codec)  {
		return 0; 
	} 
		//allocate codec context
    c = avcodec_alloc_context(); 

	if(!c){
		return 0;
	}
	//open codec
    if (avcodec_open(c, codec) < 0) {
		return 0; 
	} 
	
	//allocate frame buffer
    picture   = avcodec_alloc_frame();
	if(!picture){
		return 0;
	}

	while(!feof(inpf))
	{
		
		nalLen = getNextNal(inpf, Buf);

		//try to decode this frame
//		consumed_bytes= decode_frame(c, picture, &got_picture, Buf, nalLen); 
//		if (got_picture > 0)
//	       c->frame_number++;

		consumed_bytes= avcodec_decode_video(c, picture, &got_picture, Buf, nalLen);

		if(consumed_bytes > 0)
		{
			/*
			for(i=0; i<c->height; i++)
				fwrite(picture->data[0] + i * picture->linesize[0], 1, c->width, outf);
			for(i=0; i<c->height/2; i++)
				fwrite(picture->data[1] + i * picture->linesize[1], 1, c->width/2, outf);
			for(i=0; i<c->height/2; i++)
				fwrite(picture->data[2] + i * picture->linesize[2], 1, c->width/2, outf);
				*/
			p=0;
			for(i=0; i<c->height; i++)
			{
				memcpy(DisplayBuf+p,picture->data[0] + i * picture->linesize[0], c->width);
				p+=c->width;
			}
			for(i=0; i<c->height/2; i++)
			{
				memcpy(DisplayBuf+p,picture->data[1] + i * picture->linesize[1], c->width/2);
				p+=c->width/2;
			}
			for(i=0; i<c->height/2; i++)
			{
				memcpy(DisplayBuf+p,picture->data[2] + i * picture->linesize[2], c->width/2);
				p+=c->width/2;
			}
			//向窗口发送消息显示画面
			pDialog->SendMessage(WM_DISPLAY_FRAME,(WPARAM)DisplayBuf,(LPARAM)p);
		}
	}

	if(inpf)
		fclose(inpf);

	/*
	if(outf)
		fclose(outf);
		*/

	if(c) {
		avcodec_close(c); 
		av_free(c);
		c = NULL;
	} 
	if(picture) {
		av_free(picture);
		picture = NULL;
	}

	if(Buf)
	{
		free(Buf);
		Buf = NULL;
	}    

	delete DisplayBuf;

	pDialog->SendMessage(WM_DECODE_COMPLETE,(WPARAM)NULL,(LPARAM)NULL);

//AE by tiany for test on 20060331
    return 0;
}

void CH264PlayerDlg::DisplayVideo(unsigned char* displaybuf)
{
	ConvertYUVtoRGB (displaybuf,(displaybuf+25344),(displaybuf+31680),bufRGB,width,height);
	
	unsigned char* rgbdata=bufRGB;
	
	::DrawDibDraw(hdib,
				  m_hdc,
				  remote_wnd_x,		// dest : left pos
				  remote_wnd_y,		// dest : top pos
				  -1,					 // don't zoom x
				  -1,					 // don't zoom y
				  &m_bmpinfo->bmiHeader,			 // bmp header info
				  rgbdata,					 // bmp data
				  0,					 // src :left
				  0,					 // src :top
				  IMAGE_WIDTH,				 // src : width
				  IMAGE_HEIGHT,				 // src : height
				  DDF_SAME_DRAW			 // use prev params....
				  );
}

void CH264PlayerDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	if(m_bmpinfo)
	{
		delete m_bmpinfo;
	}
	// Close graphics....
	if(hdib!=NULL)
	{
		::DrawDibEnd(hdib);
		::DrawDibClose(hdib);
	}

	free(clp1);
}

LONG CH264PlayerDlg::OnDisplayFrameMsg(WPARAM wParam,LPARAM lParam)
{
	unsigned char* DisplayBuf=(unsigned char*)wParam;
	int length=(int)lParam;

	int i;
	for(i=0;i<length/38016;i++)
	{
		DisplayVideo(DisplayBuf+i*38016);
	}

	return 1;
}

LONG CH264PlayerDlg::OnDecodeCompleteMsg(WPARAM wParam,LPARAM lParam)
{
	SetDlgItemText(IDC_PLAY,_T("解码"));
	//停止编码线程
	if(hDecodeThread)
	{
		TerminateThread(hDecodeThread,0);
		CloseHandle(hDecodeThread);
		hDecodeThread=NULL;
	}
	m_bDecoding=FALSE;

	return 1;
}

⌨️ 快捷键说明

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