/*++ Module Name: sample2.c Abstract: simultaneously grabbing of 2 cameras by GINGA++ M2 or M4. Environment: user mode Notes: gingapp driver usage sample 2 Revision History: --*/ #include #include #include "GINGAPPEX.H" #define BUFFER_WIDTH 640 #define BUFFER_HEIGHT 480 #define TIMEOUT 10000 /* 10 sec */ #define USE_CAPTURE_CHANNEL 2 #define REPEAT 10 #define CAM_FILE "teli/CS8550_NI_NORM" //#define CAM_FILE "cis/VCC850A_NI_NORM" #define NUM_BUFFERS 200 typedef enum { GINGAPP_M4 = 0, GINGAPP_M2 } GINGAPP_BOARD_TYPE; typedef struct tagFunctions { HMODULE hGingaDll; /* Ginga++ API */ long (*GingaPPResetDevice)(void); unsigned long (*GingaPPCountCaptureChannel)(void); void **(*GingaPPAllocFrameBuffer)(unsigned long Width, unsigned long Height, unsigned long NFrame); long (*GingaPPFreeFrameBuffer)(void **BufferId); long (*GingaPPOpenConfiguration)(char * pConfigFilePath, GINGAPP_CAPTURE_CONFIGURATION ** ppConfig); long (*GingaPPCloseConfiguration)(GINGAPP_CAPTURE_CONFIGURATION * pConfig); long (*GingaPPSetConfiguration)(unsigned long ChannelNumber, GINGAPP_CAPTURE_CONFIGURATION * pConfig); long (*GingaPPStartCapture)(unsigned long ChannelNumber, unsigned long StartFrameNumber, unsigned long EndFrameNumber); long (*GingaPPForceShot)(unsigned long ChannelNumber); long (*GingaPPSenseStatus)(unsigned long ChannelNumber, long * pStatus); long (*GingaPPStopCapture)(unsigned long ChannelNumber); long (*GingaPPAbortCapture)(unsigned long ChannelNumber); long (*GingaPPGetLastFrame)(void ** BufferId, unsigned long * pFrameNumber, unsigned long ChannelNumber); long (*GingaPPIsFrameValid)(void ** BufferId, unsigned long FrameNumber, BOOL * pValid, unsigned long ChannelNumber); } Functions; void DriverErrorCheck( long Status, char * pErrorMessage ); int DetectDevice( GINGAPP_BOARD_TYPE type ); Functions * LoadFunctions( GINGAPP_BOARD_TYPE type ); void FreeFunctions( Functions *fc ); int main(void) { GINGAPP_CAPTURE_CONFIGURATION * pConfig; void ** BufferId[USE_CAPTURE_CHANNEL]; const unsigned long Width = BUFFER_WIDTH; const unsigned long Height = BUFFER_HEIGHT; long Status; long ChannelStatus; long NumberOfChannels; HANDLE hFrameComplete[USE_CAPTURE_CHANNEL]; HANDLE hCaptureStop[USE_CAPTURE_CHANNEL]; HANDLE WaithFrameComplete[USE_CAPTURE_CHANNEL]; HANDLE WaithCaptureStop[USE_CAPTURE_CHANNEL]; DWORD WaitResult; int i; int m4_num, m2_num; Functions *fc = NULL; /* 接続されているボードのタイプと枚数を取得する */ m4_num = DetectDevice(GINGAPP_M4) >> 2; m2_num = DetectDevice(GINGAPP_M2) >> 2; /* ボードのタイプに応じで明示的に銀河++のAPIをロードする */ if (m4_num > 0) { fc = LoadFunctions(GINGAPP_M4); } else if (m2_num > 0) { fc = LoadFunctions(GINGAPP_M2); } if (!fc) { printf("LoadFunctions failed.\n"); exit(0); } /* 取り込み可能チャンネル数を問い合わせる */ NumberOfChannels = fc->GingaPPCountCaptureChannel(); if(NumberOfChannels < USE_CAPTURE_CHANNEL) { printf("capture channel not exist.\n"); exit(0); } /* 各取り込みポートごとにフレームバッファを確保 */ for(i = 0; i < USE_CAPTURE_CHANNEL; ++i) { BufferId[i] = fc->GingaPPAllocFrameBuffer(Width, Height, NUM_BUFFERS); if(BufferId[i] == NULL) { printf("frame buffer allocate error.\n"); exit(0); } } // カメラファイルを読み込む Status = fc->GingaPPOpenConfiguration(CAM_FILE, &pConfig); DriverErrorCheck(Status, "configuration file open failed."); // 1フレームの取り込み完了イベントとして割り当てるイベントを生成 for(i = 0; i < USE_CAPTURE_CHANNEL; ++i) { hFrameComplete[i] = CreateEvent(NULL, FALSE, FALSE, NULL); if(hFrameComplete[i] == NULL) { printf("\"frame complete\"event create failed.\n", i); exit(0); } } // 全ての取り込み停止イベントとして割り当てるイベントを生成 for(i = 0; i < USE_CAPTURE_CHANNEL; ++i) { hCaptureStop[i] = CreateEvent(NULL, FALSE, FALSE, NULL); if(hCaptureStop[i] == NULL) { printf("\"capture stop\"event create failed.\n"); exit(0); } } // 取り込み設定情報にバッファIDとイベントハンドルを追加する for(i = 0; i < USE_CAPTURE_CHANNEL; ++i) { pConfig->Destination.BufferId = BufferId[i]; pConfig->Events.FrameComplete = hFrameComplete[i]; pConfig->Events.CaptureStop = hCaptureStop[i]; // 各チャンネルへ取り込みの設定を行う Status = fc->GingaPPSetConfiguration(i, pConfig); DriverErrorCheck(Status, "configuration failed.\n"); } for(i = 0; i < USE_CAPTURE_CHANNEL; ++i) { WaithFrameComplete[i] = hFrameComplete[i]; WaithCaptureStop[i] = hCaptureStop[i]; } /* 取り込みを開始する */ for(i = 0; i < USE_CAPTURE_CHANNEL; ++i) { Status = fc->GingaPPStartCapture(i, 0, NUM_BUFFERS - 1); DriverErrorCheck(Status, "capture start failed.\n"); } /* 取り込みの停止を"TIMEOUT"(msec)だけ待つ */ WaitResult = WaitForMultipleObjects(USE_CAPTURE_CHANNEL, WaithCaptureStop, TRUE, TIMEOUT); if (WaitResult == WAIT_TIMEOUT) { printf("capture timeout.\n"); for(i = 0; i < USE_CAPTURE_CHANNEL; ++i) { Status = fc->GingaPPSenseStatus(i, &ChannelStatus); DriverErrorCheck(Status, "sense channel status failed.\n"); if(Status != GINGAPP_STATUS_IDLE) { Status = fc->GingaPPAbortCapture(i); DriverErrorCheck(Status, "capture abort failed.\n"); WaitResult = WaitForSingleObject(hCaptureStop[i], TIMEOUT); if(WaitResult == WAIT_TIMEOUT) { printf("abort timeout.\n"); exit(0); } } } } else if (WaitResult == WAIT_OBJECT_0) { printf("capture complete.\n"); } /* 取り込み設定情報を閉じる */ Status = fc->GingaPPCloseConfiguration(pConfig); if(Status != GINGAPP_NO_ERROR) { printf("configuration close failed.\n"); } /* イベントを開放する */ for(i = 0; i < USE_CAPTURE_CHANNEL; ++i) { CloseHandle(hCaptureStop[i]); CloseHandle(hFrameComplete[i]); } /* フレームバッファを開放する */ for(i = 0; i < USE_CAPTURE_CHANNEL; ++i) { Status = fc->GingaPPFreeFrameBuffer(BufferId[i]); if(Status != GINGAPP_NO_ERROR) { printf("framebuffer free failed.\n"); } } FreeFunctions(fc); return(1); } /********************/ /* DriverErrorCheck */ /********************/ // エラーチェック関数、エラー内容を出力後、プログラムを終了させる void DriverErrorCheck( long Status, char * pErrorMessage ) { if(Status != GINGAPP_NO_ERROR) { printf("%s", pErrorMessage); exit(0); } } /*********************/ /*** DetectDevice ****/ /*********************/ static int DetectDevice(GINGAPP_BOARD_TYPE type) { int ret = 0; /* port number */ HMODULE hDll; char DllName[256]; unsigned long (*GingaPPCountCaptureChannel)(void); if (type == GINGAPP_M4) { strcpy(DllName, "GingaPP.dll"); } else if (type == GINGAPP_M2) { strcpy(DllName, "GingaM2.dll"); } else return ret; hDll = LoadLibrary(DllName); if (!hDll) return ret; GingaPPCountCaptureChannel = (unsigned long (*)(void)) GetProcAddress(hDll, "GingaPPCountCaptureChannel"); if (GingaPPCountCaptureChannel) ret = GingaPPCountCaptureChannel(); FreeLibrary(hDll); return ret; } /**********************/ /*** LoadFunctions ****/ /**********************/ Functions * LoadFunctions(GINGAPP_BOARD_TYPE type) { Functions *fc = NULL; // メモリ領域の確保 fc = (Functions *) malloc(sizeof(Functions)); if (!fc) { printf("LoadFunctions: could not allocate memory.\n"); return fc; } memset(fc, 0, sizeof(Functions)); // ボードの種類に対応したライブラリの読み込み if (type == GINGAPP_M2) { fc->hGingaDll = LoadLibrary("GingaM2.dll"); } else if (type == GINGAPP_M4) { fc->hGingaDll = LoadLibrary("GingaPP.dll"); } else { printf("LoadFunctions: could not find board type.\n"); return NULL; } if (!fc->hGingaDll) { printf("LoadFunctions: LoadLibray failed.\n"); return NULL; } /* GingaPPResetDevice */ fc->GingaPPResetDevice = (long (*)(void)) GetProcAddress(fc->hGingaDll, "GingaPPResetDevice"); if (!fc->GingaPPResetDevice) { printf("load address error. GingaPPResetDevice\n"); FreeFunctions(fc); return NULL; } /* GingaPPCountCaptureChannel */ fc->GingaPPCountCaptureChannel = (unsigned long (*)(void)) GetProcAddress(fc->hGingaDll, "GingaPPCountCaptureChannel"); if (!fc->GingaPPCountCaptureChannel) { printf("load address error. GingaPPCountCaptureChannel\n"); FreeFunctions(fc); return NULL; } /* GingaPPAllocFrameBuffer */ fc->GingaPPAllocFrameBuffer = (void ** (*)(unsigned long, unsigned long, unsigned long)) GetProcAddress(fc->hGingaDll, "GingaPPAllocFrameBuffer"); if (!fc->GingaPPAllocFrameBuffer) { printf("load address error. GingaPPAllocFrameBuffer\n"); FreeFunctions(fc); return NULL; } /* GingaPPFreeFrameBuffer */ fc->GingaPPFreeFrameBuffer = (long (*)(void **)) GetProcAddress(fc->hGingaDll, "GingaPPFreeFrameBuffer"); if (!fc->GingaPPFreeFrameBuffer) { printf("load address error. GingaPPFreeFrameBuffer\n"); FreeFunctions(fc); return NULL; } /* GingaPPOpenConfiguration */ fc->GingaPPOpenConfiguration = (long (*)(char *, GINGAPP_CAPTURE_CONFIGURATION **)) GetProcAddress(fc->hGingaDll, "GingaPPOpenConfiguration"); if (!fc->GingaPPOpenConfiguration) { printf("load address error. GingaPPOpenConfiguration\n"); FreeFunctions(fc); return NULL; } /* GingaPPCloseConfiguration */ fc->GingaPPCloseConfiguration = (long (*)(GINGAPP_CAPTURE_CONFIGURATION *)) GetProcAddress(fc->hGingaDll, "GingaPPCloseConfiguration"); if (!fc->GingaPPCloseConfiguration) { printf("load address error. GingaPPCloseConfiguration\n"); FreeFunctions(fc); return NULL; } /* GingaPPSetConfiguration */ fc->GingaPPSetConfiguration = (long (*)(unsigned long, GINGAPP_CAPTURE_CONFIGURATION *)) GetProcAddress(fc->hGingaDll, "GingaPPSetConfiguration"); if (!fc->GingaPPSetConfiguration) { printf("load address error. GingaPPSetConfiguration\n"); FreeFunctions(fc); return NULL; } /* GingaPPStartCapture */ fc->GingaPPStartCapture = (long (*)(unsigned long, unsigned long, unsigned long)) GetProcAddress(fc->hGingaDll, "GingaPPStartCapture"); if (!fc->GingaPPStartCapture) { printf("load address error. GingaPPStartCapture\n"); FreeFunctions(fc); return NULL; } /* GingaPPForceShot */ fc->GingaPPForceShot = (long (*)(unsigned long)) GetProcAddress(fc->hGingaDll, "GingaPPForceShot"); if (!fc->GingaPPForceShot) { printf("load address error. GingaPPForceShot\n"); FreeFunctions(fc); return NULL; } /* GingaPPSenseStatus */ fc->GingaPPSenseStatus = (long (*)(unsigned long, long *)) GetProcAddress(fc->hGingaDll, "GingaPPSenseStatus"); if (!fc->GingaPPSenseStatus) { printf("load address error. GingaPPSenseStatus\n"); FreeFunctions(fc); return NULL; } /* GingaPPStopCapture */ fc->GingaPPStopCapture = (long (*)(unsigned long)) GetProcAddress(fc->hGingaDll, "GingaPPStopCapture"); if (!fc->GingaPPStopCapture) { printf("load address error. GingaPPStopCapture\n"); FreeFunctions(fc); return NULL; } /* GingaPPAbortCapture */ fc->GingaPPAbortCapture = (long (*)(unsigned long)) GetProcAddress(fc->hGingaDll, "GingaPPAbortCapture"); if (!fc->GingaPPAbortCapture) { printf("load address error. GingaPPAbortCapture\n"); FreeFunctions(fc); return NULL; } /* GingaPPGetLastFrame */ fc->GingaPPGetLastFrame = (long (*)(void **, unsigned long *, unsigned long)) GetProcAddress(fc->hGingaDll, "GingaPPGetLastFrame"); if (!fc->GingaPPGetLastFrame) { printf("load address error. GingaPPGetLastFrame\n"); FreeFunctions(fc); return NULL; } /* GingaPPIsFrameValid */ fc->GingaPPIsFrameValid = (long (*)(void **, unsigned long, BOOL *, unsigned long)) GetProcAddress(fc->hGingaDll, "GingaPPIsFrameValid"); if (!fc->GingaPPIsFrameValid) { printf("load address error. GingaPPIsFrameValid\n"); FreeFunctions(fc); return NULL; } return fc; } void FreeFunctions(Functions *fc) { FreeLibrary(fc->hGingaDll); free(fc); fc = NULL; }