diff --git a/ChangeLog b/ChangeLog index dae77c4..fa140ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +- adding save of videodump files for debugging purposes +- adding make target checkdumpfile to test and gain some basic information + on videodumpfiles + 2022-11-07: - fixed: clear control grid after stoping a recording - fixed: serval gtk warnings fixed. Checked if scale has a valid diff --git a/Makefile b/Makefile index 0f9baa8..b12ec91 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,9 @@ help: echo "set up configuration" echo " make configlinux to generate the linix build" +checkdumpfile: checkdumpfile.cc + c++ -o checkdumpfile checkdumpfile.cc + configlinux: clean cp -f Makefile.rules.linux Makefile.rules make config @@ -56,6 +59,7 @@ clean: rm -rf *.dll rm -rf *.exe rm -rf Makefile.rules + rm -rf checkdumpfile rm -rf U2SM200C-AST_Cfg_A.bin rm -rf U2SM200C-AST_Cfg_SAVE.bin diff --git a/checkdumpfile.cc b/checkdumpfile.cc new file mode 100644 index 0000000..25e8413 --- /dev/null +++ b/checkdumpfile.cc @@ -0,0 +1,103 @@ + +#include +#include +#include +#include +#include +#include + +#include + +std::string convert_from_pixelformat (uint32_t fmt) { + char txt[5]; + + snprintf (txt, 5, "%c%c%c%c", ((char*)&fmt)[0], ((char*)&fmt)[1], ((char*)&fmt)[2], ((char*)&fmt)[3]); + return txt; +}; + + + +int main(int argc, char **argv) { + int fd; + int cnt = 0; + char *inbuf = NULL; + int inbufsize = 0; + + uint32_t i; + uint32_t size; + + if (argc != 2) { + printf ("please give a file name as parameter.\n"); + return -1; + } + + printf ("reading file :'%s'\n", argv[1]); + + if ((fd = open (argv[1], O_RDONLY)) < 0) { + printf ("could not open file: %s\n", strerror(errno)); + } + + // + // read header w, h, pixfmt + if (read (fd, &i, 4) != 4) { + printf ("could not read all bytes.\n"); + close (fd); + return -1; + } + printf (" Width: %d\n", ntohl(i)); + + if (read (fd, &i, 4) != 4) { + printf ("could not read all bytes.\n"); + close (fd); + return -1; + } + printf (" Height: %d\n", ntohl(i)); + + if (read (fd, &i, 4) != 4) { + printf ("could not read all bytes.\n"); + close (fd); + return -1; + } + printf(" Pixfmt: %s\n", convert_from_pixelformat(ntohl(i)).c_str()); + + + // + // read frame + while (read (fd, &size, 4) == 4) { + size = ntohl(size); + if (read (fd, &i, 4) != 4) { + printf ("could not read all bytes.\n"); + close (fd); + return -1; + } + i = ntohl(i); + + if (inbuf == NULL){ + inbuf = (char*) malloc (size); + inbufsize = size; + } + else if (inbufsize < size) { + inbuf = (char*)realloc(inbuf, size); + inbufsize = size; + } + + if (inbuf == NULL) { + printf ("Error could not allocate enough memory\n"); + close (fd); + return -1; + } + if (read (fd, inbuf, size) != size) { + printf ("could not read to next frame.\n"); + close (fd); + return -1; + } + + printf ("Frame: %-9d Timestamp:%-9d Size:%d\n", cnt++, i, size); + } + + printf ("\nFile seems to be fine.\n"); + + close (fd); + return 0; +} + diff --git a/configuration.h b/configuration.h index ebfda6c..4ab4c4f 100644 --- a/configuration.h +++ b/configuration.h @@ -33,4 +33,6 @@ public: list GetPresetButton (int btn); }; +extern char *debugpath; + #endif diff --git a/convert.cc b/convert.cc index 7429676..3181ed9 100644 --- a/convert.cc +++ b/convert.cc @@ -1,8 +1,15 @@ #include +#include +#include +#include +#include +#include + #include "convert.h" #include "gui.h" #include "video.h" +#include "configuration.h" uint32_t convert_pixelformats [] = { V4L2_PIX_FMT_MJPEG, @@ -16,6 +23,127 @@ uint32_t convert_pixelformats [] = { }; +/* + * dump data into debug file + * + * file description: + * + * uint32_t width; + * uint32_t height; + * uint32_t pixelformat; + * + * uint32_t size; + * uint32_t timestamp_ms; + * + * uint8_t data[size]; + * + * + * .... + */ +int convert_debug_fd = -1; +struct timeval convert_debug_tv; + +/* + * will be called on first frame + */ +#define LEN_FILENAME 64 +#define LEN_FULLFILENAME 256 +int convert_debug_open(uint32_t pixelformat, int srcw, int srch) { + time_t t = time(NULL); + struct tm *tmptr; + char fname[LEN_FILENAME]; + char fullfname[LEN_FULLFILENAME]; + + if (debugpath == NULL) return -1; + + printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); + + // + // check to create file, if not possible try creating the directory and create the file again + tmptr = localtime(&t); + strftime(fname, LEN_FILENAME, "%F-%R", tmptr); + snprintf (fullfname, LEN_FULLFILENAME, "%s/%s.videodump", debugpath, fname); + + if ((convert_debug_fd = creat (fullfname, 0666)) == -1) { + printf ("%s:%d could not create file '%s'. Error:%s\n", __FILE__, __LINE__, fullfname, strerror(errno)); + printf ("%s:%d try to create folder\n", __FILE__, __LINE__); + + // create folder + if ((mkdir (debugpath, 0777)) == -1) { + printf ("%s:%d could not create debug folder.\n", __FILE__, __LINE__); + return -1; + } + + if ((convert_debug_fd = creat (fullfname, 0666)) == -1) { + printf ("%s:%d could again not create file '%s'. Error:%s\n", __FILE__, __LINE__, fullfname, strerror(errno)); + return -1; + } + } + + + // + // file is open for writing, write header information + uint32_t wwidth = htonl(srcw); + uint32_t wheight = htonl(srch); + uint32_t wpixfmt = htonl(pixelformat); + write (convert_debug_fd, &wwidth, 4); + write (convert_debug_fd, &wheight, 4); + write (convert_debug_fd, &wpixfmt, 4); + + // + // save start time, this is needed to calculate the time between the frames + gettimeofday (&convert_debug_tv, NULL); + + return 0; +} + + +/* + * if fd is not open open file and set up header + */ +void convert_debug_dumpframe(unsigned char *ptrsrc, int srcsize, uint32_t pixelformat, int srcw, int srch) { + struct timeval tv; + uint32_t wts, ts; + uint32_t wsize; + + if (ptrsrc == NULL) return; + if (debugpath == NULL) return; + if (convert_debug_fd == -1) + if (convert_debug_open(pixelformat, srcw, srch) == -1) return; + + // + // construct and write header + wsize = htonl(srcsize); + gettimeofday (&tv, NULL); + ts = 1000 * (tv.tv_sec - convert_debug_tv.tv_sec) + + (tv.tv_usec - convert_debug_tv.tv_usec) / 1000; + wts = htonl(ts); + + write (convert_debug_fd, &wsize, 4); + write (convert_debug_fd, &wts, 4); + + // + // write frame + write (convert_debug_fd, ptrsrc, srcsize); +}; + + +/* + * close file and reset all data + */ +void convert_debug_close() { + + printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); + + if (convert_debug_fd != -1) { + close (convert_debug_fd); + convert_debug_fd = -1; + } +} + + + + /* * helper part for converting different video types @@ -69,8 +197,9 @@ int ConvertStart(ConvertData *cdata, uint32_t pixelformat) { }; int ConvertStop(ConvertData *cdata, uint32_t pixelformat) { - if (cdata == NULL) return VDEV_STATUS_ERROR; + convert_debug_close(); + if (cdata == NULL) return VDEV_STATUS_ERROR; if (pixelformat == V4L2_PIX_FMT_MJPEG) jpeg_destroy_decompress(&cdata->cinfo); return VDEV_STATUS_OK; @@ -86,6 +215,8 @@ int Convert (ConvertData *cdata, VideoFrame *dest, unsigned char *ptrsrc, int sr unsigned char cb, cr, y1; unsigned char *ptrdst = NULL; + if (debugpath != NULL) convert_debug_dumpframe(ptrsrc, srcsize, pixelformat, srcw, srch); + struct jpg_error_mgr jerr; if (cdata == NULL) return VDEV_STATUS_ERROR; diff --git a/main.cc b/main.cc index 5947b4e..7016a30 100644 --- a/main.cc +++ b/main.cc @@ -21,6 +21,8 @@ GtkBuilder *_builder_ = NULL; // work around for the thread situation Filter filter; Detect detect; Configuration config; +char *debugpath = NULL; +char *readdumppath = NULL; int main (int argc, char **argv) { GtkBuilder *builder; @@ -33,6 +35,29 @@ int main (int argc, char **argv) { printf ("SimpleSkyCam - %s\n", VERSION); printf (" written by Steffen Pohle \n"); + printf ("\n"); + printf ("Command Line Options for testing purpose:\n"); + printf (" -d destination for video debugging path\n"); + printf (" -dd disable debugging path\n"); + printf ("\n"); + printf (" -rd read video from dumpfile folder\n"); + printf ("\n"); + printf ("\n"); + + for (int i = 1; i < argc; i++) { + if (strcmp (argv[i], "-d") == 0) { + i++; + debugpath = argv[i]; + } + if (strcmp (argv[i], "-dd") == 0) { + i++; + debugpath = NULL; + } + if (strcmp (argv[i], "-rd") == 0) { + i++; + readdumppath = argv[i]; + } + } gtk_init (&argc, &argv); _builder_ = builder = gtk_builder_new ();