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

📄 h264decodedlg.cpp

📁 H264EncPlayer,H264协议解码与播放代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	CenterWindow(GetDesktopWindow());	// center to the hpc screen

	// TODO: Add extra initialization here
	
	m_strDecodeFile="";

	m_bDecoding=FALSE;

	//初始化视频窗口
	// Adjust display windows
	int remote_wnd_x , remote_wnd_y;
	CWnd *wnd,*bwnd;
	CRect rect,brect;

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

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

int32_t CH264DecodeDlg::decode()
{
	SYSTEMTIME beg,end;
	float total_time;
    /* just for show how to drive the decoder */
#define BUFFER_SIZE 4096
    T264_t* t = T264dec_open();
    uint8_t buffer[BUFFER_SIZE + 4];
    int32_t run = 1,screen = 0;
	char *a=new char[m_strDecodeFile.GetLength()];
	for(int i=0;i<m_strDecodeFile.GetLength();i++)
	{
		a[i]=m_strDecodeFile.GetAt(i);
	}
    FILE* src_file = fopen(a, "rb");
	delete a;
    size_t size;
    FILE* f_rec = 0;
	//for decoder PSNR
	int frame_num = 0;
	FILE* f_ref = 0;
	uint8_t *ref_buf = NULL;
    int32_t frame_nums = 0;

	CString m_strOutInformation;
	CString m_strTemp;

	m_strOutInformation="";


	
    //支持解码
    m_strOutInformation+=L"目前全部支持T264编码器比特流!\r\n";

    if (!src_file)
    {
        AfxMessageBox("无法打开文件!"+m_strDecodeFile);
        return -1;
    }
    if (rec_path[0])
    {
        f_rec = fopen(rec_path, "wb");
        if (!f_rec)
        {
            //printf("cannot open rec file %s.\n", rec_path);
        }
    }
	//for decoder PSNR
	if(ref_path[0])
	{
		f_ref = fopen(ref_path, "rb");
		if(!f_ref)
		{
			printf("cannot open ref file %s.\n", ref_path);
		}
	}

	GetSystemTime(&beg);

    while (run) 
    {
        decoder_state_t state = T264dec_parse(t);
        switch(state) 
        {
        case DEC_STATE_BUFFER:
            /* read more data */
            size = fread(buffer, 1, BUFFER_SIZE, src_file);
            if (size > 0)
            {
                if (size != BUFFER_SIZE)
                {
                    buffer[size] = 0;
                    buffer[size + 1] = 0;
                    buffer[size + 2] = 0;
                    buffer[size + 3] = 1;
                    size += 4;
                }

                T264dec_buffer(t, buffer, size);
            }
            else
            {
                /* if all data has readed, here we will return */
                run = 0;
                /* NOTE: here we should get the last frame */
                write_frame(t, T264dec_flush_frame(t), f_rec);
				//显示最后一帧画面
				PlayingVideo=FALSE;
				VideoDisplay(t, T264dec_flush_frame(t));
				DisplayVideo(bufRGB);

                frame_nums ++;
            }
            break;
        case DEC_STATE_PIC:
            /* write one pic */
            break;
        case DEC_STATE_SEQ:

            if (screen == 0)
            {
				//初始化显示窗口
				//初始化视频窗口
				
				width=t->width;
				height=t->height;
				bufRGB = (unsigned char *)malloc(sizeof(unsigned char)*(3 * width * height));
				init_dither_tab();

				PlayingVideo=TRUE;

                screen++;
            }
            if (t->frame_id > 0)
            {
                /* NOTE: here we should get the last frame */
                write_frame(t, T264dec_flush_frame(t), f_rec);
				//显示最后一帧画面
				PlayingVideo=FALSE;
				VideoDisplay(t, T264dec_flush_frame(t));
				DisplayVideo(bufRGB);

                frame_nums ++;
            }
			//显示参考帧和画面尺寸信息
			m_strTemp.Format(L"参考帧数目: %d。\r\n", t->ss.num_ref_frames);
			m_strOutInformation+=m_strTemp;
            m_strTemp.Format(L"宽度: %d.\r\n", (t->ss.pic_width_in_mbs_minus1 + 1) << 4);
			m_strOutInformation+=m_strTemp;
            m_strTemp.Format(L"高度: %d.\r\n", (t->ss.pic_height_in_mbs_minus1 + 1) << 4);
			m_strOutInformation+=m_strTemp;
            break;
        case DEC_STATE_SLICE:
            {
                if (t->output.poc >= 0)
                {
                    write_frame(t, &t->output, f_rec);
				//for decoder PSNR
				if(f_ref)
				{
					float psnr_y, psnr_u, psnr_v;
					int size;
					size = t->width*t->height;
					if(ref_buf == NULL)
					{
						ref_buf = (uint8_t *)malloc(size);
					}
					
					if(ref_buf != NULL)
					{
						uint8_t *p;
						p = t->output.Y[0];
						fread(ref_buf, 1, size, f_ref);
						psnr_y = dec_psnr(p, ref_buf, t->edged_stride, t->width, t->height, 0);

						size >>= 2;
						p = t->output.U;
						fread(ref_buf, 1, size, f_ref);
						psnr_u = dec_psnr(p, ref_buf, t->edged_stride_uv, t->width>>1, t->height>>1, 0);
						p = t->output.V;
						fread(ref_buf, 1, size, f_ref);
						psnr_v = dec_psnr(p, ref_buf, t->edged_stride_uv, t->width>>1, t->height>>1, 0);
						//显示信噪比信息
						m_strTemp.Format(L"%4d, %.2f, %.2f, %.2f\n", frame_num++, psnr_y, psnr_u, psnr_v);
						m_strOutInformation+=m_strTemp;
						if(ref_skip > 0)
						{
							fseek(f_ref, ref_skip*size*6, SEEK_CUR);
						}
					}
				}
				//显示一帧画面
				VideoDisplay(t, &t->output);
				DisplayVideo(bufRGB);
				
				frame_nums ++;                
                }
            };
            break;
        case DEC_STATE_CUSTOM_SET:
            {
				//显示是否使用了快速插值
				m_strTemp.Format(L"是否使用了快速插值: %s.\r\n", t->flags & USE_FASTINTERPOLATE ? L"是" : L"否");
				m_strOutInformation+=m_strTemp;
            }
            break;
        default:
            /* do not care */
            break;
        }
    };

#ifndef CHIP_DM642

	GetSystemTime(&end);

	total_time = (float)(end.wHour*3600+end.wMinute*60+end.wSecond - beg.wHour*3600-beg.wMinute*60-beg.wSecond) + (float)(end.wMilliseconds - beg.wMilliseconds) / 1000;

	SetDlgItemText(IDC_DECODE,_T("解码"));	
	m_bDecoding=FALSE;
	//显示播放速度信息
	m_strTemp.Format(L"fps: %.2ffps(总共解码: %d 帧).\r\n", (float)frame_nums / total_time, frame_nums);
	m_strOutInformation+=m_strTemp;
	AfxMessageBox(m_strOutInformation);
#endif    
#ifdef CHIP_DM642
	printf("fps: %.2ffps(total decode: %d frames).\n", (float)frame_nums / total_time, frame_nums);
#endif
    T264dec_close(t);
    fclose(src_file);
    if (f_rec)
        fclose(f_rec);
	if (f_ref)
		fclose(f_ref);
	if(ref_buf != NULL)
		free(ref_buf);

	//关闭播放窗口
	
	if(bufRGB != NULL)
	{
		free(bufRGB);
	}
	if(clp1 != NULL)
	{
		free(clp1);
	}
	PlayingVideo=FALSE;
	

    return 0;
}

void CH264DecodeDlg::DisplayVideo(unsigned char *rgbdata)
{	
	int x,y;
	unsigned char temp;
	if(PlayingVideo)
	{
		for(y=0;y<144;y++)
		{
			for(x=0;x<88;x++)
			{			
				temp=rgbdata[(176*y+x)*3];
				rgbdata[(176*y+x)*3]=rgbdata[(176*y+176-x)*3];
				rgbdata[(176*y+176-x)*3]=temp;
				
				temp=rgbdata[(176*y+x)*3+1];
				rgbdata[(176*y+x)*3+1]=rgbdata[(176*y+176-x)*3+1];
				rgbdata[(176*y+176-x)*3+1]=temp;
				
				temp=rgbdata[(176*y+x)*3+2];
				rgbdata[(176*y+x)*3+2]=rgbdata[(176*y+176-x)*3+2];
				rgbdata[(176*y+176-x)*3+2]=temp;
			}
		}
		for(x=0;x<38016;x++)
		{
			temp=rgbdata[x];
			rgbdata[x]=rgbdata[76032-x];
			rgbdata[76032-x]=temp;
		}
	}

	/*CString strResult;
	strResult.Format(_T("%d"),retvalue);
	AfxMessageBox(strResult);*/
	
	CBitmap bitmap;
	
	bitmap.CreateBitmap(176,144,1,24,rgbdata);

	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,176,144,SRCCOPY);
	pDC->BitBlt(0,0,176,144,&bitmapDC,0,0,SRCCOPY);
	bitmapDC.SelectObject(pOldBitmap);
	bitmap.DeleteObject();
}

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

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

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

//解码线程
DWORD CH264DecodeDlg::DecodeThread(void *pDlg)
{
	((CH264DecodeDlg*)pDlg)->decode();

	return 0;
}

⌨️ 快捷键说明

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