00001 /* --------------------------------------------------------------------------- 00002 Phission : 00003 Realtime Vision Processing System 00004 00005 Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu) 00006 University of Massachusetts at Lowell, 00007 Laboratory for Artificial Intelligence and Robotics 00008 00009 This file is part of Phission. 00010 00011 Phission is free software; you can redistribute it and/or modify 00012 it under the terms of the GNU Lesser General Public License as published by 00013 the Free Software Foundation; either version 2 of the License, or 00014 (at your option) any later version. 00015 00016 Phission is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 GNU Lesser General Public License for more details. 00020 00021 You should have received a copy of the GNU Lesser General Public License 00022 along with Phission; if not, write to the Free Software 00023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00024 00025 ---------------------------------------------------------------------------*/ 00026 #ifdef HAVE_CONFIG_H 00027 #include <phissionconfig.h> 00028 #endif 00029 00030 #if !defined(UNICODE) 00031 #define UNICODE 1 00032 #endif 00033 00034 #include <phStandard.h> 00035 #include <ImageConversions.h> 00036 00037 #include <phObject.h> 00038 #include <phMutex.h> 00039 #include <phSemaphore.h> 00040 #include <phCondition.h> 00041 #include <phRWLock.h> 00042 #include <phThread.h> 00043 #include <phList.h> 00044 #include <phTimeStamp.h> 00045 #include <phTimeInterval.h> 00046 #include <phLiveObject.h> 00047 #include <phDataObject.h> 00048 #include <phImage.h> 00049 #include <phCaptureInterface.h> 00050 #include <phImageCapture.h> 00051 00052 #include <phVFW.h> 00053 #include <VFWSource.h> 00054 00055 #define TIMESTUFF() 0 00056 #if TIMESTUFF() 00057 #include <phTime.h> 00058 #endif 00059 00060 #include <phError.h> 00061 #include <phMemory.h> 00062 #include <phPrint.h> 00063 00064 /* ---------------------------------------------------------------------- */ 00065 #define WM_USER_SHOW (WM_USER + 200) 00066 #define WM_USER_HIDE (WM_USER + 201) 00067 #define WM_USER_RESIZE (WM_USER + 202) 00068 #define WM_USER_MOVE (WM_USER + 203) 00069 #define WM_USER_UPDATE (WM_USER + 204) 00070 #define WM_USER_REDRAW (WM_USER + 205) 00071 00072 #define phBITMAP_REALLOCED 1 00073 #define phDISPLAY_CHANGED 1 00074 00075 /* ---------------------------------------------------------------------- */ 00076 struct phVFWWindowInfo_t 00077 { 00078 HMODULE module; 00079 HINSTANCE instance; 00080 LPTSTR command_line; 00081 STARTUPINFO startup_info; 00082 HWND window; 00083 WNDCLASS window_class; 00084 wchar_t *window_class_name; 00085 ATOM window_atom; 00086 00087 /* Bitmap image info and structures */ 00088 HBITMAP bitmap; 00089 BITMAPINFO bitmap_info; 00090 void *pixels; 00091 uint32_t bitmap_width; 00092 uint32_t bitmap_height; 00093 00094 /* Capture Variables */ 00095 int device; 00096 int connected; 00097 int started; 00098 HWND capwin; 00099 CAPSTATUS d_status; 00100 CAPDRIVERCAPS d_caps; 00101 CAPTUREPARMS d_setup; 00102 wchar_t d_name[255]; 00103 wchar_t d_version[255]; 00104 LPBITMAPINFO d_lpbi; 00105 }; 00106 00107 /* ---------------------------------------------------------------------- */ 00108 struct phVFW_pair_t 00109 { 00110 VFWSource *thisptr; 00111 HHOOK hook; 00112 }; 00113 00114 /* ---------------------------------------------------------------------- */ 00115 struct phVFWHandlerParameters_t 00116 { 00117 HWND window; 00118 UINT message; 00119 WPARAM wp; 00120 LPARAM lp; 00121 }; 00122 00123 /* ---------------------------------------------------------------------- */ 00124 static void print_POINT(POINT p) 00125 { 00126 phFUNCTION("print_POINT") 00127 DEBUG_PRINT("(%d,%d)", 00128 p.x, 00129 p.y); 00130 } 00131 00132 /* ---------------------------------------------------------------------- */ 00133 static void print_RECT(RECT rect) 00134 { 00135 phFUNCTION("print_RECT") 00136 DEBUG_PRINT("(%d,%d,%d,%d)", 00137 rect.left, 00138 rect.top, 00139 rect.right, 00140 rect.bottom); 00141 } 00142 00143 /* ---------------------------------------------------------------------- */ 00144 static void print_MINMAXINFO(MINMAXINFO m) 00145 { 00146 phFUNCTION("print_MINMAXINFO") 00147 DEBUG_PRINT("[reserved:"); 00148 print_POINT(m.ptReserved); 00149 DEBUG_PRINT("maxsize:"); 00150 print_POINT(m.ptMaxSize); 00151 DEBUG_PRINT("maxpos:"); 00152 print_POINT(m.ptMaxPosition); 00153 DEBUG_PRINT("mintrack:"); 00154 print_POINT(m.ptMinTrackSize); 00155 DEBUG_PRINT("maxtrack:"); 00156 print_POINT(m.ptMaxTrackSize); 00157 DEBUG_PRINT("]"); 00158 } 00159 00160 /* ---------------------------------------------------------------------- */ 00161 static void print_WINDOWPOS(WINDOWPOS w) 00162 { 00163 phFUNCTION("print_WINDOWPOS") 00164 DEBUG_PRINT("(%d,%d,x:%d,y:%d,cx:%d,cy:%d)", 00165 w.hwnd,w.hwndInsertAfter, 00166 w.x,w.y,w.cx,w.cy); 00167 if (w.flags & SWP_DRAWFRAME) 00168 { 00169 DEBUG_PRINT("SWP_DRAWFRAME:"); 00170 } 00171 if (w.flags & SWP_FRAMECHANGED) 00172 { 00173 DEBUG_PRINT("SWP_FRAMECHANGED:"); 00174 } 00175 if (w.flags & SWP_HIDEWINDOW) 00176 { 00177 DEBUG_PRINT("SWP_HIDEWINDOW:"); 00178 } 00179 if (w.flags & SWP_NOACTIVATE) 00180 { 00181 DEBUG_PRINT("SWP_NOACTIVATE:"); 00182 } 00183 if (w.flags & SWP_NOCOPYBITS) 00184 { 00185 DEBUG_PRINT("SWP_NOCOPYBITS:"); 00186 } 00187 if (w.flags & SWP_NOMOVE) 00188 { 00189 DEBUG_PRINT("SWP_NOMOVE:"); 00190 } 00191 if (w.flags & SWP_NOOWNERZORDER) 00192 { 00193 DEBUG_PRINT("SWP_NOOWNERZORDER:"); 00194 } 00195 if (w.flags & SWP_NOREDRAW) 00196 { 00197 DEBUG_PRINT("SWP_NOREDRAW:"); 00198 } 00199 if (w.flags & SWP_NOREPOSITION) 00200 { 00201 DEBUG_PRINT("SWP_NOREPOSITION:"); 00202 } 00203 if (w.flags & SWP_NOSENDCHANGING) 00204 { 00205 DEBUG_PRINT("SWP_NOSENDCHANGING:"); 00206 } 00207 if (w.flags & SWP_NOSIZE) 00208 { 00209 DEBUG_PRINT("SWP_NOSIZE:"); 00210 } 00211 if (w.flags & SWP_NOZORDER) 00212 { 00213 DEBUG_PRINT("SWP_NOZORDER:"); 00214 } 00215 if (w.flags & SWP_SHOWWINDOW ) 00216 { 00217 DEBUG_PRINT("SWP_SHOWWINDOW:"); 00218 } 00219 } 00220 00221 /* ---------------------------------------------------------------------- */ 00222 static void print_CREATESTRUCT(CREATESTRUCT c) 00223 { 00224 phFUNCTION("print_CREATESTRUCT") 00225 DEBUG_PRINT("(%p,%d,%d,%d,cy:%d,cx:%d,y:%d,x:%d,%ld,%s,%s,%ld)", 00226 c.lpCreateParams, 00227 c.hInstance, 00228 c.hMenu, 00229 c.hwndParent, 00230 c.cy,c.cx,c.y,c.x, 00231 c.style,c.lpszName,c.lpszClass,c.dwExStyle); 00232 } 00233 00234 /* ---------------------------------------------------------------------- */ 00235 static void print_SIDE(WPARAM fwSide) 00236 { 00237 phFUNCTION("print_SIDE") 00238 if (fwSide & WMSZ_BOTTOM) 00239 { 00240 DEBUG_PRINT("WMSZ_BOTTOM:"); 00241 } 00242 if (fwSide == WMSZ_BOTTOMLEFT) 00243 { 00244 DEBUG_PRINT("WMSZ_BOTTOMLEFT:"); 00245 } 00246 if (fwSide == WMSZ_BOTTOMRIGHT) 00247 { 00248 DEBUG_PRINT("WMSZ_BOTTOMRIGHT:"); 00249 } 00250 if (fwSide & WMSZ_LEFT) 00251 { 00252 DEBUG_PRINT("WMSZ_LEFT:"); 00253 } 00254 if (fwSide & WMSZ_RIGHT) 00255 { 00256 DEBUG_PRINT("WMSZ_RIGHT:"); 00257 } 00258 if (fwSide & WMSZ_TOP) 00259 { 00260 DEBUG_PRINT("WMSZ_TOP:"); 00261 } 00262 if (fwSide == WMSZ_TOPLEFT) 00263 { 00264 DEBUG_PRINT("WMSZ_TOPLEFT:"); 00265 } 00266 if (fwSide == WMSZ_TOPRIGHT) 00267 { 00268 DEBUG_PRINT("WMSZ_TOPRIGHT:"); 00269 } 00270 } 00271 00272 /* ---------------------------------------------------------------------- */ 00273 static BOOL CALLBACK phVFWSource_enumChildProc( HWND hwnd, LPARAM lParam ) 00274 { 00275 phFUNCTION("phVFWSource_enumChildProc") 00276 wchar_t text[255]; 00277 RECT rect; 00278 00279 GetWindowText(hwnd,(LPWSTR)text,255); 00280 GetWindowRect( hwnd, &rect ); 00281 print_RECT(rect); 00282 00283 return TRUE; 00284 } 00285 00286 /* ---------------------------------------------------------------------- */ 00287 static void print_window_info(HWND window) 00288 { 00289 phFUNCTION("print_window_info") 00290 RECT rect; 00291 DEBUG_PRINT("Window(%d):",window); 00292 GetWindowRect( window, &rect ); 00293 print_RECT(rect); 00294 DEBUG_PRINT("\n"); 00295 DEBUG_PRINT("Client:"); 00296 GetClientRect( window, &rect ); 00297 print_RECT(rect); 00298 DEBUG_PRINT("\n"); 00299 00300 EnumChildWindows(window,phVFWSource_enumChildProc,0); 00301 } 00302 00303 /* ---------------------------------------------------------------------- */ 00304 static void print_CAPDRIVERCAPS(CAPDRIVERCAPS caps) 00305 { 00306 phFUNCTION("print_CAPDRIVERCAPS") 00307 DEBUG_PRINT("CAPDRIVERCAPS\n{\n"); 00308 DEBUG_PRINT("\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:0x%08x\n\t%s:0x%08x\n\t%s:0x%08x\n\t%s:0x%08x\n", 00309 "wNumAudioAllocated: Driver index in system.ini ",caps.wDeviceIndex, 00310 "fHasOverlay: Can device overlay? ",caps.fHasOverlay, 00311 "fHasDlgVideoSource: Has Video source dlg? ",caps.fHasDlgVideoSource, 00312 "fHasDlgVideoFormat: Has Format dlg? ",caps.fHasDlgVideoFormat, 00313 "fHasDlgVideoDisplay: Has External out dlg? ",caps.fHasDlgVideoDisplay, 00314 "fCaptureInitialized: Driver ready to capture? ",caps.fCaptureInitialized, 00315 "fDriverSuppliesPalettes:Can driver make palettes? ",caps.fDriverSuppliesPalettes, 00316 "hVideoIn: Driver In channel ",caps.hVideoIn, 00317 "hVideoOut: Driver Out channel ",caps.hVideoOut, 00318 "hVideoExtIn: Driver Ext In channel ",caps.hVideoExtIn, 00319 "hVideoExtOut: Driver Ext Out channel ",caps.hVideoExtOut); 00320 DEBUG_PRINT("};\n"); 00321 } 00322 00323 /* ---------------------------------------------------------------------- */ 00324 static void print_CAPSTATUS(CAPSTATUS stat) 00325 { 00326 phFUNCTION("print_CAPSTATUS") 00327 DEBUG_PRINT("CAPSTAUTS\n{\n"); 00328 DEBUG_PRINT("\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n", 00329 "uiImageWidth: Width of the image ",stat.uiImageWidth, 00330 "uiImageHeight: Height of the image ",stat.uiImageHeight, 00331 "fLiveWindow: Now Previewing video? ",stat.fLiveWindow, 00332 "fOverlayWindow: Now Overlaying video? ",stat.fOverlayWindow, 00333 "fScale: Scale image to client? ",stat.fScale, 00334 "fUsingDefaultPalette: Using default driver palette? ",stat.fUsingDefaultPalette, 00335 "fAudioHardware: Audio hardware present? ",stat.fAudioHardware, 00336 "fCapFileExists: Does capture file exist? ",stat.fCapFileExists, 00337 "dwCurrentVideoFrame: # of video frames cap'td ",stat.dwCurrentVideoFrame, 00338 "dwCurrentVideoFramesDropped:# of video frames dropped ",stat.dwCurrentVideoFramesDropped 00339 ); 00340 DEBUG_PRINT("\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n", 00341 "dwCurrentWaveSamples: # of wave samples cap'td ",stat.dwCurrentWaveSamples, 00342 "dwCurrentTimeElapsedMS:Elapsed capture duration ",stat.dwCurrentTimeElapsedMS, 00343 "hPalCurrent: Current palette in use ",stat.hPalCurrent, 00344 "fCapturingNow: Capture in progress? ",stat.fCapturingNow, 00345 "dwReturn: Error value after any operation ",stat.dwReturn, 00346 "wNumVideoAllocated: Actual number of video buffers ",stat.wNumVideoAllocated, 00347 "wNumAudioAllocated: Actual number of audio buffers ",stat.wNumAudioAllocated); 00348 DEBUG_PRINT("\tScroll position:"); 00349 print_POINT(stat.ptScroll); 00350 DEBUG_PRINT("\n"); 00351 DEBUG_PRINT("};\n"); 00352 } 00353 00354 /* ---------------------------------------------------------------------- */ 00355 static void print_CAPTUREPARMS(CAPTUREPARMS parms) 00356 { 00357 phFUNCTION("print_CAPTUREPARMS") 00358 DEBUG_PRINT("\nCAPTUREPARMS\n{\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n", 00359 "dwRequestMicroSecPerFrame: Requested capture rate ",parms.dwRequestMicroSecPerFrame, 00360 "fMakeUserHitOKToCapture: Show \"Hit OK to cap\" dlg? ",parms.fMakeUserHitOKToCapture, 00361 "wPercentDropForError: Give error msg if > (10%) ",parms.wPercentDropForError, 00362 "fYield: Capture via background task? ",parms.fYield, 00363 "dwIndexSize: Max index size in frames (32K) ",parms.dwIndexSize, 00364 "wChunkGranularity: Junk chunk granularity (2K) ",parms.wChunkGranularity, 00365 "fUsingDOSMemory: Use DOS buffers? ",parms.fUsingDOSMemory, 00366 "wNumVideoRequested: # video buffers, If 0, autocalc ",parms.wNumVideoRequested, 00367 "fCaptureAudio: Capture audio? ",parms.fCaptureAudio, 00368 "wNumAudioRequested: # audio buffers, If 0, autocalc ",parms.wNumAudioRequested 00369 ); 00370 DEBUG_PRINT("\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n", 00371 "vKeyAbort: Virtual key causing abort ",parms.vKeyAbort, 00372 "fAbortLeftMouse: Abort on left mouse? ",parms.fAbortLeftMouse, 00373 "fAbortRightMouse: Abort on right mouse? ",parms.fAbortRightMouse, 00374 "fLimitEnabled: Use wTimeLimit? ",parms.fLimitEnabled, 00375 "wTimeLimit: Seconds to capture ",parms.wTimeLimit, 00376 "fMCIControl: Use MCI video source? ",parms.fMCIControl, 00377 "fStepMCIDevice: Step MCI device? ",parms.fStepMCIDevice, 00378 "dwMCIStartTime: Time to start in MS ",parms.dwMCIStartTime, 00379 "dwMCIStopTime: Time to stop in MS ",parms.dwMCIStopTime, 00380 "fStepCaptureAt2x: Perform spatial averaging 2x ",parms.fStepCaptureAt2x 00381 ); 00382 DEBUG_PRINT("\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n", 00383 "wStepCaptureAverageFrames: Temporal average n Frames ",parms.wStepCaptureAverageFrames, 00384 "dwAudioBufferSize: Size of audio bufs (0 = default) ",parms.dwAudioBufferSize, 00385 "fDisableWriteCache: Attempt to disable write cache ",parms.fDisableWriteCache, 00386 "AVStreamMaster: Which stream controls length? ",parms.AVStreamMaster 00387 ); 00388 DEBUG_PRINT("};\n"); 00389 } 00390 00391 /* ---------------------------------------------------------------------- */ 00392 static void print_VIDEOHDR( VIDEOHDR v ) 00393 { 00394 phFUNCTION("print_VIDEOHDR") 00395 DEBUG_PRINT("\nVIDEOHDR\n{\n\t%s:%p\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n", 00396 "pointer to locked data buffer - lpData ",v.lpData, 00397 "Length of data buffer - dwBufferLength",v.dwBufferLength, 00398 "Bytes actually used - dwBytesUsed ",v.dwBytesUsed, 00399 "Milliseconds from start of stream - dwTimeCaptured",v.dwTimeCaptured, 00400 "for client's use - dwUser ",v.dwUser, 00401 "assorted flags (see defines) - dwFlags ",v.dwFlags, 00402 "reserved for driver - dwReserved[0] ",v.dwReserved[0], 00403 " - dwReserved[1] ",v.dwReserved[1], 00404 " - dwReserved[2] ",v.dwReserved[2], 00405 " - dwReserved[3] ",v.dwReserved[3]); 00406 DEBUG_PRINT("\tdwFlags:\n"); 00407 if (v.dwFlags & VHDR_DONE) 00408 { 00409 DEBUG_PRINT("\t\tVHDR_DONE\n"); 00410 } 00411 if (v.dwFlags & VHDR_PREPARED) 00412 { 00413 DEBUG_PRINT("\t\tVHDR_PREPARED\n"); 00414 } 00415 if (v.dwFlags & VHDR_INQUEUE) 00416 { 00417 DEBUG_PRINT("\t\tVHDR_INQUEUE\n"); 00418 } 00419 if (v.dwFlags & VHDR_KEYFRAME) 00420 { 00421 DEBUG_PRINT("\t\tVHDR_KEYFRAME\n"); 00422 } 00423 DEBUG_PRINT("};\n"); 00424 } 00425 00426 /* ---------------------------------------------------------------------- */ 00427 static void print_WAVEHDR( WAVEHDR w ) 00428 { 00429 phFUNCTION("print_WAVEHDR") 00430 DEBUG_PRINT("\nWAVEHDR\n{\n\t%s:%p\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%p\n\t%s:%d\n", 00431 "pointer to locked data buffer: lpData ", w.lpData, 00432 "length of data buffer: dwBufferLength ", w.dwBufferLength, 00433 "used for input only: dwBytesRecorded ", w.dwBytesRecorded, 00434 "for client's use: dwUser ", w.dwUser, 00435 "assorted flags (see defines): dwFlags ", w.dwFlags, 00436 "loop control counter: dwLoops ", w.dwLoops, 00437 "reserved for driver: lpNext ", w.lpNext, 00438 "reserved for driver: reserved ", w.reserved ); 00439 00440 if (w.dwFlags & WHDR_BEGINLOOP) 00441 { 00442 DEBUG_PRINT("WHDR_BEGINLOOP\n"); 00443 } 00444 if (w.dwFlags & WHDR_DONE) 00445 { 00446 DEBUG_PRINT("WHDR_DONE\n"); 00447 } 00448 if (w.dwFlags & WHDR_ENDLOOP) 00449 { 00450 DEBUG_PRINT("WHDR_ENDLOOP\n"); 00451 } 00452 if (w.dwFlags & WHDR_INQUEUE) 00453 { 00454 DEBUG_PRINT("WHDR_INQUEUE\n"); 00455 } 00456 if (w.dwFlags & WHDR_PREPARED) 00457 { 00458 DEBUG_PRINT("\n"); 00459 } 00460 /* 00461 This buffer is the first buffer in a loop. This flag is used only with output buffers. 00462 Set by the device driver to indicate that it is finished with the buffer and is returning it to the application. 00463 This buffer is the last buffer in a loop. This flag is used only with output buffers. 00464 Set by Windows to indicate that the buffer is queued for playback. 00465 Set by Windows to indicate that the buffer has been prepared with the waveInPrepareHeader or waveOutPrepareHeader function. 00466 */ 00467 DEBUG_PRINT("};\n"); 00468 } 00469 00470 /* ---------------------------------------------------------------------- */ 00471 static void print_BITMAPINFOHEADER( BITMAPINFOHEADER b ) 00472 { 00473 phFUNCTION("print_BITMAPINFOHEADER") 00474 DEBUG_PRINT("\nBITMAPINFOHEADER\n{\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n\t%s:%d\n", 00475 "biSize",b.biSize, 00476 "biWidth",b.biWidth, 00477 "biHeight",b.biHeight, 00478 "biPlanes",b.biPlanes, 00479 "biBitCount",b.biBitCount, 00480 "biCompression",b.biCompression, 00481 "biSizeImage",b.biSizeImage, 00482 "biXPelsPerMeter",b.biXPelsPerMeter, 00483 "biYPelsPerMeter",b.biYPelsPerMeter, 00484 "biClrUsed",b.biClrUsed, 00485 "biClrImportant",b.biClrImportant); 00486 00487 if (b.biCompression == BI_RGB) 00488 { 00489 DEBUG_PRINT("BI_RGB\n"); 00490 } 00491 if (b.biCompression == BI_RLE8) 00492 { 00493 DEBUG_PRINT("BI_RLE8\n"); 00494 } 00495 if (b.biCompression == BI_RLE4) 00496 { 00497 DEBUG_PRINT("BI_RLE4\n"); 00498 } 00499 if (b.biCompression == BI_BITFIELDS) 00500 { 00501 DEBUG_PRINT("BI_BITFIELDS\n"); 00502 } 00503 if (b.biCompression == BI_JPEG) 00504 { 00505 DEBUG_PRINT("BI_JPEG\n"); 00506 } 00507 if (b.biCompression == BI_PNG) 00508 { 00509 DEBUG_PRINT("BI_PNG\n"); 00510 } 00511 00512 DEBUG_PRINT("\n};\n"); 00513 } 00514 00515 /* ---------------------------------------------------------------------- */ 00516 LRESULT CALLBACK phVFWSource_WndProc( HWND hw, UINT message, 00517 WPARAM wp, LPARAM lp ) 00518 { 00519 phFUNCTION("phVFWSource_WndProc") 00520 00521 VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hw,GWL_USERDATA); 00522 00523 /* 00524 DEBUG_PRINT("hw:%p msg:%u win:%p wp:%p lp:%p\n", 00525 hw,message,win,wp,lp); 00526 */ 00527 if (win != NULL) 00528 { 00529 struct phVFWHandlerParameters_t params; 00530 params.window = hw; 00531 params.message = message; 00532 params.wp = wp; 00533 params.lp = lp; 00534 00535 return win->handle_message(¶ms); 00536 } 00537 else 00538 { 00539 return DefWindowProc(hw,message,wp,lp); 00540 } 00541 00542 return 0; 00543 } 00544 /* ---------------------------------------------------------------------- */ 00545 /* The HOOK idea came from: 00546 * http://www.rpi.edu/~pudeyo/articles/wndproc/hook.cpp */ 00547 /* ---------------------------------------------------------------------- */ 00548 /* The CBT hook procedure. It is called during CreateWindow call before 00549 * WndProc receives any messages. Its job is to set per-window Window 00550 * pointer to the one passed through lpParam to CreateWindow. */ 00551 /* ---------------------------------------------------------------------- */ 00552 LRESULT CALLBACK phVFWSource_CBTProc(int code, WPARAM wp, LPARAM lp) 00553 { 00554 phFUNCTION("phVFWSource_CBTProc") 00555 00556 LONG_PTR ptr_rc = NULL; 00557 00558 if (code != HCBT_CREATEWND) 00559 { 00560 /* Ignore everything but create window requests 00561 * Note: generally, HCBT_CREATEWND is the only notification we 00562 * will get, assuming the thread is hooked only for the duration 00563 * of CreateWindow call. However, we may receive other 00564 * notifications, in which case they will not be passed to other 00565 * CBT hooks. */ 00566 return 0; 00567 } 00568 /* Grab a pointer passed to CreateWindow as lpParam */ 00569 phVFW_pair_t *p = (phVFW_pair_t *)LPCBT_CREATEWND(lp)->lpcs->lpCreateParams; 00570 /* Only handle this window if it wasn't handled before, to prevent 00571 * rehooking windows when CreateWindow is called recursively */ 00572 /* ie, when you create windows from a WM_CREATE handler */ 00573 if (p->thisptr != NULL) 00574 { 00575 /* Stash the associated Window pointer, which is the first member 00576 * of the pair, into per-window data area */ 00577 ::SetLastError(ERROR_SUCCESS); 00578 ptr_rc = ::SetWindowLongPtr((HWND)wp, 00579 GWL_USERDATA, 00580 (LONG)p->thisptr); 00581 if ((ptr_rc == NULL) && (GetLastError() != ERROR_SUCCESS)) 00582 rc = phFAIL; 00583 else 00584 rc = phSUCCESS; 00585 phPRINT_RC(rc,"SetWindowLongPtr","SetWindowLongPtr failed."); 00586 00587 /* Mark this window as handled */ 00588 p->thisptr = NULL; 00589 } 00590 /* Call the next hook in chain, using the second member of the pair */ 00591 return CallNextHookEx(p->hook, code, wp, lp); 00592 } 00593 00594 /* ---------------------------------------------------------------------- */ 00595 static LRESULT CALLBACK phVFWSource_ErrorCallbackProc(HWND hWnd, int nErrID, LPSTR lpErrorText) 00596 { 00597 phFUNCTION("phVFWSource_ErrorCallbackProc") 00598 00599 VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA); 00600 00601 phPRINT("(%s) thisptr:%p hWnd:%p nErrID:%d lpErrorText:%s\n", 00602 function,win,hWnd,nErrID,lpErrorText); 00603 if (win != NULL) 00604 { 00605 } 00606 00607 return TRUE; 00608 } 00609 00610 /* ---------------------------------------------------------------------- */ 00611 static LRESULT CALLBACK phVFWSource_StatusCallbackProc(HWND hWnd, int nID, LPSTR lpStatusText) 00612 { 00613 phFUNCTION("phVFWSource_StatusCallbackProc") 00614 00615 VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA); 00616 00617 DEBUG_PRINT("(%s) thisptr:%p hWnd:%p nID:%d lpStatusText:%s\n", 00618 function,win,hWnd,nID,lpStatusText); 00619 00620 if (win != NULL) 00621 { 00622 } 00623 00624 return TRUE; 00625 } 00626 00627 /* ---------------------------------------------------------------------- */ 00628 static LRESULT CALLBACK phVFWSource_ControlCallbackProc(HWND hWnd, int nState) 00629 { 00630 phFUNCTION("phVFWSource_ControlCallbackProc") 00631 00632 VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA); 00633 00634 DEBUG_PRINT("(%s) thisptr:%p hWnd:%p nState:%d\n", 00635 function,win,hWnd,nState); 00636 00637 if (win != NULL) 00638 { 00639 switch (nState) 00640 { 00641 case CONTROLCALLBACK_PREROLL: 00642 DEBUG_PRINT("CONTROLCALLBACK_PREROLL\n"); 00643 break; 00644 case CONTROLCALLBACK_CAPTURING: 00645 DEBUG_PRINT("CONTROLCALLBACK_CAPTURING\n"); 00646 #if 0 00647 /* This doesn't work yet because isRunning is set after 00648 * the device is opened */ 00649 if (!win->isRunning()) 00650 { 00651 return FALSE; 00652 } 00653 #endif 00654 break; 00655 default: 00656 break; 00657 } 00658 } 00659 00660 return TRUE; 00661 } 00662 00663 /* ---------------------------------------------------------------------- */ 00664 static LRESULT CALLBACK phVFWSource_VidStreamCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr) 00665 { 00666 phFUNCTION("phVFWSource_VidStreamCallbackProc") 00667 00668 VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA); 00669 VFWSource *win2 = (VFWSource *)capGetUserData(hWnd); 00670 phImage *img = NULL; 00671 UINT header_size = 0; 00672 DWORD dwSize; 00673 LPBITMAPINFO lpbi; 00674 int32_t f = phImageNOFORMAT; 00675 int32_t out_format = (win != NULL ? win->getFormat() : phImageRGB24); 00676 00677 uint32_t width = 0; 00678 uint32_t height = 0; 00679 uint32_t format = 0; 00680 uint8_t *data = NULL; 00681 uint32_t size = 0; 00682 00683 if ((win != NULL) && (lpVHdr != NULL)) 00684 { 00685 DEBUG_PRINT("(%s) wthisptr:%p cthisptr:%p hWnd:%p lpVHdr:%p\n", 00686 function,win,win2,hWnd,lpVHdr); 00687 00688 //print_VIDEOHDR(*lpVHdr); 00689 00690 if (!win->isRunning()) return TRUE; 00691 00692 img = win->getImage(); 00693 00694 dwSize = capGetVideoFormatSize(hWnd); 00695 lpbi = (LPBITMAPINFO)phCalloc(1,dwSize); 00696 phPRINT_PTR(lpbi,"phCalloc","phCalloc failed."); 00697 00698 capGetVideoFormat(hWnd, lpbi, dwSize); 00699 00700 DEBUG_PRINT("updating with...\n"); 00701 //print_BITMAPINFOHEADER(lpbi->bmiHeader); 00702 00703 if ((lpbi->bmiHeader.biCompression == BI_RGB) && 00704 (lpbi->bmiHeader.biPlanes == 1) && 00705 (lpbi->bmiHeader.biSizeImage > 0)) 00706 { 00707 if (lpbi->bmiHeader.biBitCount == 24) 00708 f = phImageBGR24; 00709 else if (lpbi->bmiHeader.biBitCount == 32) 00710 f = phImageBGRA32; 00711 00712 if (lpbi->bmiHeader.biHeight < 0) 00713 { 00714 lpbi->bmiHeader.biHeight *= -1; 00715 } 00716 if (f != phImageNOFORMAT) 00717 { 00718 if (f != out_format) 00719 { 00720 /* We'll disable the notify signals here so we can use 00721 * the phImage::convert method without having clients 00722 * copy the data before the convert. Then we'll call 00723 * the convert method and do two fake swap datas, one 00724 * before we re-enable notify and the other after it's 00725 * re-enabled so we can get the notify signal out */ 00726 img->disableNotify(); 00727 #if 0 00728 phPRINT("VFW(%u x %u)\n", 00729 lpbi->bmiHeader.biWidth, 00730 lpbi->bmiHeader.biHeight ); 00731 #endif 00732 rc = img->setImage( lpbi->bmiHeader.biWidth, 00733 lpbi->bmiHeader.biHeight, 00734 f, 00735 lpbi->bmiHeader.biSizeImage, 00736 lpVHdr->lpData); 00737 phPRINT_RC(rc,NULL,"img->setImage"); 00738 00739 rc = img->convert(f); 00740 phPRINT_RC(rc,NULL,"img->convert()"); 00741 00742 rc = img->swapData(&width,&height,&format,&data,&size); 00743 phPRINT_RC(rc,NULL,"img->swapData"); 00744 00745 img->enableNotify(); 00746 00747 rc = img->swapData(&width,&height,&format,&data,&size); 00748 phPRINT_RC(rc,NULL,"img->swapData"); 00749 } 00750 else 00751 { 00752 rc = img->setImage( lpbi->bmiHeader.biWidth, 00753 lpbi->bmiHeader.biHeight, 00754 f, 00755 lpbi->bmiHeader.biSizeImage, 00756 lpVHdr->lpData); 00757 phPRINT_RC(rc,NULL,"img->setImage"); 00758 } 00759 } 00760 } 00761 00762 phFree(lpbi); 00763 } 00764 return TRUE; 00765 } 00766 00767 /* ---------------------------------------------------------------------- */ 00768 static LRESULT CALLBACK phVFWSource_FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr) 00769 { 00770 phFUNCTION("phVFWSource_FrameCallbackProc") 00771 00772 VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA); 00773 VFWSource *win2 = (VFWSource *)capGetUserData(hWnd); 00774 00775 if ((win != NULL) && (lpVHdr != NULL)) 00776 { 00777 DEBUG_PRINT("(%s) wthisptr:%p cthisptr:%p hWnd:%p lpVHdr:%p\n", 00778 function,win,win2,hWnd,lpVHdr); 00779 00780 //print_VIDEOHDR(*lpVHdr); 00781 } 00782 00783 return TRUE; 00784 } 00785 00786 /* ---------------------------------------------------------------------- */ 00787 static LRESULT CALLBACK phVFWSource_WaveStreamCallbackProc( HWND hWnd, LPWAVEHDR lpWHdr ) 00788 { 00789 phFUNCTION("phVFWSource_WaveStreamFrameCallbackProc") 00790 00791 VFWSource *win = (VFWSource *)(uint64_t)::GetWindowLongPtr(hWnd,GWL_USERDATA); 00792 VFWSource *win2 = (VFWSource *)capGetUserData(hWnd); 00793 00794 if ((win != NULL) && (lpWHdr != NULL)) 00795 { 00796 DEBUG_PRINT("(%s) wthisptr:%p cthisptr:%p hWnd:%p lpWHdr:%p\n", 00797 function,win,win2,hWnd,lpWHdr); 00798 00799 //print_WAVEHDR(*lpWHdr); 00800 } 00801 00802 return TRUE; 00803 } 00804 /* ---------------------------------------------------------------------- */ 00805 VFWSource::VFWSource(char *path) 00806 { 00807 phFUNCTION("VFWSource::VFWSource") 00808 00809 rc = this->lock(); 00810 phPRINT_RC(rc,NULL,"this->lock()"); 00811 00812 this->setName("VFWSource"); 00813 00814 if (path != NULL) 00815 { 00816 this->setPath(path); 00817 } 00818 else 00819 { 00820 this->setPath("0"); 00821 } 00822 00823 this->m_info = NULL; 00824 this->m_show_first = 0; 00825 this->m_image_size = 0; 00826 this->m_private_format = this->m_format; 00827 this->m_channel = 0; 00828 this->m_changed_settings = 0; 00829 this->m_changed_channel = 0; 00830 00831 /* This applies the default (1) picture/image settings[w,h,format,etc.] 00832 * (2) channel settings */ 00833 this->applySettings(); 00834 00835 /* opening the device must be explicitly done */ 00836 /* capturing must be explicitly done. */ 00837 #if 0 00838 error: 00839 #endif 00840 rc = this->unlock(); 00841 phPRINT_RC(rc,NULL,"this->unlock()"); 00842 00843 return; 00844 } 00845 00846 /* ---------------------------------------------------------------------- */ 00847 VFWSource::~VFWSource () 00848 { 00849 phFUNCTION("VFWSource::~VFWSource") 00850 00851 rc = this->lock(); 00852 phPRINT_RC(rc,NULL,"this->lock()"); 00853 00854 if (this->isRunning()) 00855 { 00856 /* this unmaps the hw_buffer and closes the device */ 00857 rc = this->stop(); 00858 phPRINT_RC(rc,NULL,"this->stop()"); 00859 } 00860 00861 if (this->isOpen()) 00862 { 00863 rc = this->close(); 00864 phPRINT_RC(rc,NULL,"this->close()"); 00865 } 00866 00867 rc = this->unlock(); 00868 phPRINT_RC(rc,NULL,"this->unlock()"); 00869 } 00870 00871 /* ---------------------------------------------------------------------- */ 00872 int VFWSource::init_window() 00873 { 00874 phFUNCTION("VFWSource::init_window") 00875 int locked = 0; 00876 ATOM arc = 0; 00877 BOOL brc = FALSE; 00878 HHOOK hook; 00879 phVFW_pair_t pair; 00880 RECT rect; 00881 LONG_PTR ptr_rc = NULL; 00882 00883 phTHIS_LOCK(locked); 00884 00885 if (this->m_info != NULL) goto error; 00886 00887 this->m_info = (struct phVFWWindowInfo_t *)phCalloc(1,sizeof(struct phVFWWindowInfo_t)); 00888 phPRINT_PTR(this->m_info,"phCalloc","phCalloc failed for m_info"); 00889 00890 this->m_info->device = -1; 00891 00892 this->m_info->window_class_name = (wchar_t *)phCalloc(255,sizeof(wchar_t)); 00893 phPRINT_PTR(this->m_info->window_class_name,"phCalloc", 00894 "phCalloc failed."); 00895 00896 wsprintf(this->m_info->window_class_name, 00897 L"VFWSource%u%p", 00898 (unsigned int)phGetCurrentThreadId(), 00899 this); 00900 00901 /* Create Window */ 00902 this->m_info->module = ::GetModuleHandle(NULL); 00903 this->m_info->instance = (HINSTANCE)this->m_info->module; 00904 this->m_info->command_line = GetCommandLine(); 00905 GetStartupInfo(&(this->m_info->startup_info)); 00906 00907 /* Register the main window class. */ 00908 this->m_info->window_class.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; 00909 this->m_info->window_class.lpfnWndProc = (WNDPROC)phVFWSource_WndProc; 00910 this->m_info->window_class.cbClsExtra = 0; 00911 this->m_info->window_class.cbWndExtra = sizeof(VFWSource *); 00912 this->m_info->window_class.hInstance = this->m_info->instance; 00913 this->m_info->window_class.hIcon = ::LoadIcon (NULL, IDI_APPLICATION); 00914 this->m_info->window_class.hCursor = ::LoadCursor(NULL, IDC_ARROW); 00915 this->m_info->window_class.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);//(COLOR_BACKGROUND); 00916 this->m_info->window_class.lpszMenuName = NULL; 00917 this->m_info->window_class.lpszClassName = (LPCWSTR)this->m_info->window_class_name; 00918 00919 this->m_info->window_atom = arc = ::RegisterClass(&(this->m_info->window_class)); 00920 if (arc == 0) rc = phFAIL; else rc = phSUCCESS; 00921 phPRINT_RC(rc,"RegisterClass","RegisterClass failed."); 00922 00923 /* Setup the hooks */ 00924 hook = SetWindowsHookEx(WH_CBT, phVFWSource_CBTProc, 0, GetCurrentThreadId()); 00925 pair.thisptr = this; 00926 pair.hook = hook; 00927 00928 SetLastError(ERROR_SUCCESS); 00929 00930 this->m_info->window = ::CreateWindowEx(0, 00931 (LPCWSTR)this->m_info->window_class_name, 00932 (LPCWSTR)"VFWSource capture stuff", 00933 WS_BORDER | 00934 WS_THICKFRAME | 00935 WS_CAPTION | 00936 WS_MINIMIZEBOX | 00937 WS_MAXIMIZEBOX | 00938 WS_SYSMENU, 00939 CW_USEDEFAULT,CW_USEDEFAULT, 00940 this->m_width,this->m_height, 00941 NULL, 00942 NULL, 00943 this->m_info->instance, 00944 &pair); 00945 phPRINT_PTR(this->m_info->window,"CreateWindow","CreateWindow failed."); 00946 00947 /* Disable the hooks */ 00948 UnhookWindowsHookEx(hook); 00949 00950 /* 00951 DEBUG_PRINT("CreateWindowEx\n"); 00952 print_window_info(this->m_info->window); 00953 DEBUG_PRINT("\n"); 00954 */ 00955 00956 /* Make sure the client area is sized correctly */ 00957 GetClientRect( this->m_info->window, &rect ); 00958 00959 MoveWindow(this->m_info->window, 00960 10,10, 00961 this->m_width + (this->m_width - (rect.right -rect.left)), 00962 this->m_height + (this->m_height - (rect.bottom - rect.top)), 00963 FALSE); 00964 00965 this->m_show_first = 1; 00966 00967 this->m_info->capwin = capCreateCaptureWindow ((LPCWSTR) "My Capture Window", 00968 WS_CHILD | WS_VISIBLE, 00969 0, 0, this->m_width, this->m_height, 00970 (HWND)this->m_info->window, 00971 (int) 10); 00972 phPRINT_PTR(this->m_info->capwin,"capCreateCaptureWindow", 00973 "capCreateCaptureWindow failed."); 00974 00975 ::SetLastError(ERROR_SUCCESS); 00976 ptr_rc = ::SetWindowLongPtr((HWND)this->m_info->capwin,GWL_USERDATA,(LONG32)this); 00977 if ((ptr_rc == NULL) && (GetLastError() != ERROR_SUCCESS)) 00978 rc = phFAIL; 00979 else 00980 rc = phSUCCESS; 00981 phPRINT_RC(rc,"SetWindowLongPtr","SetWindowLongPtr failed."); 00982 00983 capSetUserData(this->m_info->capwin,this); 00984 00985 error: 00986 phTHIS_ERROR_UNLOCK(locked); 00987 return phSUCCESS; 00988 } 00989 00990 /* ---------------------------------------------------------------------- */ 00991 int VFWSource::destroy_window() 00992 { 00993 phFUNCTION("VFWSource::destroy_window") 00994 BOOL brc = TRUE; 00995 int locked = 0; 00996 00997 phTHIS_LOCK(locked); 00998 00999 if (this->m_info != NULL) 01000 { 01001 rc = this->disconnect_device(); 01002 phPRINT_RC(rc,NULL,"disconnect_device"); 01003 01004 rc = this->remove_callbacks(); 01005 phPRINT_RC(rc,NULL,"remove_callbacks"); 01006 01007 brc = DestroyWindow(this->m_info->capwin); 01008 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01009 phPRINT_RC(rc,"DestroyWindow","DestroyWindow failed (0x%08x).",brc); 01010 01011 brc = DestroyWindow(this->m_info->window); 01012 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01013 phPRINT_RC(rc,"DestroyWindow","DestroyWindow failed (0x%08x).",brc); 01014 01015 brc = UnregisterClass((LPCWSTR)this->m_info->window_class_name, 01016 this->m_info->instance); 01017 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01018 phPRINT_RC(rc,"UnregisterClass","UnregisterClass failed (0x%08x)",brc); 01019 01020 phFree(this->m_info->window_class_name); 01021 phFree(this->m_info->d_lpbi); 01022 phFree(this->m_info); 01023 } 01024 01025 phTHIS_UNLOCK(locked); 01026 01027 return phSUCCESS; 01028 error: 01029 phTHIS_ERROR_UNLOCK(locked); 01030 01031 return phFAIL; 01032 } 01033 01034 /* ---------------------------------------------------------------------- */ 01035 int64_t VFWSource::handle_message( phVFWHandlerParameters params ) 01036 { 01037 phFUNCTION("VFWSource::handle_message") 01038 int locked = 0; 01039 LRESULT retrc = 0; 01040 HWND hw = params->window; 01041 UINT message = params->message; 01042 WPARAM wp = params->wp; 01043 LPARAM lp = params->lp; 01044 int message_handled = 0; 01045 int close_window = 0; 01046 01047 phTHIS_LOCK(locked); 01048 /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ 01049 winui/winui/windowsuserinterface/windowing/windows/ 01050 windowreference/windowmessages/wm_size.asp 01051 */ 01052 switch (message) 01053 { 01054 case WM_DESTROY: 01055 /*phPROGRESS("WM_DESTROY\n");*/ 01056 close_window = 1; 01057 break; 01058 01059 case WM_CLOSE: 01060 /*phPROGRESS("WM_CLOSE\n");*/ 01061 close_window = 1; 01062 break; 01063 01064 case WM_CHAR: 01065 DEBUG_PRINT("WM_CHAR\n"); 01066 /* if key pressed is ESC/Q/q then close the window */ 01067 if ((wp == 27) || (wp == 'q') || (wp == 'Q')) 01068 { 01069 message_handled = close_window = 1; 01070 } 01071 break; 01072 01073 case WM_ACTIVATE: 01074 { 01075 /* activation flag */ 01076 int fActive = LOWORD(wp); 01077 /* minimized flag */ 01078 BOOL fMinimized = (BOOL) HIWORD(wp); 01079 /* window handle */ 01080 HWND hwndPrevious = (HWND) lp; 01081 01082 DEBUG_PRINT("WM_ACTIVATE(%d,%d,%d)\n",fActive,fMinimized,hwndPrevious); 01083 } 01084 case WM_PAINT: 01085 { 01086 DEBUG_PRINT("WM_PAINT\n"); 01087 } 01088 break; 01089 case WM_USER_REDRAW: 01090 { 01091 DEBUG_PRINT("WM_USER_REDRAW\n"); 01092 } 01093 break; 01094 case WM_USER_UPDATE: 01095 { 01096 DEBUG_PRINT("WM_UPDATE\n"); 01097 } 01098 break; 01099 01100 case WM_USER_MOVE: 01101 { 01102 int32_t xPos = (int32_t)(short) LOWORD(lp); 01103 int32_t yPos = (int32_t)(short) HIWORD(lp); 01104 DEBUG_PRINT("WM_USER_MOVE(%d,%d)\n",xPos,yPos); 01105 } 01106 break; 01107 case WM_USER_RESIZE: 01108 { 01109 #if 0 01110 uint32_t width = (uint32_t)(short) LOWORD(lp); 01111 uint32_t height = (uint32_t)(short) HIWORD(lp); 01112 DEBUG_PRINT("WM_USER_RESIZE(%u,%u)\n",width,height); 01113 RECT rect; 01114 01115 GetClientRect( this->m_info->window, &rect ); 01116 //print_RECT(rect); 01117 DEBUG_PRINT("\n"); 01118 #endif 01119 } 01120 break; 01121 case WM_USER_SHOW: 01122 { 01123 DEBUG_PRINT("WM_USER_SHOW\n"); 01124 } 01125 break; 01126 case WM_USER_HIDE: 01127 { 01128 DEBUG_PRINT("WM_USER_HIDE\n"); 01129 } 01130 break; 01131 01132 case WM_CREATE: 01133 { 01134 /* structure with creation data */ 01135 LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lp; 01136 01137 DEBUG_PRINT("WM_CREATE"); 01138 //print_CREATESTRUCT(*lpcs); 01139 DEBUG_PRINT("\n"); 01140 } 01141 break; 01142 case WM_KEYDOWN: 01143 DEBUG_PRINT("WM_KEYDOWN\n"); 01144 break; 01145 case WM_KEYUP: 01146 DEBUG_PRINT("WM_KEYUP\n"); 01147 break; 01148 case WM_SYSKEYDOWN: 01149 DEBUG_PRINT("WM_SYSKEYDOWN\n"); 01150 break; 01151 case WM_SYSKEYUP: 01152 DEBUG_PRINT("WM_SYSKEYUP\n"); 01153 break; 01154 case WM_ACTIVATEAPP: 01155 { 01156 /* activation flag */ 01157 BOOL fActive = (BOOL) wp; 01158 /* thread identifier */ 01159 DWORD dwThreadId = (DWORD) lp; 01160 DEBUG_PRINT("WM_ACTIVATEAPP(%d,%ld)\n",fActive,dwThreadId); 01161 } 01162 break; 01163 case WM_SHOWWINDOW: 01164 { 01165 DEBUG_PRINT("WM_SHOWWINDOW\n"); 01166 } 01167 break; 01168 case WM_CANCELMODE: 01169 DEBUG_PRINT("WM_CANCELMODE\n"); 01170 break; 01171 case WM_CHILDACTIVATE: 01172 { 01173 DEBUG_PRINT("WM_CHILDACTIVATE\n"); 01174 } 01175 break; 01176 case WM_COMPACTING: 01177 { 01178 /* compacting ratio */ 01179 WPARAM wCompactRatio = wp; 01180 DEBUG_PRINT("WM_COMPACTING(0x%08x)\n",wCompactRatio); 01181 } 01182 break; 01183 case WM_ENABLE: 01184 { 01185 /* enabled/disabled flag */ 01186 BOOL fEnabled = (BOOL) wp; 01187 DEBUG_PRINT("WM_ENABLE(%d)\n",fEnabled); 01188 } 01189 break; 01190 case WM_ENTERSIZEMOVE: 01191 DEBUG_PRINT("WM_ENTERSIZEMOVE\n"); 01192 break; 01193 case WM_EXITSIZEMOVE: 01194 DEBUG_PRINT("WM_EXITSIZEMOVE\n"); 01195 break; 01196 case WM_GETICON: 01197 { 01198 WPARAM fType = wp; 01199 DEBUG_PRINT("WM_GETICON"); 01200 DEBUG_PRINT("%s\n",(fType == ICON_BIG ? " ICON_BIG" : " ICON_SMALL")); 01201 } 01202 break; 01203 case WM_GETMINMAXINFO: 01204 { 01205 LPMINMAXINFO lpmmi = (LPMINMAXINFO) lp; 01206 DEBUG_PRINT("WM_GETMINMAXINFO"); 01207 //print_MINMAXINFO(*lpmmi); 01208 DEBUG_PRINT("\n"); 01209 } 01210 break; 01211 case WM_INPUTLANGCHANGE: 01212 DEBUG_PRINT("WM_INPUTLANGCHANGE\n"); 01213 break; 01214 case WM_INPUTLANGCHANGEREQUEST: 01215 DEBUG_PRINT("WM_INPUTLANGCHANGEREQUEST\n"); 01216 break; 01217 case WM_MOVE: 01218 { 01219 #if 0 01220 int32_t xPos = (int32_t)(short) LOWORD(lp); 01221 int32_t yPos = (int32_t)(short) HIWORD(lp); 01222 RECT rect; 01223 01224 GetWindowRect( this->m_info->window, &rect ); 01225 01226 DEBUG_PRINT("WM_MOVE(%d,%d)(%d,%d)\n", 01227 xPos,yPos,rect.left,rect.top); 01228 #endif 01229 } 01230 break; 01231 case WM_MOVING: 01232 { 01233 /* edge of window to be moved */ 01234 WPARAM fwSide = wp; 01235 /* screen coordinates of drag rectangle */ 01236 LPRECT lprc = (LPRECT) lp; 01237 01238 /* 01239 DEBUG_PRINT("WM_MOVING"); 01240 print_RECT(*lprc); 01241 print_SIDE(fwSide); 01242 DEBUG_PRINT("\n"); 01243 if (this->m_info->window != NULL) 01244 { 01245 print_window_info(this->m_info->window); 01246 } 01247 */ 01248 } 01249 break; 01250 case WM_NCACTIVATE: 01251 { 01252 DEBUG_PRINT("WM_NCACTIVATE\n"); 01253 } 01254 break; 01255 case WM_NCCALCSIZE: 01256 { 01257 /* valid area flag */ 01258 BOOL fCalcValidRects = (BOOL) wp; 01259 01260 DEBUG_PRINT("WM_NCCALCSIZE"); 01261 if (fCalcValidRects ) 01262 { 01263 /* size calculation data */ 01264 LPNCCALCSIZE_PARAMS lpncsp = (LPNCCALCSIZE_PARAMS)lp; 01265 for (int i = 0; i < 3; i++ ) print_RECT(lpncsp->rgrc[i]); 01266 //print_WINDOWPOS(*(lpncsp->lppos)); 01267 } 01268 else 01269 { 01270 /* new window coordinates */ 01271 LPRECT lpncsp = (LPRECT) lp; 01272 //print_RECT(*lpncsp); 01273 } 01274 DEBUG_PRINT("\n"); 01275 /* 01276 if (this->m_info->window != NULL) 01277 { 01278 print_window_info(this->m_info->window); 01279 } 01280 */ 01281 } 01282 break; 01283 case WM_NCCREATE: 01284 DEBUG_PRINT("WM_NCCREATE\n"); 01285 break; 01286 case WM_NCDESTROY: 01287 DEBUG_PRINT("WM_NCDESTROY\n"); 01288 break; 01289 case WM_NULL: 01290 DEBUG_PRINT("WM_NULL\n"); 01291 break; 01292 case WM_PARENTNOTIFY: 01293 DEBUG_PRINT("WM_PARENTNOTIFY\n"); 01294 break; 01295 case WM_QUERYDRAGICON: 01296 DEBUG_PRINT("WM_QUERYDRAGICON\n"); 01297 break; 01298 case WM_QUERYOPEN: 01299 DEBUG_PRINT("WM_QUERYOPEN\n"); 01300 break; 01301 case WM_SIZE: 01302 { 01303 RECT rect; 01304 uint32_t width = 0; 01305 uint32_t height = 0; 01306 #if 0 01307 GetWindowRect( this->m_info->window, &rect ); 01308 #else 01309 ::GetClientRect( this->m_info->window, &rect ); 01310 #endif 01311 if ((this->m_info != NULL) && 01312 (this->m_info->window != NULL) && 01313 (this->m_info->capwin != NULL)) 01314 { 01315 ::SetWindowPos(this->m_info->capwin, NULL, 01316 0, 0, 01317 rect.right, rect.bottom, 01318 SWP_NOZORDER | SWP_NOMOVE); 01319 } 01320 width = rect.right - rect.left; 01321 height = rect.bottom - rect.top; 01322 DEBUG_PRINT("WM_SIZE(%u,%u)\n", width,height); 01323 } 01324 break; 01325 case WM_SIZING: 01326 { 01327 int32_t width = 0; 01328 int32_t height= 0; 01329 /* edge of window to be moved */ 01330 WPARAM fwSide = wp; 01331 /* screen coordinates of drag rectangle */ 01332 LPRECT lprc = (LPRECT) lp; 01333 01334 /* 01335 DEBUG_PRINT("WM_SIZING"); 01336 print_RECT(*lprc); 01337 print_SIDE(fwSide); 01338 DEBUG_PRINT("\n"); 01339 */ 01340 } 01341 break; 01342 case WM_STYLECHANGED: 01343 DEBUG_PRINT("WM_STYLECHANGED\n"); 01344 break; 01345 case WM_STYLECHANGING: 01346 DEBUG_PRINT("WM_STYLECHANGING\n"); 01347 break; 01348 case WM_USERCHANGED: 01349 DEBUG_PRINT("WM_USERCHANGED\n"); 01350 break; 01351 case WM_WINDOWPOSCHANGED: 01352 { 01353 LPWINDOWPOS lpwp = (LPWINDOWPOS)lp; 01354 DEBUG_PRINT("WM_WINDOWPOSCHANGED"); 01355 //print_WINDOWPOS(*lpwp); 01356 DEBUG_PRINT("\n"); 01357 } 01358 break; 01359 case WM_WINDOWPOSCHANGING: 01360 { 01361 LPWINDOWPOS lpwp = (LPWINDOWPOS)lp; 01362 DEBUG_PRINT("WM_WINDOWPOSCHANGING"); 01363 //print_WINDOWPOS(*lpwp); 01364 DEBUG_PRINT("\n"); 01365 } 01366 break; 01367 case WM_CAP_ABORT: DEBUG_PRINT("WM_CAP_ABORT\n"); break; 01368 case WM_CAP_DLG_VIDEOCOMPRESSION: DEBUG_PRINT("WM_CAP_DLG_VIDEOCOMPRESSION\n"); break; 01369 case WM_CAP_DLG_VIDEODISPLAY: DEBUG_PRINT("WM_CAP_DLG_VIDEODISPLAY\n"); break; 01370 case WM_CAP_DLG_VIDEOFORMAT: DEBUG_PRINT("WM_CAP_DLG_VIDEOFORMAT\n"); break; 01371 case WM_CAP_DLG_VIDEOSOURCE: DEBUG_PRINT("WM_CAP_DLG_VIDEOSOURCE\n"); break; 01372 case WM_CAP_DRIVER_CONNECT: DEBUG_PRINT("WM_CAP_DRIVER_CONNECT\n"); break; 01373 case WM_CAP_DRIVER_DISCONNECT: DEBUG_PRINT("WM_CAP_DRIVER_DISCONNECT\n"); break; 01374 case WM_CAP_DRIVER_GET_CAPS: DEBUG_PRINT("WM_CAP_DRIVER_GET_CAPS\n"); break; 01375 case WM_CAP_DRIVER_GET_NAME: DEBUG_PRINT("WM_CAP_DRIVER_GET_NAME\n"); break; 01376 case WM_CAP_DRIVER_GET_VERSION: DEBUG_PRINT("WM_CAP_DRIVER_GET_VERSION\n"); break; 01377 case WM_CAP_EDIT_COPY: DEBUG_PRINT("WM_CAP_EDIT_COPY\n"); break; 01378 case WM_CAP_FILE_ALLOCATE: DEBUG_PRINT("WM_CAP_FILE_ALLOCATE\n"); break; 01379 case WM_CAP_FILE_GET_CAPTURE_FILE: DEBUG_PRINT("WM_CAP_FILE_GET_CAPTURE_FILE\n"); break; 01380 case WM_CAP_FILE_SAVEAS: DEBUG_PRINT("WM_CAP_FILE_SAVEAS\n"); break; 01381 case WM_CAP_FILE_SAVEDIB: DEBUG_PRINT("WM_CAP_FILE_SAVEDIB\n"); break; 01382 case WM_CAP_FILE_SET_CAPTURE_FILE: DEBUG_PRINT("WM_CAP_FILE_SET_CAPTURE_FILE\n"); break; 01383 case WM_CAP_FILE_SET_INFOCHUNK: DEBUG_PRINT("WM_CAP_FILE_SET_INFOCHUNK\n"); break; 01384 case WM_CAP_GET_AUDIOFORMAT: DEBUG_PRINT("WM_CAP_GET_AUDIOFORMAT\n"); break; 01385 case WM_CAP_GET_MCI_DEVICE: DEBUG_PRINT("WM_CAP_GET_MCI_DEVICE\n"); break; 01386 case WM_CAP_GET_SEQUENCE_SETUP: DEBUG_PRINT("WM_CAP_GET_SEQUENCE_SETUP\n"); break; 01387 case WM_CAP_GET_STATUS: DEBUG_PRINT("WM_CAP_GET_STATUS\n"); break; 01388 case WM_CAP_GET_USER_DATA: DEBUG_PRINT("WM_CAP_GET_USER_DATA\n"); break; 01389 case WM_CAP_GET_VIDEOFORMAT: DEBUG_PRINT("WM_CAP_GET_VIDEOFORMAT\n"); break; 01390 case WM_CAP_GRAB_FRAME: DEBUG_PRINT("WM_CAP_GRAB_FRAME\n"); break; 01391 case WM_CAP_GRAB_FRAME_NOSTOP: DEBUG_PRINT("WM_CAP_GRAB_FRAME_NOSTOP\n"); break; 01392 case WM_CAP_PAL_AUTOCREATE: DEBUG_PRINT("WM_CAP_PAL_AUTOCREATE\n"); break; 01393 case WM_CAP_PAL_MANUALCREATE: DEBUG_PRINT("WM_CAP_PAL_MANUALCREATE\n"); break; 01394 case WM_CAP_PAL_OPEN: DEBUG_PRINT("WM_CAP_PAL_OPEN\n"); break; 01395 case WM_CAP_PAL_PASTE: DEBUG_PRINT("WM_CAP_PAL_PASTE\n"); break; 01396 case WM_CAP_PAL_SAVE: DEBUG_PRINT("WM_CAP_PAL_SAVE\n"); break; 01397 case WM_CAP_SEQUENCE: DEBUG_PRINT("WM_CAP_SEQUENCE\n"); break; 01398 case WM_CAP_SEQUENCE_NOFILE: DEBUG_PRINT("WM_CAP_SEQUENCE_NOFILE\n"); break; 01399 case WM_CAP_SET_AUDIOFORMAT: DEBUG_PRINT("WM_CAP_SET_AUDIOFORMAT\n"); break; 01400 case WM_CAP_SET_CALLBACK_CAPCONTROL: DEBUG_PRINT("WM_CAP_SET_CALLBACK_CAPCONTROL\n"); break; 01401 case WM_CAP_SET_CALLBACK_ERROR: DEBUG_PRINT("WM_CAP_SET_CALLBACK_ERROR\n"); break; 01402 case WM_CAP_SET_CALLBACK_FRAME: DEBUG_PRINT("WM_CAP_SET_CALLBACK_FRAME\n"); break; 01403 case WM_CAP_SET_CALLBACK_STATUS: DEBUG_PRINT("WM_CAP_SET_CALLBACK_STATUS\n"); break; 01404 case WM_CAP_SET_CALLBACK_VIDEOSTREAM: DEBUG_PRINT("WM_CAP_SET_CALLBACK_VIDEOSTREAM\n"); break; 01405 case WM_CAP_SET_CALLBACK_WAVESTREAM: DEBUG_PRINT("WM_CAP_SET_CALLBACK_WAVESTREAM\n"); break; 01406 case WM_CAP_SET_CALLBACK_YIELD: DEBUG_PRINT("WM_CAP_SET_CALLBACK_YIELD\n"); break; 01407 case WM_CAP_SET_MCI_DEVICE: DEBUG_PRINT("WM_CAP_SET_MCI_DEVICE\n"); break; 01408 case WM_CAP_SET_OVERLAY: DEBUG_PRINT("WM_CAP_SET_OVERLAY\n"); break; 01409 case WM_CAP_SET_PREVIEW: DEBUG_PRINT("WM_CAP_SET_PREVIEW\n"); break; 01410 case WM_CAP_SET_PREVIEWRATE: DEBUG_PRINT("WM_CAP_SET_PREVIEWRATE\n"); break; 01411 case WM_CAP_SET_SCALE: DEBUG_PRINT("WM_CAP_SET_SCALE\n"); break; 01412 case WM_CAP_SET_SCROLL: DEBUG_PRINT("WM_CAP_SET_SCROLL\n"); break; 01413 case WM_CAP_SET_SEQUENCE_SETUP: DEBUG_PRINT("WM_CAP_SET_SEQUENCE_SETUP\n"); break; 01414 case WM_CAP_SET_USER_DATA: DEBUG_PRINT("WM_CAP_SET_USER_DATA\n"); break; 01415 case WM_CAP_SET_VIDEOFORMAT: DEBUG_PRINT("WM_CAP_SET_VIDEOFORMAT\n"); break; 01416 case WM_CAP_SINGLE_FRAME: DEBUG_PRINT("WM_CAP_SINGLE_FRAME\n"); break; 01417 case WM_CAP_SINGLE_FRAME_CLOSE: DEBUG_PRINT("WM_CAP_SINGLE_FRAME_CLOSE\n"); break; 01418 case WM_CAP_SINGLE_FRAME_OPEN: DEBUG_PRINT("WM_CAP_SINGLE_FRAME_OPEN\n"); break; 01419 case WM_CAP_STOP: DEBUG_PRINT("WM_CAP_STOP\n"); break; 01420 01421 default: 01422 break; 01423 } 01424 01425 if (close_window) 01426 { 01427 01428 this->setRunning(0); 01429 this->wakeup(); 01430 message_handled = 1; 01431 } 01432 01433 if (message_handled != 1) 01434 { 01435 DEBUG_PRINT("DefWindowProc(wnd:%d msg:%u wp:%d lp:%d)\n",hw,message,wp,lp); 01436 retrc = DefWindowProc(hw,message,wp,lp); 01437 } 01438 01439 phTHIS_UNLOCK(locked); 01440 01441 return retrc; 01442 error: 01443 phTHIS_ERROR_UNLOCK(locked); 01444 01445 return phFAIL; 01446 } 01447 01448 /* ---------------------------------------------------------------------- */ 01449 int VFWSource::set_callbacks() 01450 { 01451 phFUNCTION("VFWSource::set_callbacks") 01452 BOOL brc; 01453 int locked = 0; 01454 01455 phTHIS_LOCK(locked); 01456 01457 if ((this->m_info != NULL) && 01458 (this->m_info->capwin != NULL) && 01459 (this->m_info->window != NULL)) 01460 { 01461 /* Set all the callbacks */ 01462 brc = capSetCallbackOnError (this->m_info->capwin, 01463 phVFWSource_ErrorCallbackProc); 01464 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01465 phPRINT_RC(rc,"capSetCallbackOnError","capSetCallbackOnError failed (0x%08x).",brc); 01466 01467 brc = capSetCallbackOnStatus (this->m_info->capwin, 01468 phVFWSource_StatusCallbackProc); 01469 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01470 phPRINT_RC(rc,"capSetCallbackOnStatus","capSetCallbackOnStatus failed (0x%08x).",brc); 01471 01472 brc = capSetCallbackOnCapControl(this->m_info->capwin, 01473 phVFWSource_ControlCallbackProc); 01474 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01475 phPRINT_RC(rc,"capSetCallbackOnCapControl","capSetCallbackOnCapControl failed (0x%08x).",brc); 01476 01477 brc = capSetCallbackOnVideoStream(this->m_info->capwin, 01478 phVFWSource_VidStreamCallbackProc); 01479 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01480 phPRINT_RC(rc,"capSetCallbackOnVideoStream","capSetCallbackOnVideoStream failed (0x%08x).",brc); 01481 01482 brc = capSetCallbackOnFrame(this->m_info->capwin, 01483 phVFWSource_FrameCallbackProc); 01484 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01485 phPRINT_RC(rc,"capSetCallbackOnFrame","capSetCallbackOnFrame failed (0x%08x).",brc); 01486 01487 brc = capSetCallbackOnWaveStream(this->m_info->capwin, 01488 phVFWSource_WaveStreamCallbackProc); 01489 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01490 phPRINT_RC(rc,"capSetCallbackOnWaveStream","capSetCallbackOnWaveStream failed (0x%08x).",brc); 01491 } 01492 01493 phTHIS_UNLOCK(locked); 01494 01495 return phSUCCESS; 01496 error: 01497 phTHIS_ERROR_UNLOCK(locked); 01498 01499 return phSUCCESS; 01500 } 01501 01502 /* ---------------------------------------------------------------------- */ 01503 int VFWSource::remove_callbacks() 01504 { 01505 phFUNCTION("VFWSource::remove_callbacks") 01506 01507 BOOL brc; 01508 int locked = 0; 01509 01510 phTHIS_LOCK(locked); 01511 01512 if ((this->m_info != NULL) && 01513 (this->m_info->capwin != NULL) && 01514 (this->m_info->window != NULL)) 01515 { 01516 brc = capSetCallbackOnError (this->m_info->capwin, NULL); 01517 brc = capSetCallbackOnStatus (this->m_info->capwin, NULL); 01518 brc = capSetCallbackOnCapControl (this->m_info->capwin, NULL); 01519 brc = capSetCallbackOnVideoStream (this->m_info->capwin, NULL); 01520 brc = capSetCallbackOnFrame (this->m_info->capwin, NULL); 01521 } 01522 01523 phTHIS_UNLOCK(locked); 01524 01525 return phSUCCESS; 01526 error: 01527 phTHIS_ERROR_UNLOCK(locked); 01528 01529 return phSUCCESS; 01530 } 01531 01532 /* ---------------------------------------------------------------------- */ 01533 int VFWSource::list_devices() 01534 { 01535 phFUNCTION("VFWSource::list_devices") 01536 01537 BOOL brc; 01538 int locked = 0; 01539 int i = 0; 01540 wchar_t szDeviceName[80]; 01541 wchar_t szDeviceVersion[80]; 01542 int count = 0; 01543 01544 phTHIS_LOCK(locked); 01545 01546 for (i = 0; i < 10; i++) 01547 { 01548 brc = capGetDriverDescription (i, 01549 (LPWSTR)szDeviceName, 01550 sizeof (szDeviceName), 01551 (LPWSTR)szDeviceVersion, 01552 sizeof (szDeviceVersion)); 01553 if (brc) 01554 { 01555 //DEBUG_PRINT("%d:%s:%s\n",i,szDeviceName,szDeviceVersion); 01556 DEBUG_PRINT("%d:%s:%s\n",i,szDeviceName,szDeviceVersion); 01557 count++; 01558 } 01559 } 01560 01561 phTHIS_UNLOCK(locked); 01562 01563 return count; 01564 error: 01565 phTHIS_ERROR_UNLOCK(locked); 01566 return phFAIL; 01567 } 01568 /* ---------------------------------------------------------------------- */ 01569 int VFWSource::connect_device(int index) 01570 { 01571 phFUNCTION("VFWSource::connect_device") 01572 BOOL brc; 01573 wchar_t driverName[256]; 01574 wchar_t driverVersion[256]; 01575 int locked = 0; 01576 01577 phTHIS_LOCK(locked); 01578 01579 if ((this->m_info != NULL) && (this->m_info->window != NULL)) 01580 { 01581 /* If the current device index is the one being chosen, don't 01582 * disconnect and reconnect */ 01583 if (index != this->m_info->device) 01584 { 01585 if (this->m_info->device != -1) 01586 { 01587 rc = this->disconnect_device(); 01588 phPRINT_RC(rc,NULL,"disconnect_device"); 01589 } 01590 01591 /* 01592 * 1.) Get Driver description 01593 * 2.) Connect to the driver 01594 * 3.) Set the window text to the driver name 01595 * 4.) Get, Adjust and Set the setup of the driver 01596 * 5.) Get the driver capabilities 01597 * 6.) Get the driver status 01598 * 7.) Set the callbacks 01599 * 8.) Set the video format 01600 */ 01601 01602 /* now set the text of the window to the driver's name */ 01603 brc = ::capGetDriverDescriptionW( index, 01604 (LPWSTR)driverName, 01605 sizeof(driverName), 01606 (LPWSTR)driverVersion, 01607 sizeof(driverVersion) ); 01608 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01609 phCHECK_RC(rc,"capGetDriverDescription", 01610 "capGetDriverDescription=%d failed (because there is no device at index %d ?).", 01611 brc, index); 01612 01613 /* Connect to the specified driver */ 01614 brc = capDriverConnect (this->m_info->capwin, index); 01615 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01616 phCHECK_RC(rc,"capDriverConnect","capDriverConnect failed (0x%08x).",brc); 01617 01618 this->m_info->connected = 1; 01619 01620 /* store the index of the device being used */ 01621 this->m_info->device = index; 01622 01623 brc = ::SetWindowText(this->m_info->window,(LPCWSTR)driverName); 01624 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01625 phPRINT_RC(rc,"SetWindowText","SetWindowText (0x%08x)",brc); 01626 01627 /* get the description */ 01628 phMemcpy(this->m_info->d_name,driverName,256); 01629 phMemcpy(this->m_info->d_version,driverVersion,256); 01630 01631 /* Get the capture setup */ 01632 brc = capCaptureGetSetup(this->m_info->capwin, 01633 &(this->m_info->d_setup), 01634 sizeof(CAPTUREPARMS)); 01635 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01636 phPRINT_RC(rc,"capDriverGetDescription","capDriverGetDescription (0x%08x)",brc); 01637 01638 /* Adjust the setup */ 01639 this->m_info->d_setup.fAbortLeftMouse = FALSE; 01640 this->m_info->d_setup.fAbortRightMouse = FALSE; 01641 this->m_info->d_setup.fYield = TRUE; 01642 this->m_info->d_setup.fCaptureAudio = FALSE; 01643 this->m_info->d_setup.wPercentDropForError = 100; 01644 01645 /* Set the parameters of the capture setup */ 01646 brc = capCaptureSetSetup(this->m_info->capwin, 01647 &(this->m_info->d_setup), 01648 sizeof(CAPTUREPARMS)); 01649 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01650 phPRINT_RC(rc,"capDriverGetDescription","capDriverGetDescription (0x%08x)",brc); 01651 01652 /* Get the capabilities */ 01653 brc = capDriverGetCaps(this->m_info->capwin, 01654 &this->m_info->d_caps, 01655 sizeof(CAPDRIVERCAPS)); 01656 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01657 phPRINT_RC(rc,"capDriverGetCaps","capDriverGetCaps (0x%08x)",brc); 01658 01659 /* resize the capture window to match the size of the driver */ 01660 brc = capGetStatus(this->m_info->capwin, 01661 &this->m_info->d_status, 01662 sizeof (CAPSTATUS)); 01663 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01664 phPRINT_RC(rc,"capGetStatus","capGetStatus (0x%08x)",brc); 01665 01666 /* Resize the window to match the size of the captured image 01667 * and then ... */ 01668 ::SetWindowPos(this->m_info->window, NULL, 0, 0, 01669 this->m_info->d_status.uiImageWidth, 01670 this->m_info->d_status.uiImageHeight, 01671 SWP_NOZORDER | SWP_NOMOVE); 01672 01673 rc = this->set_callbacks(); 01674 phPRINT_RC(rc,NULL,"set_callbacks (0x%08x)",brc); 01675 01676 /* ... Enable the preview */ 01677 // capPreview(this->m_info->capwin, FALSE); 01678 // capPreviewRate(this->m_info->capwin,66); 01679 01680 rc = this->setVideoFormat( this->m_width,this->m_height, phImageRGB24 ); 01681 phPRINT_RC(rc,NULL,"this->setVideoFormat (0x%08x)",brc); 01682 } 01683 } 01684 01685 if ((this->m_info != NULL) && (this->m_info->device == -1)) 01686 { 01687 brc = ::SetWindowText(this->m_info->window,(LPCWSTR)"No Drivers"); 01688 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01689 phPRINT_RC(rc,"SetWindowText","SetWindowText (0x%08x)",brc); 01690 } 01691 01692 phTHIS_UNLOCK(locked); 01693 01694 return phSUCCESS; 01695 01696 error: 01697 phTHIS_ERROR_UNLOCK(locked); 01698 01699 if (this->m_info != NULL) 01700 { 01701 this->m_info->device = -1; 01702 } 01703 01704 return phFAIL; 01705 } 01706 01707 /* ---------------------------------------------------------------------- */ 01708 int VFWSource::disconnect_device() 01709 { 01710 phFUNCTION("VFWSource::disconnect_device") 01711 BOOL brc; 01712 int locked = 0; 01713 01714 phTHIS_LOCK(locked); 01715 01716 if ((this->m_info != NULL) && (this->m_info->window != NULL)) 01717 { 01718 rc = this->device_stop(); 01719 phPRINT_RC(rc,NULL,"device_stop"); 01720 01721 if ((this->m_info->device != -1) && (this->m_info->connected)) 01722 { 01723 ::SetLastError(ERROR_SUCCESS); 01724 brc = capDriverDisconnect(this->m_info->capwin); 01725 if ((brc == 0) && (GetLastError() != ERROR_SUCCESS)) 01726 rc = phFAIL; 01727 else 01728 rc = phSUCCESS; 01729 phPRINT_RC(rc,"capDriverDisconnect","capDriverDisconnect failed (0x%08x).",brc); 01730 01731 this->m_info->connected = 0; 01732 this->m_info->device = -1; 01733 } 01734 01735 phMemset(&this->m_info->d_status,0, sizeof (CAPSTATUS)); 01736 01737 brc = ::SetWindowText(this->m_info->window,(LPCWSTR)"No Drivers"); 01738 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01739 phPRINT_RC(rc,"SetWindowText","SetWindowText (0x%08x)",brc); 01740 } 01741 01742 phTHIS_UNLOCK(locked); 01743 01744 return phSUCCESS; 01745 error: 01746 phTHIS_ERROR_UNLOCK(locked); 01747 01748 return phSUCCESS; 01749 } 01750 01751 /* ---------------------------------------------------------------------- */ 01752 int VFWSource::device_start() 01753 { 01754 phFUNCTION("VFWSource::device_start"); 01755 01756 int locked = 0; 01757 BOOL brc = FALSE; 01758 01759 phTHIS_LOCK(locked); 01760 01761 if ((this->m_info != NULL) && 01762 (this->m_info->started == 0) && 01763 (this->m_info->window != NULL) && 01764 (this->m_info->capwin != NULL) && 01765 (this->m_info->device >= 0)) 01766 { 01767 brc = capCaptureSequenceNoFile(this->m_info->capwin); 01768 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01769 phPRINT_RC(rc,"capCaptureSequence","capCaptureSequence failed (0x%08x).",brc); 01770 01771 if (rc != phFAIL) 01772 this->m_info->started = 1; 01773 } 01774 01775 phTHIS_UNLOCK(locked); 01776 01777 return phSUCCESS; 01778 error: 01779 phTHIS_ERROR_UNLOCK(locked); 01780 01781 return phFAIL; 01782 } 01783 01784 /* ---------------------------------------------------------------------- */ 01785 int VFWSource::device_stop() 01786 { 01787 phFUNCTION("VFWSource::device_stop"); 01788 01789 int locked = 0; 01790 BOOL brc = FALSE; 01791 01792 phTHIS_LOCK(locked); 01793 01794 if ((this->m_info != NULL) && 01795 (this->m_info->started == 1) && 01796 (this->m_info->window != NULL) && 01797 (this->m_info->capwin != NULL) && 01798 (this->m_info->device >= 0)) 01799 { 01800 brc = capCaptureAbort(this->m_info->capwin); 01801 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01802 phPRINT_RC(rc,"capCaptureAbort","capCaptureAbort failed (0x%08x).",brc); 01803 01804 if (rc != phFAIL) 01805 this->m_info->started = 0; 01806 } 01807 01808 phTHIS_UNLOCK(locked); 01809 01810 return phSUCCESS; 01811 error: 01812 phTHIS_ERROR_UNLOCK(locked); 01813 01814 return phFAIL; 01815 } 01816 01817 /* ---------------------------------------------------------------------- */ 01818 int VFWSource::setVideoFormat( uint32_t w, uint32_t h, int32_t f ) 01819 { 01820 phFUNCTION("VFWSource::setVideoFormat"); 01821 01822 int locked = 0; 01823 LPBITMAPINFO lpbi = NULL; 01824 int restart = 0; 01825 DWORD dwSize; 01826 BOOL brc = FALSE; 01827 01828 phTHIS_LOCK(locked); 01829 01830 if ((this->m_info != NULL) && 01831 (this->m_info->window != NULL) && 01832 (this->m_info->capwin != NULL) && 01833 (this->m_info->device >= 0)) 01834 { 01835 if (this->m_info->started) 01836 { 01837 rc = this->device_stop(); 01838 phPRINT_RC(rc,NULL,"device_stop"); 01839 restart = 1; 01840 } 01841 01842 switch (f) 01843 { 01844 /* --------------------------------------------------- */ 01845 case phImageGREY8: 01846 break; 01847 /* --------------------------------------------------- */ 01848 case phImageBGR24: 01849 case phImageRGB24: 01850 break; 01851 /* --------------------------------------------------- */ 01852 case phImageBGRA32: 01853 case phImageRGBA32: 01854 break; 01855 /* --------------------------------------------------- */ 01856 /* if multiple formats are specified or the format is 01857 * invalid, then phImageRGB24 is used */ 01858 default: 01859 this->m_private_format = this->m_format = f = phImageRGB24; 01860 } 01861 01862 dwSize = capGetVideoFormatSize(this->m_info->capwin); 01863 01864 lpbi = (LPBITMAPINFO)phCalloc(1,dwSize); 01865 phPRINT_PTR(lpbi,"phCalloc","phCalloc failed."); 01866 01867 brc = capGetVideoFormat(this->m_info->capwin, lpbi, dwSize); 01868 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01869 phPRINT_RC(rc,"capGetVideoFormat","capGetVideoFormat (0x%08x)",brc); 01870 01871 lpbi->bmiHeader.biSize = dwSize; 01872 lpbi->bmiHeader.biWidth = w; 01873 lpbi->bmiHeader.biHeight = h; 01874 lpbi->bmiHeader.biPlanes = 1; 01875 lpbi->bmiHeader.biBitCount = phImageFormatToDepth(f) * 8; 01876 lpbi->bmiHeader.biCompression = BI_RGB; 01877 lpbi->bmiHeader.biSizeImage = w * h * phImageFormatToDepth(f); 01878 lpbi->bmiHeader.biClrUsed = 0; 01879 lpbi->bmiHeader.biClrImportant = 0; 01880 01881 brc = capSetVideoFormat(this->m_info->capwin, lpbi, dwSize); 01882 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 01883 phPRINT_RC(rc,"capSetVideoFormat","capSetVideoFormat (0x%08x)",brc); 01884 01885 if (rc != phFAIL) 01886 { 01887 if (this->m_info->d_lpbi != NULL) phFree(this->m_info->d_lpbi); 01888 01889 this->m_info->d_lpbi = lpbi; 01890 } 01891 else 01892 { 01893 phFree(lpbi); 01894 } 01895 01896 if (restart) 01897 { 01898 rc = this->device_start(); 01899 phPRINT_RC(rc,NULL,"device_start"); 01900 } 01901 } 01902 01903 phTHIS_UNLOCK(locked); 01904 01905 return phSUCCESS; 01906 01907 error: 01908 phTHIS_ERROR_UNLOCK(locked); 01909 01910 return phFAIL; 01911 } 01912 01913 /* ---------------------------------------------------------------------- */ 01914 int VFWSource::open(char *path) 01915 { 01916 phFUNCTION("VFWSource::open") 01917 01918 rc = this->lock(); 01919 phPRINT_RC(rc,NULL,"this->lock()"); 01920 01921 /* device is already open, close it */ 01922 if (this->isOpen()) 01923 { 01924 rc = this->close(); 01925 phPRINT_RC(rc,NULL,"this->close()"); 01926 } 01927 01928 if (path != NULL) 01929 { 01930 rc = this->setPath( path ); 01931 phPRINT_RC(rc,NULL,"this->setPath( path:%s )",path); 01932 } 01933 01934 /* If the device isn't already open....*/ 01935 /* open the device */ 01936 /* Find out info the device is capable of */ 01937 /* ... apply all of the current settings to the device */ 01938 /* ... set the device as open */ 01939 01940 rc = this->unlock(); 01941 phPRINT_RC(rc,NULL,"this->unlock()"); 01942 01943 return phSUCCESS; 01944 #if 0 01945 error: 01946 rc = this->unlock(); 01947 phPRINT_RC(rc,NULL,"this->unlock()"); 01948 01949 return phFAIL; 01950 #endif 01951 } 01952 01953 /* ---------------------------------------------------------------------- */ 01954 int VFWSource::isOpen() 01955 { 01956 return this->isRunning(); 01957 } 01958 01959 /* ---------------------------------------------------------------------- */ 01960 int VFWSource::close() 01961 { 01962 phFUNCTION("VFWSource::close") 01963 01964 rc = this->lock(); 01965 phPRINT_RC(rc,NULL,"this->lock()"); 01966 01967 /* Close the device and reset all the parameters */ 01968 01969 #if 0 01970 success: 01971 #endif 01972 rc = this->unlock(); 01973 phPRINT_RC(rc,NULL,"this->unlock()"); 01974 01975 return phSUCCESS; 01976 01977 #if 0 01978 error: 01979 rc = this->unlock(); 01980 phPRINT_RC(rc,NULL,"this->unlock()"); 01981 01982 return phFAIL; 01983 #endif 01984 } 01985 01986 /* ---------------------------------------------------------------------- */ 01987 /* m_settings and this are locked upon entry */ 01988 /* ---------------------------------------------------------------------- */ 01989 int VFWSource::onApplySettings() 01990 { 01991 phFUNCTION("VFWSource::onApplySettings") 01992 int retrc = phSUCCESS; 01993 int locked = 0; 01994 int set_locked = 0; 01995 01996 int ch_init = 0; 01997 int ch_b = 0; 01998 int ch_hue = 0; 01999 int ch_color = 0; 02000 int ch_con = 0; 02001 int ch_white = 0; 02002 int ch_channel = 0; 02003 int ch_h = 0; 02004 int ch_w = 0; 02005 int ch_f = 0; 02006 int ch_p = 0; 02007 02008 ch_init = ph_int32_array_find(this->m_changed_array, phCHANGE_INIT,NULL); 02009 /* 02010 * this->m_changed_array contains the list of changes that are to 02011 * be applied. 02012 * 02013 * This method will call phImageCapture::onApplySettings which will empty 02014 * the array so that settings are applied only once. 02015 */ 02016 02017 /* Copy the image settings into the VFW structure */ 02018 ch_b = ph_int32_array_find(this->m_changed_array, phCHANGE_BRIGHTNESS, 02019 NULL); 02020 ch_hue = ph_int32_array_find(this->m_changed_array, phCHANGE_HUE, 02021 NULL); 02022 ch_color = ph_int32_array_find(this->m_changed_array, phCHANGE_COLOR, 02023 NULL); 02024 ch_con = ph_int32_array_find(this->m_changed_array, phCHANGE_CONTRAST, 02025 NULL); 02026 ch_white = ph_int32_array_find(this->m_changed_array, phCHANGE_WHITENESS, 02027 NULL); 02028 if (ch_init > 0) ch_b = ch_hue = ch_color = ch_con = ch_white = 1; 02029 if ((ch_b > 0) || (ch_hue > 0) || (ch_color > 0) || 02030 (ch_con > 0) || (ch_white > 0)) 02031 { 02032 #if 0 02033 this->m_changed_settings = 1; 02034 if (ch_b > 0) 02035 this->m_settings.brightness = this->m_brightness; 02036 if (ch_hue > 0) 02037 this->m_settings.hue = this->m_hue; 02038 if (ch_color > 0) 02039 this->m_settings.colour = this->m_color; 02040 if (ch_con > 0) 02041 this->m_settings.contrast = this->m_contrast; 02042 if (ch_white > 0) 02043 this->m_settings.whiteness = this->m_whiteness; 02044 #endif 02045 } 02046 02047 /*--------------------------------------------------------------------* 02048 *--------------------------------------------------------------------*/ 02049 ch_channel = ph_int32_array_find(this->m_changed_array,phCHANGE_CHANNEL, 02050 NULL); 02051 if ((ch_channel > 0) || (ch_init > 0)) 02052 { 02053 this->m_changed_channel = 1; 02054 } 02055 /* else, the channel is < 0 or the current chn # */ 02056 02057 /* settings that require the capture to not be in progress for the 02058 * VFWSource settings changes to be applied */ 02059 ch_h = ph_int32_array_find(this->m_changed_array, phCHANGE_HEIGHT, NULL); 02060 ch_w = ph_int32_array_find(this->m_changed_array, phCHANGE_WIDTH, NULL); 02061 ch_f = ph_int32_array_find(this->m_changed_array, phCHANGE_FORMAT, NULL); 02062 02063 if (ch_init > 0) ch_h = ch_w = ch_f = 1; 02064 02065 if ((ch_h > 0) || (ch_w > 0) || (ch_f > 0)) 02066 { 02067 /* if the retrc variable isn't set to 1, then copy these 02068 * into the private values for the VFWSource class */ 02069 /* Settings not applied until restart */ 02070 // if ((!this->isRunning()) && (this->m_hw_mmapped == 0)) 02071 if (this->isRunning()) 02072 { 02073 int changed_image_dimensions = 0; 02074 02075 uint32_t width = 0; 02076 uint32_t height = 0; 02077 02078 if ((this->m_info != NULL) && (this->m_info->d_lpbi != NULL)) 02079 { 02080 width = this->m_info->d_lpbi->bmiHeader.biWidth; 02081 height = this->m_info->d_lpbi->bmiHeader.biHeight; 02082 height = height * (height < 0 ? -1 : 1); 02083 } 02084 02085 /* use OR/|| because sometimes the change must be forced 02086 * to actually apply the settings */ 02087 if ((ch_w > 0) || (width != this->m_width) || 02088 (ch_h > 0) || (height != this->m_height)) 02089 { 02090 changed_image_dimensions = 1; 02091 } 02092 02093 /* use OR/|| because sometimes the change must be forced 02094 * to actually apply the settings */ 02095 if ((ch_f > 0) || (this->m_private_format != this->m_format)) 02096 { 02097 int32_t f = this->m_format; 02098 int32_t validFormats = (phImageRGB24 | 02099 phImageBGR24 | 02100 phImageRGBA32 | 02101 phImageBGRA32 | 02102 phImageGREY8); 02103 changed_image_dimensions = 1; 02104 02105 /* make sure any special flags are removed */ 02106 f &= validFormats; 02107 02108 02109 02110 this->m_private_format = this->m_format = f; 02111 } 02112 02113 /* if any of the fields changed, then apply the changes 02114 * to the device if it's open and set the new image size */ 02115 if (changed_image_dimensions == 1) 02116 { 02117 #if 0 02118 phIMAGE_SIZE_IN_BYTES(this->m_image_size, 02119 this->m_captureSpec.width, 02120 this->m_captureSpec.height, 02121 this->m_private_format ); 02122 #endif 02123 rc = this->setVideoFormat( this->m_width, 02124 this->m_height, 02125 this->m_format ); 02126 phPRINT_RC(rc,NULL,"setVideoFormat"); 02127 02128 this->m_changed_settings = 1; 02129 } 02130 } 02131 else 02132 { 02133 retrc = 1; 02134 } 02135 } 02136 02137 ch_p = ph_int32_array_find(this->m_changed_array, phCHANGE_PATH, NULL); 02138 if ((ch_p > 0) || (ch_init > 0)) 02139 { 02140 /* this->m_path is used in 'open', no special VFWSource 02141 * settings have to be applied here */ 02142 retrc = 1; 02143 } 02144 02145 /* if the device is open, apply the settings... */ 02146 /* can really only apply the settings if the device is open */ 02147 /* until the device is open we're merely saving the values */ 02148 /* TODO: if reopening and stopping of the thread is necessary 02149 * then this is likely the place to do it */ 02150 02151 02152 /* The value m_changed_settings is persistent across calls to 02153 * applySettings in the case the settings aren't applied 02154 * in one call of applySettings */ 02155 if (this->m_changed_settings == 1) 02156 { 02157 /* Apply the picture settings */ 02158 this->m_changed_settings = 0; 02159 } 02160 02161 /* The value m_changed_channel is persistent across calls to 02162 * applySettings in the case the settings aren't applied 02163 * in one call of applySettings */ 02164 if (this->m_changed_channel == 1) 02165 { 02166 /* get channel: fills the structure's fields with default values*/ 02167 02168 /* set image source and TV norm */ 02169 02170 /* set channel */ 02171 02172 this->m_changed_channel = 0; 02173 } 02174 02175 rc = this->phImageCapture::onApplySettings(); 02176 phCHECK_RC(rc,NULL,"this->phImageCapture::onApplySettings() failed."); 02177 02178 return retrc; 02179 error: 02180 return phFAIL; 02181 } 02182 /* ---------------------------------------------------------------------- */ 02183 int VFWSource::wakeup() 02184 { 02185 phFUNCTION("VFWSource::wakeup()") 02186 02187 if ((this->m_info != NULL) && (this->m_info->window != NULL)) 02188 { 02189 BOOL brc = TRUE; 02190 brc = ::PostMessage(this->m_info->window, 02191 WM_QUIT, 02192 NULL, NULL); 02193 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 02194 phPRINT_RC(rc,"PostMessage","PostMessage (0x%08x)",brc); 02195 } 02196 /* 02197 rc = this->phImageWindow::wakeup(); 02198 phPRINT_RC(rc,NULL,"this->phImageWindow::wakeup()"); 02199 */ 02200 return phSUCCESS; 02201 } 02202 02203 /* ---------------------------------------------------------------------- */ 02204 int VFWSource::cleanup() 02205 { 02206 phFUNCTION("VFWSource::cleanup()") 02207 02208 rc = this->lock(); 02209 phPRINT_RC(rc,NULL,"this->lock()"); 02210 02211 rc = this->phImageCapture::cleanup(); 02212 phPRINT_RC(rc,NULL,"this->phImageCapture::cleanup()"); 02213 02214 rc = this->unlock(); 02215 phPRINT_RC(rc,NULL,"this->unlock()"); 02216 02217 return phSUCCESS; 02218 } 02219 02220 /* ---------------------------------------------------------------------- */ 02221 int VFWSource::gui_show() 02222 { 02223 phFUNCTION("VFWSource::gui_show") 02224 BOOL brc = TRUE; 02225 int locked = 0; 02226 int retrc = phSUCCESS; 02227 02228 phTHIS_LOCK(locked); 02229 02230 if ((this->m_info != NULL) && (this->m_info->window != NULL)) 02231 { 02232 if (this->m_show_first) 02233 { 02234 brc = ShowWindow(this->m_info->window,SW_SHOWNORMAL); 02235 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 02236 02237 brc = SetWindowPos(this->m_info->window, 02238 HWND_TOP, 02239 10,10,320,240, 02240 SWP_NOCOPYBITS | 02241 SWP_NOSIZE | 02242 SWP_NOMOVE | 02243 SWP_SHOWWINDOW); 02244 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 02245 02246 SetActiveWindow(this->m_info->window); 02247 02248 brc = SetForegroundWindow(this->m_info->window); 02249 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 02250 02251 this->m_show_first = 0; 02252 } 02253 else 02254 { 02255 brc = ShowWindow(this->m_info->window,SW_SHOW); 02256 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 02257 } 02258 02259 brc = ShowWindow(this->m_info->capwin,SW_SHOW); 02260 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 02261 02262 SetFocus(this->m_info->capwin); 02263 } 02264 else 02265 retrc = 1; 02266 02267 phTHIS_UNLOCK(locked); 02268 02269 return retrc; 02270 02271 error: 02272 phTHIS_ERROR_UNLOCK(locked); 02273 02274 return phFAIL; 02275 } 02276 02277 /* ---------------------------------------------------------------------- */ 02278 int VFWSource::gui_hide() 02279 { 02280 phFUNCTION("VFWSource::gui_hide") 02281 BOOL brc = TRUE; 02282 int locked = 0; 02283 int retrc = phSUCCESS; 02284 02285 phTHIS_LOCK(locked); 02286 02287 if (this->m_info != NULL) 02288 { 02289 brc = ShowWindow(this->m_info->window,SW_HIDE); 02290 brc = ShowWindow(this->m_info->capwin,SW_HIDE); 02291 } 02292 else 02293 retrc = 1; 02294 02295 phTHIS_UNLOCK(locked); 02296 02297 return retrc; 02298 02299 error: 02300 phTHIS_ERROR_UNLOCK(locked); 02301 02302 return phFAIL; 02303 } 02304 02305 02306 /* ---------------------------------------------------------------------- */ 02307 int VFWSource::run() 02308 { 02309 phFUNCTION("VFWSource::run") 02310 MSG msg; 02311 BOOL brc = TRUE; 02312 LRESULT lrc = 0; 02313 int device = -1; 02314 int total_devices = 0; 02315 02316 phImage *output_buffer = this->getImage(); 02317 02318 uint32_t i = 0; 02319 02320 /* Setup */ 02321 rc = this->init_window(); 02322 phCHECK_RC(rc,NULL,"this->init_window"); 02323 02324 total_devices = rc = this->list_devices(); 02325 phPRINT_RC(rc,NULL,"list_Devices"); 02326 02327 /* Convert the device path to a number for VFW */ 02328 if (this->getPath() != NULL) 02329 device = atoi(this->getPath()); 02330 if ((device < 0) || (device >= total_devices)) rc = phFAIL; else rc = phSUCCESS; 02331 phCHECK_RC(rc,NULL,"device index out of range:%d",device); 02332 02333 rc = this->connect_device(device); 02334 phCHECK_RC(rc,NULL,"this->connect_device(%d)",device); 02335 02336 rc = this->device_start(); 02337 phCHECK_RC(rc,NULL,"this->device_start()"); 02338 02339 #if 0 02340 /* .) Set the variables for remote viewing */ 02341 rc = this->gui_show(); 02342 phCHECK_RC(rc,NULL,"this->gui_show()"); 02343 #endif 02344 /* Release the thread that spawned this one */ 02345 /* Everything has been copied and everything is ready to start */ 02346 rc = this->signal_running(); 02347 phPRINT_RC(rc,NULL,"this->signal_running"); 02348 02349 DEBUG_PRINT("Thread Started\n"); 02350 02351 #if 0 02352 brc = capDlgVideoSource(this->m_info->window); 02353 if (brc == 0) rc = phFAIL; else rc = phSUCCESS; 02354 phPRINT_RC(rc,"capDlgVideoSource","capDlgVideoSource"); 02355 #endif 02356 print_CAPTUREPARMS(this->m_info->d_setup); 02357 print_CAPDRIVERCAPS(this->m_info->d_caps); 02358 print_CAPSTATUS(this->m_info->d_status); 02359 02360 while (this->isRunning()) 02361 { 02362 //brc = ::GetMessage(&msg,NULL,0,0); 02363 brc = ::GetMessage(&msg,this->m_info->window,0,0); 02364 02365 if (brc == -1) 02366 { 02367 if (GetLastError() == ERROR_INVALID_WINDOW_HANDLE) 02368 { 02369 this->setRunning(0); 02370 continue; 02371 } 02372 else 02373 { 02374 phPRINT_RC(phFAIL,"GetMessage","GetMessage failed."); 02375 } 02376 } 02377 else 02378 { 02379 brc = TranslateMessage(&msg); 02380 lrc = DispatchMessage(&msg); 02381 } 02382 } 02383 02384 DEBUG_PRINT("Thread returning cleanly\n"); 02385 02386 rc = this->device_stop(); 02387 phCHECK_RC(rc,NULL,"this->device_stop()"); 02388 02389 rc = this->gui_hide(); 02390 phPRINT_RC(rc,NULL,"this->gui_hide()"); 02391 02392 rc = this->disconnect_device(); 02393 phPRINT_RC(rc,NULL,"this->disconnect_device()"); 02394 02395 rc = this->destroy_window(); 02396 phPRINT_RC(rc,NULL,"this->init_window"); 02397 02398 return phSUCCESS; 02399 02400 error: 02401 phPROGRESS("Thread returning with error\n"); 02402 02403 rc = this->gui_hide(); 02404 phPRINT_RC(rc,NULL,"this->gui_hide()"); 02405 02406 rc = this->destroy_window(); 02407 phPRINT_RC(rc,NULL,"this->init_window"); 02408 02409 rc = this->signal_error(); 02410 phPRINT_RC(rc,NULL,"this->signal_error"); 02411 02412 return phFAIL; 02413 } 02414
Copyright (C) 2002 - 2007 |
Philip D.S. Thoren ( pthoren@users.sourceforge.net ) University Of Massachusetts at Lowell Robotics Lab |