#include #include #include #include #include #include "configuration.h" #include "miniwebcam.h" int running = 1; pthread_mutex_t mtx; static void sig_int(int); int SetupSignals(); std::string GetDefaultConfig(std::string name); VideoFrame inputimage; VideoFrameFloat inputfloat; VideoFrameFloat inputfloatfilter; VideoFrame currentimage; VideoFrame currentimagefloat; VideoDevice *vdev= NULL; static void *thread_webserver(void *ignored_argument) { WebCamServer webserver; webserver.SetupPorts(config.http_port, config.https_port); webserver.SetupSSL(config.ssl_key, config.ssl_cert); webserver.Start(); while (running) { webserver.Loop(); usleep (200); } running = 0; // force running to 0 webserver.Stop(); return NULL; }; static void *thread_video(void *ignored_argument) { if (config.vdev_dumpfile.length() > 0) { vdev = new VideoDevice_Dump(); } else { vdev = new VideoDevice_V4L2(); } if (vdev->SetDevice (config.vdev_device, config.vdev_cdevice, config.vdev_width, config.vdev_height, convert_to_pixelformat(config.vdev_format)) == 0) { debug ("could not setup device.\n"); goto thread_video_exit; // we use goto for a better cleanup of the thread } if (vdev->SetIOMode (config.vdev_iomode) == 0) { debug ("could not setup iomode.\n"); goto thread_video_exit; } if (vdev->Start() == 0) { debug ("Error: could not start video.\n"); goto thread_video_exit; } currentimage.SetSize (config.web_width, config.web_height); while (running) { if (vdev->GetFrame(&inputimage, &inputfloat) == 0) { vdev->Stop(); vdev->Start(); } Lock(); inputimage.CopyTo(¤timage, config.web_width, config.web_height); if (inputfloatfilter.AddScaledImage(&inputfloat, config.filter_ratio) == 0) inputfloat.CopyTo(&inputfloatfilter); inputfloatfilter.CopyTo(¤timagefloat); UnLock(); } thread_video_exit: running = 0; // force the other threads to stop vdev->Stop(); delete vdev; vdev = NULL; return NULL; } void ErrorExit(std::string text, int errorcode) { printf ("Error: %s\n", text.c_str()); exit (errorcode); }; int Lock () { if (pthread_mutex_lock(&mtx) == 0) return 1; else return 0; }; int UnLock () { if (pthread_mutex_unlock(&mtx) == 0) return 1; else return 0; }; int main(int argc, char **argv) { pthread_t thr_webserver; pthread_t thr_video; // prepare signals, mutex and test output image if (SetupSignals() == 0) return 0; pthread_mutex_init(&mtx, NULL); currentimage.TestScreen(1920, 1080); // read and setup config config.LoadFile (config.GetFilename()); config.LoadFile (GetDefaultConfig("miniwebcam.conf")); config.LoadArgs (argc, argv); if (config.GetInitFlags() & CONF_INITFLAGS_PRINT) { config.PrintConfig(); return 0; } printf ("MiniWebCam:\n"); if (config.GetInitFlags() & CONF_INITFLAGS_HELP) { config.Help(); return 0; } pthread_create(&thr_webserver, NULL, &thread_webserver, NULL); pthread_create(&thr_video, NULL, &thread_video, NULL); while (running) { usleep (1000); } return 0; }; std::string GetDefaultConfig(std::string name) { std::string fn = ""; char *hd = getenv ((char*)"HOME"); if (hd != NULL) { fn = hd; fn = fn + "/." + name; } return fn; }; int SetupSignals() { if (signal(SIGINT, sig_int) == SIG_ERR) { errorexit ("%s:%d could not set signal for SIGINT\n", __FILE__, __LINE__); return 0; } if (signal(SIGTERM, sig_int) == SIG_ERR) { errorexit ("%s:%d could not set signal for SIGTERM\n", __FILE__, __LINE__); return 0; } if (signal(SIGHUP, sig_int) == SIG_ERR) { errorexit ("%s:%d could not set signal for SIGHUB\n", __FILE__, __LINE__); return 0; } if (signal(SIGUSR1, sig_int) == SIG_ERR) { errorexit ("%s:%d could not set signal for SIGHUB\n", __FILE__, __LINE__); return 0; } return 1; }; static void sig_int(int sig) { if (signal (SIGINT, sig_int) == SIG_ERR) errorexit ("could not set up signal SIGINT\n"); printf ("\n\nSignal Int\n\n"); running = 0; }; int isfile(std::string fname) { struct stat st; if (stat (fname.c_str(), &st) == -1) return 0; if ((st.st_mode & S_IFMT) == S_IFREG) return 1; return 0; };