📄 h264ce.cpp
字号:
return TRUE;
}
BOOL CloseGAPI()
{
return GXCloseDisplay();
}
void Blt(int x,int y,int width,int height,unsigned char *data)
{
int i;
unsigned short * VideoBuffer=(unsigned short *)GXBeginDraw();
for(i=0;i<25344;i++)
{
*(VideoBuffer+((25344-i)/176+y)*g_gxdp.cxWidth+i%176+x)=RGBto16bit565(data[3*i+1],data[3*i+2],data[3*i]);
}
GXEndDraw(); //绘图完毕一定要结束
}
void DisplayVideo(unsigned char* displaybuf)
{
if(!m_bGapi)
{
return;
}
ConvertYUVtoRGB(displaybuf,(displaybuf+25344),(displaybuf+31680),bufRGB,width,height);
//GAPI绘图
Blt(30,50,176,144,bufRGB);
}
//解码线程
DWORD DecodeThread(void *para)
{
THDP* threadpara=(THDP*)para;
FILE * inpf;
//FILE * outf;
int nWrite;
int i,p;
int nalLen;
unsigned char* Buf;
int got_picture, consumed_bytes;
unsigned char *DisplayBuf;
DisplayBuf=(unsigned char *)malloc(60000);
char outfile[] = "test.pgm";
//读取文件
char *name;
name=new char [wcslen(threadpara->File)];
//中文转换
int actuallength=0;
actuallength=WideCharToMultiByte(CP_ACP,NULL,(LPCWSTR)threadpara->File,wcslen(threadpara->File),(LPSTR)name,0,NULL,NULL);
delete name;
name=new char [actuallength];
ZeroMemory(name,actuallength);
WideCharToMultiByte(CP_ACP,NULL,(LPCWSTR)threadpara->File,wcslen(threadpara->File),(LPSTR)name,actuallength,NULL,NULL);
inpf = fopen(name, "rb");
LocalFree(threadpara->File);
delete name;
//outf = fopen("out.yuv", "wb");
if(!inpf)
{
goto Decodereturn;
}
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;
}
rgbdatanew = (unsigned char *)malloc(sizeof(unsigned char)*(3 * width * height));
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;
}
//向窗口发送消息显示画面
//::SendMessage(threadpara->hWnd,WM_DISPLAY_FRAME,(WPARAM)DisplayBuf,(LPARAM)p);
DisplayVideo(DisplayBuf);
}
}
if(inpf)
fclose(inpf);
/*
if(outf)
fclose(outf);
*/
Decodereturn:
if(c) {
avcodec_close(c);
av_free(c);
c = NULL;
}
if(picture) {
av_free(picture);
picture = NULL;
}
if(Buf)
{
free(Buf);
Buf = NULL;
}
free(DisplayBuf);
free(rgbdatanew);
//::SendMessage(threadpara->hWnd,WM_DECODE_COMPLETE,(WPARAM)NULL,(LPARAM)NULL);
CloseGAPI();
//AE by tiany for test on 20060331
return 0;
}
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_H264CE);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// It is important to call this function so that the application
// will get 'well formed' small icons associated with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_H264CE));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd = NULL;
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The window class name
g_hInst = hInstance; // Store instance handle in our global variable
// Initialize global strings
LoadString(hInstance, IDC_H264CE, szWindowClass, MAX_LOADSTRING);
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
//If it is already running, then focus on the window
hWnd = FindWindow(szWindowClass, szTitle);
if (hWnd)
{
// set focus to foremost child window
// The "| 0x01" is used to bring any owned windows to the foreground and
// activate them.
SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
return 0;
}
MyRegisterClass(hInstance, szWindowClass);
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
//When the main window is created using CW_USEDEFAULT the height of the menubar (if one
// is created is not taken into account). So we resize the window after creating it
// if a menubar is present
if (g_hwndCB)
{
RECT rc;
RECT rcMenuBar;
GetWindowRect(hWnd, &rc);
GetWindowRect(g_hwndCB, &rcMenuBar);
rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE);
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
// Mesage handler for the open dialog
LRESULT CALLBACK Open(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
SHINITDLGINFO shidi;
switch (message)
{
case WM_INITDIALOG:
// Create a Done button and size it.
shidi.dwMask = SHIDIM_FLAGS;
shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
shidi.hDlg = hDlg;
SHInitDialog(&shidi);
// provide a default file name
SetDlgItemText(hDlg, IDC_OPENFILE, _T("\\My Documents\\test.264"));
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
// allocate memory for the file name the user typed in
TCHAR* pszFileName = NULL;
pszFileName = (TCHAR*)LocalAlloc(LPTR, MAX_PATH);
if(pszFileName)
{
// get the file name
GetDlgItemText(hDlg, IDC_OPENFILE, pszFileName, MAX_PATH);
// end the dialog passing a pointer to the TCHAR string
EndDialog(hDlg, (INT)pszFileName);
}
else
{
MessageBox(hDlg, TEXT("无法为文件名称分配内存"), TEXT("打开错误"), MB_OK);
EndDialog(hDlg, NULL);
}
return TRUE;
}
if(LOWORD(wParam) == IDC_CANCEL)
{
// send null as return value so we know the user clicked cancel
EndDialog(hDlg, NULL);
return TRUE;
}
break;
}
return FALSE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
int wmId, wmEvent;
PAINTSTRUCT ps;
TCHAR szTitle[MAX_LOADSTRING];
static THDP threadpara;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_HELP_ABOUT:
DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDOK:
SendMessage (hWnd, WM_CLOSE, 0, 0);
break;
case IDM_EXIT:
//如果有的话,停止解码线程
if(hDecodeThread)
{
TerminateThread(hDecodeThread,0);
CloseHandle(hDecodeThread);
hDecodeThread=NULL;
CloseGAPI();
m_bGapi=FALSE;
}
free(clp1);
DestroyWindow(hWnd);
break;
case ID_FILE_OPEN:
{
//如果有的话,停止解码线程
if(hDecodeThread)
{
TerminateThread(hDecodeThread,0);
CloseHandle(hDecodeThread);
hDecodeThread=NULL;
CloseGAPI();
m_bGapi=FALSE;
}
TCHAR* pszFileToOpen = NULL;
// get the name of the file the user wishes to use
pszFileToOpen = (TCHAR*)DialogBox(g_hInst, (LPCTSTR)IDD_OPEN, NULL, (DLGPROC)Open);
// check to see if we returned null - means the user clicked cancel
if(pszFileToOpen)
{
// check to see if the file name has greater than 0 length
if(wcslen(pszFileToOpen))
{
//打开文件并且播放
//如果有的话,停止解码线程
if(hDecodeThread)
{
TerminateThread(hDecodeThread,0);
CloseHandle(hDecodeThread);
hDecodeThread=NULL;
CloseGAPI();
m_bGapi=FALSE;
}
//开始解码线程
//m_bDecoding=TRUE;
m_bGapi=OpenGAPI(&hWnd);
//SetDlgItemText(IDC_PLAY,_T("停止解码"));
threadpara.hWnd=hWnd;
threadpara.File=pszFileToOpen;
hDecodeThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DecodeThread,(void*)&threadpara,0,&dwThreadID);
}
}
}
break;
case ID_TOOL_STOP:
//如果有的话,停止解码线程
if(hDecodeThread)
{
TerminateThread(hDecodeThread,0);
CloseHandle(hDecodeThread);
hDecodeThread=NULL;
CloseGAPI();
m_bGapi=FALSE;
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_CREATE:
g_hwndCB = CreateRpCommandBar(hWnd);
// Initialize the shell activate info structure
memset (&s_sai, 0, sizeof (s_sai));
s_sai.cbSize = sizeof (s_sai);
//初始化显示
width=IMAGE_WIDTH;height=IMAGE_HEIGHT;
//bufRGB = (unsigned char *)malloc(sizeof(unsigned char)*(3 * width * height));
init_dither_tab();
//m_bDecoding=FALSE;
hDecodeThread=NULL;
break;
case WM_PAINT:
RECT rt;
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rt);
LoadString(g_hInst, IDS_TITLE, szTitle, MAX_LOADSTRING);
rt.top=0;
rt.bottom=20;
DrawText(hdc, szTitle, _tcslen(szTitle), &rt,
DT_SINGLELINE | DT_VCENTER | DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
CommandBar_Destroy(g_hwndCB);
PostQuitMessage(0);
break;
case WM_ACTIVATE:
// Notify shell of our activate message
SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
break;
case WM_SETTINGCHANGE:
SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
break;
case WM_DISPLAY_FRAME:
unsigned char* DisplayBuf;
DisplayBuf=(unsigned char*)wParam;
DisplayVideo(DisplayBuf);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
HWND CreateRpCommandBar(HWND hwnd)
{
SHMENUBARINFO mbi;
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hwnd;
mbi.nToolBarId = IDM_MENU;
mbi.hInstRes = g_hInst;
mbi.nBmpId = 0;
mbi.cBmpImages = 0;
if (!SHCreateMenuBar(&mbi))
return NULL;
return mbi.hwndMB;
}
// Mesage handler for the About box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
SHINITDLGINFO shidi;
switch (message)
{
case WM_INITDIALOG:
// Create a Done button and size it.
shidi.dwMask = SHIDIM_FLAGS;
shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
shidi.hDlg = hDlg;
SHInitDialog(&shidi);
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -