int main(int argc, char *argv[]) { unsigned int deviceCount = 1; unsigned int cameraScale = 1; //640x480 bool saveVideo = false; //Read the command line options if (!getOptions(argc, argv, deviceCount, saveVideo)) { return (-1); } std::vector<vpV4l2Grabber *> grabbers; const unsigned int offsetX = 100, offsetY = 100; for(unsigned int devicedId = 0; devicedId < deviceCount; devicedId++) { try { vpV4l2Grabber *pGrabber = new vpV4l2Grabber; std::stringstream ss; ss << "/dev/video" << devicedId; pGrabber->setDevice(ss.str()); pGrabber->setScale(cameraScale); grabbers.push_back(pGrabber); } catch(vpException &e) { std::cerr << "Exception: " << e.what() << std::endl; } } std::cout << "Grabbers: " << grabbers.size() << std::endl; std::vector<ShareImage> share_images(grabbers.size()); std::vector<std::thread> capture_threads; std::vector<std::thread> display_threads; //Synchronized queues for each camera stream std::vector<FrameQueue> save_queues(grabbers.size()); std::vector<StorageWorker> storages; std::vector<std::thread> storage_threads; std::string parent_directory = vpTime::getDateTime("%Y-%m-%d_%H.%M.%S"); if(saveVideo) { std::cout << "Create parent_directory: " << parent_directory << std::endl; vpIoTools::makeDirectory(parent_directory); } for(size_t deviceId = 0; deviceId < grabbers.size(); deviceId++) { //Start the capture thread for the current camera stream capture_threads.emplace_back( capture, grabbers[deviceId], std::ref(share_images[deviceId]) ); int win_x = deviceId * offsetX, win_y = deviceId * offsetY; //Start the display thread for the current camera stream display_threads.emplace_back( display, grabbers[deviceId]->getWidth(), grabbers[deviceId]->getHeight(), win_x, win_y, deviceId, std::ref(share_images[deviceId]), std::ref(save_queues[deviceId]), saveVideo ); if(saveVideo) { std::stringstream ss; ss << parent_directory << "/Camera_Stream" << deviceId; std::cout << "Create directory: " << ss.str() << std::endl; vpIoTools::makeDirectory(ss.str()); ss << "/%06d.png"; std::string filename = ss.str(); storages.emplace_back( std::ref(save_queues[deviceId]), std::cref(filename), grabbers[deviceId]->getWidth(), grabbers[deviceId]->getHeight() ); } } if(saveVideo) { for(auto& s : storages) { //Start the storage thread for the current camera stream storage_threads.emplace_back(&StorageWorker::run, &s); } } //Join all the worker threads, waiting for them to finish for(auto& ct : capture_threads) { ct.join(); } for (auto& dt : display_threads) { dt.join(); } //Clean first the grabbers to avoid camera problems when cancelling the storage threads in the terminal for(auto& g : grabbers) { delete g; } if(saveVideo) { std::cout << "\nWaiting for finishing thread to write images..." << std::endl; } // We're done reading, cancel all the queues for (auto& qu : save_queues) { qu.cancel(); } //Join all the worker threads, waiting for them to finish for (auto& st : storage_threads) { st.join(); } return 0; }
void svr_shutdown( int type) /* I */ { pbs_attribute *pattr; job *pjob; long state = SV_STATE_DOWN; int iter; char log_buf[LOCAL_LOG_BUF_SIZE]; close(lockfds); save_queues(); /* Lets start by logging shutdown and saving everything */ get_svr_attr_l(SRV_ATR_State, &state); strcpy(log_buf, msg_shutdown_start); if (state == SV_STATE_SHUTIMM) { /* if already shuting down, another Immed/sig will force it */ if ((type == SHUT_IMMEDIATE) || (type == SHUT_SIG)) { state = SV_STATE_DOWN; set_svr_attr(SRV_ATR_State, &state); strcat(log_buf, "Forced"); log_event( PBSEVENT_SYSTEM | PBSEVENT_ADMIN | PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER, msg_daemonname, log_buf); return; } } if (type == SHUT_IMMEDIATE) { state = SV_STATE_SHUTIMM; set_svr_attr(SRV_ATR_State, &state); strcat(log_buf, "Immediate"); } else if (type == SHUT_DELAY) { state = SV_STATE_SHUTDEL; set_svr_attr(SRV_ATR_State, &state); strcat(log_buf, "Delayed"); } else if (type == SHUT_QUICK) { state = SV_STATE_DOWN; /* set to down to brk pbsd_main loop */ set_svr_attr(SRV_ATR_State, &state); strcat(log_buf, "Quick"); } else { state = SV_STATE_SHUTIMM; set_svr_attr(SRV_ATR_State, &state); strcat(log_buf, "By Signal"); } log_event( PBSEVENT_SYSTEM | PBSEVENT_ADMIN | PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER, msg_daemonname, log_buf); if ((type == SHUT_QUICK) || (type == SHUT_SIG)) /* quick, leave jobs as are */ { return; } svr_save(&server, SVR_SAVE_QUICK); iter = -1; while ((pjob = next_job(&alljobs,&iter)) != NULL) { if (pjob->ji_qs.ji_state == JOB_STATE_RUNNING) { pjob->ji_qs.ji_svrflags |= JOB_SVFLG_HOTSTART | JOB_SVFLG_HASRUN; pattr = &pjob->ji_wattr[JOB_ATR_checkpoint]; if ((pattr->at_flags & ATR_VFLAG_SET) && ((csv_find_string(pattr->at_val.at_str, "s") != NULL) || (csv_find_string(pattr->at_val.at_str, "c") != NULL) || (csv_find_string(pattr->at_val.at_str, "shutdown") != NULL))) { /* do checkpoint of job */ if (shutdown_checkpoint(&pjob) == 0) { if (pjob != NULL) unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); continue; } } /* if no checkpoint (not supported, not allowed, or fails */ /* rerun if possible, else kill job */ rerun_or_kill(&pjob, msg_on_shutdown); } if (pjob != NULL) unlock_ji_mutex(pjob, __func__, "2", LOGLEVEL); } return; } /* END svr_shutdown() */