📄 h264decodedlg.cpp
字号:
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 + -