You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
4.5 KiB

#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <signal.h>
#include <string>
#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(&currentimage, config.web_width, config.web_height);
if (inputfloatfilter.AddScaledImage(&inputfloat, config.filter_ratio) == 0)
inputfloat.CopyTo(&inputfloatfilter);
inputfloatfilter.CopyTo(&currentimagefloat);
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;
};