/************************************************************************ * * win.c, display routines for Win32 for tmndecode (H.263 decoder) * ************************************************************************/ /* Disclaimer of Warranty * * These software programs are available to the user without any license fee * or royalty on an "as is" basis. The University of British Columbia * disclaims any and all warranties, whether express, implied, or * statuary, including any implied warranties or merchantability or of * fitness for a particular purpose. In no event shall the * copyright-holder be liable for any incidental, punitive, or * consequential damages of any kind whatsoever arising from the use of * these programs. * * This disclaimer of warranty extends to the user of these programs and * user's customers, employees, agents, transferees, successors, and * assigns. * * The University of British Columbia does not represent or warrant that the * programs furnished hereunder are free of infringement of any * third-party patents. * * Commercial implementations of H.263, including shareware, are subject to * royalty fees to patent holders. Many of these patents are general * enough such that they are unavoidable regardless of implementation * design. * */ /* Copyright ¨ 1996 Intel Corporation All Rights Reserved * * Permission is granted to use, copy and distribute the software in this * file for any purpose and without fee, provided, that the above * copyright notice and this statement appear in all copies. Intel makes * no representations about the suitability of this software for any * purpose. This software is provided "AS IS." * * Intel specifically disclaims all warranties, express or implied, and all * liability, including consequential and other indirect damages, for the * use of this software, including liability for infringement of any * proprietary rights, and including the warranties of merchantability and * fitness for a particular purpose. Intel does not assume any * responsibility for any errors which may appear in this software nor any * responsibility to update it. */ /************************************************************************ * These routines were written by Intel Architecture Labs (IAL) * * v1 : Michael Third * v2 : Karl (removed unnecessary code, collected routines in one file) * (moved and changed parts of message loop) * (changed YUVtoRGB routine) * (added synchronization with events * instead of empty while loop) ************************************************************************/ #include "config.h" #include "tmndec.h" #include "global.h" #include "win.h" #ifdef WINDOWS /* vdinit.c */ T_VDWINDOW vdWindow; int initDisplay (int pels, int lines) { int errFlag = 0; init_dither_tab (); errFlag |= InitDisplayWindowThread (pels, lines); return errFlag; } int InitDisplayWindowThread (int width, int height) { int errFlag = 0; /* now modify the couple that need it */ vdWindow.width = width; vdWindow.height = height; vdWindow.biHeader.biWidth = vdWindow.width; vdWindow.biHeader.biHeight = vdWindow.height; vdWindow.biHeader.biSize = sizeof (BITMAPINFOHEADER); vdWindow.biHeader.biCompression = BI_RGB; vdWindow.biHeader.biPlanes = 1; vdWindow.biHeader.biBitCount = 24; vdWindow.biHeader.biSizeImage = 3 * vdWindow.width * vdWindow.height; vdWindow.imageIsReady = FALSE; /* allocate the memory needed to hold the RGB and visualization * information */ vdWindow.bufRGB = (unsigned char *) malloc (3 * vdWindow.width * vdWindow.height); /* Create synchronization event */ vdWindow.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); vdWindow.hThread = CreateThread ( NULL, 0, (LPTHREAD_START_ROUTINE) DisplayWinMain, (LPVOID) NULL, 0, &(vdWindow.dwThreadID) ); if (vdWindow.hThread == NULL) { errFlag = 1; return errFlag; } return errFlag; } /* vddraw.c */ int displayImage (unsigned char *lum, unsigned char *Cr, unsigned char *Cb) { int errFlag = 0; DWORD dwRetVal; /* wait until we have finished drawing the last frame */ if (vdWindow.windowDismissed == FALSE) { vdWindow.src[0] = lum; vdWindow.src[1] = Cb; vdWindow.src[2] = Cr; vdWindow.imageIsReady = TRUE; /* Post message to drawing thread's window to draw frame */ PostMessage (vdWindow.hWnd, VIDEO_DRAW_FRAME, (WPARAM) NULL, (LPARAM) NULL); /* wait until the frame has been drawn */ dwRetVal = WaitForSingleObject (vdWindow.hEvent, INFINITE); } return errFlag; } int DrawDIB () { int errFlag = 0; errFlag |= DrawDibDraw ( vdWindow.hDrawDib, vdWindow.hDC, 0, 0, vdWindow.zoom * vdWindow.width, vdWindow.zoom * vdWindow.height, &vdWindow.biHeader, vdWindow.bufRGB, 0, 0, vdWindow.width, vdWindow.height, DDF_SAME_DRAW ); return errFlag; } /* vdwinman.c */ void DisplayWinMain (void *dummy) { int errFlag = 0; DWORD dwStyle; vdWindow.wc.style = CS_BYTEALIGNWINDOW; vdWindow.wc.lpfnWndProc = MainWndProc; vdWindow.wc.cbClsExtra = 0; vdWindow.wc.cbWndExtra = 0; vdWindow.wc.hInstance = 0; vdWindow.wc.hIcon = LoadIcon (NULL, IDI_APPLICATION); vdWindow.wc.hCursor = LoadCursor (NULL, IDC_ARROW); vdWindow.wc.hbrBackground = GetStockObject (WHITE_BRUSH); vdWindow.wc.lpszMenuName = NULL; vdWindow.zoom = 1; strcpy (vdWindow.lpszAppName, "H.263 Display"); vdWindow.wc.lpszClassName = vdWindow.lpszAppName; RegisterClass (&vdWindow.wc); dwStyle = WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; vdWindow.hWnd = CreateWindow (vdWindow.lpszAppName, vdWindow.lpszAppName, dwStyle, CW_USEDEFAULT, CW_USEDEFAULT, vdWindow.width + 6, vdWindow.height + 25, NULL, NULL, 0, NULL ); if (vdWindow.hWnd == NULL) ExitThread (errFlag = 1); ShowWindow (vdWindow.hWnd, SW_SHOWNOACTIVATE); UpdateWindow (vdWindow.hWnd); /* Message loop for display window's thread */ while (GetMessage (&(vdWindow.msg), NULL, 0, 0)) { TranslateMessage (&(vdWindow.msg)); DispatchMessage (&(vdWindow.msg)); } ExitThread (0); } LRESULT APIENTRY MainWndProc (HWND hWnd, UINT msg, UINT wParam, LONG lParam) { LPMINMAXINFO lpmmi; switch (msg) { case VIDEO_BEGIN: vdWindow.hDC = GetDC (vdWindow.hWnd); vdWindow.hDrawDib = DrawDibOpen (); vdWindow.zoom = 1; vdWindow.oldzoom = 0; DrawDibBegin ( vdWindow.hDrawDib, vdWindow.hDC, 2 * vdWindow.width, 2 * vdWindow.height, &vdWindow.biHeader, vdWindow.width, vdWindow.height, 0 ); /*SetEvent (vdWindow.hEvent);*/ vdWindow.windowDismissed = FALSE; ReleaseDC (vdWindow.hWnd, vdWindow.hDC); break; case VIDEO_DRAW_FRAME: vdWindow.hDC = GetDC (vdWindow.hWnd); ConvertYUVtoRGB ( vdWindow.src[0], vdWindow.src[1], vdWindow.src[2], vdWindow.bufRGB, vdWindow.width, vdWindow.height ); /* draw the picture onto the screen */ DrawDIB (); SetEvent (vdWindow.hEvent); ReleaseDC (vdWindow.hWnd, vdWindow.hDC); break; case VIDEO_END: /* Window has been closed. The following lines handle the cleanup. */ vdWindow.hDC = GetDC (vdWindow.hWnd); DrawDibEnd (vdWindow.hDrawDib); DrawDibClose (vdWindow.hDrawDib); ReleaseDC (vdWindow.hWnd, vdWindow.hDC); vdWindow.windowDismissed = TRUE; PostQuitMessage (0); break; case WM_CREATE: PostMessage (hWnd, VIDEO_BEGIN, 0, 0); break; case WM_SIZE: switch (wParam) { case SIZE_MAXIMIZED: vdWindow.zoom = 2; break; case SIZE_MINIMIZED: vdWindow.oldzoom = vdWindow.zoom; break; case SIZE_RESTORED: if (vdWindow.oldzoom) { vdWindow.zoom = vdWindow.oldzoom; vdWindow.oldzoom = 0; } else vdWindow.zoom = 1; break; case SIZE_MAXHIDE: break; case SIZE_MAXSHOW: break; } PostMessage (hWnd, WM_PAINT, 0, 0); break; case WM_GETMINMAXINFO: lpmmi = (LPMINMAXINFO) lParam; GetWindowRect (hWnd, &vdWindow.rect); lpmmi->ptMaxPosition.x = vdWindow.rect.left; lpmmi->ptMaxPosition.y = vdWindow.rect.top; lpmmi->ptMaxSize.x = 2 * (vdWindow.width) + 6; lpmmi->ptMaxSize.y = 2 * (vdWindow.height) + 25; break; case WM_DESTROY: /* Window has been closed. The following lines handle the cleanup. */ DrawDibEnd (vdWindow.hDrawDib); ReleaseDC (vdWindow.hWnd, vdWindow.hDC); DrawDibClose (vdWindow.hDrawDib); vdWindow.windowDismissed = TRUE; PostQuitMessage (0); break; case WM_PAINT: if (vdWindow.imageIsReady) { vdWindow.hDC = GetDC (vdWindow.hWnd); DrawDIB (); ReleaseDC (vdWindow.hWnd, vdWindow.hDC); } break; } return DefWindowProc (hWnd, msg, wParam, lParam); } /* vdclose.c */ int closeDisplay () { int errFlag = 0; if (vdWindow.hWnd) { PostMessage (vdWindow.hWnd, VIDEO_END, (WPARAM) NULL, (LPARAM) NULL); while (vdWindow.windowDismissed == FALSE) ; } if (vdWindow.hEvent) CloseHandle (vdWindow.hEvent); if (vdWindow.hThread) CloseHandle (vdWindow.hThread); free (vdWindow.bufRGB); return errFlag; } #endif