📄 h264ce.cpp
字号:
//can't jump here
break;
}
i_cur++;//!!
}//end of while (i_cur<i_data_size && !b_find_nal)
//when we haven't found a nal...
if (!b_find_nal && !b_eof_h264)
{
b_need_buffer=1;
continue;
}
//judge decode finish
if (i_cur>=i_data_size)
{
if (b_eof_h264)
{
i_start_code_size=0;//for it is the last nal //lsp!!!!
b_decode_finish=1;
}
else
{
b_need_buffer=1; //the buffer is extractly used over
}
}
__try
{
consumed_bytes= avcodec_decode_video(c, picture, &got_picture, &data[i_nal_start-i_start_code_size], i_cur-i_nal_start);
//DEBUGMSG(1,(L"data:%d length:%d\r\n",data[i_nal_start-i_start_code_size+4],i_cur-i_nal_start));
i_nal_start=i_cur;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
if(consumed_bytes > 0)
{
/*
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;
}
//显示画面
DisplayYUV(colortab,rgb_2_pix,DisplayBuf,(DisplayBuf+76800),(DisplayBuf+96000),VideoBuffer,240,320,1);
*/
memcpy(displaypicture,picture,sizeof(AVFrame));
SetEvent(hDisplayEvent);
i_frames++;
}
}//end of while (!b_ctrl_c)
EndTime=GetTickCount();
Decodereturn:
//结束显示线程
bDisplay=FALSE;
SetEvent(hDisplayEvent);
WaitForSingleObject(hDisplayThread,INFINITE);
CloseHandle(hDisplayEvent);
CloseHandle(hDisplayThread);
GXEndDraw(); //绘图完毕一定要结束
CloseGAPI();
if(inpf)
{
fclose(inpf);
}
if(c) {
avcodec_close(c);
av_free(c);
c = NULL;
}
if(picture) {
av_free(picture);
picture = NULL;
}
if(displaypicture)
{
av_free(displaypicture);
displaypicture=NULL;
}
delete data;
delete DisplayBuf;
wsprintf(fps,L"%f fps",(float)(1000*i_frames)/(float)(EndTime-StartTime));
MessageBox(NULL,fps,L"H264CE",MB_OK);
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\\qvga.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:
FreeYUVTable();
SendMessage (hWnd, WM_CLOSE, 0, 0);
break;
case IDM_EXIT:
//如果有的话,停止解码线程
if(hDecodeThread)
{
TerminateThread(hDecodeThread,0);
CloseHandle(hDecodeThread);
hDecodeThread=NULL;
CloseGAPI();
m_bGapi=FALSE;
}
DestroyWindow(hWnd);
break;
case ID_FILE_OPEN:
{
//如果有的话,停止解码线程
if(hDecodeThread)
{
m_bDecoding=FALSE;
WaitForSingleObject(hDecodeThread,INFINITE);
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))
{
//打开文件并且播放
//开始解码线程
m_bDecoding=TRUE;
m_bGapi=OpenGAPI(&hWnd);
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)
{
m_bDecoding=FALSE;
WaitForSingleObject(hDecodeThread,INFINITE);
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;
CreateYUVTable();
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;
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 + -