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.
184 lines
4.1 KiB
184 lines
4.1 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;
|
|
VideoFrame currentimage;
|
|
|
|
|
|
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) {
|
|
VideoDevice *vdev= NULL;
|
|
|
|
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) == 0) {
|
|
vdev->Stop();
|
|
vdev->Start();
|
|
}
|
|
Lock();
|
|
inputimage.CopyTo(¤timage, config.web_width, config.web_height);
|
|
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;
|
|
}
|
|
|
|
|