/************************************************************************************ * videodev-dumpfile: * raw videodump input file support. It will scan the directory givin by the command * line argument -rd DIRECTORY and for each it will create an own device. This file * will be read in a loop. * * This is needed only for debugging. ************************************************************************************/ #include #include #include #include #include #include "convert.h" #include "configuration.h" #include "videodev-dumpfile.h" VideoDev_Dumpfile::VideoDev_Dumpfile() { printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); fd = -1; w = 0; h = 0; pixformat = 0; inframe = NULL; inframe_size = 0; inframe_maxsize = 0; inframe_nexttime = 0; }; VideoDev_Dumpfile::~VideoDev_Dumpfile() { printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); if (running > 0) CaptureStop(); Close(); } /* * searchs in the given path for any videodump files and present them as * video device. */ int VideoDev_Dumpfile::GetDeviceList(std::list *list) { std::string device; DIR *dir; struct dirent *de = NULL; char fname[256]; int i; printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); if (list == NULL || config.readdumppath == NULL) return 0; if ((dir = opendir (config.readdumppath)) == NULL) { printf ("%s:%d could not read directory '%s'\n", __FILE__, __LINE__, config.readdumppath); return 0; } while ((de = readdir (dir))) { if (de->d_type & DT_REG) { for (i = 0; i < 255 && de->d_name[i] != 0; i++) fname[i] = toupper(de->d_name[i]); fname[i] = 0; if (strstr (fname, ".VIDEODUMP") != NULL) { device = (std::string) "VIDEODUMP " + (std::string) de->d_name; list->push_back(device); } } } closedir(dir); return 1; } /* * Open Device * prepare the buffer, InitMMAP and read all controls */ int VideoDev_Dumpfile::Open() { std::string fname = config.readdumppath; fname = fname + "/" + conf_device; uint32_t inbuf[3]; int i; printf ("%s:%d %s file %s\n", __FILE__, __LINE__, __FUNCTION__, fname.c_str()); if (fd >= 0) close (fd); if ((fd = open(fname.c_str(), O_RDONLY)) == -1) { printf ("%s:%d could not open file '%s' error:%s\n", __FILE__, __LINE__, fname.c_str(), strerror(errno)); return VDEV_STATUS_ERROR; } // // read header if (read (fd, inbuf, 12) != 12) { printf ("%s:%d could not read all header data.\n", __FILE__, __LINE__); close (fd); fd = -1; return VDEV_STATUS_ERROR; } i = 0; w = ntohl(inbuf[i++]); h = ntohl(inbuf[i++]); pixformat = ntohl(inbuf[i++]); return VDEV_STATUS_OK; }; /* * Close Device * Free videobuffer */ int VideoDev_Dumpfile::Close() { printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); if (fd >= 0) { close(fd); fd = -1; } return VDEV_STATUS_OK; }; /***************************************************************************************************** * VideoGrabbing */ /* * send the start capture signal to the cam */ int VideoDev_Dumpfile::CaptureStart() { printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); Close(); if (Open() != VDEV_STATUS_OK) return VDEV_STATUS_ERROR; // read timestamp and first header and frame gettimeofday(&starttv, NULL); ConvertStart(&cdata, pixformat); ReadFrame(); return VDEV_STATUS_OK; }; int VideoDev_Dumpfile::CaptureStop() { printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); if (fd >= 0) { close(fd); fd = -1; } if (inframe != NULL) { free (inframe); inframe_size = 0; inframe = NULL; } ConvertStop(&cdata, pixformat); return VDEV_STATUS_OK; }; /* * try to grab one frame and convert it into RGB32. * If something goes wrong return an error code. * Return code VDEV_STATUS_AGAIN is not an error. There was no video image ready to read. */ int VideoDev_Dumpfile::Grab(VideoFrame *vf) { struct timeval curtv; unsigned int diff = 0; if (fd == -1) return VDEV_STATUS_ERROR; // // is it time? do { gettimeofday(&curtv, NULL); diff = 1000 * (curtv.tv_sec - starttv.tv_sec) + (curtv.tv_usec - starttv.tv_usec) / 1000; if (diff < inframe_nexttime) usleep ((inframe_nexttime-diff)*1000); } while (diff < inframe_nexttime); if (diff - inframe_nexttime > 1000) printf ("%s:%d time difference to big. (%dms) Maybe to slow hard drive?\n", __FILE__, __LINE__, (diff - inframe_nexttime)); LockMutex(); Convert(&cdata, vf, inframe, inframe_size, pixformat, w, h); UnLockMutex(); // // read next frame ReadFrame(); return VDEV_STATUS_OK; } /***************************************************************************************************** * Read Frame */ int VideoDev_Dumpfile::ReadFrame() { uint32_t inbuf[2]; if (fd < 0) return VDEV_STATUS_ERROR; // read header if (read (fd, inbuf, 4*2) != 4*2) { printf ("%s:%d could not read frame header\n", __FILE__, __LINE__); Close(); } inframe_size = ntohl(inbuf[0]); inframe_nexttime = ntohl(inbuf[1]); // read header if (inframe == NULL) { inframe = (unsigned char*) malloc (inframe_size); inframe_maxsize = inframe_size; } else if (inframe_maxsize < inframe_size) { inframe = (unsigned char*) realloc (inframe, inframe_size); inframe_maxsize = inframe_size; } // allocate memory and read frame if (inframe == NULL) { Close(); printf ("%s:%d cloud not allocate enought memory\n", __FILE__, __LINE__); return VDEV_CBSTATUS_ERROR; } if (read (fd, inframe, inframe_size) != inframe_size) { printf ("%s:%d could not read frame\n", __FILE__, __LINE__); Close(); } return VDEV_STATUS_OK; } /***************************************************************************************************** * Controls */ /* * set video control identified by id */ int VideoDev_Dumpfile::SetDevCtrl(unsigned int id, int value) { return VDEV_STATUS_OK; }; /* * get video control identified by id */ int VideoDev_Dumpfile::GetDevCtrl(unsigned int id, int *value) { return VDEV_STATUS_OK; };