Image* Camera::captureImage() { if(!this->initialized) return NULL; uint8* rawPic = NULL; int mb = this->isMultiBuffered ? OSC_CAM_MULTI_BUFFER : 0; if(OscCamReadPicture(mb, &rawPic,0,0) == SUCCESS) { if(OscCamSetupCapture(mb) != SUCCESS) Debug::log(Debug::ERROR, "Failed to setup capture\n"); if(OscGpioTriggerImage() != SUCCESS) Debug::log(Debug::ERROR, "GPIO trigger image failed\n"); memcpy(this->rawImage->getDataPtr(), rawPic, this->aoi.width * this->aoi.height); rawPic = this->rawImage->getDataPtr(); if(this->debayer != NULL) { this->debayer->debayer(this->rawImage, this->image); } for(unsigned int i = 0;i<this->fp.size();i++) { this->fp.at(i)->process(this->image); } return this->image; } return NULL; }
OSC_ERR StateControl( void) { OSC_ERR err; MainState mainState; uint8 *pCurRawImg = NULL; /* Setup main state machine. Start with idle mode. */ MainStateConstruct(&mainState); HsmOnStart((Hsm *)&mainState); /*----------- infinite main loop */ while( TRUE) { /*----------- wait for captured picture */ while (TRUE) { /*----------- Alternating a) check for new connections * b) check for commands (and do process) * c) check for available picture */ err = Comm_AcceptConnections(&data.comm, ACCEPT_CONNS_TIMEOUT); if(err != SUCCESS && err != -ETIMEOUT) { OscLog(ERROR, "%s: Error accepting new connections (%d)!\n", __func__, err); } err = Comm_HandleCommands(&data.comm, &mainState, GET_CMDS_TIMEOUT); if(err != SUCCESS && err != -ETIMEOUT) { OscLog(ERROR, "%s: Error handling commands (%d)!\n", __func__, err); } else if(err == SUCCESS) { OscLog(INFO, "Command received.\n"); } err = OscCamReadPicture(OSC_CAM_MULTI_BUFFER, &pCurRawImg, 0, CAMERA_TIMEOUT); if ((err != -ETIMEOUT) ||(err != -ENO_CAPTURE_STARTED) ) { /* Anything other than a timeout or no pending capture means that we should * stop trying and analyze the situation. */ break; } } if( err == SUCCESS) /* only if breaked due to CamReadPic() */ { data.pCurRawImg = pCurRawImg; OscLog(DEBUG, "---image available\n"); } else { pCurRawImg = NULL; } /*----------- process frame by state engine (pre-setup) Sequentially with next capture */ if( pCurRawImg) { ThrowEvent(&mainState, FRAMESEQ_EVT); } /*----------- prepare next capture */ if( pCurRawImg) { err = OscCamSetupCapture( OSC_CAM_MULTI_BUFFER); if (err != SUCCESS) { OscLog(ERROR, "%s: Unable to setup capture (%d)!\n", __func__, err); break; } } /*----------- do self-triggering (if required) */ ThrowEvent(&mainState, TRIGGER_EVT); /*----------- process frame by state engine (post-setup) Parallel with next capture */ if( pCurRawImg) { ThrowEvent(&mainState, FRAMEPAR_EVT); } } /* end while ever */ return SUCCESS; }
Msg const *MainState_capture(MainState *me, Msg *msg) { OSC_ERR err; uint8 *pDummyImg = NULL; uint32 imgSize; switch (msg->evt) { case ENTRY_EVT: OscLog(INFO, "Enter generic capture mode.\n"); #ifndef HAS_CPLD /* Set onboard LED red */ OscGpioSetTestLed( TRUE); OscGpioSetTestLedColor(TRUE, FALSE); /* R, G*/ #endif /* !HAS_CPLD */ OscLog(INFO, "Setup capture\n"); err = OscCamSetupCapture( OSC_CAM_MULTI_BUFFER); if (err != SUCCESS) { OscLog(ERROR, "%s: Unable to setup initial capture (%d)!\n", __func__, err); } return 0; case FRAMESEQ_EVT: /* Fill out the feed header. */ data.comm.feedHdr.seqNr++; /* We need the uptime in milliseconds. */ data.comm.feedHdr.timeStamp = (uint32)(OscSupCycToMilliSecs(OscSupCycGet64())); data.comm.feedHdr.imgWidth = OSC_CAM_MAX_IMAGE_WIDTH; data.comm.feedHdr.imgHeight = OSC_CAM_MAX_IMAGE_HEIGHT; #ifdef TARGET_TYPE_LEANXCAM data.comm.feedHdr.pixFmt = V4L2_PIX_FMT_GREY; imgSize = data.comm.feedHdr.imgWidth * data.comm.feedHdr.imgHeight * 1; #endif /* TARGET_TYPE_LEANXCAM */ #ifdef TARGET_TYPE_INDXCAM data.comm.feedHdr.pixFmt = V4L2_PIX_FMT_SBGGR8; imgSize = data.comm.feedHdr.imgWidth * data.comm.feedHdr.imgHeight * 1; #endif /* TARGET_TYPE_INDXCAM */ /* Send the image to the host. */ Comm_SendImage(&data.comm, data.pCurRawImg, imgSize, &data.comm.feedHdr); return 0; case FRAMEPAR_EVT: return 0; case CMD_GO_IDLE_EVT: /* Read picture until no more capture is active.Always use self-trigg*/ err = SUCCESS; while(err != -ENO_CAPTURE_STARTED) { SelfTrigger(); err = OscCamReadPicture(OSC_CAM_MULTI_BUFFER, &pDummyImg, 0, CAMERA_TIMEOUT); OscLog(DEBUG, "%s: Removed picture from queue! (%d)\n", __func__, err); } STATE_TRAN(me, &me->idle); data.comm.enReqState = REQ_STATE_ACK_PENDING; return 0; case CMD_GO_ACQ_EVT: data.comm.enReqState = REQ_STATE_ACK_PENDING; return 0; case CMD_USE_INTERN_TRIGGER_EVT: case CMD_USE_EXTERN_TRIGGER_EVT: /* Not supported in acquisition mode. */ data.comm.enReqState = REQ_STATE_NACK_PENDING; return 0; case EXIT_EVT: /* Read picture until no more capture is active. Always use self-trigg*/ err = SUCCESS; while(err != -ENO_CAPTURE_STARTED) { SelfTrigger(); err = OscCamReadPicture(OSC_CAM_MULTI_BUFFER, &pDummyImg, 0, CAMERA_TIMEOUT); OscLog(DEBUG, "%s: Removed picture from queue! (%d)\n", __func__, err); } return 0; } return msg; }
/*********************************************************************//*! * @brief The main program * * Opens the camera and reads pictures as fast as possible * Makes a debayering of the image * Writes the debayered image to a buffer which can be read by * TCP clients on Port 8111. Several concurrent clients are allowed. * The simplest streaming video client looks like this: * * nc 192.168.1.10 8111 | mplayer - -demuxer rawvideo -rawvideo w=376:h=240:format=bgr24:fps=100 * * Writes every 10th picture to a .jpg file in the Web Server Directory *//*********************************************************************/ int main(const int argc, const char * argv[]) { struct OSC_PICTURE calcPic; struct OSC_PICTURE rawPic; unsigned char *tmpbuf; int loops=0; int numalarm=0; char filename[100]; initSystem(&sys); ip_start_server(); /* setup variables */ rawPic.width = OSC_CAM_MAX_IMAGE_WIDTH; rawPic.height = OSC_CAM_MAX_IMAGE_HEIGHT; rawPic.type = OSC_PICTURE_GREYSCALE; /* calcPic width, height etc. are set in the debayering algos */ calcPic.data = malloc(3 * OSC_CAM_MAX_IMAGE_WIDTH * OSC_CAM_MAX_IMAGE_HEIGHT); if (calcPic.data == 0) fatalerror("Did not get memory\n"); tmpbuf = malloc(500000); if (tmpbuf == 0) fatalerror("Did not get memory\n"); #if defined(OSC_TARGET) /* Take a picture, first time slower ;-) */ usleep(10000); OscGpioTriggerImage(); usleep(10000); OscLog(DEBUG,"Triggered CAM "); #endif while(true) { OscCamReadPicture(OSC_CAM_MULTI_BUFFER, (void *) &rawPic.data, 0, 0); /* Take a picture */ usleep(2000); OscCamSetupCapture(OSC_CAM_MULTI_BUFFER); #if defined(OSC_TARGET) OscGpioTriggerImage(); #else usleep(10000); #endif if (is_alarm(&rawPic)) { OscGpioSetTestLed(TRUE); printf("alarm\n"); sprintf(filename, "/home/httpd/alarm_pic%02i.jpg", numalarm%16); writeJPG(&calcPic, tmpbuf, filename); numalarm++; } else { OscGpioSetTestLed(FALSE); } fastdebayerBGR(rawPic, &calcPic, NULL); ip_send_all((char *)calcPic.data, calcPic.width*calcPic.height* OSC_PICTURE_TYPE_COLOR_DEPTH(calcPic.type)/8); loops+=1; if (loops%20 == 0) { writeJPG(&calcPic, tmpbuf, "/home/httpd/liveimage.jpg"); } ip_do_work(); } ip_stop_server(); cleanupSystem(&sys); return 0; } /* main */
OSC_ERR StateControl( void) { OSC_ERR camErr, err; MainState mainState; uint8 *pCurRawImg = NULL; /* Setup main state machine */ MainStateConstruct(&mainState); HsmOnStart((Hsm *)&mainState); OscSimInitialize(); /*----------- initial capture preparation*/ camErr = OscCamSetupCapture( OSC_CAM_MULTI_BUFFER); if (camErr != SUCCESS) { OscLog(ERROR, "%s: Unable to setup initial capture (%d)!\n", __func__, camErr); return camErr; } err = OscGpioTriggerImage(); if (err != SUCCESS) { OscLog(ERROR, "%s: Unable to trigger initial capture (%d)!\n", __func__, err); } /*----------- infinite main loop */ while (TRUE) { /*----------- wait for captured picture */ while (TRUE) { err = HandleIpcRequests(&mainState); if (err != SUCCESS) { OscLog(ERROR, "%s: IPC error! (%d)\n", __func__, err); Unload(); return err; } camErr = OscCamReadPicture(OSC_CAM_MULTI_BUFFER, &pCurRawImg, 0, CAMERA_TIMEOUT); if (camErr != -ETIMEOUT) { /* Anything other than a timeout means that we should * stop trying and analyze the situation. */ break; } else { /*----------- procress CGI request * Check for CGI request only if ReadPicture generated a * time out. Process request directely or involve state * engine with event */ /* Read request. */ err = HandleIpcRequests(&mainState); if (err != SUCCESS) { OscLog(ERROR, "%s: IPC error! (%d)\n", __func__, err); Unload(); return err; } } } if (camErr == -EPICTURE_TOO_OLD) { /* We have a picture, but it already has been laying * around for a while. Most likely we won't be able to * make the deadline for this picture, so we better just * give it up and don't portrude our delay to the next * frame. */ OscLog(WARN, "%s: Captured picture too old!\n", __func__); /*----------- prepare next capture */ camErr = OscCamSetupCapture( OSC_CAM_MULTI_BUFFER); if (camErr != SUCCESS) { OscLog(ERROR, "%s: Unable to setup capture (%d)!\n", __func__, camErr); break; } err = OscGpioTriggerImage(); if (err != SUCCESS) { OscLog(ERROR, "%s: Unable to trigger capture (%d)!\n", __func__, err); break; } continue; } else if (camErr != SUCCESS) { /* Fatal error, giving up. */ OscLog(ERROR, "%s: Unable to read picture from cam!\n", __func__); break; } data.pCurRawImg = pCurRawImg; /*----------- process frame by state engine (pre-setup) Sequentially with next capture */ ThrowEvent(&mainState, FRAMESEQ_EVT); /*----------- prepare next capture */ camErr = OscCamSetupCapture( OSC_CAM_MULTI_BUFFER); if (camErr != SUCCESS) { OscLog(ERROR, "%s: Unable to setup capture (%d)!\n", __func__, camErr); break; } err = OscGpioTriggerImage(); if (err != SUCCESS) { OscLog(ERROR, "%s: Unable to trigger capture (%d)!\n", __func__, err); break; } /*----------- process frame by state engine (post-setup) Parallel with next capture */ ThrowEvent(&mainState, FRAMEPAR_EVT); /* Advance the simulation step counter. */ OscSimStep(); } /* end while ever */ return SUCCESS; }
/*********************************************************************//*! * @brief Program entry. * * @param argc Command line argument count. * @param argv Command line argument string. * @return 0 on success *//*********************************************************************/ int main(const int argc, const char * argv[]) { /* Handle to framework instance. */ void *hFramework; #if defined(OSC_HOST) || defined(OSC_SIM) /* Handle to file name reader, if compiled for host platform. */ void *hFileNameReader; #endif /* Camera parameters */ uint32 shutterWidth; uint16 x, y, width, height; uint16 blackOffset; uint8 bufferIDs[2]; /* Frame buffers. */ uint8 frameBuffer0[OSC_CAM_MAX_IMAGE_WIDTH * OSC_CAM_MAX_IMAGE_HEIGHT]; uint8 frameBuffer1[OSC_CAM_MAX_IMAGE_WIDTH * OSC_CAM_MAX_IMAGE_HEIGHT]; /* Pointer to captured picture */ void *pic; struct OSC_PICTURE p; OSC_ERR err = SUCCESS; /* Create framework */ OscCreate(&hFramework); /* Load camera module */ OscCamCreate(hFramework); /* Load GPIO module */ OscGpioCreate(hFramework); p.width = OSC_CAM_MAX_IMAGE_WIDTH; p.height = OSC_CAM_MAX_IMAGE_HEIGHT; p.type = OSC_PICTURE_GREYSCALE; /* Get camera settings */ OscCamGetShutterWidth(&shutterWidth); OscCamGetAreaOfInterest(&x, &y, &width, &height); OscCamGetBlackLevelOffset(&blackOffset); printf("ShutterWidth=%lu\n",shutterWidth); printf("AreaOfInterest: x=%u y=%u width=%u height=%u\n", x, y, width, height); printf("BlackLevelOffset=%u\n",blackOffset); /* Process settings */ /* ---------------- */ /* Set new camera settings */ shutterWidth = 50000; /* set shutter to 50ms, 0 => automatic */ OscCamSetShutterWidth(shutterWidth); OscCamSetAreaOfInterest(0,0,OSC_CAM_MAX_IMAGE_WIDTH, OSC_CAM_MAX_IMAGE_HEIGHT); OscCamSetBlackLevelOffset(blackOffset); OscCamSetupPerspective(OSC_CAM_PERSPECTIVE_VERTICAL_MIRROR); #if defined(OSC_HOST) || defined(OSC_SIM) /* Setup file name reader if compiled for host platform */ OscFrdCreateConstantReader(&hFileNameReader, "imgCapture.bmp"); OscCamSetFileNameReader(hFileNameReader); #endif /* Setup framebuffers - double buffering */ OscCamSetFrameBuffer(0, OSC_CAM_MAX_IMAGE_WIDTH*OSC_CAM_MAX_IMAGE_HEIGHT, frameBuffer0, TRUE); OscCamSetFrameBuffer(1, OSC_CAM_MAX_IMAGE_WIDTH*OSC_CAM_MAX_IMAGE_HEIGHT, frameBuffer1, TRUE); bufferIDs[0] = 0; bufferIDs[1] = 1; OscCamCreateMultiBuffer(2, bufferIDs); /* Setup capture to first frame buffer */ err = OscCamSetupCapture(OSC_CAM_MULTI_BUFFER); if(err != SUCCESS){ printf("%s: Unable to setup initial capture (%d)!\n", __func__, err); return err; } /* Trigger image capturing */ err = OscGpioTriggerImage(); if(err != SUCCESS){ printf("%s: Unable to trigger capture (%d)!\n", __func__, err); return err; } /* Do something ... */ /* ---------------- */ /* Read Picture */ err = OscCamReadPicture(OSC_CAM_MULTI_BUFFER, (void *) &pic, 0, 0); if(err != SUCCESS){ printf("%s: Unable to read picture (%d)!\n", __func__, err); return err; } /* Process picture */ /* --------------- */ /* Capture picture to second frame buffer */ err = OscCamSetupCapture(OSC_CAM_MULTI_BUFFER); if(err != SUCCESS){ printf("%s: Unable to setup initial capture (%d)!\n", __func__, err); return err; } /* Do something ... */ /* ---------------- */ err = OscCamReadPicture(OSC_CAM_MULTI_BUFFER, (void *) &pic, 0, 0); if(err != SUCCESS){ printf("%s: Unable to read picture (%d)!\n", __func__, err); return err; } /* Process picture */ /* --------------- */ /* Unload camera module */ OscCamDestroy(hFramework); /* Unload GPIO module */ OscGpioDestroy(hFramework); /* Destroy framework */ OscDestroy(hFramework); return 0; }