parent
3b44f3ae66
commit
9cab2c3722
@ -0,0 +1,274 @@
|
||||
/************************************************************************************
|
||||
* 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 <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
#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<std::string> *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);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,60 @@
|
||||
|
||||
#ifndef _H_VIDEODEV_DUMPFILE_H_
|
||||
#define _H_VIDEODEV_DUMPFILE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/mman.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
|
||||
#include "convert.h"
|
||||
#include "gui.h"
|
||||
#include "videodev.h"
|
||||
|
||||
|
||||
class VideoDev_Dumpfile: public VideoDev {
|
||||
private:
|
||||
ConvertData cdata;
|
||||
int fd;
|
||||
uint32_t w;
|
||||
uint32_t h;
|
||||
uint32_t pixformat;
|
||||
struct timeval starttv;
|
||||
unsigned char *inframe;
|
||||
uint32_t inframe_nexttime;
|
||||
int inframe_maxsize;
|
||||
int inframe_size;
|
||||
|
||||
int Grab(VideoFrame *vf);
|
||||
int Open();
|
||||
int Close();
|
||||
int CaptureStart();
|
||||
int CaptureStop();
|
||||
int SetDevCtrl(unsigned int id, int value);
|
||||
int GetDevCtrl(unsigned int id, int *value);
|
||||
|
||||
int ReadFrame();
|
||||
public:
|
||||
VideoDev_Dumpfile();
|
||||
~VideoDev_Dumpfile();
|
||||
int GetDeviceList(std::list<std::string> *list);
|
||||
int GetDeviceFormats(string device, std::list<string> *formats) { return VDEV_STATUS_OK; };
|
||||
int GetDeviceResolutions(string device, std::list<string> *formats) { return VDEV_STATUS_OK; };
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in new issue