mirror of
https://github.com/Motion-Project/motion.git
synced 2026-05-24 14:37:31 -04:00
Revise to use webu classes
This commit is contained in:
@@ -46,10 +46,13 @@ motionplus_SOURCES = \
|
||||
video_common.hpp video_common.cpp \
|
||||
video_loopback.hpp video_loopback.cpp \
|
||||
webu.hpp webu.cpp \
|
||||
webu_ans.hpp webu_ans.cpp \
|
||||
webu_file.hpp webu_file.cpp \
|
||||
webu_html.hpp webu_html.cpp \
|
||||
webu_json.hpp webu_json.cpp \
|
||||
webu_post.hpp webu_post.cpp \
|
||||
webu_common.hpp webu_common.cpp \
|
||||
webu_stream.hpp webu_stream.cpp \
|
||||
webu_getimg.hpp webu_getimg.cpp \
|
||||
webu_mpegts.hpp webu_mpegts.cpp
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "dbse.hpp"
|
||||
#include "video_loopback.hpp"
|
||||
#include "video_common.hpp"
|
||||
#include "webu_stream.hpp"
|
||||
#include "webu_getimg.hpp"
|
||||
#include "alg_sec.hpp"
|
||||
|
||||
const char *eventList[] = {
|
||||
@@ -106,7 +106,7 @@ static void on_event_end_command(ctx_dev *cam)
|
||||
|
||||
static void event_stream_put(ctx_dev *cam)
|
||||
{
|
||||
webu_stream_getimg(cam);
|
||||
webu_getimg_main(cam);
|
||||
}
|
||||
|
||||
static void event_vlp_putpipe(ctx_dev *cam)
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "webu.hpp"
|
||||
#include "dbse.hpp"
|
||||
#include "draw.hpp"
|
||||
#include "webu_stream.hpp"
|
||||
#include "webu_getimg.hpp"
|
||||
|
||||
/* Resize the image ring */
|
||||
static void mlp_ring_resize(ctx_dev *cam)
|
||||
@@ -615,7 +615,7 @@ void mlp_cleanup(ctx_dev *cam)
|
||||
dbse_exec(cam, NULL, "event_end");
|
||||
}
|
||||
|
||||
webu_stream_deinit(cam);
|
||||
webu_getimg_deinit(cam);
|
||||
|
||||
algsec_deinit(cam);
|
||||
|
||||
@@ -685,7 +685,7 @@ static void mlp_init(ctx_dev *cam)
|
||||
|
||||
mlp_init_buffers(cam);
|
||||
|
||||
webu_stream_init(cam);
|
||||
webu_getimg_init(cam);
|
||||
|
||||
algsec_init(cam);
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ static void motpls_signal_process(ctx_motapp *motapp)
|
||||
break;
|
||||
case MOTPLS_SIGNAL_SIGHUP: /* Reload the parameters and restart*/
|
||||
motapp->reload_all = true;
|
||||
motapp->webcontrol_finish = true;
|
||||
motapp->webu->wb_finish = true;
|
||||
for (indx=0; indx<motapp->cam_cnt; indx++) {
|
||||
motapp->cam_list[indx]->event_stop = true;
|
||||
motapp->cam_list[indx]->finish_dev = true;
|
||||
@@ -70,7 +70,7 @@ static void motpls_signal_process(ctx_motapp *motapp)
|
||||
break;
|
||||
case MOTPLS_SIGNAL_SIGTERM: /* Quit application */
|
||||
|
||||
motapp->webcontrol_finish = true;
|
||||
motapp->webu->wb_finish = true;
|
||||
for (indx=0; indx<motapp->cam_cnt; indx++) {
|
||||
motapp->cam_list[indx]->event_stop = true;
|
||||
motapp->cam_list[indx]->finish_dev = true;
|
||||
@@ -501,13 +501,17 @@ static void motpls_shutdown(ctx_motapp *motapp)
|
||||
|
||||
log_deinit(motapp);
|
||||
|
||||
webu_deinit(motapp);
|
||||
delete motapp->webu;
|
||||
|
||||
dbse_deinit(motapp);
|
||||
|
||||
conf_deinit(motapp);
|
||||
|
||||
delete motapp->conf;
|
||||
motapp->conf = nullptr;;
|
||||
|
||||
motpls_allcams_deinit(motapp);
|
||||
|
||||
}
|
||||
|
||||
static void motpls_device_ids(ctx_motapp *motapp)
|
||||
@@ -635,9 +639,10 @@ static void motpls_ntc(void)
|
||||
/** Initialize upon start up or restart */
|
||||
static void motpls_startup(ctx_motapp *motapp, int daemonize)
|
||||
{
|
||||
|
||||
log_init_app(motapp); /* This is needed prior to any function possibly calling motion_log*/
|
||||
|
||||
motapp->conf = new ctx_config;
|
||||
|
||||
conf_init(motapp);
|
||||
|
||||
log_init(motapp);
|
||||
@@ -669,7 +674,7 @@ static void motpls_startup(ctx_motapp *motapp, int daemonize)
|
||||
|
||||
draw_init_chars();
|
||||
|
||||
webu_init(motapp);
|
||||
motapp->webu = new cls_webu(motapp);
|
||||
|
||||
motpls_allcams_init(motapp);
|
||||
|
||||
@@ -810,7 +815,7 @@ static void motpls_watchdog(ctx_motapp *motapp, int camindx)
|
||||
}
|
||||
motapp->restart_all = true;
|
||||
motapp->finish_all = true;
|
||||
motapp->webcontrol_finish = true;
|
||||
motapp->webu->wb_finish = true;
|
||||
motapp->threads_running = 0;
|
||||
|
||||
}
|
||||
@@ -832,8 +837,8 @@ static int motpls_check_threadcount(ctx_motapp *motapp)
|
||||
}
|
||||
}
|
||||
|
||||
if ((motapp->webcontrol_finish == false) &&
|
||||
(motapp->webcontrol_daemon != NULL)) {
|
||||
if ((motapp->webu->wb_finish == false) &&
|
||||
(motapp->webu->wb_daemon != NULL)) {
|
||||
thrdcnt++;
|
||||
}
|
||||
|
||||
@@ -868,17 +873,9 @@ static void motpls_init(ctx_motapp *motapp, int argc, char *argv[])
|
||||
motapp->cam_cnt = 0;
|
||||
motapp->snd_cnt = 0;
|
||||
|
||||
motapp->conf = new ctx_config;
|
||||
|
||||
motapp->dbse = NULL;
|
||||
|
||||
motapp->webcontrol_running = false;
|
||||
motapp->webcontrol_finish = false;
|
||||
motapp->webcontrol_daemon = NULL;
|
||||
motapp->webcontrol_headers = NULL;
|
||||
motapp->webcontrol_actions = NULL;
|
||||
motapp->webcontrol_clients.clear();
|
||||
memset(motapp->webcontrol_digest_rand, 0, sizeof(motapp->webcontrol_digest_rand));
|
||||
motapp->conf = nullptr;
|
||||
motapp->dbse = nullptr;
|
||||
motapp->webu = nullptr;
|
||||
|
||||
pthread_key_create(&tls_key_threadnr, NULL);
|
||||
pthread_setspecific(tls_key_threadnr, (void *)(0));
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
#include <regex.h>
|
||||
#include <dirent.h>
|
||||
#include <algorithm>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
#if defined(HAVE_PTHREAD_NP_H)
|
||||
#include <pthread_np.h>
|
||||
@@ -121,6 +125,15 @@ struct ctx_webui;
|
||||
struct ctx_netcam;
|
||||
|
||||
class cls_libcam;
|
||||
class cls_webu;
|
||||
class cls_webu_ans;
|
||||
class cls_webu_file;
|
||||
class cls_webu_html;
|
||||
class cls_webu_json;
|
||||
class cls_webu_mpegts;
|
||||
class cls_webu_post;
|
||||
class cls_webu_common;
|
||||
class cls_webu_stream;
|
||||
|
||||
#define MYFFVER (LIBAVFORMAT_VERSION_MAJOR * 1000)+LIBAVFORMAT_VERSION_MINOR
|
||||
|
||||
@@ -553,16 +566,8 @@ struct ctx_motapp {
|
||||
int cam_cnt;
|
||||
int snd_cnt;
|
||||
ctx_all_sizes *all_sizes;
|
||||
|
||||
volatile int webcontrol_running;
|
||||
volatile int webcontrol_finish;
|
||||
struct MHD_Daemon *webcontrol_daemon;
|
||||
struct MHD_Daemon *webcontrol_daemon2;
|
||||
char webcontrol_digest_rand[12];
|
||||
std::list<ctx_webu_clients> webcontrol_clients; /* C++ list of client ips */
|
||||
ctx_params *webcontrol_headers; /* parameters for header */
|
||||
ctx_params *webcontrol_actions; /* parameters for actions */
|
||||
ctx_dbse *dbse; /* user specified database */
|
||||
cls_webu *webu;
|
||||
ctx_dbse *dbse; /* user specified database */
|
||||
|
||||
bool parms_changed; /*bool indicating if the parms have changed */
|
||||
pthread_mutex_t mutex_parms; /* mutex used to lock when changing parms */
|
||||
|
||||
16
src/util.hpp
16
src/util.hpp
@@ -92,11 +92,17 @@
|
||||
while (nanosleep(&ts1, &ts1) == -1); \
|
||||
}
|
||||
|
||||
#if MHD_VERSION >= 0x00097002
|
||||
typedef enum MHD_Result mhdrslt; /* Version independent return result from MHD */
|
||||
#else
|
||||
typedef int mhdrslt; /* Version independent return result from MHD */
|
||||
#endif
|
||||
#if MHD_VERSION >= 0x00097002
|
||||
typedef enum MHD_Result mhdrslt; /* Version independent return result from MHD */
|
||||
#else
|
||||
typedef int mhdrslt; /* Version independent return result from MHD */
|
||||
#endif
|
||||
/* Version independent uint */
|
||||
#if (MYFFVER <= 60016)
|
||||
typedef uint8_t myuint;
|
||||
#else
|
||||
typedef const uint8_t myuint;
|
||||
#endif
|
||||
|
||||
void myfree(void *ptr_addr);
|
||||
|
||||
|
||||
1380
src/webu.cpp
1380
src/webu.cpp
File diff suppressed because it is too large
Load Diff
101
src/webu.hpp
101
src/webu.hpp
@@ -64,61 +64,52 @@
|
||||
size_t key_sz; /* The size of the value */
|
||||
};
|
||||
|
||||
struct ctx_webui {
|
||||
std::string url; /* The URL sent from the client */
|
||||
std::string uri_camid; /* Parsed camera number from the url eg /camid/cmd1/cmd2/cmd3 */
|
||||
std::string uri_cmd1; /* Parsed command1 from the url eg /camid/cmd1/cmd2/cmd3 */
|
||||
std::string uri_cmd2; /* Parsed command2 from the url eg /camid/cmd1/cmd2/cmd3 */
|
||||
std::string uri_cmd3; /* Parsed command3 from the url eg /camid/cmd1/cmd2/cmd3 */
|
||||
|
||||
std::string clientip; /* IP of the connecting client */
|
||||
std::string hostfull; /* Full http name for host with port number */
|
||||
|
||||
char *auth_opaque; /* Opaque string for digest authentication*/
|
||||
char *auth_realm; /* Realm string for digest authentication*/
|
||||
char *auth_user; /* Parsed user from config authentication string*/
|
||||
char *auth_pass; /* Parsed password from config authentication string*/
|
||||
int authenticated; /* Boolean for whether authentication has been passed */
|
||||
|
||||
std::string resp_page; /* The response that will be sent */
|
||||
unsigned char *resp_image; /* Response image to provide to user */
|
||||
int resp_type; /* indicator for the type of response to provide. */
|
||||
size_t resp_size; /* The allocated size of the response */
|
||||
size_t resp_used; /* The amount of the response page used */
|
||||
size_t aviobuf_sz; /* The size of the mpegts avio buffer */
|
||||
struct timespec start_time; /* Start time of the mpegts stream*/
|
||||
|
||||
AVFormatContext *fmtctx;
|
||||
AVCodecContext *ctx_codec;
|
||||
AVFrame *picture; /* contains default image pointers */
|
||||
|
||||
std::string lang; /* Two character abbreviation for locale language*/
|
||||
int camindx; /* Index number of the cam */
|
||||
int device_id; /* Device id number requested */
|
||||
enum WEBUI_CNCT cnct_type; /* Type of connection we are processing */
|
||||
|
||||
int post_sz; /* The number of entries in the post info */
|
||||
std::string post_cmd; /* The command sent with the post */
|
||||
ctx_key *post_info; /* Structure of the entries provided from the post data */
|
||||
struct MHD_PostProcessor *post_processor; /* Processor for handling Post method connections */
|
||||
|
||||
FILE *req_file; /* requested file*/
|
||||
|
||||
unsigned char *all_img_data; /* Image for all cameras */
|
||||
|
||||
enum WEBUI_METHOD cnct_method; /* Connection method. Get or Post */
|
||||
|
||||
size_t stream_pos; /* Stream position of sent image */
|
||||
int stream_fps; /* Stream rate per second */
|
||||
struct timespec time_last; /* Keep track of processing time for stream thread*/
|
||||
int mhd_first; /* Boolean for whether it is the first connection*/
|
||||
struct MHD_Connection *connection; /* The MHD connection value from the client */
|
||||
ctx_motapp *motapp; /* The motionplus context pointer */
|
||||
ctx_dev *cam; /* The ctx_dev information for the camera requested */
|
||||
|
||||
/* Context to pass the parms to functions to start mhd */
|
||||
struct ctx_mhdstart {
|
||||
std::string tls_cert;
|
||||
std::string tls_key;
|
||||
bool tls_use;
|
||||
struct MHD_OptionItem *mhd_ops;
|
||||
int mhd_opt_nbr;
|
||||
unsigned int mhd_flags;
|
||||
int ipv6;
|
||||
struct sockaddr_in lpbk_ipv4;
|
||||
struct sockaddr_in6 lpbk_ipv6;
|
||||
};
|
||||
|
||||
void webu_init(ctx_motapp *motapp);
|
||||
void webu_deinit(ctx_motapp *motapp);
|
||||
class cls_webu {
|
||||
public:
|
||||
cls_webu(ctx_motapp *p_motapp);
|
||||
~cls_webu();
|
||||
bool wb_finish;
|
||||
ctx_params *wb_headers;
|
||||
ctx_params *wb_actions;
|
||||
char wb_digest_rand[12];
|
||||
struct MHD_Daemon *wb_daemon;
|
||||
struct MHD_Daemon *wb_daemon2;
|
||||
std::list<ctx_webu_clients> wb_clients;
|
||||
int cnct_cnt;
|
||||
|
||||
#endif /* _INCLUDE_WEBU_HPP_ */
|
||||
private:
|
||||
ctx_mhdstart *mhdst;
|
||||
ctx_motapp *c_motapp;
|
||||
void init_actions();
|
||||
void start_daemon_port1();
|
||||
void start_daemon_port2();
|
||||
void mhd_features_basic();
|
||||
void mhd_features_digest();
|
||||
void mhd_features_ipv6();
|
||||
void mhd_features_tls();
|
||||
void mhd_features();
|
||||
void mhd_loadfile(std::string fname, std::string &filestr);
|
||||
void mhd_checktls();
|
||||
void mhd_opts_init();
|
||||
void mhd_opts_deinit();
|
||||
void mhd_opts_localhost();
|
||||
void mhd_opts_digest();
|
||||
void mhd_opts_tls();
|
||||
void mhd_opts();
|
||||
void mhd_flags();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
856
src/webu_ans.cpp
Normal file
856
src/webu_ans.cpp
Normal file
@@ -0,0 +1,856 @@
|
||||
/*
|
||||
* This file is part of MotionPlus.
|
||||
*
|
||||
* MotionPlus is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MotionPlus is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MotionPlus. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "motionplus.hpp"
|
||||
#include "conf.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "util.hpp"
|
||||
#include "webu.hpp"
|
||||
#include "webu_ans.hpp"
|
||||
#include "webu_html.hpp"
|
||||
#include "webu_common.hpp"
|
||||
#include "webu_stream.hpp"
|
||||
#include "webu_mpegts.hpp"
|
||||
#include "webu_json.hpp"
|
||||
#include "webu_post.hpp"
|
||||
#include "webu_file.hpp"
|
||||
#include "video_v4l2.hpp"
|
||||
|
||||
|
||||
/* Extract the camid and cmds from the url */
|
||||
int cls_webu_ans::parseurl()
|
||||
{
|
||||
char *tmpurl;
|
||||
size_t pos_slash1, pos_slash2, baselen;
|
||||
|
||||
/* Example: /camid/cmd1/cmd2/cmd3 */
|
||||
uri_camid = "";
|
||||
uri_cmd1 = "";
|
||||
uri_cmd2 = "";
|
||||
uri_cmd3 = "";
|
||||
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO, _("Sent url: %s"),url.c_str());
|
||||
|
||||
tmpurl = (char*)mymalloc(url.length()+1);
|
||||
memcpy(tmpurl, url.c_str(), url.length());
|
||||
|
||||
MHD_http_unescape(tmpurl);
|
||||
|
||||
url.assign(tmpurl);
|
||||
free(tmpurl);
|
||||
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO, _("Decoded url: %s"),url.c_str());
|
||||
|
||||
baselen = app->conf->webcontrol_base_path.length();
|
||||
|
||||
if (url.length() < baselen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (url.substr(baselen) == "/favicon.ico") {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (url.substr(0, baselen) !=
|
||||
app->conf->webcontrol_base_path) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (url == "/") {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove any trailing slash to keep parms clean */
|
||||
if (url.substr(url.length()-1,1) == "/") {
|
||||
url = url.substr(0, url.length()-1);
|
||||
}
|
||||
|
||||
if (url.length() == baselen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos_slash1 = url.find("/", baselen+1);
|
||||
if (pos_slash1 != std::string::npos) {
|
||||
uri_camid = url.substr(baselen+1, pos_slash1-baselen- 1);
|
||||
} else {
|
||||
uri_camid = url.substr(baselen+1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos_slash1++;
|
||||
if (pos_slash1 >= url.length()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos_slash2 = url.find("/", pos_slash1);
|
||||
if (pos_slash2 != std::string::npos) {
|
||||
uri_cmd1 = url.substr(pos_slash1, pos_slash2 - pos_slash1);
|
||||
} else {
|
||||
uri_cmd1 = url.substr(pos_slash1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos_slash1 = ++pos_slash2;
|
||||
if (pos_slash1 >= url.length()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (uri_cmd1 == "movies") {
|
||||
/* Whole remaining url is the movie name and possibly subdir */
|
||||
uri_cmd2 = url.substr(pos_slash1);
|
||||
return 0;
|
||||
} else {
|
||||
pos_slash2 = url.find("/", pos_slash1);
|
||||
if (pos_slash2 != std::string::npos) {
|
||||
uri_cmd2 = url.substr(pos_slash1, pos_slash2 - pos_slash1);
|
||||
} else {
|
||||
uri_cmd2 = url.substr(pos_slash1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos_slash1 = ++pos_slash2;
|
||||
if (pos_slash1 >= url.length()) {
|
||||
return 0;
|
||||
}
|
||||
uri_cmd3 = url.substr(pos_slash1);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
/* Edit the parameters specified in the url sent */
|
||||
void cls_webu_ans::parms_edit()
|
||||
{
|
||||
int indx, is_nbr;
|
||||
|
||||
if (parseurl() != 0) {
|
||||
uri_camid = "";
|
||||
uri_cmd1 = "";
|
||||
uri_cmd2 = "";
|
||||
uri_cmd3 = "";
|
||||
url = "";
|
||||
}
|
||||
|
||||
if (uri_camid.length() > 0) {
|
||||
is_nbr = true;
|
||||
for (indx=0; indx < (int)uri_camid.length(); indx++) {
|
||||
if ((uri_camid[indx] > '9') || (uri_camid[indx] < '0')) {
|
||||
is_nbr = false;
|
||||
}
|
||||
}
|
||||
if (is_nbr) {
|
||||
device_id = atoi(uri_camid.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
if (app->cam_list[indx]->device_id == device_id) {
|
||||
camindx = indx;
|
||||
cam = app->cam_list[indx];
|
||||
}
|
||||
}
|
||||
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO
|
||||
, "camid: >%s< camindx: >%d< cmd1: >%s< cmd2: >%s< cmd3: >%s<"
|
||||
, uri_camid.c_str(), camindx
|
||||
, uri_cmd1.c_str(), uri_cmd2.c_str()
|
||||
, uri_cmd3.c_str());
|
||||
|
||||
}
|
||||
|
||||
/* Log the ip of the client connecting*/
|
||||
void cls_webu_ans::clientip_get()
|
||||
{
|
||||
const union MHD_ConnectionInfo *con_info;
|
||||
char client[WEBUI_LEN_URLI];
|
||||
const char *ip_dst;
|
||||
struct sockaddr_in6 *con_socket6;
|
||||
struct sockaddr_in *con_socket4;
|
||||
int is_ipv6;
|
||||
|
||||
is_ipv6 = false;
|
||||
if (app->conf->webcontrol_ipv6) {
|
||||
is_ipv6 = true;
|
||||
}
|
||||
|
||||
con_info = MHD_get_connection_info(connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS);
|
||||
if (is_ipv6) {
|
||||
con_socket6 = (struct sockaddr_in6 *)con_info->client_addr;
|
||||
ip_dst = inet_ntop(AF_INET6, &con_socket6->sin6_addr, client, WEBUI_LEN_URLI);
|
||||
if (ip_dst == NULL) {
|
||||
clientip = "Unknown";
|
||||
} else {
|
||||
clientip.assign(client);
|
||||
if (clientip.substr(0, 7) == "::ffff:") {
|
||||
clientip = clientip.substr(7);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
con_socket4 = (struct sockaddr_in *)con_info->client_addr;
|
||||
ip_dst = inet_ntop(AF_INET, &con_socket4->sin_addr, client, WEBUI_LEN_URLI);
|
||||
if (ip_dst == NULL) {
|
||||
clientip = "Unknown";
|
||||
} else {
|
||||
clientip.assign(client);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Get the hostname */
|
||||
void cls_webu_ans::hostname_get()
|
||||
{
|
||||
const char *hdr;
|
||||
|
||||
hdr = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_HOST);
|
||||
if (hdr == NULL) {
|
||||
hostfull = "//localhost:" +
|
||||
std::to_string(app->conf->webcontrol_port) +
|
||||
app->conf->webcontrol_base_path;
|
||||
} else {
|
||||
hostfull = "//" + std::string(hdr) +
|
||||
app->conf->webcontrol_base_path;
|
||||
}
|
||||
|
||||
MOTPLS_LOG(DBG,TYPE_ALL, NO_ERRNO, _("Full Host: %s"), hostfull.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Log the failed authentication check */
|
||||
void cls_webu_ans::failauth_log(bool userid_fail)
|
||||
{
|
||||
timespec tm_cnct;
|
||||
ctx_webu_clients clients;
|
||||
std::list<ctx_webu_clients>::iterator it;
|
||||
|
||||
MOTPLS_LOG(ALR, TYPE_STREAM, NO_ERRNO
|
||||
,_("Failed authentication from %s"), clientip.c_str());
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &tm_cnct);
|
||||
|
||||
it = webu->wb_clients.begin();
|
||||
while (it != webu->wb_clients.end()) {
|
||||
if (it->clientip == clientip) {
|
||||
it->conn_nbr++;
|
||||
it->conn_time.tv_sec =tm_cnct.tv_sec;
|
||||
it->authenticated = false;
|
||||
if (userid_fail) {
|
||||
it->userid_fail_nbr++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
clients.clientip = clientip;
|
||||
clients.conn_nbr = 1;
|
||||
clients.conn_time = tm_cnct;
|
||||
clients.authenticated = false;
|
||||
if (userid_fail) {
|
||||
clients.userid_fail_nbr = 1;
|
||||
} else {
|
||||
clients.userid_fail_nbr = 0;
|
||||
}
|
||||
|
||||
webu->wb_clients.push_back(clients);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void cls_webu_ans::client_connect()
|
||||
{
|
||||
timespec tm_cnct;
|
||||
ctx_webu_clients clients;
|
||||
std::list<ctx_webu_clients>::iterator it;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &tm_cnct);
|
||||
|
||||
/* First we need to clean out any old IPs from the list*/
|
||||
it = webu->wb_clients.begin();
|
||||
while (it != webu->wb_clients.end()) {
|
||||
if ((tm_cnct.tv_sec - it->conn_time.tv_sec) >=
|
||||
(app->conf->webcontrol_lock_minutes*60)) {
|
||||
it = webu->wb_clients.erase(it);
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
/* When this function is called, we know that we are authenticated
|
||||
* so we reset the info and as needed print a message that the
|
||||
* ip is connected.
|
||||
*/
|
||||
it = webu->wb_clients.begin();
|
||||
while (it != webu->wb_clients.end()) {
|
||||
if (it->clientip == clientip) {
|
||||
if (it->authenticated == false) {
|
||||
MOTPLS_LOG(INF,TYPE_ALL, NO_ERRNO, _("Connection from: %s"),clientip.c_str());
|
||||
}
|
||||
it->authenticated = true;
|
||||
it->conn_nbr = 1;
|
||||
it->userid_fail_nbr = 0;
|
||||
it->conn_time.tv_sec = tm_cnct.tv_sec;
|
||||
return;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
/* The ip was not already in our list. */
|
||||
clients.clientip = clientip;
|
||||
clients.conn_nbr = 1;
|
||||
clients.userid_fail_nbr = 0;
|
||||
clients.conn_time = tm_cnct;
|
||||
clients.authenticated = true;
|
||||
webu->wb_clients.push_back(clients);
|
||||
|
||||
MOTPLS_LOG(INF,TYPE_ALL, NO_ERRNO, _("Connection from: %s"),clientip.c_str());
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* Check for ips with excessive failed authentication attempts */
|
||||
mhdrslt cls_webu_ans::failauth_check()
|
||||
{
|
||||
timespec tm_cnct;
|
||||
std::list<ctx_webu_clients>::iterator it;
|
||||
std::string tmp;
|
||||
|
||||
if (webu->wb_clients.size() == 0) {
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &tm_cnct);
|
||||
it = webu->wb_clients.begin();
|
||||
while (it != webu->wb_clients.end()) {
|
||||
if ((it->clientip == clientip) &&
|
||||
((tm_cnct.tv_sec - it->conn_time.tv_sec) <
|
||||
(app->conf->webcontrol_lock_minutes*60)) &&
|
||||
(it->authenticated == false) &&
|
||||
(it->conn_nbr > app->conf->webcontrol_lock_attempts)) {
|
||||
MOTPLS_LOG(EMG, TYPE_STREAM, NO_ERRNO
|
||||
, "Ignoring connection from: %s"
|
||||
, clientip.c_str());
|
||||
it->conn_time = tm_cnct;
|
||||
if (app->conf->webcontrol_lock_script != "") {
|
||||
tmp = app->conf->webcontrol_lock_script + " " +
|
||||
std::to_string(it->userid_fail_nbr) + " " + clientip;
|
||||
util_exec_command(cam, tmp.c_str(), NULL);
|
||||
}
|
||||
return MHD_NO;
|
||||
} else if ((tm_cnct.tv_sec - it->conn_time.tv_sec) >=
|
||||
(app->conf->webcontrol_lock_minutes*60)) {
|
||||
it = webu->wb_clients.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
return MHD_YES;
|
||||
|
||||
}
|
||||
|
||||
/* Create a authorization denied response to user*/
|
||||
mhdrslt cls_webu_ans::mhd_digest_fail(int signal_stale)
|
||||
{
|
||||
struct MHD_Response *response;
|
||||
mhdrslt retcd;
|
||||
|
||||
authenticated = false;
|
||||
|
||||
resp_page = "<html><head><title>Access denied</title>"
|
||||
"</head><body>Access denied</body></html>";
|
||||
|
||||
response = MHD_create_response_from_buffer(resp_page.length()
|
||||
,(void *)resp_page.c_str(), MHD_RESPMEM_PERSISTENT);
|
||||
|
||||
if (response == NULL) {
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
retcd = MHD_queue_auth_fail_response(connection, auth_realm
|
||||
,auth_opaque, response
|
||||
,(signal_stale == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
|
||||
|
||||
MHD_destroy_response(response);
|
||||
|
||||
return retcd;
|
||||
}
|
||||
|
||||
/* Perform digest authentication */
|
||||
mhdrslt cls_webu_ans::mhd_digest()
|
||||
{
|
||||
/* This function gets called a couple of
|
||||
* times by MHD during the authentication process.
|
||||
*/
|
||||
int retcd;
|
||||
char *user;
|
||||
|
||||
/*Get username or prompt for a user/pass */
|
||||
user = MHD_digest_auth_get_username(connection);
|
||||
if (user == NULL) {
|
||||
return mhd_digest_fail(MHD_NO);
|
||||
}
|
||||
|
||||
/* Check for valid user name */
|
||||
if (mystrne(user, auth_user)) {
|
||||
failauth_log(true);
|
||||
myfree(&user);
|
||||
return mhd_digest_fail(MHD_NO);
|
||||
}
|
||||
myfree(&user);
|
||||
|
||||
/* Check the password as well*/
|
||||
retcd = MHD_digest_auth_check(connection, auth_realm
|
||||
, auth_user, auth_pass, 300);
|
||||
|
||||
if (retcd == MHD_NO) {
|
||||
failauth_log(false);
|
||||
}
|
||||
|
||||
if ( (retcd == MHD_INVALID_NONCE) || (retcd == MHD_NO) ) {
|
||||
return mhd_digest_fail(retcd);
|
||||
}
|
||||
|
||||
authenticated = true;
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
/* Create a authorization denied response to user*/
|
||||
mhdrslt cls_webu_ans::mhd_basic_fail()
|
||||
{
|
||||
struct MHD_Response *response;
|
||||
int retcd;
|
||||
|
||||
authenticated = false;
|
||||
|
||||
resp_page = "<html><head><title>Access denied</title>"
|
||||
"</head><body>Access denied</body></html>";
|
||||
|
||||
response = MHD_create_response_from_buffer(resp_page.length()
|
||||
,(void *)resp_page.c_str(), MHD_RESPMEM_PERSISTENT);
|
||||
|
||||
if (response == NULL) {
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
retcd = MHD_queue_basic_auth_fail_response (connection, auth_realm, response);
|
||||
|
||||
MHD_destroy_response(response);
|
||||
|
||||
if (retcd == MHD_YES) {
|
||||
return MHD_YES;
|
||||
} else {
|
||||
return MHD_NO;
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform Basic Authentication. */
|
||||
mhdrslt cls_webu_ans::mhd_basic()
|
||||
{
|
||||
char *user, *pass;
|
||||
|
||||
pass = NULL;
|
||||
user = NULL;
|
||||
|
||||
user = MHD_basic_auth_get_username_password (connection, &pass);
|
||||
if ((user == NULL) || (pass == NULL)) {
|
||||
myfree(&user);
|
||||
myfree(&pass);
|
||||
return mhd_basic_fail();
|
||||
}
|
||||
|
||||
if ((mystrne(user, auth_user)) || (mystrne(pass, auth_pass))) {
|
||||
failauth_log(mystrne(user, auth_user));
|
||||
myfree(&user);
|
||||
myfree(&pass);
|
||||
return mhd_basic_fail();
|
||||
}
|
||||
|
||||
myfree(&user);
|
||||
myfree(&pass);
|
||||
|
||||
authenticated = true;
|
||||
|
||||
return MHD_YES;
|
||||
|
||||
}
|
||||
|
||||
/* Parse apart the user:pass provided*/
|
||||
void cls_webu_ans::mhd_auth_parse()
|
||||
{
|
||||
int auth_len;
|
||||
char *col_pos;
|
||||
|
||||
myfree(&auth_user);
|
||||
myfree(&auth_pass);
|
||||
|
||||
auth_len = (int)app->conf->webcontrol_authentication.length();
|
||||
col_pos =(char*) strstr(app->conf->webcontrol_authentication.c_str() ,":");
|
||||
if (col_pos == NULL) {
|
||||
auth_user = (char*)mymalloc(auth_len+1);
|
||||
auth_pass = (char*)mymalloc(2);
|
||||
snprintf(auth_user, auth_len + 1, "%s"
|
||||
,app->conf->webcontrol_authentication.c_str());
|
||||
snprintf(auth_pass, 2, "%s","");
|
||||
} else {
|
||||
auth_user = (char*)mymalloc(auth_len - strlen(col_pos) + 1);
|
||||
auth_pass =(char*)mymalloc(strlen(col_pos));
|
||||
snprintf(auth_user, auth_len - strlen(col_pos) + 1, "%s"
|
||||
,app->conf->webcontrol_authentication.c_str());
|
||||
snprintf(auth_pass, strlen(col_pos), "%s", col_pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize for authorization */
|
||||
mhdrslt cls_webu_ans::mhd_auth()
|
||||
{
|
||||
unsigned int rand1,rand2;
|
||||
|
||||
srand((unsigned int)time(NULL));
|
||||
rand1 = (unsigned int)(42000000.0 * rand() / (RAND_MAX + 1.0));
|
||||
rand2 = (unsigned int)(42000000.0 * rand() / (RAND_MAX + 1.0));
|
||||
snprintf(auth_opaque, WEBUI_LEN_PARM, "%08x%08x", rand1, rand2);
|
||||
|
||||
snprintf(auth_realm, WEBUI_LEN_PARM, "%s","Motion");
|
||||
|
||||
if (app->conf->webcontrol_authentication == "") {
|
||||
authenticated = true;
|
||||
if (app->conf->webcontrol_auth_method != "none") {
|
||||
MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO ,_("No webcontrol user:pass provided"));
|
||||
}
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
if (auth_user == NULL) {
|
||||
mhd_auth_parse();
|
||||
}
|
||||
|
||||
if (app->conf->webcontrol_auth_method == "basic") {
|
||||
return mhd_basic();
|
||||
} else if (app->conf->webcontrol_auth_method == "digest") {
|
||||
return mhd_digest();
|
||||
}
|
||||
|
||||
|
||||
authenticated = true;
|
||||
return MHD_YES;
|
||||
|
||||
}
|
||||
|
||||
/* Send the response that we created back to the user. */
|
||||
void cls_webu_ans::mhd_send()
|
||||
{
|
||||
mhdrslt retcd;
|
||||
struct MHD_Response *response;
|
||||
p_lst *lst = &webu->wb_headers->params_array;
|
||||
p_it it;
|
||||
|
||||
response = MHD_create_response_from_buffer(resp_page.length()
|
||||
,(void *)resp_page.c_str(), MHD_RESPMEM_PERSISTENT);
|
||||
if (!response) {
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO, _("Invalid response"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (webu->wb_headers->params_count > 0) {
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
MHD_add_response_header (response
|
||||
, it->param_name.c_str(),it->param_value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (resp_type == WEBUI_RESP_TEXT) {
|
||||
MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE, "text/plain;");
|
||||
} else if (resp_type == WEBUI_RESP_JSON) {
|
||||
MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE, "application/json;");
|
||||
} else {
|
||||
MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE, "text/html");
|
||||
}
|
||||
|
||||
retcd = MHD_queue_response (connection, MHD_HTTP_OK, response);
|
||||
MHD_destroy_response (response);
|
||||
|
||||
if (retcd == MHD_NO) {
|
||||
MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO ,_("send page failed."));
|
||||
}
|
||||
}
|
||||
|
||||
void cls_webu_ans::bad_request()
|
||||
{
|
||||
resp_page =
|
||||
"<!DOCTYPE html>\n"
|
||||
"<html>\n"
|
||||
"<body>\n"
|
||||
"<p>Bad Request</p>\n"
|
||||
"<p>The server did not understand your request.</p>\n"
|
||||
"</body>\n"
|
||||
"</html>\n";
|
||||
mhd_send();
|
||||
}
|
||||
|
||||
/* Answer the get request from the user */
|
||||
void cls_webu_ans::answer_get()
|
||||
{
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO ,"processing get");
|
||||
|
||||
if ((uri_cmd1 == "mjpg") || (uri_cmd1 == "mpegts") ||
|
||||
(uri_cmd1 == "static")) {
|
||||
if (webu_stream == nullptr) {
|
||||
webu_stream = new cls_webu_stream(this);
|
||||
}
|
||||
webu_stream->main();
|
||||
|
||||
} else if (uri_cmd1 == "movies") {
|
||||
if (webu_file == nullptr) {
|
||||
webu_file = new cls_webu_file(this);
|
||||
}
|
||||
webu_file->main();
|
||||
|
||||
} else if ((uri_cmd1 == "config.json") ||
|
||||
(uri_cmd1 == "movies.json") || (uri_cmd1 == "status.json")) {
|
||||
if (webu_json == nullptr) {
|
||||
webu_json = new cls_webu_json(this);
|
||||
}
|
||||
webu_json->main();
|
||||
|
||||
} else {
|
||||
if (webu_html == nullptr) {
|
||||
webu_html = new cls_webu_html(this);
|
||||
}
|
||||
webu_html->main();
|
||||
}
|
||||
}
|
||||
|
||||
/* Answer the connection request for the webcontrol*/
|
||||
mhdrslt cls_webu_ans::answer_main(struct MHD_Connection *p_connection
|
||||
, const char *method, const char *upload_data, size_t *upload_data_size)
|
||||
{
|
||||
mhdrslt retcd;
|
||||
|
||||
cnct_type = WEBUI_CNCT_CONTROL;
|
||||
connection = p_connection;
|
||||
|
||||
if (url.length() == 0) {
|
||||
bad_request();
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
if (app->finish_all) {
|
||||
MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO ,_("Shutting down camera"));
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
if (cam != NULL) {
|
||||
if (cam->finish_dev) {
|
||||
MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO ,_("Shutting down camera"));
|
||||
return MHD_NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (clientip.length() == 0) {
|
||||
clientip_get();
|
||||
}
|
||||
|
||||
if (failauth_check() == MHD_NO) {
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
if (authenticated == false) {
|
||||
retcd = mhd_auth();
|
||||
if (authenticated == false) {
|
||||
return retcd;
|
||||
}
|
||||
}
|
||||
|
||||
client_connect();
|
||||
|
||||
if (mhd_first) {
|
||||
mhd_first = false;
|
||||
if (mystreq(method,"POST")) {
|
||||
if (webu_post == nullptr) {
|
||||
webu_post = new cls_webu_post(this);
|
||||
}
|
||||
cnct_method = WEBUI_METHOD_POST;
|
||||
retcd = webu_post->processor_init();
|
||||
} else {
|
||||
cnct_method = WEBUI_METHOD_GET;
|
||||
retcd = MHD_YES;
|
||||
}
|
||||
|
||||
return retcd;
|
||||
}
|
||||
|
||||
hostname_get();
|
||||
|
||||
if (mystreq(method,"POST")) {
|
||||
retcd = webu_post->processor_start(upload_data, upload_data_size);
|
||||
} else {
|
||||
answer_get();
|
||||
retcd = MHD_YES;
|
||||
}
|
||||
return retcd;
|
||||
|
||||
}
|
||||
|
||||
cls_webu_ans::cls_webu_ans(ctx_motapp *p_motapp, const char *uri)
|
||||
{
|
||||
app = p_motapp;
|
||||
webu = p_motapp->webu;
|
||||
|
||||
char *tmplang;
|
||||
|
||||
url = "";
|
||||
uri_camid = "";
|
||||
uri_cmd1 = "";
|
||||
uri_cmd2 = "";
|
||||
uri_cmd3 = "";
|
||||
clientip = "";
|
||||
lang = ""; /* Two digit lang code */
|
||||
|
||||
auth_opaque = (char*)mymalloc(WEBUI_LEN_PARM);
|
||||
auth_realm = (char*)mymalloc(WEBUI_LEN_PARM);
|
||||
auth_user = nullptr; /* Buffer to hold the user name*/
|
||||
auth_pass = nullptr; /* Buffer to hold the password */
|
||||
authenticated = false; /* boolean for whether we are authenticated*/
|
||||
|
||||
resp_page = ""; /* The response being constructed */
|
||||
req_file = nullptr;
|
||||
|
||||
cnct_type = WEBUI_CNCT_UNKNOWN;
|
||||
resp_type = WEBUI_RESP_HTML; /* Default to html response */
|
||||
cnct_method = WEBUI_METHOD_GET;
|
||||
camindx = -1;
|
||||
device_id = -1;
|
||||
|
||||
tmplang = setlocale(LC_ALL, NULL);
|
||||
if (tmplang == nullptr) {
|
||||
lang = "en";
|
||||
} else {
|
||||
lang.assign(tmplang, 2);
|
||||
}
|
||||
mhd_first = true;
|
||||
|
||||
cam = nullptr;
|
||||
webu_file = nullptr;
|
||||
webu_html = nullptr;
|
||||
webu_json = nullptr;
|
||||
webu_post = nullptr;
|
||||
webu_stream = nullptr;
|
||||
|
||||
url.assign(uri);
|
||||
|
||||
parms_edit();
|
||||
webu->cnct_cnt++;
|
||||
}
|
||||
|
||||
void cls_webu_ans::deinit_counter()
|
||||
{
|
||||
ctx_stream_data *strm;
|
||||
ctx_dev *p_cam;
|
||||
int indx, cam_max, cam_min;
|
||||
|
||||
if (cnct_type < WEBUI_CNCT_JPG_MIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (device_id == 0) {
|
||||
cam_min = 0;
|
||||
cam_max = app->cam_cnt;
|
||||
} else if ((device_id > 0) && (camindx >= 0)) {
|
||||
cam_min = camindx;
|
||||
cam_max = cam_min +1;
|
||||
} else {
|
||||
cam_min = 1;
|
||||
cam_max = 0;
|
||||
}
|
||||
|
||||
for (indx=cam_min; indx<cam_max; indx++) {
|
||||
p_cam = app->cam_list[indx];
|
||||
pthread_mutex_lock(&p_cam->stream.mutex);
|
||||
if ((cnct_type == WEBUI_CNCT_JPG_FULL) ||
|
||||
(cnct_type == WEBUI_CNCT_TS_FULL)) {
|
||||
strm = &p_cam->stream.norm;
|
||||
} else if ( (cnct_type == WEBUI_CNCT_JPG_SUB) ||
|
||||
(cnct_type == WEBUI_CNCT_TS_SUB)) {
|
||||
strm = &p_cam->stream.sub;
|
||||
} else if ( (cnct_type == WEBUI_CNCT_JPG_MOTION) ||
|
||||
(cnct_type == WEBUI_CNCT_TS_MOTION )) {
|
||||
strm = &p_cam->stream.motion;
|
||||
} else if ( (cnct_type == WEBUI_CNCT_JPG_SOURCE) ||
|
||||
(cnct_type == WEBUI_CNCT_TS_SOURCE)) {
|
||||
strm = &p_cam->stream.source;
|
||||
} else if ( (cnct_type == WEBUI_CNCT_JPG_SECONDARY) ||
|
||||
(cnct_type == WEBUI_CNCT_TS_SECONDARY)) {
|
||||
strm = &p_cam->stream.secondary;
|
||||
} else {
|
||||
strm = &p_cam->stream.norm;
|
||||
}
|
||||
|
||||
if ((cnct_type > WEBUI_CNCT_JPG_MIN) &&
|
||||
(cnct_type < WEBUI_CNCT_JPG_MAX)) {
|
||||
if ((device_id == 0) && (strm->all_cnct > 0)) {
|
||||
strm->all_cnct--;
|
||||
} else if ((device_id > 0) && (strm->jpg_cnct > 0)) {
|
||||
strm->jpg_cnct--;
|
||||
}
|
||||
} else if ((cnct_type > WEBUI_CNCT_TS_MIN) &&
|
||||
(cnct_type < WEBUI_CNCT_TS_MAX)) {
|
||||
if ((device_id == 0) && (strm->all_cnct > 0)) {
|
||||
strm->all_cnct--;
|
||||
} else if ((device_id > 0) && (strm->ts_cnct > 0)) {
|
||||
strm->ts_cnct--;
|
||||
}
|
||||
}
|
||||
if ((strm->all_cnct == 0) &&
|
||||
(strm->jpg_cnct == 0) &&
|
||||
(strm->ts_cnct == 0) &&
|
||||
(p_cam->passflag)) {
|
||||
myfree(&strm->img_data);
|
||||
myfree(&strm->jpg_data);
|
||||
}
|
||||
pthread_mutex_unlock(&p_cam->stream.mutex);
|
||||
}
|
||||
}
|
||||
|
||||
cls_webu_ans::~cls_webu_ans()
|
||||
{
|
||||
deinit_counter();
|
||||
|
||||
if (webu_file != nullptr) {
|
||||
delete webu_file;
|
||||
}
|
||||
if (webu_html != nullptr) {
|
||||
delete webu_html;
|
||||
}
|
||||
if (webu_json != nullptr) {
|
||||
delete webu_json;
|
||||
}
|
||||
if (webu_post != nullptr) {
|
||||
delete webu_post;
|
||||
}
|
||||
if (webu_stream != nullptr) {
|
||||
delete webu_stream;
|
||||
}
|
||||
|
||||
myfree(&auth_user);
|
||||
myfree(&auth_pass);
|
||||
myfree(&auth_opaque);
|
||||
myfree(&auth_realm);
|
||||
webu->cnct_cnt--;
|
||||
}
|
||||
87
src/webu_ans.hpp
Normal file
87
src/webu_ans.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of MotionPlus.
|
||||
*
|
||||
* MotionPlus is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MotionPlus is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MotionPlus. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_WEBU_ANS_HPP_
|
||||
#define _INCLUDE_WEBU_ANS_HPP_
|
||||
class cls_webu_ans {
|
||||
public:
|
||||
cls_webu_ans(ctx_motapp *p_motapp, const char *uri);
|
||||
~cls_webu_ans();
|
||||
|
||||
mhdrslt answer_main(struct MHD_Connection *connection, const char *method
|
||||
, const char *upload_data, size_t *upload_data_size);
|
||||
|
||||
void mhd_send();
|
||||
void bad_request();
|
||||
|
||||
ctx_motapp *app;
|
||||
cls_webu *webu;
|
||||
ctx_dev *cam;
|
||||
|
||||
struct MHD_Connection *connection;
|
||||
|
||||
FILE *req_file; /* requested file*/
|
||||
std::string lang; /* Two character abbreviation for locale language*/
|
||||
|
||||
std::string url; /* The URL sent from the client */
|
||||
std::string uri_camid; /* Parsed camera number from the url eg /camid/cmd1/cmd2/cmd3 */
|
||||
std::string uri_cmd1; /* Parsed command1 from the url eg /camid/cmd1/cmd2/cmd3 */
|
||||
std::string uri_cmd2; /* Parsed command2 from the url eg /camid/cmd1/cmd2/cmd3 */
|
||||
std::string uri_cmd3; /* Parsed command3 from the url eg /camid/cmd1/cmd2/cmd3 */
|
||||
|
||||
enum WEBUI_RESP resp_type; /* indicator for the type of response to provide. */
|
||||
std::string resp_page; /* The response that will be sent */
|
||||
int camindx; /* Index number of the cam */
|
||||
int device_id; /* Device id number requested */
|
||||
enum WEBUI_CNCT cnct_type; /* Type of connection we are processing */
|
||||
std::string clientip; /* IP of the connecting client */
|
||||
std::string hostfull; /* Full http name for host with port number */
|
||||
|
||||
private:
|
||||
cls_webu_file *webu_file;
|
||||
cls_webu_html *webu_html;
|
||||
cls_webu_json *webu_json;
|
||||
cls_webu_post *webu_post;
|
||||
cls_webu_stream *webu_stream;
|
||||
|
||||
int mhd_first; /* Boolean for whether it is the first connection*/
|
||||
char *auth_opaque; /* Opaque string for digest authentication*/
|
||||
char *auth_realm; /* Realm string for digest authentication*/
|
||||
char *auth_user; /* Parsed user from config authentication string*/
|
||||
char *auth_pass; /* Parsed password from config authentication string*/
|
||||
bool authenticated; /* Boolean for whether authentication has been passed */
|
||||
enum WEBUI_METHOD cnct_method; /* Connection method. Get or Post */
|
||||
|
||||
void parms_edit();
|
||||
int parseurl();
|
||||
void clientip_get();
|
||||
void hostname_get();
|
||||
void failauth_log(bool userid_fail);
|
||||
void client_connect();
|
||||
mhdrslt failauth_check();
|
||||
mhdrslt mhd_digest_fail(int signal_stale);
|
||||
mhdrslt mhd_digest();
|
||||
mhdrslt mhd_basic_fail();
|
||||
mhdrslt mhd_basic();
|
||||
void mhd_auth_parse();
|
||||
mhdrslt mhd_auth();
|
||||
void deinit_counter();
|
||||
void answer_get();
|
||||
};
|
||||
|
||||
#endif
|
||||
599
src/webu_common.cpp
Normal file
599
src/webu_common.cpp
Normal file
@@ -0,0 +1,599 @@
|
||||
/*
|
||||
* This file is part of MotionPlus.
|
||||
*
|
||||
* MotionPlus is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MotionPlus is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MotionPlus. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "motionplus.hpp"
|
||||
#include "conf.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "util.hpp"
|
||||
#include "webu.hpp"
|
||||
#include "webu_common.hpp"
|
||||
#include "webu_ans.hpp"
|
||||
#include "webu_html.hpp"
|
||||
#include "webu_stream.hpp"
|
||||
#include "webu_mpegts.hpp"
|
||||
#include "webu_json.hpp"
|
||||
#include "webu_post.hpp"
|
||||
#include "webu_file.hpp"
|
||||
#include "video_v4l2.hpp"
|
||||
|
||||
|
||||
bool cls_webu_common::check_finish()
|
||||
{
|
||||
if (webu->wb_finish){
|
||||
resp_used = 0;
|
||||
return true;
|
||||
}
|
||||
if (webua->cam != NULL) {
|
||||
if ((webua->cam->finish_dev == true) ||
|
||||
(webua->cam->passflag == false)) {
|
||||
resp_used = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cls_webu_common::set_fps()
|
||||
{
|
||||
if ((webua->cam->detecting_motion == false) &&
|
||||
(app->cam_list[webua->camindx]->conf->stream_motion)) {
|
||||
stream_fps = 1;
|
||||
} else {
|
||||
stream_fps = app->cam_list[webua->camindx]->conf->stream_maxrate;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sleep required time to get to the user requested framerate for the stream */
|
||||
void cls_webu_common::delay()
|
||||
{
|
||||
long stream_rate;
|
||||
struct timespec time_curr;
|
||||
long stream_delay;
|
||||
|
||||
if (check_finish()) {
|
||||
return;
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &time_curr);
|
||||
|
||||
/* The stream rate MUST be less than 1000000000 otherwise undefined behaviour
|
||||
* will occur with the SLEEP function.
|
||||
*/
|
||||
stream_delay = ((time_curr.tv_nsec - time_last.tv_nsec)) +
|
||||
((time_curr.tv_sec - time_last.tv_sec)*1000000000);
|
||||
if (stream_delay < 0) {
|
||||
stream_delay = 0;
|
||||
}
|
||||
if (stream_delay > 1000000000 ) {
|
||||
stream_delay = 1000000000;
|
||||
}
|
||||
|
||||
if (stream_fps >= 1) {
|
||||
stream_rate = ( (1000000000 / stream_fps) - stream_delay);
|
||||
if ((stream_rate > 0) && (stream_rate < 1000000000)) {
|
||||
SLEEP(0,stream_rate);
|
||||
} else if (stream_rate == 1000000000) {
|
||||
SLEEP(1,0);
|
||||
}
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC, &time_last);
|
||||
}
|
||||
|
||||
void cls_webu_common::img_sizes(ctx_dev *p_cam, int &img_w, int &img_h)
|
||||
{
|
||||
if (((webua->cnct_type == WEBUI_CNCT_JPG_SUB) ||
|
||||
(webua->cnct_type == WEBUI_CNCT_TS_SUB)) &&
|
||||
(((p_cam->imgs.width % 16) == 0) &&
|
||||
((p_cam->imgs.height % 16) == 0))) {
|
||||
img_w = (p_cam->imgs.width/2);
|
||||
img_h = (p_cam->imgs.height/2);
|
||||
} else {
|
||||
img_w = p_cam->imgs.width;
|
||||
img_h = p_cam->imgs.height;
|
||||
}
|
||||
img_w = ((p_cam->all_loc.scale * img_w) / 100);
|
||||
if ((img_w % 16) != 0) {
|
||||
img_w = img_w - (img_w % 16) + 16;
|
||||
}
|
||||
|
||||
img_h = ((p_cam->all_loc.scale * img_h) / 100);
|
||||
if ((img_h % 16) != 0) {
|
||||
img_h = img_h - (img_h % 16) + 16;
|
||||
}
|
||||
|
||||
if (img_w < 64){
|
||||
img_w = 64;
|
||||
}
|
||||
if (img_h < 64){
|
||||
img_h = 64;
|
||||
}
|
||||
}
|
||||
|
||||
void cls_webu_common::img_resize(ctx_dev *p_cam
|
||||
, uint8_t *src, uint8_t *dst, int dst_w, int dst_h)
|
||||
{
|
||||
int retcd, img_sz, src_h, src_w;
|
||||
char errstr[128];
|
||||
uint8_t *buf;
|
||||
AVFrame *frm_in, *frm_out;
|
||||
struct SwsContext *swsctx;
|
||||
|
||||
src_h = p_cam->imgs.height;
|
||||
src_w = p_cam->imgs.width;
|
||||
|
||||
img_sz = (dst_h * dst_w * 3)/2;
|
||||
memset(dst, 0x00, (size_t)img_sz);
|
||||
|
||||
frm_in = myframe_alloc();
|
||||
if (frm_in == NULL) {
|
||||
MOTPLS_LOG(ERR, TYPE_NETCAM, NO_ERRNO
|
||||
, _("Unable to allocate frm_in."));
|
||||
return;
|
||||
}
|
||||
|
||||
frm_out = myframe_alloc();
|
||||
if (frm_out == NULL) {
|
||||
MOTPLS_LOG(ERR, TYPE_NETCAM, NO_ERRNO
|
||||
, _("Unable to allocate frm_out."));
|
||||
myframe_free(frm_in);
|
||||
return;
|
||||
}
|
||||
|
||||
retcd = myimage_fill_arrays(frm_in, src, MY_PIX_FMT_YUV420P, src_w, src_h);
|
||||
if (retcd < 0) {
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTPLS_LOG(ERR, TYPE_NETCAM, NO_ERRNO
|
||||
, "Error filling arrays: %s", errstr);
|
||||
myframe_free(frm_in);
|
||||
myframe_free(frm_out);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = (uint8_t *)mymalloc((size_t)img_sz);
|
||||
|
||||
retcd = myimage_fill_arrays(frm_out, buf, MY_PIX_FMT_YUV420P, dst_w, dst_h);
|
||||
if (retcd < 0) {
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTPLS_LOG(ERR, TYPE_NETCAM, NO_ERRNO
|
||||
, "Error Filling array 2: %s", errstr);
|
||||
free(buf);
|
||||
myframe_free(frm_in);
|
||||
myframe_free(frm_out);
|
||||
return;
|
||||
}
|
||||
|
||||
swsctx = sws_getContext(
|
||||
src_w, src_h, MY_PIX_FMT_YUV420P
|
||||
,dst_w, dst_h, MY_PIX_FMT_YUV420P
|
||||
,SWS_BICUBIC, NULL, NULL, NULL);
|
||||
if (swsctx == NULL) {
|
||||
MOTPLS_LOG(ERR, TYPE_NETCAM, NO_ERRNO
|
||||
, _("Unable to allocate scaling context."));
|
||||
free(buf);
|
||||
myframe_free(frm_in);
|
||||
myframe_free(frm_out);
|
||||
return;
|
||||
}
|
||||
|
||||
retcd = sws_scale(swsctx
|
||||
, (const uint8_t* const *)frm_in->data, frm_in->linesize
|
||||
, 0, src_h, frm_out->data, frm_out->linesize);
|
||||
if (retcd < 0) {
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTPLS_LOG(ERR, TYPE_NETCAM, NO_ERRNO
|
||||
,_("Error resizing/reformatting: %s"), errstr);
|
||||
free(buf);
|
||||
myframe_free(frm_in);
|
||||
myframe_free(frm_out);
|
||||
sws_freeContext(swsctx);
|
||||
return;
|
||||
}
|
||||
|
||||
retcd = myimage_copy_to_buffer(
|
||||
frm_out, (uint8_t *)dst
|
||||
,MY_PIX_FMT_YUV420P, dst_w, dst_h, img_sz);
|
||||
if (retcd < 0) {
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTPLS_LOG(ERR, TYPE_NETCAM, NO_ERRNO
|
||||
,_("Error putting frame into output buffer: %s"), errstr);
|
||||
free(buf);
|
||||
myframe_free(frm_in);
|
||||
myframe_free(frm_out);
|
||||
sws_freeContext(swsctx);
|
||||
return;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
myframe_free(frm_in);
|
||||
myframe_free(frm_out);
|
||||
sws_freeContext(swsctx);
|
||||
}
|
||||
|
||||
void cls_webu_common::all_getimg()
|
||||
{
|
||||
int a_y, a_u, a_v; /* all img y,u,v */
|
||||
int c_y, c_u, c_v; /* camera img y,u,v */
|
||||
int dst_h, dst_w, dst_sz, src_sz, img_orow, img_ocol;
|
||||
int indx, row, indx1;
|
||||
unsigned char *dst_img, *src_img;
|
||||
ctx_stream_data *strm;
|
||||
ctx_all_sizes *all_sz;
|
||||
ctx_dev *p_cam;
|
||||
|
||||
memset(resp_image, '\0', resp_size);
|
||||
|
||||
all_sz = app->all_sizes;
|
||||
|
||||
a_y = 0;
|
||||
a_u = (all_sz->width * all_sz->height);
|
||||
a_v = a_u + (a_u / 4);
|
||||
|
||||
memset(all_img_data , 0x80, (size_t)a_u);
|
||||
memset(all_img_data + a_u, 0x80, (size_t)(a_u/2));
|
||||
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
p_cam = app->cam_list[indx];
|
||||
img_sizes(p_cam, dst_w, dst_h);
|
||||
|
||||
dst_sz = (dst_h * dst_w * 3)/2;
|
||||
src_sz = (p_cam->imgs.width * p_cam->imgs.height * 3)/2;
|
||||
img_orow = p_cam->all_loc.offset_row;
|
||||
img_ocol = p_cam->all_loc.offset_col;
|
||||
|
||||
if ((webua->cnct_type == WEBUI_CNCT_JPG_FULL) ||
|
||||
(webua->cnct_type == WEBUI_CNCT_TS_FULL)) {
|
||||
strm = &p_cam->stream.norm;
|
||||
} else if ((webua->cnct_type == WEBUI_CNCT_JPG_SUB) ||
|
||||
(webua->cnct_type == WEBUI_CNCT_TS_SUB)) {
|
||||
/* The use of the full size image is is is not an error here.
|
||||
For the all_img, we are using a different scaling/resizing method
|
||||
and as a result, we need to start with the full size image then
|
||||
resize to substream and stream_preview_scale*/
|
||||
strm = &p_cam->stream.norm; /* <<==Normal size is correct here*/
|
||||
} else if ((webua->cnct_type == WEBUI_CNCT_JPG_MOTION) ||
|
||||
(webua->cnct_type == WEBUI_CNCT_TS_MOTION)) {
|
||||
strm = &p_cam->stream.motion;
|
||||
} else if ((webua->cnct_type == WEBUI_CNCT_JPG_SOURCE) ||
|
||||
(webua->cnct_type == WEBUI_CNCT_TS_SOURCE )) {
|
||||
strm = &p_cam->stream.source;
|
||||
} else if ((webua->cnct_type == WEBUI_CNCT_JPG_SECONDARY) ||
|
||||
(webua->cnct_type == WEBUI_CNCT_TS_SECONDARY)) {
|
||||
strm = &p_cam->stream.secondary;
|
||||
} else { /* Should not be possible*/
|
||||
return;
|
||||
}
|
||||
|
||||
dst_img = (unsigned char*) mymalloc(dst_sz);
|
||||
src_img = (unsigned char*) mymalloc(src_sz);
|
||||
|
||||
pthread_mutex_lock(&p_cam->stream.mutex);
|
||||
indx1=0;
|
||||
while (indx1 < 1000) {
|
||||
if (strm->img_data == NULL) {
|
||||
if (strm->all_cnct == 0){
|
||||
strm->all_cnct++;
|
||||
}
|
||||
pthread_mutex_unlock(&p_cam->stream.mutex);
|
||||
SLEEP(0, 1000);
|
||||
pthread_mutex_lock(&p_cam->stream.mutex);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
indx1++;
|
||||
}
|
||||
if (strm->img_data == NULL) {
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO
|
||||
, "Could not get image for device %d", p_cam->device_id);
|
||||
memset(src_img, 0x00, src_sz);
|
||||
} else {
|
||||
memcpy(src_img, strm->img_data, src_sz);
|
||||
}
|
||||
pthread_mutex_unlock(&p_cam->stream.mutex);
|
||||
|
||||
img_resize(p_cam, src_img, dst_img, dst_w, dst_h);
|
||||
|
||||
/*
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO
|
||||
, "src w %d h %d dst w %d h %d all w %d h %d "
|
||||
, p_cam->imgs.width, p_cam->imgs.height
|
||||
, dst_w, dst_h
|
||||
, all_sz->width,all_sz->height);
|
||||
*/
|
||||
a_y = (img_orow * all_sz->width) + img_ocol;
|
||||
a_u =(all_sz->height * all_sz->width) +
|
||||
((img_orow / 4) * all_sz->width) + (img_ocol / 2) ;
|
||||
a_v = a_u + ((all_sz->height * all_sz->width) / 4);
|
||||
|
||||
c_y = 0;
|
||||
c_u = (dst_w * dst_h);
|
||||
c_v = c_u + (c_u / 4);
|
||||
|
||||
/*
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO
|
||||
, "r %d c %d a %d %d %d h %d w %d"
|
||||
, img_orow, img_ocol
|
||||
, a_y, a_u, a_v
|
||||
, all_sz->height, all_sz->width);
|
||||
*/
|
||||
|
||||
for (row=0; row<dst_h; row++) {
|
||||
memcpy(all_img_data + a_y, dst_img + c_y, dst_w);
|
||||
a_y += all_sz->width;
|
||||
c_y += dst_w;
|
||||
if (row % 2) {
|
||||
memcpy(all_img_data + a_u, dst_img + c_u, dst_w / 2);
|
||||
//memset(webui->all_img_data + a_u, 0xFA, dst_w/2);
|
||||
a_u += (all_sz->width / 2);
|
||||
c_u += (dst_w / 2);
|
||||
memcpy(all_img_data + a_v, dst_img + c_v, dst_w / 2);
|
||||
a_v += (all_sz->width / 2);
|
||||
c_v += (dst_w / 2);
|
||||
}
|
||||
}
|
||||
|
||||
myfree(&dst_img);
|
||||
myfree(&src_img);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cls_webu_common::all_sizes()
|
||||
{
|
||||
int indx, row, col;
|
||||
int chk_sz, chk_w, mx_col, mx_row;
|
||||
int mx_h, mx_w, img_h, img_w;
|
||||
bool dflt_scale;
|
||||
ctx_dev *p_cam;
|
||||
|
||||
if (app->all_sizes->reset == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
mx_row = 0;
|
||||
mx_col = 0;
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
p_cam = app->cam_list[indx];
|
||||
if (mx_row < p_cam->all_loc.row) {
|
||||
mx_row = p_cam->all_loc.row;
|
||||
}
|
||||
if (mx_col < p_cam->all_loc.col) {
|
||||
mx_col = p_cam->all_loc.col;
|
||||
}
|
||||
}
|
||||
|
||||
dflt_scale = false;
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
if (app->cam_list[indx]->all_loc.scale == -1) {
|
||||
dflt_scale = true;
|
||||
}
|
||||
}
|
||||
if (dflt_scale) {
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
app->cam_list[indx]->all_loc.scale = 100;
|
||||
}
|
||||
for (row=1; row<=mx_row; row++) {
|
||||
mx_h = 0;
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
p_cam = app->cam_list[indx];
|
||||
if (row == p_cam->all_loc.row) {
|
||||
img_sizes(p_cam, img_w, img_h);
|
||||
if (mx_h < img_h) {
|
||||
mx_h = img_h;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
p_cam = app->cam_list[indx];
|
||||
if (row == p_cam->all_loc.row) {
|
||||
img_sizes(p_cam, img_w, img_h);
|
||||
p_cam->all_loc.scale = (int)((float)(mx_h*100 / img_h ));
|
||||
}
|
||||
}
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
p_cam = app->cam_list[indx];
|
||||
img_sizes(p_cam, img_w, img_h);
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO
|
||||
, "Device %d Original Size %dx%d Scale %d New Size %dx%d"
|
||||
, p_cam->device_id
|
||||
, p_cam->imgs.width, p_cam->imgs.height
|
||||
, p_cam->all_loc.scale, img_w, img_h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app->all_sizes->width = 0;
|
||||
app->all_sizes->height = 0;
|
||||
for (row=1; row<=mx_row; row++) {
|
||||
chk_sz = 0;
|
||||
mx_h = 0;
|
||||
for (col=1; col<=mx_col; col++) {
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
p_cam = app->cam_list[indx];
|
||||
img_sizes(p_cam, img_w, img_h);
|
||||
if ((row == p_cam->all_loc.row) &&
|
||||
(col == p_cam->all_loc.col)) {
|
||||
p_cam->all_loc.offset_col = chk_sz;
|
||||
chk_sz += img_w;
|
||||
if (mx_h < img_h) {
|
||||
mx_h = img_h;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Align/center vert. the images in each row*/
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
p_cam = app->cam_list[indx];
|
||||
img_sizes(p_cam, img_w, img_h);
|
||||
if (p_cam->all_loc.row == row) {
|
||||
p_cam->all_loc.offset_row =
|
||||
app->all_sizes->height +
|
||||
((mx_h - img_h)/2) ;
|
||||
}
|
||||
}
|
||||
app->all_sizes->height += mx_h;
|
||||
if (app->all_sizes->width < chk_sz) {
|
||||
app->all_sizes->width = chk_sz;
|
||||
}
|
||||
}
|
||||
|
||||
/* Align/center horiz. the images within each column area */
|
||||
chk_w = 0;
|
||||
for (col=1; col<=mx_col; col++) {
|
||||
chk_sz = 0;
|
||||
mx_w = 0;
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
p_cam = app->cam_list[indx];
|
||||
img_sizes(p_cam, img_w, img_h);
|
||||
if (p_cam->all_loc.col == col) {
|
||||
if (p_cam->all_loc.offset_col < chk_w) {
|
||||
p_cam->all_loc.offset_col = chk_w;
|
||||
}
|
||||
if (chk_sz < p_cam->all_loc.offset_col) {
|
||||
chk_sz = p_cam->all_loc.offset_col;
|
||||
}
|
||||
if (mx_w < img_w) {
|
||||
mx_w = img_w;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
p_cam = app->cam_list[indx];
|
||||
img_sizes(p_cam, img_w, img_h);
|
||||
if (p_cam->all_loc.col == col) {
|
||||
p_cam->all_loc.offset_col =
|
||||
chk_sz + ((mx_w - img_w) /2) ;
|
||||
}
|
||||
}
|
||||
chk_w = mx_w + chk_sz;
|
||||
if (app->all_sizes->width < chk_w) {
|
||||
app->all_sizes->width = chk_w;
|
||||
}
|
||||
}
|
||||
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
p_cam = app->cam_list[indx];
|
||||
img_sizes(p_cam, img_w, img_h);
|
||||
|
||||
chk_sz = p_cam->all_loc.offset_col + p_cam->all_loc.offset_user_col;
|
||||
if (chk_sz < 0) {
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO
|
||||
, "Device %d invalid image column offset. (%d + %d) less than zero "
|
||||
, p_cam->device_id
|
||||
, p_cam->all_loc.offset_col
|
||||
, p_cam->all_loc.offset_user_col);
|
||||
} else if ((chk_sz + img_w) > app->all_sizes->width) {
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO
|
||||
, "Device %d invalid image column offset. (%d + %d) over image size"
|
||||
, p_cam->device_id
|
||||
, p_cam->all_loc.offset_col
|
||||
, p_cam->all_loc.offset_user_col);
|
||||
} else {
|
||||
p_cam->all_loc.offset_col = chk_sz;
|
||||
}
|
||||
|
||||
chk_sz = p_cam->all_loc.offset_row + p_cam->all_loc.offset_user_row;
|
||||
if (chk_sz < 0 ) {
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO
|
||||
, "Device %d invalid image row offset. (%d + %d) less than zero "
|
||||
, p_cam->device_id
|
||||
, p_cam->all_loc.offset_row
|
||||
, p_cam->all_loc.offset_user_row);
|
||||
} else if ((chk_sz + img_h) > app->all_sizes->height) {
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO
|
||||
, "Device %d invalid image row offset. (%d + %d) over image size"
|
||||
, p_cam->device_id
|
||||
, p_cam->all_loc.offset_row
|
||||
, p_cam->all_loc.offset_user_row);
|
||||
} else {
|
||||
p_cam->all_loc.offset_row = chk_sz;
|
||||
}
|
||||
}
|
||||
|
||||
app->all_sizes->img_sz =((
|
||||
app->all_sizes->height *
|
||||
app->all_sizes->width * 3)/2);
|
||||
|
||||
/*
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO
|
||||
, "row %d col %d offset row %d offset col %d"
|
||||
, app->cam_list[indx]->all_loc.row
|
||||
, app->cam_list[indx]->all_loc.col
|
||||
, app->cam_list[indx]->all_loc.offset_row
|
||||
, app->cam_list[indx]->all_loc.offset_col);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/* Allocate buffers if needed. */
|
||||
void cls_webu_common::one_buffer()
|
||||
{
|
||||
if (webua->cam == NULL) {
|
||||
return;
|
||||
}
|
||||
if (resp_size < (size_t)webua->cam->imgs.size_norm) {
|
||||
if (resp_image != NULL) {
|
||||
myfree(&resp_image);
|
||||
}
|
||||
resp_image = (unsigned char*) mymalloc(webua->cam->imgs.size_norm);
|
||||
memset(resp_image,'\0',webua->cam->imgs.size_norm);
|
||||
resp_size = webua->cam->imgs.size_norm;
|
||||
resp_used = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void cls_webu_common::all_buffer()
|
||||
{
|
||||
if (resp_size < (size_t)app->all_sizes->img_sz) {
|
||||
if (resp_image != nullptr) {
|
||||
myfree(&resp_image);
|
||||
}
|
||||
resp_size = app->all_sizes->img_sz;
|
||||
resp_image = (unsigned char*) mymalloc(resp_size);
|
||||
memset(resp_image, '\0', resp_size);
|
||||
resp_used = 0;
|
||||
}
|
||||
if ((all_img_data == nullptr) &&
|
||||
(app->all_sizes->img_sz >0)) {
|
||||
all_img_data = (unsigned char*)
|
||||
mymalloc((size_t)app->all_sizes->img_sz);
|
||||
}
|
||||
}
|
||||
|
||||
cls_webu_common::cls_webu_common(cls_webu_ans *p_webua)
|
||||
{
|
||||
app = p_webua->app;
|
||||
webu = p_webua->webu;
|
||||
webua = p_webua;
|
||||
|
||||
all_img_data = nullptr;
|
||||
resp_image = nullptr;
|
||||
resp_size = 0; /* The size of the resp_page buffer. May get adjusted */
|
||||
resp_used = 0; /* How many bytes used so far in resp_page*/
|
||||
stream_fps = 1; /* Stream rate */
|
||||
}
|
||||
|
||||
cls_webu_common::~cls_webu_common()
|
||||
{
|
||||
app = nullptr;
|
||||
webu = nullptr;
|
||||
webua = nullptr;
|
||||
myfree(&resp_image);
|
||||
myfree(&all_img_data);
|
||||
}
|
||||
52
src/webu_common.hpp
Normal file
52
src/webu_common.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of MotionPlus.
|
||||
*
|
||||
* MotionPlus is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MotionPlus is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MotionPlus. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_WEBU_COMMON_HPP_
|
||||
#define _INCLUDE_WEBU_COMMON_HPP_
|
||||
class cls_webu_common {
|
||||
public:
|
||||
cls_webu_common(cls_webu_ans *p_webua);
|
||||
~cls_webu_common();
|
||||
bool check_finish();
|
||||
void delay();
|
||||
void set_fps();
|
||||
void all_getimg();
|
||||
void all_sizes();
|
||||
void all_buffer();
|
||||
void one_buffer();
|
||||
|
||||
struct timespec time_last; /* Keep track of processing time for stream thread*/
|
||||
|
||||
size_t resp_size; /* The allocated size of the response */
|
||||
size_t resp_used; /* The amount of the response page used */
|
||||
unsigned char *resp_image; /* Response image to provide to user */
|
||||
unsigned char *all_img_data; /* Image for all cameras */
|
||||
int stream_fps; /* Stream rate per second */
|
||||
|
||||
private:
|
||||
ctx_motapp *app;
|
||||
cls_webu *webu;
|
||||
cls_webu_ans *webua;
|
||||
|
||||
void img_sizes(ctx_dev *cam, int &img_w, int &img_h);
|
||||
void img_resize(ctx_dev *cam
|
||||
, uint8_t *src, uint8_t *dst, int dst_w, int dst_h);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -22,51 +22,54 @@
|
||||
#include "util.hpp"
|
||||
#include "picture.hpp"
|
||||
#include "webu.hpp"
|
||||
#include "webu_ans.hpp"
|
||||
#include "webu_common.hpp"
|
||||
#include "webu_file.hpp"
|
||||
#include "dbse.hpp"
|
||||
|
||||
|
||||
/* Callback for the file reader response*/
|
||||
static ssize_t webu_file_reader (void *cls, uint64_t pos, char *buf, size_t max)
|
||||
{
|
||||
ctx_webui *webui =(ctx_webui *)cls;
|
||||
cls_webu_ans *webu_ans =(cls_webu_ans *)cls;
|
||||
|
||||
(void)fseek (webui->req_file, (long)pos, SEEK_SET);
|
||||
return fread (buf, 1, max, webui->req_file);
|
||||
(void)fseek (webu_ans->req_file, (long)pos, SEEK_SET);
|
||||
return fread (buf, 1, max, webu_ans->req_file);
|
||||
}
|
||||
|
||||
/* Close the requested file */
|
||||
static void webu_file_free (void *cls)
|
||||
{
|
||||
ctx_webui *webui =(ctx_webui *)cls;
|
||||
myfclose(webui->req_file);
|
||||
cls_webu_ans *webu_ans =(cls_webu_ans *)cls;
|
||||
myfclose(webu_ans->req_file);
|
||||
}
|
||||
|
||||
/* Entry point for answering file request*/
|
||||
mhdrslt webu_file_main(ctx_webui *webui)
|
||||
{
|
||||
/****************************************************/
|
||||
|
||||
void cls_webu_file::main() {
|
||||
mhdrslt retcd;
|
||||
struct stat statbuf;
|
||||
struct MHD_Response *response;
|
||||
std::string full_nm;
|
||||
int indx;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
/*If we have not fully started yet, simply return*/
|
||||
if (webui->cam->motapp->dbse == NULL) {
|
||||
return MHD_NO;
|
||||
if (app->dbse == NULL) {
|
||||
webua->bad_request();
|
||||
return;
|
||||
}
|
||||
|
||||
if (webui->cam->motapp->dbse->movie_cnt == 0) {
|
||||
dbse_movies_getlist(webui->cam->motapp, webui->cam->device_id);
|
||||
if (app->dbse->movie_cnt == 0) {
|
||||
dbse_movies_getlist(app, webua->cam->device_id);
|
||||
}
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
if (it->param_name == "movies") {
|
||||
if (it->param_value == "off") {
|
||||
MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO, "Movies via webcontrol disabled");
|
||||
return MHD_NO;
|
||||
webua->bad_request();
|
||||
return;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -74,45 +77,58 @@ mhdrslt webu_file_main(ctx_webui *webui)
|
||||
}
|
||||
|
||||
full_nm = "";
|
||||
for (indx=0; indx < webui->cam->motapp->dbse->movie_cnt; indx++) {
|
||||
if (mystreq(webui->cam->motapp->dbse->movie_list[indx].movie_nm
|
||||
, webui->uri_cmd2.c_str())) {
|
||||
full_nm = webui->cam->motapp->dbse->movie_list[indx].full_nm;
|
||||
for (indx=0; indx < app->dbse->movie_cnt; indx++) {
|
||||
if (mystreq(app->dbse->movie_list[indx].movie_nm
|
||||
,webua->uri_cmd2.c_str())) {
|
||||
full_nm = app->dbse->movie_list[indx].full_nm;
|
||||
}
|
||||
}
|
||||
|
||||
if (stat(full_nm.c_str(), &statbuf) == 0) {
|
||||
webui->req_file = myfopen(full_nm.c_str(), "rbe");
|
||||
webua->req_file = myfopen(full_nm.c_str(), "rbe");
|
||||
} else {
|
||||
webui->req_file = NULL;
|
||||
webua->req_file = NULL;
|
||||
MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO
|
||||
,"Security warning: Client IP %s requested file: %s"
|
||||
,webui->clientip.c_str(), webui->uri_cmd2.c_str());
|
||||
,webua->clientip.c_str(), webua->uri_cmd2.c_str());
|
||||
}
|
||||
|
||||
if (webui->req_file == NULL) {
|
||||
webui->resp_page = "<html><head><title>Bad File</title>"
|
||||
if (webua->req_file == NULL) {
|
||||
webua->resp_page = "<html><head><title>Bad File</title>"
|
||||
"</head><body>Bad File</body></html>";
|
||||
|
||||
response = MHD_create_response_from_buffer(webui->resp_page.length()
|
||||
,(void *)webui->resp_page.c_str(), MHD_RESPMEM_PERSISTENT);
|
||||
retcd = MHD_queue_response (webui->connection, MHD_HTTP_NOT_FOUND, response);
|
||||
MHD_destroy_response (response);
|
||||
webua->resp_type = WEBUI_RESP_HTML;
|
||||
webua->mhd_send();
|
||||
|
||||
} else {
|
||||
response = MHD_create_response_from_callback (
|
||||
statbuf.st_size, 32 * 1024
|
||||
, &webu_file_reader
|
||||
, webui
|
||||
, this
|
||||
, &webu_file_free);
|
||||
if (response == NULL) {
|
||||
myfclose(webui->req_file);
|
||||
return MHD_NO;
|
||||
myfclose(webua->req_file);
|
||||
webua->bad_request();
|
||||
return;
|
||||
}
|
||||
retcd = MHD_queue_response (webui->connection, MHD_HTTP_OK, response);
|
||||
retcd = MHD_queue_response (webua->connection, MHD_HTTP_OK, response);
|
||||
MHD_destroy_response (response);
|
||||
}
|
||||
if (retcd == MHD_NO) {
|
||||
MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO, "Error processing file request");
|
||||
}
|
||||
|
||||
return retcd;
|
||||
}
|
||||
|
||||
cls_webu_file::cls_webu_file(cls_webu_ans *p_webua)
|
||||
{
|
||||
app = p_webua->app;
|
||||
webu = p_webua->webu;
|
||||
webua = p_webua;
|
||||
}
|
||||
|
||||
cls_webu_file::~cls_webu_file()
|
||||
{
|
||||
app = nullptr;
|
||||
webu = nullptr;
|
||||
webua = nullptr;
|
||||
}
|
||||
@@ -18,7 +18,15 @@
|
||||
|
||||
#ifndef _INCLUDE_WEBU_FILE_HPP_
|
||||
#define _INCLUDE_WEBU_FILE_HPP_
|
||||
|
||||
mhdrslt webu_file_main(ctx_webui *webui);
|
||||
class cls_webu_file {
|
||||
public:
|
||||
cls_webu_file(cls_webu_ans *p_webua);
|
||||
~cls_webu_file();
|
||||
void main();
|
||||
private:
|
||||
ctx_motapp *app;
|
||||
cls_webu *webu;
|
||||
cls_webu_ans *webua;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE_WEBU_FILE_HPP_ */
|
||||
|
||||
317
src/webu_getimg.cpp
Normal file
317
src/webu_getimg.cpp
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* This file is part of MotionPlus.
|
||||
*
|
||||
* MotionPlus is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MotionPlus is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MotionPlus. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "motionplus.hpp"
|
||||
#include "conf.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "util.hpp"
|
||||
#include "picture.hpp"
|
||||
#include "webu_getimg.hpp"
|
||||
#include "alg_sec.hpp"
|
||||
|
||||
/* NOTE: These run on the motion_loop thread. */
|
||||
|
||||
/* Initial the stream context items for the camera */
|
||||
void webu_getimg_init(ctx_dev *cam)
|
||||
{
|
||||
pthread_mutex_init(&cam->stream.mutex, NULL);
|
||||
|
||||
cam->imgs.image_substream = NULL;
|
||||
|
||||
cam->stream.norm.jpg_sz = 0;
|
||||
cam->stream.norm.jpg_data = NULL;
|
||||
cam->stream.norm.jpg_cnct = 0;
|
||||
cam->stream.norm.ts_cnct = 0;
|
||||
cam->stream.norm.all_cnct = 0;
|
||||
cam->stream.norm.consumed = true;
|
||||
cam->stream.norm.img_data = NULL;
|
||||
|
||||
cam->stream.sub.jpg_sz = 0;
|
||||
cam->stream.sub.jpg_data = NULL;
|
||||
cam->stream.sub.jpg_cnct = 0;
|
||||
cam->stream.sub.ts_cnct = 0;
|
||||
cam->stream.sub.all_cnct = 0;
|
||||
cam->stream.sub.consumed = true;
|
||||
cam->stream.sub.img_data = NULL;
|
||||
|
||||
cam->stream.motion.jpg_sz = 0;
|
||||
cam->stream.motion.jpg_data = NULL;
|
||||
cam->stream.motion.jpg_cnct = 0;
|
||||
cam->stream.motion.ts_cnct = 0;
|
||||
cam->stream.motion.all_cnct = 0;
|
||||
cam->stream.motion.consumed = true;
|
||||
cam->stream.motion.img_data = NULL;
|
||||
|
||||
cam->stream.source.jpg_sz = 0;
|
||||
cam->stream.source.jpg_data = NULL;
|
||||
cam->stream.source.jpg_cnct = 0;
|
||||
cam->stream.source.ts_cnct = 0;
|
||||
cam->stream.source.all_cnct = 0;
|
||||
cam->stream.source.consumed = true;
|
||||
cam->stream.source.img_data = NULL;
|
||||
|
||||
cam->stream.secondary.jpg_sz = 0;
|
||||
cam->stream.secondary.jpg_data = NULL;
|
||||
cam->stream.secondary.jpg_cnct = 0;
|
||||
cam->stream.secondary.ts_cnct = 0;
|
||||
cam->stream.secondary.all_cnct = 0;
|
||||
cam->stream.secondary.consumed = true;
|
||||
cam->stream.secondary.img_data = NULL;
|
||||
|
||||
}
|
||||
|
||||
/* Free the stream buffers and mutex for shutdown */
|
||||
void webu_getimg_deinit(ctx_dev *cam)
|
||||
{
|
||||
/* NOTE: This runs on the motion_loop thread. */
|
||||
myfree(&cam->imgs.image_substream);
|
||||
|
||||
pthread_mutex_lock(&cam->stream.mutex);
|
||||
myfree(&cam->stream.norm.jpg_data);
|
||||
myfree(&cam->stream.sub.jpg_data);
|
||||
myfree(&cam->stream.motion.jpg_data);
|
||||
myfree(&cam->stream.source.jpg_data);
|
||||
myfree(&cam->stream.secondary.jpg_data);
|
||||
|
||||
myfree(&cam->stream.norm.img_data) ;
|
||||
myfree(&cam->stream.sub.img_data) ;
|
||||
myfree(&cam->stream.motion.img_data) ;
|
||||
myfree(&cam->stream.source.img_data) ;
|
||||
myfree(&cam->stream.secondary.img_data) ;
|
||||
pthread_mutex_unlock(&cam->stream.mutex);
|
||||
|
||||
pthread_mutex_destroy(&cam->stream.mutex);
|
||||
|
||||
}
|
||||
|
||||
/* Get a normal image from the motion loop and compress it*/
|
||||
static void webu_getimg_norm(ctx_dev *cam)
|
||||
{
|
||||
if ((cam->stream.norm.jpg_cnct == 0) &&
|
||||
(cam->stream.norm.ts_cnct == 0) &&
|
||||
(cam->stream.norm.all_cnct == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cam->stream.norm.jpg_cnct > 0) {
|
||||
if (cam->stream.norm.jpg_data == NULL) {
|
||||
cam->stream.norm.jpg_data =(unsigned char*)mymalloc(cam->imgs.size_norm);
|
||||
}
|
||||
if (cam->current_image->image_norm != NULL && cam->stream.norm.consumed) {
|
||||
cam->stream.norm.jpg_sz = pic_put_memory(cam
|
||||
,cam->stream.norm.jpg_data
|
||||
,cam->imgs.size_norm
|
||||
,cam->current_image->image_norm
|
||||
,cam->conf->stream_quality
|
||||
,cam->imgs.width
|
||||
,cam->imgs.height);
|
||||
cam->stream.norm.consumed = false;
|
||||
}
|
||||
}
|
||||
if ((cam->stream.norm.ts_cnct > 0) || (cam->stream.norm.all_cnct > 0)) {
|
||||
if (cam->stream.norm.img_data == NULL) {
|
||||
cam->stream.norm.img_data =(unsigned char*)mymalloc(cam->imgs.size_norm);
|
||||
}
|
||||
memcpy(cam->stream.norm.img_data, cam->current_image->image_norm, cam->imgs.size_norm);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a substream image from the motion loop and compress it*/
|
||||
static void webu_getimg_sub(ctx_dev *cam)
|
||||
{
|
||||
int subsize;
|
||||
|
||||
if ((cam->stream.sub.jpg_cnct == 0) &&
|
||||
(cam->stream.sub.ts_cnct == 0) &&
|
||||
(cam->stream.sub.all_cnct == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cam->stream.sub.jpg_cnct > 0) {
|
||||
if (cam->stream.sub.jpg_data == NULL) {
|
||||
cam->stream.sub.jpg_data =(unsigned char*)mymalloc(cam->imgs.size_norm);
|
||||
}
|
||||
if (cam->current_image->image_norm != NULL && cam->stream.sub.consumed) {
|
||||
/* Resulting substream image must be multiple of 8 */
|
||||
if (((cam->imgs.width % 16) == 0) &&
|
||||
((cam->imgs.height % 16) == 0)) {
|
||||
|
||||
subsize = ((cam->imgs.width / 2) * (cam->imgs.height / 2) * 3 / 2);
|
||||
if (cam->imgs.image_substream == NULL) {
|
||||
cam->imgs.image_substream =(unsigned char*)mymalloc(subsize);
|
||||
}
|
||||
pic_scale_img(cam->imgs.width
|
||||
,cam->imgs.height
|
||||
,cam->current_image->image_norm
|
||||
,cam->imgs.image_substream);
|
||||
cam->stream.sub.jpg_sz = pic_put_memory(cam
|
||||
,cam->stream.sub.jpg_data
|
||||
,subsize
|
||||
,cam->imgs.image_substream
|
||||
,cam->conf->stream_quality
|
||||
,(cam->imgs.width / 2)
|
||||
,(cam->imgs.height / 2));
|
||||
} else {
|
||||
/* Substream was not multiple of 8 so send full image*/
|
||||
cam->stream.sub.jpg_sz = pic_put_memory(cam
|
||||
,cam->stream.sub.jpg_data
|
||||
,cam->imgs.size_norm
|
||||
,cam->current_image->image_norm
|
||||
,cam->conf->stream_quality
|
||||
,cam->imgs.width
|
||||
,cam->imgs.height);
|
||||
}
|
||||
cam->stream.sub.consumed = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((cam->stream.sub.ts_cnct > 0) || (cam->stream.sub.all_cnct > 0)) {
|
||||
if (cam->stream.sub.img_data == NULL) {
|
||||
cam->stream.sub.img_data =(unsigned char*)mymalloc(cam->imgs.size_norm);
|
||||
}
|
||||
if (((cam->imgs.width % 16) == 0) &&
|
||||
((cam->imgs.height % 16) == 0)) {
|
||||
subsize = ((cam->imgs.width / 2) * (cam->imgs.height / 2) * 3 / 2);
|
||||
if (cam->imgs.image_substream == NULL) {
|
||||
cam->imgs.image_substream =(unsigned char*)mymalloc(subsize);
|
||||
}
|
||||
pic_scale_img(cam->imgs.width
|
||||
,cam->imgs.height
|
||||
,cam->current_image->image_norm
|
||||
,cam->imgs.image_substream);
|
||||
memcpy(cam->stream.sub.img_data, cam->imgs.image_substream, subsize);
|
||||
} else {
|
||||
memcpy(cam->stream.sub.img_data, cam->current_image->image_norm, cam->imgs.size_norm);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Get a motion image from the motion loop and compress it*/
|
||||
static void webu_getimg_motion(ctx_dev *cam)
|
||||
{
|
||||
if ((cam->stream.motion.jpg_cnct == 0) &&
|
||||
(cam->stream.motion.ts_cnct == 0) &&
|
||||
(cam->stream.motion.all_cnct == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cam->stream.motion.jpg_cnct > 0) {
|
||||
if (cam->stream.motion.jpg_data == NULL) {
|
||||
cam->stream.motion.jpg_data =(unsigned char*)mymalloc(cam->imgs.size_norm);
|
||||
}
|
||||
if (cam->imgs.image_motion.image_norm != NULL && cam->stream.motion.consumed) {
|
||||
cam->stream.motion.jpg_sz = pic_put_memory(cam
|
||||
,cam->stream.motion.jpg_data
|
||||
,cam->imgs.size_norm
|
||||
,cam->imgs.image_motion.image_norm
|
||||
,cam->conf->stream_quality
|
||||
,cam->imgs.width
|
||||
,cam->imgs.height);
|
||||
cam->stream.motion.consumed = false;
|
||||
}
|
||||
}
|
||||
if ((cam->stream.motion.ts_cnct > 0) || (cam->stream.motion.all_cnct > 0)) {
|
||||
if (cam->stream.motion.img_data == NULL) {
|
||||
cam->stream.motion.img_data =(unsigned char*)mymalloc(cam->imgs.size_norm);
|
||||
}
|
||||
memcpy(cam->stream.motion.img_data
|
||||
, cam->imgs.image_motion.image_norm
|
||||
, cam->imgs.size_norm);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a source image from the motion loop and compress it*/
|
||||
static void webu_getimg_source(ctx_dev *cam)
|
||||
{
|
||||
if ((cam->stream.source.jpg_cnct == 0) &&
|
||||
(cam->stream.source.ts_cnct == 0) &&
|
||||
(cam->stream.source.all_cnct == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cam->stream.source.jpg_cnct > 0) {
|
||||
if (cam->stream.source.jpg_data == NULL) {
|
||||
cam->stream.source.jpg_data =(unsigned char*)mymalloc(cam->imgs.size_norm);
|
||||
}
|
||||
if (cam->imgs.image_virgin != NULL && cam->stream.source.consumed) {
|
||||
cam->stream.source.jpg_sz = pic_put_memory(cam
|
||||
,cam->stream.source.jpg_data
|
||||
,cam->imgs.size_norm
|
||||
,cam->imgs.image_virgin
|
||||
,cam->conf->stream_quality
|
||||
,cam->imgs.width
|
||||
,cam->imgs.height);
|
||||
cam->stream.source.consumed = false;
|
||||
}
|
||||
}
|
||||
if ((cam->stream.source.ts_cnct > 0) || (cam->stream.source.all_cnct > 0)) {
|
||||
if (cam->stream.source.img_data == NULL) {
|
||||
cam->stream.source.img_data =(unsigned char*)mymalloc(cam->imgs.size_norm);
|
||||
}
|
||||
memcpy(cam->stream.source.img_data
|
||||
, cam->imgs.image_virgin
|
||||
, cam->imgs.size_norm);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a secondary image from the motion loop and compress it*/
|
||||
static void webu_getimg_secondary(ctx_dev *cam)
|
||||
{
|
||||
if ((cam->stream.secondary.jpg_cnct == 0) &&
|
||||
(cam->stream.secondary.ts_cnct == 0) &&
|
||||
(cam->stream.secondary.all_cnct == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cam->stream.secondary.jpg_cnct > 0) {
|
||||
if (cam->imgs.size_secondary>0) {
|
||||
pthread_mutex_lock(&cam->algsec->mutex);
|
||||
if (cam->stream.secondary.jpg_data == NULL) {
|
||||
cam->stream.secondary.jpg_data =(unsigned char*)mymalloc(cam->imgs.size_norm);
|
||||
}
|
||||
|
||||
memcpy(cam->stream.secondary.jpg_data,cam->imgs.image_secondary,cam->imgs.size_secondary);
|
||||
cam->stream.secondary.jpg_sz = cam->imgs.size_secondary;
|
||||
pthread_mutex_unlock(&cam->algsec->mutex);
|
||||
} else {
|
||||
myfree(&cam->stream.secondary.jpg_data);
|
||||
}
|
||||
}
|
||||
if ((cam->stream.secondary.ts_cnct > 0) || (cam->stream.secondary.all_cnct > 0)) {
|
||||
if (cam->stream.secondary.img_data == NULL) {
|
||||
cam->stream.secondary.img_data =(unsigned char*)mymalloc(cam->imgs.size_norm);
|
||||
}
|
||||
memcpy(cam->stream.secondary.img_data
|
||||
, cam->current_image->image_norm, cam->imgs.size_norm);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Get image from the motion loop and compress it*/
|
||||
void webu_getimg_main(ctx_dev *cam)
|
||||
{
|
||||
/*This is on the motion_loop thread */
|
||||
pthread_mutex_lock(&cam->stream.mutex);
|
||||
webu_getimg_norm(cam);
|
||||
webu_getimg_sub(cam);
|
||||
webu_getimg_motion(cam);
|
||||
webu_getimg_source(cam);
|
||||
webu_getimg_secondary(cam);
|
||||
pthread_mutex_unlock(&cam->stream.mutex);
|
||||
}
|
||||
26
src/webu_getimg.hpp
Normal file
26
src/webu_getimg.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* This file is part of MotionPlus.
|
||||
*
|
||||
* MotionPlus is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MotionPlus is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with MotionPlus. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_WEBU_GETIMG_HPP_
|
||||
#define _INCLUDE_WEBU_GETIMG_HPP_
|
||||
|
||||
void webu_getimg_init(ctx_dev *cam);
|
||||
void webu_getimg_deinit(ctx_dev *cam);
|
||||
void webu_getimg_main(ctx_dev *cam);
|
||||
|
||||
#endif
|
||||
@@ -21,13 +21,14 @@
|
||||
#include "logger.hpp"
|
||||
#include "util.hpp"
|
||||
#include "webu.hpp"
|
||||
#include "webu_common.hpp"
|
||||
#include "webu_ans.hpp"
|
||||
#include "webu_html.hpp"
|
||||
|
||||
|
||||
/* Create the CSS styles used in the navigation bar/side of the page */
|
||||
static void webu_html_style_navbar(ctx_webui *webui)
|
||||
void cls_webu_html::style_navbar()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" .sidenav {\n"
|
||||
" height: 100%;\n"
|
||||
" width: 10rem;\n"
|
||||
@@ -108,9 +109,9 @@ static void webu_html_style_navbar(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the css styles used in the config sections */
|
||||
static void webu_html_style_config(ctx_webui *webui)
|
||||
void cls_webu_html::style_config()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" .cls_config {\n"
|
||||
" background-color: #000000;\n"
|
||||
" color: #fff;\n"
|
||||
@@ -221,10 +222,9 @@ static void webu_html_style_config(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Write out the starting style section of the web page */
|
||||
static void webu_html_style_base(ctx_webui *webui)
|
||||
void cls_webu_html::style_base()
|
||||
{
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" * {\n"
|
||||
" margin: 0;\n"
|
||||
" padding: 0;\n"
|
||||
@@ -277,39 +277,36 @@ static void webu_html_style_base(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Write out the style section of the web page */
|
||||
static void webu_html_style(ctx_webui *webui)
|
||||
void cls_webu_html::style()
|
||||
{
|
||||
webui->resp_page += " <style>\n";
|
||||
webua->resp_page += " <style>\n";
|
||||
|
||||
webu_html_style_base(webui);
|
||||
style_base();
|
||||
|
||||
webu_html_style_navbar(webui);
|
||||
style_navbar();
|
||||
|
||||
webu_html_style_config(webui);
|
||||
|
||||
webui->resp_page += " </style>\n";
|
||||
style_config();
|
||||
|
||||
webua->resp_page += " </style>\n";
|
||||
}
|
||||
|
||||
/* Create the header section of the page */
|
||||
static void webu_html_head(ctx_webui *webui)
|
||||
void cls_webu_html::head()
|
||||
{
|
||||
|
||||
webui->resp_page += "<head> \n"
|
||||
webua->resp_page += "<head> \n"
|
||||
"<meta charset='UTF-8'> \n"
|
||||
"<title>MotionPlus</title> \n"
|
||||
"<meta name='viewport' content='width=device-width, initial-scale=1'> \n";
|
||||
|
||||
webu_html_style(webui);
|
||||
|
||||
webui->resp_page += "</head>\n\n";
|
||||
style();
|
||||
|
||||
webua->resp_page += "</head>\n\n";
|
||||
}
|
||||
|
||||
/* Create the navigation bar section of the page */
|
||||
static void webu_html_navbar(ctx_webui *webui)
|
||||
void cls_webu_html::navbar()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" <div id=\"divnav_main\" class=\"sidenav\">\n"
|
||||
" <a class='closebtn' onclick='nav_close()'>X</a>\n"
|
||||
" <div id=\"divnav_version\">\n"
|
||||
@@ -340,13 +337,12 @@ static void webu_html_navbar(ctx_webui *webui)
|
||||
" <!-- Filled in by script -->\n"
|
||||
" </div>\n"
|
||||
" </div>\n\n";
|
||||
|
||||
}
|
||||
|
||||
/* Create the body main section of the page */
|
||||
static void webu_html_divmain(ctx_webui *webui)
|
||||
void cls_webu_html::divmain()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" <div id='divmain' style='margin-left:10rem' >\n"
|
||||
" <button id='menu_btn' \n"
|
||||
" onclick='nav_open();' \n"
|
||||
@@ -363,13 +359,12 @@ static void webu_html_divmain(ctx_webui *webui)
|
||||
" <!-- Filled in by script -->\n"
|
||||
" </div>\n\n"
|
||||
" </div>\n\n";
|
||||
|
||||
}
|
||||
|
||||
/* Create the javascript function send_config */
|
||||
static void webu_html_script_nav(ctx_webui *webui)
|
||||
void cls_webu_html::script_nav()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function nav_open() {\n"
|
||||
" document.getElementById('divnav_main').style.width = '10rem';\n"
|
||||
" document.getElementById('divmain').style.marginLeft = '10rem';\n"
|
||||
@@ -384,9 +379,9 @@ static void webu_html_script_nav(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function send_config */
|
||||
static void webu_html_script_send_config(ctx_webui *webui)
|
||||
void cls_webu_html::script_send_config()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function send_config(category) {\n"
|
||||
" var formData = new FormData();\n"
|
||||
" var request = new XMLHttpRequest();\n"
|
||||
@@ -426,9 +421,9 @@ static void webu_html_script_send_config(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the send_action javascript function */
|
||||
static void webu_html_script_send_action(ctx_webui *webui)
|
||||
void cls_webu_html::script_send_action()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function send_action(actval) {\n\n"
|
||||
|
||||
" var dsp_cam = document.getElementById('div_cam').style.display;\n"
|
||||
@@ -459,9 +454,9 @@ static void webu_html_script_send_action(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the send_reload javascript function */
|
||||
static void webu_html_script_send_reload(ctx_webui *webui)
|
||||
void cls_webu_html::script_send_reload()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function send_reload(actval) {\n\n"
|
||||
" var formData = new FormData();\n"
|
||||
" var request = new XMLHttpRequest();\n"
|
||||
@@ -505,9 +500,9 @@ static void webu_html_script_send_reload(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function dropchange_cam */
|
||||
static void webu_html_script_dropchange_cam(ctx_webui *webui)
|
||||
void cls_webu_html::script_dropchange_cam()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function dropchange_cam(camobj) {\n"
|
||||
" var indx;\n\n"
|
||||
|
||||
@@ -529,9 +524,9 @@ static void webu_html_script_dropchange_cam(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function config_hideall */
|
||||
static void webu_html_script_config_hideall(ctx_webui *webui)
|
||||
void cls_webu_html::script_config_hideall()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function config_hideall() {\n"
|
||||
" var sect = document.getElementsByClassName('cls_config');\n"
|
||||
" for (var i = 0; i < sect.length; i++) {\n"
|
||||
@@ -542,9 +537,9 @@ static void webu_html_script_config_hideall(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function config_click */
|
||||
static void webu_html_script_config_click(ctx_webui *webui)
|
||||
void cls_webu_html::script_config_click()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function config_click(actval) {\n"
|
||||
" config_hideall();\n"
|
||||
" document.getElementById('div_cam').style.display='none';\n"
|
||||
@@ -556,9 +551,9 @@ static void webu_html_script_config_click(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function assign_camid */
|
||||
static void webu_html_script_assign_camid(ctx_webui *webui)
|
||||
void cls_webu_html::script_assign_camid()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function assign_camid() {\n"
|
||||
" if (gIndxCam == -1 ) {\n"
|
||||
" camid = 0;\n"
|
||||
@@ -567,25 +562,22 @@ static void webu_html_script_assign_camid(ctx_webui *webui)
|
||||
" }\n\n"
|
||||
" return camid; \n"
|
||||
" }\n\n";
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Create the javascript function assign_version */
|
||||
static void webu_html_script_assign_version(ctx_webui *webui)
|
||||
void cls_webu_html::script_assign_version()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function assign_version() {\n"
|
||||
" var verstr ='<a>MotionPlus \\n'+pData['version'] +'</a>';\n"
|
||||
" document.getElementById('divnav_version').innerHTML = verstr;\n"
|
||||
" }\n\n";
|
||||
|
||||
}
|
||||
|
||||
/* Create the javascript function assign_cams */
|
||||
static void webu_html_script_assign_cams(ctx_webui *webui)
|
||||
void cls_webu_html::script_assign_cams()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function assign_cams() {\n"
|
||||
" var camcnt = pData['cameras']['count'];\n"
|
||||
" var indx = 0;\n"
|
||||
@@ -626,12 +618,12 @@ static void webu_html_script_assign_cams(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function assign_actions */
|
||||
static void webu_html_script_assign_actions(ctx_webui *webui)
|
||||
void cls_webu_html::script_assign_actions()
|
||||
{
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function assign_actions() {\n"
|
||||
" var html_actions = \"\\n\";\n"
|
||||
" html_actions += \" \";\n";
|
||||
@@ -639,14 +631,14 @@ static void webu_html_script_assign_actions(ctx_webui *webui)
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
if ((it->param_name == "snapshot") &&
|
||||
(it->param_value == "on")) {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" html_actions += \"<a onclick=\\\"send_action(\";\n"
|
||||
" html_actions += \"'snapshot');\\\">\";\n"
|
||||
" html_actions += \"Snapshot</a>\\n\";\n\n"
|
||||
;
|
||||
} else if ((it->param_name == "event") &&
|
||||
(it->param_value == "on")) {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" html_actions += \"<a onclick=\\\"send_action(\";\n"
|
||||
" html_actions += \"'eventstart');\\\">\";\n"
|
||||
" html_actions += \"Start Event</a>\\n\";\n\n"
|
||||
@@ -657,7 +649,7 @@ static void webu_html_script_assign_actions(ctx_webui *webui)
|
||||
;
|
||||
} else if ((it->param_name == "pause") &&
|
||||
(it->param_value == "on")) {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" html_actions += \"<a onclick=\\\"send_action(\";\n"
|
||||
" html_actions += \"'pause');\\\">\";\n"
|
||||
" html_actions += \"Pause</a>\\n\";\n\n"
|
||||
@@ -668,42 +660,42 @@ static void webu_html_script_assign_actions(ctx_webui *webui)
|
||||
;
|
||||
} else if ((it->param_name == "camera_add") &&
|
||||
(it->param_value == "on")) {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" html_actions += \"<a onclick=\\\"send_reload(\";\n"
|
||||
" html_actions += \"'camera_add');\\\">\";\n"
|
||||
" html_actions += \"Add Camera</a>\\n\";\n\n"
|
||||
;
|
||||
} else if ((it->param_name == "camera_delete") &&
|
||||
(it->param_value == "on")) {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" html_actions += \"<a onclick=\\\"send_reload(\";\n"
|
||||
" html_actions += \"'camera_delete');\\\">\";\n"
|
||||
" html_actions += \"Delete Camera</a>\\n\";\n\n"
|
||||
;
|
||||
} else if ((it->param_name == "config_write") &&
|
||||
(it->param_value == "on")) {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" html_actions += \"<a onclick=\\\"send_action(\";\n"
|
||||
" html_actions += \"'config_write');\\\">\";\n"
|
||||
" html_actions += \"Save Config</a>\\n\";\n\n"
|
||||
;
|
||||
} else if ((it->param_name == "stop") &&
|
||||
(it->param_value == "on")) {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" html_actions += \"<a onclick=\\\"send_action(\";\n"
|
||||
" html_actions += \"'stop');\\\">\";\n"
|
||||
" html_actions += \"Stop</a>\\n\";\n\n"
|
||||
;
|
||||
} else if ((it->param_name == "restart") &&
|
||||
(it->param_value == "on")) {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" html_actions += \"<a onclick=\\\"send_action(\";\n"
|
||||
" html_actions += \"'restart');\\\">\";\n"
|
||||
" html_actions += \"Start/Restart</a>\\n\";\n\n"
|
||||
;
|
||||
} else if ((it->param_name == "action_user") &&
|
||||
(it->param_value == "on")) {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" html_actions += \"<a onclick=\\\"send_action(\";\n"
|
||||
" html_actions += \"'action_user');\\\">\";\n"
|
||||
" html_actions += \"User Action</a>\\n\";\n\n"
|
||||
@@ -711,20 +703,17 @@ static void webu_html_script_assign_actions(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" document.getElementById(\"divnav_actions\").innerHTML = html_actions;\n\n"
|
||||
" return;\n"
|
||||
|
||||
" }\n\n";
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Create the javascript function assign_vals */
|
||||
static void webu_html_script_assign_vals(ctx_webui *webui)
|
||||
void cls_webu_html::script_assign_vals()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function assign_vals(camid) {\n"
|
||||
" var pCfg;\n\n"
|
||||
|
||||
@@ -755,9 +744,9 @@ static void webu_html_script_assign_vals(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function assign_config_nav */
|
||||
static void webu_html_script_assign_config_nav(ctx_webui *webui)
|
||||
void cls_webu_html::script_assign_config_nav()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function assign_config_nav() {\n"
|
||||
" var pCfg = pData['configuration']['default'];\n"
|
||||
" var pCat = pData['categories'];\n"
|
||||
@@ -775,9 +764,9 @@ static void webu_html_script_assign_config_nav(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function assign_config_item */
|
||||
static void webu_html_script_assign_config_item(ctx_webui *webui)
|
||||
void cls_webu_html::script_assign_config_item()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function assign_config_item(jkey) {\n"
|
||||
" var pCfg = pData['configuration']['default'];\n"
|
||||
" var html_cfg = \"\";\n"
|
||||
@@ -814,9 +803,9 @@ static void webu_html_script_assign_config_item(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function assign_config_cat */
|
||||
static void webu_html_script_assign_config_cat(ctx_webui *webui)
|
||||
void cls_webu_html::script_assign_config_cat()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function assign_config_cat(jcat) {\n"
|
||||
" var pCfg = pData['configuration']['default'];\n"
|
||||
" var pCat = pData['categories'];\n"
|
||||
@@ -851,10 +840,9 @@ static void webu_html_script_assign_config_cat(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function assign_config */
|
||||
static void webu_html_script_assign_config(ctx_webui *webui)
|
||||
void cls_webu_html::script_assign_config()
|
||||
{
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function assign_config() {\n"
|
||||
" var pCat = pData['categories'];\n"
|
||||
" var html_cfg = \"\";\n\n"
|
||||
@@ -871,9 +859,9 @@ static void webu_html_script_assign_config(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function init_form */
|
||||
static void webu_html_script_initform(ctx_webui *webui)
|
||||
void cls_webu_html::script_initform()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function initform() {\n"
|
||||
" var xmlhttp = new XMLHttpRequest();\n\n"
|
||||
|
||||
@@ -903,9 +891,9 @@ static void webu_html_script_initform(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function display_cameras */
|
||||
static void webu_html_script_display_cameras(ctx_webui *webui)
|
||||
void cls_webu_html::script_display_cameras()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function display_cameras() {\n"
|
||||
" document.getElementById('divnav_config').style.display = 'none';\n"
|
||||
" document.getElementById('divnav_actions').style.display = 'none';\n"
|
||||
@@ -919,9 +907,9 @@ static void webu_html_script_display_cameras(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function display_config */
|
||||
static void webu_html_script_display_config(ctx_webui *webui)
|
||||
void cls_webu_html::script_display_config()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function display_config() {\n"
|
||||
" document.getElementById('divnav_cam').style.display = 'none';\n"
|
||||
" document.getElementById('divnav_actions').style.display = 'none';\n"
|
||||
@@ -937,9 +925,9 @@ static void webu_html_script_display_config(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function display_movies */
|
||||
static void webu_html_script_display_movies(ctx_webui *webui)
|
||||
void cls_webu_html::script_display_movies()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function display_movies() {\n"
|
||||
" document.getElementById('divnav_cam').style.display = 'none';\n"
|
||||
" document.getElementById('divnav_actions').style.display = 'none';\n"
|
||||
@@ -955,13 +943,13 @@ static void webu_html_script_display_movies(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the javascript function display_actions */
|
||||
static void webu_html_script_display_actions(ctx_webui *webui)
|
||||
void cls_webu_html::script_display_actions()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function display_actions() {\n"
|
||||
" document.getElementById('divnav_cam').style.display = 'none';\n"
|
||||
" document.getElementById('divnav_config').style.display = 'none';\n"
|
||||
" if (document.getElementById('divnav_actions').style.display == 'block') {\n"
|
||||
" if (document.getElementById('divnav_actions').style.display == 'block') {\n"
|
||||
" document.getElementById('divnav_actions').style.display = 'none';\n"
|
||||
" } else {\n"
|
||||
" document.getElementById('divnav_actions').style.display = 'block';\n"
|
||||
@@ -971,10 +959,9 @@ static void webu_html_script_display_actions(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the camera_buttons_ptz javascript function */
|
||||
static void webu_html_script_camera_buttons_ptz(ctx_webui *webui)
|
||||
void cls_webu_html::script_camera_buttons_ptz()
|
||||
{
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function camera_buttons_ptz() {\n\n"
|
||||
" var html_preview = \"\";\n"
|
||||
|
||||
@@ -1016,13 +1003,12 @@ static void webu_html_script_camera_buttons_ptz(ctx_webui *webui)
|
||||
" return html_preview;\n\n"
|
||||
|
||||
" }\n\n";
|
||||
|
||||
}
|
||||
|
||||
/* Create the image_pantilt javascript function */
|
||||
static void webu_html_script_image_pantilt(ctx_webui *webui)
|
||||
void cls_webu_html::script_image_pantilt()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function image_pantilt() {\n\n"
|
||||
" if (gIndxCam == -1 ) {\n"
|
||||
" return;\n"
|
||||
@@ -1046,21 +1032,19 @@ static void webu_html_script_image_pantilt(ctx_webui *webui)
|
||||
" }\n"
|
||||
" });\n"
|
||||
" }\n\n";
|
||||
|
||||
}
|
||||
|
||||
/* Create the cams_reset javascript function */
|
||||
static void webu_html_script_cams_reset(ctx_webui *webui)
|
||||
void cls_webu_html::script_cams_reset()
|
||||
{
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function cams_timer_stop() {\n"
|
||||
" clearInterval(cams_one_timer);\n"
|
||||
" clearInterval(cams_all_timer);\n"
|
||||
" clearInterval(cams_scan_timer);\n"
|
||||
" }\n\n";
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function cams_reset() {\n"
|
||||
" var indx, camcnt;\n"
|
||||
" camcnt = pData['cameras']['count'];\n"
|
||||
@@ -1070,14 +1054,12 @@ static void webu_html_script_cams_reset(ctx_webui *webui)
|
||||
" }\n"
|
||||
" }\n"
|
||||
" } \n\n";
|
||||
|
||||
}
|
||||
|
||||
/* Create the cams_one_click javascript function */
|
||||
static void webu_html_script_cams_one_click(ctx_webui *webui)
|
||||
void cls_webu_html::script_cams_one_click()
|
||||
{
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function cams_one_click(index_cam) {\n\n"
|
||||
" var html_preview = \"\";\n"
|
||||
" var camid;\n\n"
|
||||
@@ -1114,14 +1096,12 @@ static void webu_html_script_cams_one_click(ctx_webui *webui)
|
||||
" image_pantilt();\n\n"
|
||||
" cams_one_timer = setInterval(cams_one_fnc, 1000);\n\n"
|
||||
" }\n\n";
|
||||
|
||||
}
|
||||
|
||||
/* Create the cams_all_click javascript function */
|
||||
static void webu_html_script_cams_all_click(ctx_webui *webui)
|
||||
void cls_webu_html::script_cams_all_click()
|
||||
{
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function cams_all_click() {\n\n"
|
||||
" var html_preview = \"\";\n"
|
||||
" var indx, chk;\n"
|
||||
@@ -1182,10 +1162,11 @@ static void webu_html_script_cams_all_click(ctx_webui *webui)
|
||||
" cams_all_timer = setInterval(cams_all_fnc, 1000);\n\n"
|
||||
" }\n\n";
|
||||
}
|
||||
|
||||
/* Create the movies_page javascript function */
|
||||
static void webu_html_script_movies_page(ctx_webui *webui)
|
||||
void cls_webu_html::script_movies_page()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function movies_page() {\n\n"
|
||||
" var html_tab = \"<div>\";\n"
|
||||
" var indx, movcnt, camid, uri;\n"
|
||||
@@ -1256,14 +1237,12 @@ static void webu_html_script_movies_page(ctx_webui *webui)
|
||||
" document.getElementById('div_movies').style.display='block';\n"
|
||||
" document.getElementById('div_movies').innerHTML = html_tab;\n\n"
|
||||
" }\n\n";
|
||||
|
||||
}
|
||||
|
||||
/* Create the movies_page javascript function */
|
||||
static void webu_html_script_movies_click(ctx_webui *webui)
|
||||
void cls_webu_html::script_movies_click()
|
||||
{
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function movies_click(index_cam) {\n"
|
||||
" var camid, indx, camcnt, uri;\n\n"
|
||||
|
||||
@@ -1283,12 +1262,12 @@ static void webu_html_script_movies_click(ctx_webui *webui)
|
||||
" xmlhttp.open('GET', uri);\n"
|
||||
" xmlhttp.send();\n"
|
||||
" }\n\n";
|
||||
|
||||
}
|
||||
|
||||
/* Create the cams_scan_click javascript function */
|
||||
static void webu_html_script_cams_scan_click(ctx_webui *webui)
|
||||
void cls_webu_html::script_cams_scan_click()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function cams_scan_click() {\n\n"
|
||||
" cams_timer_stop();\n\n"
|
||||
" gIndxCam = -1; \n"
|
||||
@@ -1298,9 +1277,9 @@ static void webu_html_script_cams_scan_click(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Create the cams_one_fnc javascript function */
|
||||
static void webu_html_script_cams_one_fnc(ctx_webui *webui)
|
||||
void cls_webu_html::script_cams_one_fnc()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function cams_one_fnc () {\n"
|
||||
" var img = new Image();\n"
|
||||
" var camid;\n\n"
|
||||
@@ -1314,13 +1293,12 @@ static void webu_html_script_cams_one_fnc(ctx_webui *webui)
|
||||
" document.getElementById('pic'+gIndxCam).src = pic_url[0];\n"
|
||||
" }\n"
|
||||
" }\n\n ";
|
||||
|
||||
}
|
||||
|
||||
/* Create the cams_all_fnc javascript function */
|
||||
static void webu_html_script_cams_all_fnc(ctx_webui *webui)
|
||||
void cls_webu_html::script_cams_all_fnc()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function cams_all_fnc () {\n"
|
||||
" var previndx = gGetImgs;\n"
|
||||
" gGetImgs++;\n"
|
||||
@@ -1335,13 +1313,12 @@ static void webu_html_script_cams_all_fnc(ctx_webui *webui)
|
||||
" pData['cameras'][gGetImgs]['url'] + \"mjpg/stream\";\n"
|
||||
" }\n"
|
||||
" }\n\n";
|
||||
|
||||
}
|
||||
|
||||
/* Create the scancam_function javascript function */
|
||||
static void webu_html_script_cams_scan_fnc(ctx_webui *webui)
|
||||
void cls_webu_html::script_cams_scan_fnc()
|
||||
{
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
" function cams_scan_fnc() {\n"
|
||||
" var html_preview = \"\";\n"
|
||||
" var camid;\n"
|
||||
@@ -1379,131 +1356,131 @@ static void webu_html_script_cams_scan_fnc(ctx_webui *webui)
|
||||
" document.getElementById('div_cam').style.display='block';\n"
|
||||
" document.getElementById('div_cam').innerHTML = html_preview;\n"
|
||||
" };\n\n";
|
||||
|
||||
}
|
||||
|
||||
/* Call all the functions to create the java scripts of page*/
|
||||
static void webu_html_script(ctx_webui *webui)
|
||||
void cls_webu_html::script()
|
||||
{
|
||||
webui->resp_page += " <script>\n"
|
||||
webua->resp_page += " <script>\n"
|
||||
" var pData, pMovies, pHostFull;\n"
|
||||
" var gIndxScan, gIndxCam, gGetImgs;\n"
|
||||
" var pic_url = Array(4);\n"
|
||||
" var cams_scan_timer, cams_all_timer, cams_one_timer;\n\n";
|
||||
|
||||
webu_html_script_nav(webui);
|
||||
script_nav();
|
||||
|
||||
webu_html_script_send_config(webui);
|
||||
webu_html_script_send_action(webui);
|
||||
webu_html_script_send_reload(webui);
|
||||
script_send_config();
|
||||
script_send_action();
|
||||
script_send_reload();
|
||||
|
||||
webu_html_script_dropchange_cam(webui);
|
||||
webu_html_script_config_hideall(webui);
|
||||
webu_html_script_config_click(webui);
|
||||
script_dropchange_cam();
|
||||
script_config_hideall();
|
||||
script_config_click();
|
||||
|
||||
webu_html_script_assign_camid(webui);
|
||||
webu_html_script_assign_version(webui);
|
||||
webu_html_script_assign_cams(webui);
|
||||
webu_html_script_assign_actions(webui);
|
||||
webu_html_script_assign_vals(webui);
|
||||
webu_html_script_assign_config_nav(webui);
|
||||
webu_html_script_assign_config_item(webui);
|
||||
webu_html_script_assign_config_cat(webui);
|
||||
webu_html_script_assign_config(webui);
|
||||
script_assign_camid();
|
||||
script_assign_version();
|
||||
script_assign_cams();
|
||||
script_assign_actions();
|
||||
script_assign_vals();
|
||||
script_assign_config_nav();
|
||||
script_assign_config_item();
|
||||
script_assign_config_cat();
|
||||
script_assign_config();
|
||||
|
||||
webu_html_script_initform(webui);
|
||||
webu_html_script_display_cameras(webui);
|
||||
webu_html_script_display_config(webui);
|
||||
webu_html_script_display_movies(webui);
|
||||
webu_html_script_display_actions(webui);
|
||||
script_initform();
|
||||
script_display_cameras();
|
||||
script_display_config();
|
||||
script_display_movies();
|
||||
script_display_actions();
|
||||
|
||||
webu_html_script_camera_buttons_ptz(webui);
|
||||
webu_html_script_image_pantilt(webui);
|
||||
script_camera_buttons_ptz();
|
||||
script_image_pantilt();
|
||||
|
||||
webu_html_script_cams_reset(webui);
|
||||
script_cams_reset();
|
||||
|
||||
webu_html_script_cams_all_click(webui);
|
||||
webu_html_script_cams_one_click(webui);
|
||||
webu_html_script_cams_scan_click(webui);
|
||||
script_cams_all_click();
|
||||
script_cams_one_click();
|
||||
script_cams_scan_click();
|
||||
|
||||
webu_html_script_cams_one_fnc(webui);
|
||||
webu_html_script_cams_all_fnc(webui);
|
||||
webu_html_script_cams_scan_fnc(webui);
|
||||
script_cams_one_fnc();
|
||||
script_cams_all_fnc();
|
||||
script_cams_scan_fnc();
|
||||
|
||||
webu_html_script_movies_page(webui);
|
||||
webu_html_script_movies_click(webui);
|
||||
|
||||
webui->resp_page += " </script>\n\n";
|
||||
script_movies_page();
|
||||
script_movies_click();
|
||||
|
||||
webua->resp_page += " </script>\n\n";
|
||||
}
|
||||
|
||||
/* Create the body section of the web page */
|
||||
static void webu_html_body(ctx_webui *webui)
|
||||
void cls_webu_html::body()
|
||||
{
|
||||
webui->resp_page += "<body class='body' onload='initform()'>\n";
|
||||
webua->resp_page += "<body class='body' onload='initform()'>\n";
|
||||
|
||||
webu_html_navbar(webui);
|
||||
navbar();
|
||||
|
||||
webu_html_divmain(webui);
|
||||
divmain();
|
||||
|
||||
webu_html_script(webui);
|
||||
|
||||
webui->resp_page += "</body>\n";
|
||||
script();
|
||||
|
||||
webua->resp_page += "</body>\n";
|
||||
}
|
||||
|
||||
/* Create the default motionplus page */
|
||||
void webu_html_page(ctx_webui *webui)
|
||||
void cls_webu_html::default_page()
|
||||
{
|
||||
webui->resp_page += "<!DOCTYPE html>\n"
|
||||
"<html lang='" + webui->lang + "'>\n";
|
||||
|
||||
webu_html_head(webui);
|
||||
|
||||
webu_html_body(webui);
|
||||
|
||||
webui->resp_page += "</html>\n";
|
||||
webua->resp_page += "<!DOCTYPE html>\n"
|
||||
"<html lang='" + webua->lang + "'>\n";
|
||||
head();
|
||||
body();
|
||||
webua->resp_page += "</html>\n";
|
||||
}
|
||||
|
||||
/*Create the bad request page*/
|
||||
void webu_html_badreq(ctx_webui *webui)
|
||||
{
|
||||
webui->resp_page =
|
||||
"<!DOCTYPE html>\n"
|
||||
"<html>\n"
|
||||
"<body>\n"
|
||||
"<p>Bad Request</p>\n"
|
||||
"<p>The server did not understand your request.</p>\n"
|
||||
"</body>\n"
|
||||
"</html>\n";
|
||||
|
||||
}
|
||||
|
||||
/* Load a user provided html page */
|
||||
void webu_html_user(ctx_webui *webui)
|
||||
void cls_webu_html::user_page()
|
||||
{
|
||||
char response[PATH_MAX];
|
||||
FILE *fp = NULL;
|
||||
|
||||
fp = myfopen(webui->motapp->conf->webcontrol_html.c_str(), "re");
|
||||
|
||||
webua->resp_page = "";
|
||||
fp = myfopen(app->conf->webcontrol_html.c_str(), "re");
|
||||
if (fp == NULL) {
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO
|
||||
, _("Invalid user html file: %s")
|
||||
, webui->motapp->conf->webcontrol_html.c_str());
|
||||
|
||||
webu_html_badreq(webui);
|
||||
|
||||
return;
|
||||
, app->conf->webcontrol_html.c_str());
|
||||
} else {
|
||||
while (fgets(response, PATH_MAX-1, fp)) {
|
||||
webua->resp_page += response;
|
||||
}
|
||||
myfclose(fp);
|
||||
}
|
||||
|
||||
webui->resp_page = "";
|
||||
while (fgets(response, PATH_MAX-1, fp)) {
|
||||
webui->resp_page += response;
|
||||
}
|
||||
|
||||
myfclose(fp);
|
||||
|
||||
}
|
||||
|
||||
void cls_webu_html::main()
|
||||
{
|
||||
pthread_mutex_lock(&app->mutex_post);
|
||||
if (app->conf->webcontrol_interface == "user") {
|
||||
user_page();
|
||||
} else {
|
||||
default_page();
|
||||
}
|
||||
pthread_mutex_unlock(&app->mutex_post);
|
||||
|
||||
if (webua->resp_page == "") {
|
||||
webua->bad_request();
|
||||
} else {
|
||||
webua->mhd_send();
|
||||
}
|
||||
}
|
||||
|
||||
cls_webu_html::cls_webu_html(cls_webu_ans *p_webua)
|
||||
{
|
||||
app = p_webua->app;
|
||||
webu = p_webua->webu;
|
||||
webua = p_webua;
|
||||
}
|
||||
|
||||
cls_webu_html::~cls_webu_html()
|
||||
{
|
||||
app = nullptr;
|
||||
webu = nullptr;
|
||||
webua = nullptr;
|
||||
}
|
||||
|
||||
@@ -18,9 +18,59 @@
|
||||
|
||||
#ifndef _INCLUDE_WEBU_HTML_HPP_
|
||||
#define _INCLUDE_WEBU_HTML_HPP_
|
||||
class cls_webu_html {
|
||||
public:
|
||||
cls_webu_html(cls_webu_ans *p_webua);
|
||||
~cls_webu_html();
|
||||
void main();
|
||||
private:
|
||||
ctx_motapp *app;
|
||||
cls_webu *webu;
|
||||
cls_webu_ans *webua;
|
||||
|
||||
void webu_html_badreq(ctx_webui *webui);
|
||||
void webu_html_user(ctx_webui *webui);
|
||||
void webu_html_page(ctx_webui *webui);
|
||||
void style_navbar();
|
||||
void style_config();
|
||||
void style_base();
|
||||
void style();
|
||||
void head();
|
||||
void navbar();
|
||||
void divmain();
|
||||
void script_nav();
|
||||
void script_send_config();
|
||||
void script_send_action();
|
||||
void script_send_reload();
|
||||
void script_dropchange_cam();
|
||||
void script_config_hideall();
|
||||
void script_config_click();
|
||||
void script_assign_camid();
|
||||
void script_assign_version();
|
||||
void script_assign_cams();
|
||||
void script_assign_actions();
|
||||
void script_assign_vals();
|
||||
void script_assign_config_nav();
|
||||
void script_assign_config_item();
|
||||
void script_assign_config_cat();
|
||||
void script_assign_config();
|
||||
void script_initform();
|
||||
void script_display_cameras();
|
||||
void script_display_config();
|
||||
void script_display_movies();
|
||||
void script_display_actions();
|
||||
void script_camera_buttons_ptz();
|
||||
void script_image_pantilt();
|
||||
void script_cams_reset();
|
||||
void script_cams_one_click();
|
||||
void script_cams_all_click();
|
||||
void script_movies_page();
|
||||
void script_movies_click();
|
||||
void script_cams_scan_click();
|
||||
void script_cams_one_fnc();
|
||||
void script_cams_all_fnc();
|
||||
void script_cams_scan_fnc();
|
||||
void script();
|
||||
void body();
|
||||
void default_page();
|
||||
void user_page();
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE_WEBU_HTML_HPP_ */
|
||||
|
||||
@@ -21,10 +21,12 @@
|
||||
#include "logger.hpp"
|
||||
#include "util.hpp"
|
||||
#include "webu.hpp"
|
||||
#include "webu_ans.hpp"
|
||||
#include "webu_common.hpp"
|
||||
#include "webu_json.hpp"
|
||||
#include "dbse.hpp"
|
||||
|
||||
static void webu_json_config_item(ctx_webui *webui, ctx_config *conf, int indx_parm)
|
||||
void cls_webu_json::parms_item(ctx_config *conf, int indx_parm)
|
||||
{
|
||||
size_t indx;
|
||||
std::string parm_orig, parm_val, parm_list, parm_enable;
|
||||
@@ -33,7 +35,7 @@ static void webu_json_config_item(ctx_webui *webui, ctx_config *conf, int indx_p
|
||||
parm_val = "";
|
||||
parm_list = "";
|
||||
|
||||
if (webui->motapp->conf->webcontrol_parms < WEBUI_LEVEL_LIMITED) {
|
||||
if (app->conf->webcontrol_parms < WEBUI_LEVEL_LIMITED) {
|
||||
parm_enable = "false";
|
||||
} else {
|
||||
parm_enable = "true";
|
||||
@@ -51,7 +53,7 @@ static void webu_json_config_item(ctx_webui *webui, ctx_config *conf, int indx_p
|
||||
}
|
||||
|
||||
if (config_parms[indx_parm].parm_type == PARM_TYP_INT) {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
"\"" + config_parms[indx_parm].parm_name + "\"" +
|
||||
":{" +
|
||||
" \"value\":" + parm_val +
|
||||
@@ -62,7 +64,7 @@ static void webu_json_config_item(ctx_webui *webui, ctx_config *conf, int indx_p
|
||||
|
||||
} else if (config_parms[indx_parm].parm_type == PARM_TYP_BOOL) {
|
||||
if (parm_val == "on") {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
"\"" + config_parms[indx_parm].parm_name + "\"" +
|
||||
":{" +
|
||||
" \"value\":true" +
|
||||
@@ -71,7 +73,7 @@ static void webu_json_config_item(ctx_webui *webui, ctx_config *conf, int indx_p
|
||||
",\"type\":\"" + conf_type_desc(config_parms[indx_parm].parm_type) + "\""+
|
||||
"}";
|
||||
} else {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
"\"" + config_parms[indx_parm].parm_name + "\"" +
|
||||
":{" +
|
||||
" \"value\":false" +
|
||||
@@ -84,7 +86,7 @@ static void webu_json_config_item(ctx_webui *webui, ctx_config *conf, int indx_p
|
||||
conf_edit_list(conf, config_parms[indx_parm].parm_name
|
||||
, parm_list, config_parms[indx_parm].parm_cat);
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
"\"" + config_parms[indx_parm].parm_name + "\"" +
|
||||
":{" +
|
||||
" \"value\": \"" + parm_val + "\"" +
|
||||
@@ -95,7 +97,7 @@ static void webu_json_config_item(ctx_webui *webui, ctx_config *conf, int indx_p
|
||||
"}";
|
||||
|
||||
} else {
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
"\"" + config_parms[indx_parm].parm_name + "\"" +
|
||||
":{" +
|
||||
" \"value\":\"" + parm_val + "\"" +
|
||||
@@ -104,10 +106,9 @@ static void webu_json_config_item(ctx_webui *webui, ctx_config *conf, int indx_p
|
||||
",\"type\":\""+ conf_type_desc(config_parms[indx_parm].parm_type) + "\"" +
|
||||
"}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void webu_json_config_parms(ctx_webui *webui, ctx_config *conf)
|
||||
void cls_webu_json::parms_one(ctx_config *conf)
|
||||
{
|
||||
int indx_parm;
|
||||
bool first;
|
||||
@@ -122,16 +123,16 @@ static void webu_json_config_parms(ctx_webui *webui, ctx_config *conf)
|
||||
}
|
||||
if (first) {
|
||||
first = false;
|
||||
webui->resp_page += "{";
|
||||
webua->resp_page += "{";
|
||||
} else {
|
||||
webui->resp_page += ",";
|
||||
webua->resp_page += ",";
|
||||
}
|
||||
/* Allow limited parameters to be read only to the web page */
|
||||
if ((config_parms[indx_parm].webui_level >
|
||||
webui->motapp->conf->webcontrol_parms) &&
|
||||
app->conf->webcontrol_parms) &&
|
||||
(config_parms[indx_parm].webui_level > WEBUI_LEVEL_LIMITED)) {
|
||||
|
||||
webui->resp_page +=
|
||||
webua->resp_page +=
|
||||
"\""+config_parms[indx_parm].parm_name+"\"" +
|
||||
":{" +
|
||||
" \"value\":\"\"" +
|
||||
@@ -140,128 +141,118 @@ static void webu_json_config_parms(ctx_webui *webui, ctx_config *conf)
|
||||
",\"type\":\""+ conf_type_desc(config_parms[indx_parm].parm_type) + "\"";
|
||||
|
||||
if (config_parms[indx_parm].parm_type == PARM_TYP_LIST) {
|
||||
webui->resp_page += ",\"list\":[\"na\"]";
|
||||
webua->resp_page += ",\"list\":[\"na\"]";
|
||||
}
|
||||
webui->resp_page +="}";
|
||||
webua->resp_page +="}";
|
||||
} else {
|
||||
webu_json_config_item(webui, conf, indx_parm);
|
||||
parms_item(conf, indx_parm);
|
||||
}
|
||||
indx_parm++;
|
||||
}
|
||||
webui->resp_page += "}";
|
||||
|
||||
webua->resp_page += "}";
|
||||
}
|
||||
|
||||
static void webu_json_config_cam_parms(ctx_webui *webui)
|
||||
void cls_webu_json::parms_all()
|
||||
{
|
||||
int indx_cam;
|
||||
|
||||
webui->resp_page += "{";
|
||||
webui->resp_page += "\"default\": ";
|
||||
webu_json_config_parms(webui, webui->motapp->conf);
|
||||
webua->resp_page += "{";
|
||||
webua->resp_page += "\"default\": ";
|
||||
parms_one(app->conf);
|
||||
|
||||
for (indx_cam=0; indx_cam<webui->motapp->cam_cnt; indx_cam++) {
|
||||
webui->resp_page += ",\"cam" +
|
||||
std::to_string(webui->motapp->cam_list[indx_cam]->device_id) + "\": ";
|
||||
webu_json_config_parms(webui, webui->motapp->cam_list[indx_cam]->conf);
|
||||
for (indx_cam=0; indx_cam<app->cam_cnt; indx_cam++) {
|
||||
webua->resp_page += ",\"cam" +
|
||||
std::to_string(app->cam_list[indx_cam]->device_id) + "\": ";
|
||||
parms_one(app->cam_list[indx_cam]->conf);
|
||||
}
|
||||
webui->resp_page += "}";
|
||||
|
||||
return;
|
||||
|
||||
webua->resp_page += "}";
|
||||
}
|
||||
|
||||
static void webu_json_config_cam_list(ctx_webui *webui)
|
||||
void cls_webu_json::cameras_list()
|
||||
{
|
||||
int indx_cam;
|
||||
std::string response;
|
||||
std::string strid;
|
||||
ctx_dev *cam;
|
||||
|
||||
webui->resp_page += "{\"count\" : " + std::to_string(webui->motapp->cam_cnt);
|
||||
webua->resp_page += "{\"count\" : " + std::to_string(app->cam_cnt);
|
||||
|
||||
for (indx_cam=0; indx_cam<webui->motapp->cam_cnt; indx_cam++) {
|
||||
cam = webui->motapp->cam_list[indx_cam];
|
||||
for (indx_cam=0; indx_cam<app->cam_cnt; indx_cam++) {
|
||||
cam = app->cam_list[indx_cam];
|
||||
strid =std::to_string(cam->device_id);
|
||||
webui->resp_page += ",\"" + std::to_string(indx_cam) + "\":";
|
||||
webua->resp_page += ",\"" + std::to_string(indx_cam) + "\":";
|
||||
if (cam->conf->device_name == "") {
|
||||
webui->resp_page += "{\"name\": \"camera " + strid + "\"";
|
||||
webua->resp_page += "{\"name\": \"camera " + strid + "\"";
|
||||
} else {
|
||||
webui->resp_page += "{\"name\": \"" + cam->conf->device_name + "\"";
|
||||
webua->resp_page += "{\"name\": \"" + cam->conf->device_name + "\"";
|
||||
}
|
||||
webui->resp_page += ",\"id\": " + strid;
|
||||
webui->resp_page += ",\"url\": \"" + webui->hostfull + "/" + strid + "/\"} ";
|
||||
webua->resp_page += ",\"id\": " + strid;
|
||||
webua->resp_page += ",\"url\": \"" + webua->hostfull + "/" + strid + "/\"} ";
|
||||
}
|
||||
webui->resp_page += "}";
|
||||
|
||||
return;
|
||||
webua->resp_page += "}";
|
||||
|
||||
}
|
||||
|
||||
static void webu_json_config_categories(ctx_webui *webui)
|
||||
void cls_webu_json::categories_list()
|
||||
{
|
||||
int indx_cat;
|
||||
std::string catnm_short, catnm_long;
|
||||
|
||||
webui->resp_page += "{";
|
||||
webua->resp_page += "{";
|
||||
|
||||
indx_cat = 0;
|
||||
while (indx_cat != PARM_CAT_MAX) {
|
||||
if (indx_cat != 0) {
|
||||
webui->resp_page += ",";
|
||||
webua->resp_page += ",";
|
||||
}
|
||||
webui->resp_page += "\"" + std::to_string(indx_cat) + "\": ";
|
||||
webua->resp_page += "\"" + std::to_string(indx_cat) + "\": ";
|
||||
|
||||
catnm_long = conf_cat_desc((enum PARM_CAT)indx_cat, false);
|
||||
catnm_short = conf_cat_desc((enum PARM_CAT)indx_cat, true);
|
||||
|
||||
webui->resp_page += "{\"name\":\"" + catnm_short + "\",\"display\":\"" + catnm_long + "\"}";
|
||||
webua->resp_page += "{\"name\":\"" + catnm_short + "\",\"display\":\"" + catnm_long + "\"}";
|
||||
|
||||
indx_cat++;
|
||||
}
|
||||
|
||||
webui->resp_page += "}";
|
||||
|
||||
return;
|
||||
|
||||
webua->resp_page += "}";
|
||||
}
|
||||
|
||||
void webu_json_config(ctx_webui *webui)
|
||||
void cls_webu_json::config()
|
||||
{
|
||||
webui->resp_type = WEBUI_RESP_JSON;
|
||||
webua->resp_type = WEBUI_RESP_JSON;
|
||||
|
||||
webui->resp_page += "{\"version\" : \"" VERSION "\"";
|
||||
webua->resp_page += "{\"version\" : \"" VERSION "\"";
|
||||
|
||||
webui->resp_page += ",\"cameras\" : ";
|
||||
webu_json_config_cam_list(webui);
|
||||
webua->resp_page += ",\"cameras\" : ";
|
||||
cameras_list();
|
||||
|
||||
webui->resp_page += ",\"configuration\" : ";
|
||||
webu_json_config_cam_parms(webui);
|
||||
webua->resp_page += ",\"configuration\" : ";
|
||||
parms_all();
|
||||
|
||||
webui->resp_page += ",\"categories\" : ";
|
||||
webu_json_config_categories(webui);
|
||||
|
||||
webui->resp_page += "}";
|
||||
webua->resp_page += ",\"categories\" : ";
|
||||
categories_list();
|
||||
|
||||
webua->resp_page += "}";
|
||||
}
|
||||
|
||||
static void webu_json_movies_list(ctx_webui *webui)
|
||||
void cls_webu_json::movies_list()
|
||||
{
|
||||
int indx_mov, indx, movie_cnt;
|
||||
std::string response;
|
||||
char fmt[PATH_MAX];
|
||||
ctx_dbse_rec db;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
if (it->param_name == "movies") {
|
||||
if (it->param_value == "off") {
|
||||
MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO, "Movies via webcontrol disabled");
|
||||
webui->resp_page += "{\"count\" : 0} ";
|
||||
webui->resp_page += ",\"device_id\" : ";
|
||||
webui->resp_page += std::to_string(webui->cam->device_id);
|
||||
webui->resp_page += "}";
|
||||
webua->resp_page += "{\"count\" : 0} ";
|
||||
webua->resp_page += ",\"device_id\" : ";
|
||||
webua->resp_page += std::to_string(webua->cam->device_id);
|
||||
webua->resp_page += "}";
|
||||
return;
|
||||
} else {
|
||||
break;
|
||||
@@ -269,13 +260,13 @@ static void webu_json_movies_list(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
|
||||
dbse_movies_getlist(webui->motapp, webui->cam->device_id);
|
||||
dbse_movies_getlist(app, webua->cam->device_id);
|
||||
|
||||
movie_cnt = webui->motapp->dbse->movie_cnt;
|
||||
webui->resp_page += "{";
|
||||
movie_cnt = app->dbse->movie_cnt;
|
||||
webua->resp_page += "{";
|
||||
indx = 0;
|
||||
for (indx_mov=0; indx_mov < movie_cnt; indx_mov++) {
|
||||
db = webui->motapp->dbse->movie_list[indx_mov];
|
||||
db = app->dbse->movie_list[indx_mov];
|
||||
if (db.found == true) {
|
||||
if ((db.movie_sz/1000) < 1000) {
|
||||
snprintf(fmt,PATH_MAX,"%.1fKB"
|
||||
@@ -287,152 +278,178 @@ static void webu_json_movies_list(ctx_webui *webui)
|
||||
snprintf(fmt,PATH_MAX,"%.1fGB"
|
||||
,((double)db.movie_sz/1000000000));
|
||||
}
|
||||
webui->resp_page += "\""+ std::to_string(indx) + "\":";
|
||||
webua->resp_page += "\""+ std::to_string(indx) + "\":";
|
||||
|
||||
webui->resp_page += "{\"name\": \"";
|
||||
webui->resp_page += std::string(db.movie_nm) + "\"";
|
||||
webua->resp_page += "{\"name\": \"";
|
||||
webua->resp_page += std::string(db.movie_nm) + "\"";
|
||||
|
||||
webui->resp_page += ",\"size\": \"";
|
||||
webui->resp_page += std::string(fmt) + "\"";
|
||||
webua->resp_page += ",\"size\": \"";
|
||||
webua->resp_page += std::string(fmt) + "\"";
|
||||
|
||||
webui->resp_page += ",\"date\": \"";
|
||||
webui->resp_page += std::to_string(db.movie_dtl) + "\"";
|
||||
webua->resp_page += ",\"date\": \"";
|
||||
webua->resp_page += std::to_string(db.movie_dtl) + "\"";
|
||||
|
||||
if (db.movie_tmc != NULL) {
|
||||
webui->resp_page += ",\"time\": \"";
|
||||
webui->resp_page += std::string(db.movie_tmc) + "\"";
|
||||
webua->resp_page += ",\"time\": \"";
|
||||
webua->resp_page += std::string(db.movie_tmc) + "\"";
|
||||
}
|
||||
|
||||
webui->resp_page += ",\"diff_avg\": \"";
|
||||
webui->resp_page += std::to_string(db.diff_avg) + "\"";
|
||||
webua->resp_page += ",\"diff_avg\": \"";
|
||||
webua->resp_page += std::to_string(db.diff_avg) + "\"";
|
||||
|
||||
webui->resp_page += ",\"sdev_min\": \"";
|
||||
webui->resp_page += std::to_string(db.sdev_min) + "\"";
|
||||
webua->resp_page += ",\"sdev_min\": \"";
|
||||
webua->resp_page += std::to_string(db.sdev_min) + "\"";
|
||||
|
||||
webui->resp_page += ",\"sdev_max\": \"";
|
||||
webui->resp_page += std::to_string(db.sdev_max) + "\"";
|
||||
webua->resp_page += ",\"sdev_max\": \"";
|
||||
webua->resp_page += std::to_string(db.sdev_max) + "\"";
|
||||
|
||||
webui->resp_page += ",\"sdev_avg\": \"";
|
||||
webui->resp_page += std::to_string(db.sdev_avg) + "\"";
|
||||
webua->resp_page += ",\"sdev_avg\": \"";
|
||||
webua->resp_page += std::to_string(db.sdev_avg) + "\"";
|
||||
|
||||
webui->resp_page += "}";
|
||||
webui->resp_page += ",";
|
||||
webua->resp_page += "}";
|
||||
webua->resp_page += ",";
|
||||
indx++;
|
||||
}
|
||||
}
|
||||
webui->resp_page += "\"count\" : " + std::to_string(indx);
|
||||
webui->resp_page += ",\"device_id\" : ";
|
||||
webui->resp_page += std::to_string(webui->cam->device_id);
|
||||
webui->resp_page += "}";
|
||||
|
||||
return;
|
||||
|
||||
webua->resp_page += "\"count\" : " + std::to_string(indx);
|
||||
webua->resp_page += ",\"device_id\" : ";
|
||||
webua->resp_page += std::to_string(webua->cam->device_id);
|
||||
webua->resp_page += "}";
|
||||
}
|
||||
|
||||
void webu_json_movies(ctx_webui *webui)
|
||||
void cls_webu_json::movies()
|
||||
{
|
||||
int indx_cam, indx_req;
|
||||
|
||||
webui->resp_type = WEBUI_RESP_JSON;
|
||||
webua->resp_type = WEBUI_RESP_JSON;
|
||||
|
||||
webui->resp_page += "{\"movies\" : ";
|
||||
if (webui->cam == NULL) {
|
||||
webui->resp_page += "{\"count\" :" + std::to_string(webui->motapp->cam_cnt);
|
||||
webua->resp_page += "{\"movies\" : ";
|
||||
if (webua->cam == NULL) {
|
||||
webua->resp_page += "{\"count\" :" + std::to_string(app->cam_cnt);
|
||||
|
||||
for (indx_cam=0; indx_cam<webui->motapp->cam_cnt; indx_cam++) {
|
||||
webui->cam = webui->motapp->cam_list[indx_cam];
|
||||
webui->resp_page += ",\""+ std::to_string(indx_cam) + "\":";
|
||||
webu_json_movies_list(webui);
|
||||
for (indx_cam=0; indx_cam<app->cam_cnt; indx_cam++) {
|
||||
webua->cam = app->cam_list[indx_cam];
|
||||
webua->resp_page += ",\""+ std::to_string(indx_cam) + "\":";
|
||||
movies_list();
|
||||
}
|
||||
webui->resp_page += "}";
|
||||
webui->cam = NULL;
|
||||
webua->resp_page += "}";
|
||||
webua->cam = NULL;
|
||||
} else {
|
||||
indx_req = -1;
|
||||
for (indx_cam=0; indx_cam<webui->motapp->cam_cnt; indx_cam++) {
|
||||
if (webui->cam->device_id == webui->motapp->cam_list[indx_cam]->device_id){
|
||||
for (indx_cam=0; indx_cam<app->cam_cnt; indx_cam++) {
|
||||
if (webua->cam->device_id == app->cam_list[indx_cam]->device_id){
|
||||
indx_req = indx_cam;
|
||||
}
|
||||
}
|
||||
webui->resp_page += "{\"count\" : 1";
|
||||
webui->resp_page += ",\""+ std::to_string(indx_req) + "\":";
|
||||
webu_json_movies_list(webui);
|
||||
webui->resp_page += "}";
|
||||
webua->resp_page += "{\"count\" : 1";
|
||||
webua->resp_page += ",\""+ std::to_string(indx_req) + "\":";
|
||||
movies_list();
|
||||
webua->resp_page += "}";
|
||||
}
|
||||
webui->resp_page += "}";
|
||||
|
||||
webua->resp_page += "}";
|
||||
}
|
||||
|
||||
static void webu_json_status_vars(ctx_webui *webui, int indx_cam)
|
||||
void cls_webu_json::status_vars(int indx_cam)
|
||||
{
|
||||
char buf[32];
|
||||
struct tm timestamp_tm;
|
||||
struct timespec curr_ts;
|
||||
ctx_dev *cam;
|
||||
|
||||
cam = webui->motapp->cam_list[indx_cam];
|
||||
cam = app->cam_list[indx_cam];
|
||||
|
||||
webui->resp_page += "{";
|
||||
webua->resp_page += "{";
|
||||
|
||||
webui->resp_page += "\"name\":\"" + cam->conf->device_name+"\"";
|
||||
webui->resp_page += ",\"id\":" + std::to_string(cam->device_id);
|
||||
webui->resp_page += ",\"width\":" + std::to_string(cam->imgs.width);
|
||||
webui->resp_page += ",\"height\":" + std::to_string(cam->imgs.height);
|
||||
webui->resp_page += ",\"fps\":" + std::to_string(cam->lastrate);
|
||||
webua->resp_page += "\"name\":\"" + cam->conf->device_name+"\"";
|
||||
webua->resp_page += ",\"id\":" + std::to_string(cam->device_id);
|
||||
webua->resp_page += ",\"width\":" + std::to_string(cam->imgs.width);
|
||||
webua->resp_page += ",\"height\":" + std::to_string(cam->imgs.height);
|
||||
webua->resp_page += ",\"fps\":" + std::to_string(cam->lastrate);
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &curr_ts);
|
||||
localtime_r(&curr_ts.tv_sec, ×tamp_tm);
|
||||
strftime(buf, sizeof(buf), "%FT%T", ×tamp_tm);
|
||||
webui->resp_page += ",\"current_time\":\"" + std::string(buf)+"\"";
|
||||
webua->resp_page += ",\"current_time\":\"" + std::string(buf)+"\"";
|
||||
|
||||
webui->resp_page += ",\"missing_frame_counter\":" +
|
||||
webua->resp_page += ",\"missing_frame_counter\":" +
|
||||
std::to_string(cam->missing_frame_counter);
|
||||
|
||||
if (cam->lost_connection) {
|
||||
webui->resp_page += ",\"lost_connection\":true";
|
||||
webua->resp_page += ",\"lost_connection\":true";
|
||||
} else {
|
||||
webui->resp_page += ",\"lost_connection\":false";
|
||||
webua->resp_page += ",\"lost_connection\":false";
|
||||
}
|
||||
|
||||
if (cam->connectionlosttime.tv_sec != 0) {
|
||||
localtime_r(&cam->connectionlosttime.tv_sec, ×tamp_tm);
|
||||
strftime(buf, sizeof(buf), "%FT%T", ×tamp_tm);
|
||||
webui->resp_page += ",\"connection_lost_time\":\"" + std::string(buf)+"\"";
|
||||
webua->resp_page += ",\"connection_lost_time\":\"" + std::string(buf)+"\"";
|
||||
} else {
|
||||
webui->resp_page += ",\"connection_lost_time\":\"\"" ;
|
||||
webua->resp_page += ",\"connection_lost_time\":\"\"" ;
|
||||
}
|
||||
if (cam->detecting_motion) {
|
||||
webui->resp_page += ",\"detecting\":true";
|
||||
webua->resp_page += ",\"detecting\":true";
|
||||
} else {
|
||||
webui->resp_page += ",\"detecting\":false";
|
||||
webua->resp_page += ",\"detecting\":false";
|
||||
}
|
||||
|
||||
if (cam->pause) {
|
||||
webui->resp_page += ",\"pause\":true";
|
||||
webua->resp_page += ",\"pause\":true";
|
||||
} else {
|
||||
webui->resp_page += ",\"pause\":false";
|
||||
webua->resp_page += ",\"pause\":false";
|
||||
}
|
||||
|
||||
webui->resp_page += "}";
|
||||
|
||||
webua->resp_page += "}";
|
||||
}
|
||||
|
||||
void webu_json_status(ctx_webui *webui)
|
||||
void cls_webu_json::status()
|
||||
{
|
||||
int indx_cam;
|
||||
|
||||
webui->resp_type = WEBUI_RESP_JSON;
|
||||
webua->resp_type = WEBUI_RESP_JSON;
|
||||
|
||||
webui->resp_page += "{\"version\" : \"" VERSION "\"";
|
||||
webui->resp_page += ",\"status\" : ";
|
||||
webua->resp_page += "{\"version\" : \"" VERSION "\"";
|
||||
webua->resp_page += ",\"status\" : ";
|
||||
|
||||
webui->resp_page += "{\"count\" : " + std::to_string(webui->motapp->cam_cnt);
|
||||
for (indx_cam=0; indx_cam<webui->motapp->cam_cnt; indx_cam++) {
|
||||
webui->resp_page += ",\"cam" +
|
||||
std::to_string(webui->motapp->cam_list[indx_cam]->device_id) + "\": ";
|
||||
webu_json_status_vars(webui, indx_cam);
|
||||
webua->resp_page += "{\"count\" : " + std::to_string(app->cam_cnt);
|
||||
for (indx_cam=0; indx_cam<app->cam_cnt; indx_cam++) {
|
||||
webua->resp_page += ",\"cam" +
|
||||
std::to_string(app->cam_list[indx_cam]->device_id) + "\": ";
|
||||
status_vars(indx_cam);
|
||||
}
|
||||
webui->resp_page += "}";
|
||||
|
||||
webui->resp_page += "}";
|
||||
webua->resp_page += "}";
|
||||
|
||||
webua->resp_page += "}";
|
||||
}
|
||||
|
||||
void cls_webu_json::main()
|
||||
{
|
||||
pthread_mutex_lock(&app->mutex_post);
|
||||
if (webua->uri_cmd1 == "config.json") {
|
||||
config();
|
||||
} else if (webua->uri_cmd1 == "movies.json") {
|
||||
movies();
|
||||
} else if (webua->uri_cmd1 == "status.json") {
|
||||
status();
|
||||
} else {
|
||||
webua->bad_request();
|
||||
pthread_mutex_unlock(&app->mutex_post);
|
||||
return;
|
||||
}
|
||||
pthread_mutex_unlock(&app->mutex_post);
|
||||
webua->mhd_send();
|
||||
}
|
||||
|
||||
cls_webu_json::cls_webu_json(cls_webu_ans *p_webua)
|
||||
{
|
||||
app = p_webua->app;
|
||||
webu = p_webua->webu;
|
||||
webua = p_webua;
|
||||
}
|
||||
|
||||
cls_webu_json::~cls_webu_json()
|
||||
{
|
||||
app = nullptr;
|
||||
webu = nullptr;
|
||||
webua = nullptr;
|
||||
}
|
||||
@@ -18,9 +18,25 @@
|
||||
|
||||
#ifndef _INCLUDE_WEBU_JSON_HPP_
|
||||
#define _INCLUDE_WEBU_JSON_HPP_
|
||||
|
||||
void webu_json_config(ctx_webui *webui);
|
||||
void webu_json_movies(ctx_webui *webui);
|
||||
void webu_json_status(ctx_webui *webui);
|
||||
class cls_webu_json {
|
||||
public:
|
||||
cls_webu_json(cls_webu_ans *p_webua);
|
||||
~cls_webu_json();
|
||||
void main();
|
||||
private:
|
||||
ctx_motapp *app;
|
||||
cls_webu *webu;
|
||||
cls_webu_ans *webua;
|
||||
void parms_item(ctx_config *conf, int indx_parm);
|
||||
void parms_one(ctx_config *conf);
|
||||
void parms_all();
|
||||
void cameras_list();
|
||||
void categories_list();
|
||||
void config();
|
||||
void movies_list();
|
||||
void movies();
|
||||
void status_vars(int indx_cam);
|
||||
void status();
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE_WEBU_JSON_HPP_ */
|
||||
|
||||
@@ -22,91 +22,78 @@
|
||||
#include "util.hpp"
|
||||
#include "picture.hpp"
|
||||
#include "webu.hpp"
|
||||
#include "webu_common.hpp"
|
||||
#include "webu_ans.hpp"
|
||||
#include "webu_stream.hpp"
|
||||
#include "webu_mpegts.hpp"
|
||||
#include "alg_sec.hpp"
|
||||
|
||||
/* Version independent uint */
|
||||
#if (MYFFVER <= 60016)
|
||||
typedef uint8_t myuint;
|
||||
#else
|
||||
typedef const uint8_t myuint;
|
||||
#endif
|
||||
/****** Callback functions for MHD ****************************************/
|
||||
|
||||
void webu_mpegts_free_context(ctx_webui *webui)
|
||||
static int webu_mpegts_avio_buf(void *opaque, myuint *buf, int buf_size)
|
||||
{
|
||||
if (webui->picture != NULL) {
|
||||
myframe_free(webui->picture);
|
||||
webui->picture = NULL;
|
||||
}
|
||||
if (webui->ctx_codec != NULL) {
|
||||
myavcodec_close(webui->ctx_codec);
|
||||
webui->ctx_codec = NULL;
|
||||
}
|
||||
if (webui->fmtctx != NULL) {
|
||||
if (webui->fmtctx->pb != NULL) {
|
||||
if (webui->fmtctx->pb->buffer != NULL) {
|
||||
av_free(webui->fmtctx->pb->buffer);
|
||||
webui->fmtctx->pb->buffer = NULL;
|
||||
}
|
||||
avio_context_free(&webui->fmtctx->pb);
|
||||
webui->fmtctx->pb = NULL;
|
||||
}
|
||||
avformat_free_context(webui->fmtctx);
|
||||
webui->fmtctx = NULL;
|
||||
}
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO, _("closed"));
|
||||
|
||||
cls_webu_mpegts *webu_mpegts;
|
||||
webu_mpegts =(cls_webu_mpegts *)opaque;
|
||||
return webu_mpegts->avio_buf(buf, buf_size);
|
||||
}
|
||||
|
||||
static int webu_mpegts_pic_send(ctx_webui *webui, unsigned char *img)
|
||||
static ssize_t webu_mpegts_response(void *cls, uint64_t pos, char *buf, size_t max)
|
||||
{
|
||||
cls_webu_mpegts *webu_mpegts;
|
||||
(void)pos;
|
||||
webu_mpegts =(cls_webu_mpegts *)cls;
|
||||
return webu_mpegts->response(buf, max);
|
||||
}
|
||||
|
||||
/********Class Functions ****************************************************/
|
||||
|
||||
int cls_webu_mpegts::pic_send(unsigned char *img)
|
||||
{
|
||||
int retcd;
|
||||
char errstr[128];
|
||||
struct timespec curr_ts;
|
||||
int64_t pts_interval;
|
||||
|
||||
if (webui->picture == NULL) {
|
||||
webui->picture = myframe_alloc();
|
||||
webui->picture->linesize[0] = webui->ctx_codec->width;
|
||||
webui->picture->linesize[1] = webui->ctx_codec->width / 2;
|
||||
webui->picture->linesize[2] = webui->ctx_codec->width / 2;
|
||||
if (picture == NULL) {
|
||||
picture = myframe_alloc();
|
||||
picture->linesize[0] = ctx_codec->width;
|
||||
picture->linesize[1] = ctx_codec->width / 2;
|
||||
picture->linesize[2] = ctx_codec->width / 2;
|
||||
|
||||
webui->picture->format = webui->ctx_codec->pix_fmt;
|
||||
webui->picture->width = webui->ctx_codec->width;
|
||||
webui->picture->height = webui->ctx_codec->height;
|
||||
picture->format = ctx_codec->pix_fmt;
|
||||
picture->width = ctx_codec->width;
|
||||
picture->height = ctx_codec->height;
|
||||
|
||||
webui->picture->pict_type = AV_PICTURE_TYPE_I;
|
||||
myframe_key(webui->picture);
|
||||
webui->picture->pts = 1;
|
||||
picture->pict_type = AV_PICTURE_TYPE_I;
|
||||
myframe_key(picture);
|
||||
picture->pts = 1;
|
||||
}
|
||||
|
||||
webui->picture->data[0] = img;
|
||||
webui->picture->data[1] = webui->picture->data[0] +
|
||||
(webui->ctx_codec->width * webui->ctx_codec->height);
|
||||
webui->picture->data[2] = webui->picture->data[1] +
|
||||
((webui->ctx_codec->width * webui->ctx_codec->height) / 4);
|
||||
picture->data[0] = img;
|
||||
picture->data[1] = picture->data[0] +
|
||||
(ctx_codec->width * ctx_codec->height);
|
||||
picture->data[2] = picture->data[1] +
|
||||
((ctx_codec->width * ctx_codec->height) / 4);
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &curr_ts);
|
||||
pts_interval = ((1000000L * (curr_ts.tv_sec - webui->start_time.tv_sec)) +
|
||||
(curr_ts.tv_nsec/1000) - (webui->start_time.tv_nsec/1000));
|
||||
webui->picture->pts = av_rescale_q(pts_interval
|
||||
,av_make_q(1,1000000L), webui->ctx_codec->time_base);
|
||||
pts_interval = ((1000000L * (curr_ts.tv_sec - start_time.tv_sec)) +
|
||||
(curr_ts.tv_nsec/1000) - (start_time.tv_nsec/1000));
|
||||
picture->pts = av_rescale_q(pts_interval
|
||||
,av_make_q(1,1000000L), ctx_codec->time_base);
|
||||
|
||||
retcd = avcodec_send_frame(webui->ctx_codec, webui->picture);
|
||||
retcd = avcodec_send_frame(ctx_codec, picture);
|
||||
if (retcd < 0 ) {
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO
|
||||
, _("Error sending frame for encoding:%s"), errstr);
|
||||
myframe_free(webui->picture);
|
||||
webui->picture = NULL;
|
||||
myframe_free(picture);
|
||||
picture = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int webu_mpegts_pic_get(ctx_webui *webui)
|
||||
int cls_webu_mpegts::pic_get()
|
||||
{
|
||||
int retcd;
|
||||
char errstr[128];
|
||||
@@ -115,7 +102,7 @@ static int webu_mpegts_pic_get(ctx_webui *webui)
|
||||
pkt = NULL;
|
||||
pkt = mypacket_alloc(pkt);
|
||||
|
||||
retcd = avcodec_receive_packet(webui->ctx_codec, pkt);
|
||||
retcd = avcodec_receive_packet(ctx_codec, pkt);
|
||||
if (retcd == AVERROR(EAGAIN)) {
|
||||
mypacket_free(pkt);
|
||||
pkt = NULL;
|
||||
@@ -129,9 +116,9 @@ static int webu_mpegts_pic_get(ctx_webui *webui)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pkt->pts = webui->picture->pts;
|
||||
pkt->pts = picture->pts;
|
||||
|
||||
retcd = av_interleaved_write_frame(webui->fmtctx, pkt);
|
||||
retcd = av_interleaved_write_frame(fmtctx, pkt);
|
||||
if (retcd < 0 ) {
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO
|
||||
@@ -145,144 +132,134 @@ static int webu_mpegts_pic_get(ctx_webui *webui)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void webu_mpegts_resetpos(ctx_webui *webui)
|
||||
void cls_webu_mpegts::resetpos()
|
||||
{
|
||||
webui->stream_pos = 0;
|
||||
webui->resp_used = 0;
|
||||
stream_pos = 0;
|
||||
webuc->resp_used = 0;
|
||||
}
|
||||
|
||||
static int webu_mpegts_getimg(ctx_webui *webui)
|
||||
int cls_webu_mpegts::getimg()
|
||||
{
|
||||
ctx_stream_data *strm;
|
||||
struct timespec curr_ts;
|
||||
unsigned char *img_data;
|
||||
int img_sz;
|
||||
|
||||
if (webu_stream_check_finish(webui)) {
|
||||
webu_mpegts_resetpos(webui);
|
||||
if (webuc->check_finish()) {
|
||||
resetpos();
|
||||
return 0;
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &curr_ts);
|
||||
|
||||
memset(webui->resp_image, '\0', webui->resp_size);
|
||||
webui->resp_used = 0;
|
||||
memset(webuc->resp_image, '\0', webuc->resp_size);
|
||||
webuc->resp_used = 0;
|
||||
|
||||
if (webui->device_id > 0) {
|
||||
if ((webui->cam->detecting_motion == false) &&
|
||||
(webui->motapp->cam_list[webui->camindx]->conf->stream_motion)) {
|
||||
webui->stream_fps = 1;
|
||||
} else {
|
||||
webui->stream_fps = webui->motapp->cam_list[webui->camindx]->conf->stream_maxrate;
|
||||
}
|
||||
if (webua->device_id > 0) {
|
||||
webuc->set_fps();
|
||||
/* Assign to a local pointer the stream we want */
|
||||
if (webui->cnct_type == WEBUI_CNCT_TS_FULL) {
|
||||
strm = &webui->cam->stream.norm;
|
||||
} else if (webui->cnct_type == WEBUI_CNCT_TS_SUB) {
|
||||
strm = &webui->cam->stream.sub;
|
||||
} else if (webui->cnct_type == WEBUI_CNCT_TS_MOTION) {
|
||||
strm = &webui->cam->stream.motion;
|
||||
} else if (webui->cnct_type == WEBUI_CNCT_TS_SOURCE) {
|
||||
strm = &webui->cam->stream.source;
|
||||
} else if (webui->cnct_type == WEBUI_CNCT_TS_SECONDARY) {
|
||||
strm = &webui->cam->stream.secondary;
|
||||
if (webua->cnct_type == WEBUI_CNCT_TS_FULL) {
|
||||
strm = &webua->cam->stream.norm;
|
||||
} else if (webua->cnct_type == WEBUI_CNCT_TS_SUB) {
|
||||
strm = &webua->cam->stream.sub;
|
||||
} else if (webua->cnct_type == WEBUI_CNCT_TS_MOTION) {
|
||||
strm = &webua->cam->stream.motion;
|
||||
} else if (webua->cnct_type == WEBUI_CNCT_TS_SOURCE) {
|
||||
strm = &webua->cam->stream.source;
|
||||
} else if (webua->cnct_type == WEBUI_CNCT_TS_SECONDARY) {
|
||||
strm = &webua->cam->stream.secondary;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
img_sz = (webui->ctx_codec->width * webui->ctx_codec->height * 3)/2;
|
||||
img_sz = (ctx_codec->width * ctx_codec->height * 3)/2;
|
||||
img_data = (unsigned char*) mymalloc(img_sz);
|
||||
pthread_mutex_lock(&webui->cam->stream.mutex);
|
||||
pthread_mutex_lock(&webua->cam->stream.mutex);
|
||||
if (strm->img_data == NULL) {
|
||||
memset(img_data, 0x00, img_sz);
|
||||
} else {
|
||||
memcpy(img_data, strm->img_data, img_sz);
|
||||
strm->consumed = true;
|
||||
}
|
||||
pthread_mutex_unlock(&webui->cam->stream.mutex);
|
||||
pthread_mutex_unlock(&webua->cam->stream.mutex);
|
||||
} else {
|
||||
webu_stream_all_getimg(webui);
|
||||
webuc->all_getimg();
|
||||
|
||||
img_data = (unsigned char*) mymalloc(webui->motapp->all_sizes->img_sz);
|
||||
img_data = (unsigned char*) mymalloc(app->all_sizes->img_sz);
|
||||
|
||||
memcpy(img_data, webui->all_img_data, webui->motapp->all_sizes->img_sz);
|
||||
memcpy(img_data, webuc->all_img_data, app->all_sizes->img_sz);
|
||||
}
|
||||
|
||||
if (webu_mpegts_pic_send(webui, img_data) < 0) {
|
||||
if (pic_send(img_data) < 0) {
|
||||
myfree(&img_data);
|
||||
return -1;
|
||||
}
|
||||
myfree(&img_data);
|
||||
|
||||
if (webu_mpegts_pic_get(webui) < 0) {
|
||||
if (pic_get() < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int webu_mpegts_avio_buf(void *opaque, myuint *buf, int buf_size)
|
||||
int cls_webu_mpegts::avio_buf(myuint *buf, int buf_size)
|
||||
{
|
||||
ctx_webui *webui =(ctx_webui *)opaque;
|
||||
|
||||
if (webui->resp_size < (size_t)(buf_size + webui->resp_used)) {
|
||||
webui->resp_size = (size_t)(buf_size + webui->resp_used);
|
||||
webui->resp_image = (unsigned char*)realloc(
|
||||
webui->resp_image, webui->resp_size);
|
||||
if (webuc->resp_size < (size_t)(buf_size + webuc->resp_used)) {
|
||||
webuc->resp_size = (size_t)(buf_size + webuc->resp_used);
|
||||
webuc->resp_image = (unsigned char*)realloc(
|
||||
webuc->resp_image, webuc->resp_size);
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO
|
||||
,_("resp_image reallocated %d %d %d")
|
||||
,webui->resp_size
|
||||
,webui->resp_used
|
||||
,webuc->resp_size
|
||||
,webuc->resp_used
|
||||
,buf_size);
|
||||
}
|
||||
|
||||
memcpy(webui->resp_image + webui->resp_used, buf, buf_size);
|
||||
webui->resp_used += buf_size;
|
||||
memcpy(webuc->resp_image + webuc->resp_used, buf, buf_size);
|
||||
webuc->resp_used += buf_size;
|
||||
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
static ssize_t webu_mpegts_response(void *cls, uint64_t pos, char *buf, size_t max)
|
||||
ssize_t cls_webu_mpegts::response(char *buf, size_t max)
|
||||
{
|
||||
ctx_webui *webui =(ctx_webui *)cls;
|
||||
size_t sent_bytes;
|
||||
(void)pos;
|
||||
|
||||
if (webu_stream_check_finish(webui)) {
|
||||
if (webuc->check_finish()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (webui->stream_pos == 0) {
|
||||
webu_stream_delay(webui);
|
||||
webu_mpegts_resetpos(webui);
|
||||
if (webu_mpegts_getimg(webui) < 0) {
|
||||
if (stream_pos == 0) {
|
||||
webuc->delay();
|
||||
resetpos();
|
||||
if (getimg() < 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we don't have anything in the avio buffer at this point bail out */
|
||||
if (webui->resp_used == 0) {
|
||||
webu_mpegts_resetpos(webui);
|
||||
if (webuc->resp_used == 0) {
|
||||
resetpos();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((webui->resp_used - webui->stream_pos) > max) {
|
||||
if ((webuc->resp_used - stream_pos) > max) {
|
||||
sent_bytes = max;
|
||||
} else {
|
||||
sent_bytes = webui->resp_used - webui->stream_pos;
|
||||
sent_bytes = webuc->resp_used - stream_pos;
|
||||
}
|
||||
|
||||
memcpy(buf, webui->resp_image + webui->stream_pos, sent_bytes);
|
||||
memcpy(buf, webuc->resp_image + stream_pos, sent_bytes);
|
||||
|
||||
webui->stream_pos = webui->stream_pos + sent_bytes;
|
||||
if (webui->stream_pos >= webui->resp_used) {
|
||||
webui->stream_pos = 0;
|
||||
stream_pos = stream_pos + sent_bytes;
|
||||
if (stream_pos >= webuc->resp_used) {
|
||||
stream_pos = 0;
|
||||
}
|
||||
|
||||
return sent_bytes;
|
||||
|
||||
}
|
||||
|
||||
int webu_mpegts_open(ctx_webui *webui)
|
||||
int cls_webu_mpegts::open_mpegts()
|
||||
{
|
||||
int retcd, img_w, img_h;
|
||||
char errstr[128];
|
||||
@@ -290,131 +267,126 @@ int webu_mpegts_open(ctx_webui *webui)
|
||||
AVStream *strm;
|
||||
const AVCodec *codec;
|
||||
AVDictionary *opts;
|
||||
size_t aviobuf_sz;
|
||||
|
||||
opts = NULL;
|
||||
webui->picture = NULL;
|
||||
webui->ctx_codec = NULL;
|
||||
webui->fmtctx = NULL;
|
||||
webui->stream_fps = 10000; /* For quick start up*/
|
||||
clock_gettime(CLOCK_REALTIME, &webui->start_time);
|
||||
webuc->stream_fps = 10000; /* For quick start up*/
|
||||
aviobuf_sz = 4096;
|
||||
clock_gettime(CLOCK_REALTIME, &start_time);
|
||||
|
||||
webui->fmtctx = avformat_alloc_context();
|
||||
webui->fmtctx->oformat = av_guess_format("mpegts", NULL, NULL);
|
||||
webui->fmtctx->video_codec_id = MY_CODEC_ID_H264;
|
||||
fmtctx = avformat_alloc_context();
|
||||
fmtctx->oformat = av_guess_format("mpegts", NULL, NULL);
|
||||
fmtctx->video_codec_id = MY_CODEC_ID_H264;
|
||||
|
||||
codec = avcodec_find_encoder(MY_CODEC_ID_H264);
|
||||
strm = avformat_new_stream(webui->fmtctx, codec);
|
||||
strm = avformat_new_stream(fmtctx, codec);
|
||||
|
||||
if (webui->device_id > 0) {
|
||||
if ((webui->cnct_type == WEBUI_CNCT_TS_SUB) &&
|
||||
((webui->cam->imgs.width % 16) == 0) &&
|
||||
((webui->cam->imgs.height % 16) == 0)) {
|
||||
img_w = (webui->cam->imgs.width/2);
|
||||
img_h = (webui->cam->imgs.height/2);
|
||||
if (webua->device_id > 0) {
|
||||
if ((webua->cnct_type == WEBUI_CNCT_TS_SUB) &&
|
||||
((webua->cam->imgs.width % 16) == 0) &&
|
||||
((webua->cam->imgs.height % 16) == 0)) {
|
||||
img_w = (webua->cam->imgs.width/2);
|
||||
img_h = (webua->cam->imgs.height/2);
|
||||
} else {
|
||||
img_w = webui->cam->imgs.width;
|
||||
img_h = webui->cam->imgs.height;
|
||||
img_w = webua->cam->imgs.width;
|
||||
img_h = webua->cam->imgs.height;
|
||||
}
|
||||
} else {
|
||||
webu_stream_all_sizes(webui);
|
||||
img_w = webui->motapp->all_sizes->width;
|
||||
img_h = webui->motapp->all_sizes->height;
|
||||
webuc->all_sizes();
|
||||
img_w = app->all_sizes->width;
|
||||
img_h = app->all_sizes->height;
|
||||
}
|
||||
|
||||
webui->ctx_codec = avcodec_alloc_context3(codec);
|
||||
webui->ctx_codec->gop_size = 15;
|
||||
webui->ctx_codec->codec_id = MY_CODEC_ID_H264;
|
||||
webui->ctx_codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||
webui->ctx_codec->bit_rate = 400000;
|
||||
webui->ctx_codec->width = img_w;
|
||||
webui->ctx_codec->height = img_h;
|
||||
webui->ctx_codec->time_base.num = 1;
|
||||
webui->ctx_codec->time_base.den = 90000;
|
||||
webui->ctx_codec->pix_fmt = MY_PIX_FMT_YUV420P;
|
||||
webui->ctx_codec->max_b_frames = 1;
|
||||
webui->ctx_codec->flags |= MY_CODEC_FLAG_GLOBAL_HEADER;
|
||||
webui->ctx_codec->framerate.num = 1;
|
||||
webui->ctx_codec->framerate.den = 1;
|
||||
av_opt_set(webui->ctx_codec->priv_data, "profile", "main", 0);
|
||||
av_opt_set(webui->ctx_codec->priv_data, "crf", "22", 0);
|
||||
av_opt_set(webui->ctx_codec->priv_data, "tune", "zerolatency", 0);
|
||||
av_opt_set(webui->ctx_codec->priv_data, "preset", "superfast",0);
|
||||
ctx_codec = avcodec_alloc_context3(codec);
|
||||
ctx_codec->gop_size = 15;
|
||||
ctx_codec->codec_id = MY_CODEC_ID_H264;
|
||||
ctx_codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||
ctx_codec->bit_rate = 400000;
|
||||
ctx_codec->width = img_w;
|
||||
ctx_codec->height = img_h;
|
||||
ctx_codec->time_base.num = 1;
|
||||
ctx_codec->time_base.den = 90000;
|
||||
ctx_codec->pix_fmt = MY_PIX_FMT_YUV420P;
|
||||
ctx_codec->max_b_frames = 1;
|
||||
ctx_codec->flags |= MY_CODEC_FLAG_GLOBAL_HEADER;
|
||||
ctx_codec->framerate.num = 1;
|
||||
ctx_codec->framerate.den = 1;
|
||||
av_opt_set(ctx_codec->priv_data, "profile", "main", 0);
|
||||
av_opt_set(ctx_codec->priv_data, "crf", "22", 0);
|
||||
av_opt_set(ctx_codec->priv_data, "tune", "zerolatency", 0);
|
||||
av_opt_set(ctx_codec->priv_data, "preset", "superfast",0);
|
||||
av_dict_set(&opts, "movflags", "empty_moov", 0);
|
||||
|
||||
retcd = avcodec_open2(webui->ctx_codec, codec, &opts);
|
||||
retcd = avcodec_open2(ctx_codec, codec, &opts);
|
||||
if (retcd < 0) {
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO
|
||||
,_("Failed to copy decoder parameters!: %s"), errstr);
|
||||
webu_mpegts_free_context(webui);
|
||||
av_dict_free(&opts);
|
||||
return -1;
|
||||
}
|
||||
|
||||
retcd = avcodec_parameters_from_context(strm->codecpar, webui->ctx_codec);
|
||||
retcd = avcodec_parameters_from_context(strm->codecpar, ctx_codec);
|
||||
if (retcd < 0) {
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO
|
||||
,_("Failed to copy decoder parameters!: %s"), errstr);
|
||||
webu_mpegts_free_context(webui);
|
||||
av_dict_free(&opts);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (webui->device_id > 0) {
|
||||
webu_stream_checkbuffers(webui);
|
||||
if (webua->device_id > 0) {
|
||||
webuc->one_buffer();
|
||||
} else {
|
||||
webu_stream_all_buffers(webui);
|
||||
webuc->all_buffer();
|
||||
}
|
||||
|
||||
webui->aviobuf_sz = 4096;
|
||||
buf_image = (unsigned char*)av_malloc(webui->aviobuf_sz);
|
||||
webui->fmtctx->pb = avio_alloc_context(
|
||||
buf_image, (int)webui->aviobuf_sz, 1, webui
|
||||
, NULL, &webu_mpegts_avio_buf, NULL);
|
||||
webui->fmtctx->flags = AVFMT_FLAG_CUSTOM_IO;
|
||||
|
||||
retcd = avformat_write_header(webui->fmtctx, &opts);
|
||||
buf_image = (unsigned char*)av_malloc(aviobuf_sz);
|
||||
fmtctx->pb = avio_alloc_context(
|
||||
buf_image, (int)aviobuf_sz, 1, this
|
||||
, NULL, &webu_mpegts_avio_buf, NULL);
|
||||
fmtctx->flags = AVFMT_FLAG_CUSTOM_IO;
|
||||
|
||||
retcd = avformat_write_header(fmtctx, &opts);
|
||||
if (retcd < 0) {
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO
|
||||
,_("Failed to write header!: %s"), errstr);
|
||||
webu_mpegts_free_context(webui);
|
||||
av_dict_free(&opts);
|
||||
return -1;
|
||||
}
|
||||
|
||||
webui->stream_pos = 0;
|
||||
webui->resp_used = 0;
|
||||
stream_pos = 0;
|
||||
webuc->resp_used = 0;
|
||||
|
||||
av_dict_free(&opts);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
mhdrslt webu_mpegts_main(ctx_webui *webui)
|
||||
mhdrslt cls_webu_mpegts::main()
|
||||
{
|
||||
mhdrslt retcd;
|
||||
struct MHD_Response *response;
|
||||
p_lst *lst = &webui->motapp->webcontrol_headers->params_array;
|
||||
p_lst *lst = &webu->wb_headers->params_array;
|
||||
p_it it;
|
||||
|
||||
if (webu_mpegts_open(webui) < 0 ) {
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO, _("Unable top open mpegts"));
|
||||
if (open_mpegts() < 0 ) {
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO, _("Unable to open mpegts"));
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &webui->time_last);
|
||||
clock_gettime(CLOCK_MONOTONIC, &webuc->time_last);
|
||||
|
||||
response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 4096
|
||||
,&webu_mpegts_response, webui, NULL);
|
||||
,&webu_mpegts_response, this, NULL);
|
||||
if (!response) {
|
||||
MOTPLS_LOG(ERR, TYPE_STREAM, NO_ERRNO, _("Invalid response"));
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
if (webui->motapp->webcontrol_headers->params_count > 0) {
|
||||
if (webu->wb_headers->params_count > 0) {
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
MHD_add_response_header (response
|
||||
, it->param_name.c_str(), it->param_value.c_str());
|
||||
@@ -424,10 +396,48 @@ mhdrslt webu_mpegts_main(ctx_webui *webui)
|
||||
MHD_add_response_header(response, "Content-Transfer-Encoding", "BINARY");
|
||||
MHD_add_response_header(response, "Content-Type", "application/octet-stream");
|
||||
|
||||
retcd = MHD_queue_response (webui->connection, MHD_HTTP_OK, response);
|
||||
retcd = MHD_queue_response (webua->connection, MHD_HTTP_OK, response);
|
||||
MHD_destroy_response (response);
|
||||
|
||||
return retcd;
|
||||
|
||||
}
|
||||
|
||||
cls_webu_mpegts::cls_webu_mpegts(cls_webu_ans *p_webua)
|
||||
{
|
||||
app = p_webua->app;
|
||||
webu = p_webua->webu;
|
||||
webua = p_webua;
|
||||
webuc = new cls_webu_common(p_webua);
|
||||
stream_pos = 0;
|
||||
picture = nullptr;;
|
||||
ctx_codec = nullptr;
|
||||
fmtctx = nullptr;
|
||||
}
|
||||
|
||||
cls_webu_mpegts::~cls_webu_mpegts()
|
||||
{
|
||||
app = nullptr;
|
||||
webu = nullptr;
|
||||
webua = nullptr;
|
||||
delete webuc;
|
||||
if (picture != nullptr) {
|
||||
myframe_free(picture);
|
||||
picture = nullptr;
|
||||
}
|
||||
if (ctx_codec != nullptr) {
|
||||
myavcodec_close(ctx_codec);
|
||||
ctx_codec = nullptr;
|
||||
}
|
||||
if (fmtctx != nullptr) {
|
||||
if (fmtctx->pb != nullptr) {
|
||||
if (fmtctx->pb->buffer != nullptr) {
|
||||
av_free(fmtctx->pb->buffer);
|
||||
fmtctx->pb->buffer = nullptr;
|
||||
}
|
||||
avio_context_free(&fmtctx->pb);
|
||||
fmtctx->pb = nullptr;
|
||||
}
|
||||
avformat_free_context(fmtctx);
|
||||
fmtctx = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,31 @@
|
||||
#ifndef _INCLUDE_WEBU_MPEGTS_HPP_
|
||||
#define _INCLUDE_WEBU_MPEGTS_HPP_
|
||||
|
||||
mhdrslt webu_mpegts_main(ctx_webui *webui);
|
||||
void webu_mpegts_free_context(ctx_webui *webui);
|
||||
class cls_webu_mpegts {
|
||||
public:
|
||||
cls_webu_mpegts(cls_webu_ans *p_webua);
|
||||
~cls_webu_mpegts();
|
||||
int avio_buf(myuint *buf, int buf_size);
|
||||
ssize_t response(char *buf, size_t max);
|
||||
mhdrslt main();
|
||||
|
||||
private:
|
||||
ctx_motapp *app;
|
||||
cls_webu *webu;
|
||||
cls_webu_ans *webua;
|
||||
cls_webu_common *webuc;
|
||||
|
||||
AVFrame *picture;
|
||||
AVFormatContext *fmtctx;
|
||||
AVCodecContext *ctx_codec;
|
||||
size_t stream_pos; /* Stream position of sent image */
|
||||
struct timespec start_time; /* Start time of the stream*/
|
||||
|
||||
int pic_send(unsigned char *img);
|
||||
int pic_get();
|
||||
void resetpos();
|
||||
int getimg();
|
||||
int open_mpegts();
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE_WEBU_MPEGTS_HPP_ */
|
||||
|
||||
@@ -21,13 +21,35 @@
|
||||
#include "logger.hpp"
|
||||
#include "util.hpp"
|
||||
#include "webu.hpp"
|
||||
#include "webu_ans.hpp"
|
||||
#include "webu_html.hpp"
|
||||
#include "webu_common.hpp"
|
||||
#include "webu_post.hpp"
|
||||
|
||||
/**************Callback functions for MHD **********************/
|
||||
|
||||
mhdrslt webup_iterate_post (void *ptr, enum MHD_ValueKind kind
|
||||
, const char *key, const char *filename, const char *content_type
|
||||
, const char *transfer_encoding, const char *data, uint64_t off, size_t datasz)
|
||||
{
|
||||
(void) kind;
|
||||
(void) filename;
|
||||
(void) content_type;
|
||||
(void) transfer_encoding;
|
||||
(void) off;
|
||||
cls_webu_post *webu_post;
|
||||
|
||||
webu_post = (cls_webu_post *)ptr;
|
||||
return webu_post->iterate_post(key, data, datasz);
|
||||
}
|
||||
|
||||
/**************Class methods**********************/
|
||||
|
||||
/* Process the add camera action */
|
||||
static void webu_post_cam_add(ctx_webui *webui)
|
||||
void cls_webu_post::cam_add()
|
||||
{
|
||||
int indx, maxcnt;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
@@ -45,15 +67,15 @@ static void webu_post_cam_add(ctx_webui *webui)
|
||||
|
||||
maxcnt = 100;
|
||||
|
||||
webui->motapp->cam_add = true;
|
||||
app->cam_add = true;
|
||||
indx = 0;
|
||||
while ((webui->motapp->cam_add == true) && (indx < maxcnt)) {
|
||||
while ((app->cam_add == true) && (indx < maxcnt)) {
|
||||
SLEEP(0, 50000000)
|
||||
indx++;
|
||||
}
|
||||
|
||||
if (indx == maxcnt) {
|
||||
webui->motapp->cam_add = false;
|
||||
app->cam_add = false;
|
||||
MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO, "Error adding camera. Timed out");
|
||||
return;
|
||||
}
|
||||
@@ -61,11 +83,12 @@ static void webu_post_cam_add(ctx_webui *webui)
|
||||
MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO, "New camera added.");
|
||||
|
||||
}
|
||||
|
||||
/* Process the delete camera action */
|
||||
static void webu_post_cam_delete(ctx_webui *webui)
|
||||
void cls_webu_post::cam_delete()
|
||||
{
|
||||
int indx, maxcnt;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
@@ -79,66 +102,65 @@ static void webu_post_cam_delete(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
|
||||
if (webui->camindx == -1) {
|
||||
if (webua->camindx == -1) {
|
||||
MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO, "No camera specified for deletion." );
|
||||
return;
|
||||
} else {
|
||||
MOTPLS_LOG(INF, TYPE_ALL, NO_ERRNO, "Deleting camera.");
|
||||
}
|
||||
|
||||
webui->motapp->cam_delete = webui->camindx;
|
||||
app->cam_delete = webua->camindx;
|
||||
|
||||
maxcnt = 100;
|
||||
indx = 0;
|
||||
while ((webui->motapp->cam_delete != -1) && (indx < maxcnt)) {
|
||||
while ((app->cam_delete != -1) && (indx < maxcnt)) {
|
||||
SLEEP(0, 50000000)
|
||||
indx++;
|
||||
}
|
||||
if (indx == maxcnt) {
|
||||
MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO, "Error stopping camera. Timed out shutting down");
|
||||
webui->motapp->cam_delete = -1;
|
||||
app->cam_delete = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Get the command, device_id and camera index from the post data */
|
||||
void webu_post_cmdindx(ctx_webui *webui)
|
||||
void cls_webu_post::parse_cmd()
|
||||
{
|
||||
int indx;
|
||||
|
||||
webui->post_cmd = "";
|
||||
webui->camindx = -1;
|
||||
webui->device_id = -1;
|
||||
post_cmd = "";
|
||||
webua->camindx = -1;
|
||||
webua->device_id = -1;
|
||||
|
||||
for (indx = 0; indx < webui->post_sz; indx++) {
|
||||
if (mystreq(webui->post_info[indx].key_nm, "command")) {
|
||||
webui->post_cmd = webui->post_info[indx].key_val;
|
||||
for (indx = 0; indx < post_sz; indx++) {
|
||||
if (mystreq(post_info[indx].key_nm, "command")) {
|
||||
post_cmd = post_info[indx].key_val;
|
||||
}
|
||||
if (mystreq(webui->post_info[indx].key_nm, "camid")) {
|
||||
webui->device_id = atoi(webui->post_info[indx].key_val);
|
||||
if (mystreq(post_info[indx].key_nm, "camid")) {
|
||||
webua->device_id = atoi(post_info[indx].key_val);
|
||||
}
|
||||
|
||||
MOTPLS_LOG(DBG, TYPE_STREAM, NO_ERRNO ,"key: %s value: %s "
|
||||
, webui->post_info[indx].key_nm
|
||||
, webui->post_info[indx].key_val
|
||||
, post_info[indx].key_nm
|
||||
, post_info[indx].key_val
|
||||
);
|
||||
}
|
||||
|
||||
if (webui->post_cmd == "") {
|
||||
if (post_cmd == "") {
|
||||
MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO
|
||||
, "Invalid post request. No command");
|
||||
return;
|
||||
}
|
||||
if (webui->device_id == -1) {
|
||||
if (webua->device_id == -1) {
|
||||
MOTPLS_LOG(ERR, TYPE_ALL, NO_ERRNO
|
||||
, "Invalid post request. No camera id provided");
|
||||
return;
|
||||
}
|
||||
|
||||
for (indx=0; indx<webui->motapp->cam_cnt; indx++) {
|
||||
if (webui->motapp->cam_list[indx]->device_id == webui->device_id) {
|
||||
webui->camindx = indx;
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
if (app->cam_list[indx]->device_id == webua->device_id) {
|
||||
webua->camindx = indx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -146,10 +168,10 @@ void webu_post_cmdindx(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Process the event end action */
|
||||
void webu_post_action_eventend(ctx_webui *webui)
|
||||
void cls_webu_post::action_eventend()
|
||||
{
|
||||
int indx;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
@@ -163,21 +185,21 @@ void webu_post_action_eventend(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
|
||||
if (webui->device_id == 0) {
|
||||
for (indx=0; indx<webui->motapp->cam_cnt; indx++) {
|
||||
webui->motapp->cam_list[indx]->event_stop = true;
|
||||
if (webua->device_id == 0) {
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
app->cam_list[indx]->event_stop = true;
|
||||
}
|
||||
} else {
|
||||
webui->motapp->cam_list[webui->camindx]->event_stop = true;
|
||||
app->cam_list[webua->camindx]->event_stop = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Process the event start action */
|
||||
void webu_post_action_eventstart(ctx_webui *webui)
|
||||
void cls_webu_post::action_eventstart()
|
||||
{
|
||||
int indx;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
@@ -191,21 +213,21 @@ void webu_post_action_eventstart(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
|
||||
if (webui->device_id == 0) {
|
||||
for (indx=0; indx<webui->motapp->cam_cnt; indx++) {
|
||||
webui->motapp->cam_list[indx]->event_user = true;
|
||||
if (webua->device_id == 0) {
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
app->cam_list[indx]->event_user = true;
|
||||
}
|
||||
} else {
|
||||
webui->motapp->cam_list[webui->camindx]->event_user = true;
|
||||
app->cam_list[webua->camindx]->event_user = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Process the snapshot action */
|
||||
void webu_post_action_snapshot(ctx_webui *webui)
|
||||
void cls_webu_post::action_snapshot()
|
||||
{
|
||||
int indx;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
@@ -219,21 +241,21 @@ void webu_post_action_snapshot(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
|
||||
if (webui->device_id == 0) {
|
||||
for (indx=0; indx<webui->motapp->cam_cnt; indx++) {
|
||||
webui->motapp->cam_list[indx]->snapshot = true;
|
||||
if (webua->device_id == 0) {
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
app->cam_list[indx]->snapshot = true;
|
||||
}
|
||||
} else {
|
||||
webui->motapp->cam_list[webui->camindx]->snapshot = true;
|
||||
app->cam_list[webua->camindx]->snapshot = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Process the pause action */
|
||||
void webu_post_action_pause(ctx_webui *webui)
|
||||
void cls_webu_post::action_pause()
|
||||
{
|
||||
int indx;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
@@ -247,21 +269,21 @@ void webu_post_action_pause(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
|
||||
if (webui->device_id == 0) {
|
||||
for (indx=0; indx<webui->motapp->cam_cnt; indx++) {
|
||||
webui->motapp->cam_list[indx]->pause = true;
|
||||
if (webua->device_id == 0) {
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
app->cam_list[indx]->pause = true;
|
||||
}
|
||||
} else {
|
||||
webui->motapp->cam_list[webui->camindx]->pause = true;
|
||||
app->cam_list[webua->camindx]->pause = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Process the unpause action */
|
||||
void webu_post_action_unpause(ctx_webui *webui)
|
||||
void cls_webu_post::action_unpause()
|
||||
{
|
||||
int indx;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
@@ -275,21 +297,21 @@ void webu_post_action_unpause(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
|
||||
if (webui->device_id == 0) {
|
||||
for (indx=0; indx<webui->motapp->cam_cnt; indx++) {
|
||||
webui->motapp->cam_list[indx]->pause = false;
|
||||
if (webua->device_id == 0) {
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
app->cam_list[indx]->pause = false;
|
||||
}
|
||||
} else {
|
||||
webui->motapp->cam_list[webui->camindx]->pause = false;
|
||||
app->cam_list[webua->camindx]->pause = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Process the restart action */
|
||||
void webu_post_action_restart(ctx_webui *webui)
|
||||
void cls_webu_post::action_restart()
|
||||
{
|
||||
int indx;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
@@ -302,26 +324,26 @@ void webu_post_action_restart(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (webui->device_id == 0) {
|
||||
if (webua->device_id == 0) {
|
||||
MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO, _("Restarting all cameras"));
|
||||
for (indx=0; indx<webui->motapp->cam_cnt; indx++) {
|
||||
webui->motapp->cam_list[indx]->restart_dev = true;
|
||||
webui->motapp->cam_list[indx]->finish_dev = true;
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
app->cam_list[indx]->restart_dev = true;
|
||||
app->cam_list[indx]->finish_dev = true;
|
||||
}
|
||||
} else {
|
||||
MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO
|
||||
, _("Restarting camera %d")
|
||||
, webui->motapp->cam_list[webui->camindx]->device_id);
|
||||
webui->motapp->cam_list[webui->camindx]->restart_dev = true;
|
||||
webui->motapp->cam_list[webui->camindx]->finish_dev = true;
|
||||
, app->cam_list[webua->camindx]->device_id);
|
||||
app->cam_list[webua->camindx]->restart_dev = true;
|
||||
app->cam_list[webua->camindx]->finish_dev = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process the stop action */
|
||||
void webu_post_action_stop(ctx_webui *webui)
|
||||
void cls_webu_post::action_stop()
|
||||
{
|
||||
int indx;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
@@ -334,35 +356,35 @@ void webu_post_action_stop(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (webui->device_id == 0) {
|
||||
for (indx=0; indx<webui->motapp->cam_cnt; indx++) {
|
||||
if (webua->device_id == 0) {
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO
|
||||
, _("Stopping cam %d")
|
||||
, webui->motapp->cam_list[indx]->device_id);
|
||||
webui->motapp->cam_list[indx]->restart_dev = false;
|
||||
webui->motapp->cam_list[indx]->event_stop = true;
|
||||
webui->motapp->cam_list[indx]->event_user = false;
|
||||
webui->motapp->cam_list[indx]->finish_dev = true;
|
||||
, app->cam_list[indx]->device_id);
|
||||
app->cam_list[indx]->restart_dev = false;
|
||||
app->cam_list[indx]->event_stop = true;
|
||||
app->cam_list[indx]->event_user = false;
|
||||
app->cam_list[indx]->finish_dev = true;
|
||||
}
|
||||
} else {
|
||||
MOTPLS_LOG(NTC, TYPE_STREAM, NO_ERRNO
|
||||
, _("Stopping cam %d")
|
||||
, webui->motapp->cam_list[webui->camindx]->device_id);
|
||||
webui->motapp->cam_list[webui->camindx]->restart_dev = false;
|
||||
webui->motapp->cam_list[webui->camindx]->event_stop = true;
|
||||
webui->motapp->cam_list[webui->camindx]->event_user = false;
|
||||
webui->motapp->cam_list[webui->camindx]->finish_dev = true;
|
||||
, app->cam_list[webua->camindx]->device_id);
|
||||
app->cam_list[webua->camindx]->restart_dev = false;
|
||||
app->cam_list[webua->camindx]->event_stop = true;
|
||||
app->cam_list[webua->camindx]->event_user = false;
|
||||
app->cam_list[webua->camindx]->finish_dev = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Process the action_user */
|
||||
void webu_post_action_user(ctx_webui *webui)
|
||||
void cls_webu_post::action_user()
|
||||
{
|
||||
int indx, indx2;
|
||||
ctx_dev *cam;
|
||||
std::string tmp;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
@@ -376,13 +398,13 @@ void webu_post_action_user(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
|
||||
if (webui->device_id == 0) {
|
||||
for (indx=0; indx<webui->motapp->cam_cnt; indx++) {
|
||||
cam = webui->motapp->cam_list[indx];
|
||||
if (webua->device_id == 0) {
|
||||
for (indx=0; indx<app->cam_cnt; indx++) {
|
||||
cam = app->cam_list[indx];
|
||||
cam->action_user[0] = '\0';
|
||||
for (indx2 = 0; indx2 < webui->post_sz; indx2++) {
|
||||
if (mystreq(webui->post_info[indx2].key_nm, "user")) {
|
||||
tmp = std::string(webui->post_info[indx2].key_val);
|
||||
for (indx2 = 0; indx2 < post_sz; indx2++) {
|
||||
if (mystreq(post_info[indx2].key_nm, "user")) {
|
||||
tmp = std::string(post_info[indx2].key_val);
|
||||
}
|
||||
}
|
||||
for (indx2 = 0; indx2<(int)tmp.length(); indx2++) {
|
||||
@@ -400,11 +422,11 @@ void webu_post_action_user(ctx_webui *webui)
|
||||
util_exec_command(cam, cam->conf->on_action_user.c_str(), NULL);
|
||||
}
|
||||
} else {
|
||||
cam = webui->motapp->cam_list[webui->camindx];
|
||||
cam = app->cam_list[webua->camindx];
|
||||
cam->action_user[0] = '\0';
|
||||
for (indx2 = 0; indx2 < webui->post_sz; indx2++) {
|
||||
if (mystreq(webui->post_info[indx2].key_nm, "user")) {
|
||||
tmp = std::string(webui->post_info[indx2].key_val);
|
||||
for (indx2 = 0; indx2 < post_sz; indx2++) {
|
||||
if (mystreq(post_info[indx2].key_nm, "user")) {
|
||||
tmp = std::string(post_info[indx2].key_val);
|
||||
}
|
||||
}
|
||||
for (indx2 = 0; indx2<(int)tmp.length(); indx2++) {
|
||||
@@ -426,9 +448,9 @@ void webu_post_action_user(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Process the write config action */
|
||||
void webu_post_write_config(ctx_webui *webui)
|
||||
void cls_webu_post::write_config()
|
||||
{
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
for (it = lst->begin(); it != lst->end(); it++) {
|
||||
@@ -442,19 +464,19 @@ void webu_post_write_config(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
|
||||
conf_parms_write(webui->motapp);
|
||||
conf_parms_write(app);
|
||||
|
||||
}
|
||||
|
||||
/* Process the configuration parameters */
|
||||
static void webu_post_config(ctx_webui *webui)
|
||||
void cls_webu_post::config()
|
||||
{
|
||||
int indx, indx2;
|
||||
std::string tmpname;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
if (webui->camindx == -1) {
|
||||
if (webua->camindx == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -469,11 +491,11 @@ static void webu_post_config(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
|
||||
for (indx = 0; indx < webui->post_sz; indx++) {
|
||||
if (mystrne(webui->post_info[indx].key_nm, "command") &&
|
||||
mystrne(webui->post_info[indx].key_nm, "camid")) {
|
||||
for (indx = 0; indx < post_sz; indx++) {
|
||||
if (mystrne(post_info[indx].key_nm, "command") &&
|
||||
mystrne(post_info[indx].key_nm, "camid")) {
|
||||
|
||||
tmpname = webui->post_info[indx].key_nm;
|
||||
tmpname = post_info[indx].key_nm;
|
||||
indx2=0;
|
||||
while (config_parms_depr[indx2].parm_name != "") {
|
||||
if (config_parms_depr[indx2].parm_name == tmpname) {
|
||||
@@ -486,7 +508,7 @@ static void webu_post_config(ctx_webui *webui)
|
||||
/* Ignore any requests for parms above webcontrol_parms level. */
|
||||
indx2=0;
|
||||
while (config_parms[indx2].parm_name != "") {
|
||||
if ((config_parms[indx2].webui_level > webui->motapp->conf->webcontrol_parms) ||
|
||||
if ((config_parms[indx2].webui_level > app->conf->webcontrol_parms) ||
|
||||
(config_parms[indx2].webui_level == WEBUI_LEVEL_NEVER) ) {
|
||||
indx2++;
|
||||
continue;
|
||||
@@ -499,13 +521,13 @@ static void webu_post_config(ctx_webui *webui)
|
||||
|
||||
if (config_parms[indx2].parm_name != "") {
|
||||
if (config_parms[indx2].parm_cat == PARM_CAT_00) {
|
||||
conf_edit_set(webui->motapp->conf
|
||||
conf_edit_set(app->conf
|
||||
, config_parms[indx2].parm_name
|
||||
, webui->post_info[indx].key_val);
|
||||
, post_info[indx].key_val);
|
||||
} else {
|
||||
conf_edit_set(webui->motapp->cam_list[webui->camindx]->conf
|
||||
conf_edit_set(app->cam_list[webua->camindx]->conf
|
||||
, config_parms[indx2].parm_name
|
||||
, webui->post_info[indx].key_val);
|
||||
, post_info[indx].key_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -514,13 +536,13 @@ static void webu_post_config(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Process the ptz action */
|
||||
void webu_post_ptz(ctx_webui *webui)
|
||||
void cls_webu_post::ptz()
|
||||
{
|
||||
ctx_dev *cam;
|
||||
p_lst *lst = &webui->motapp->webcontrol_actions->params_array;
|
||||
p_lst *lst = &webu->wb_actions->params_array;
|
||||
p_it it;
|
||||
|
||||
if (webui->camindx == -1) {
|
||||
if (webua->camindx == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -534,34 +556,34 @@ void webu_post_ptz(ctx_webui *webui)
|
||||
}
|
||||
}
|
||||
}
|
||||
cam = webui->motapp->cam_list[webui->camindx];
|
||||
cam = app->cam_list[webua->camindx];
|
||||
|
||||
if ((webui->post_cmd == "pan_left") &&
|
||||
if ((post_cmd == "pan_left") &&
|
||||
(cam->conf->ptz_pan_left != "")) {
|
||||
cam->frame_skip = cam->conf->ptz_wait;
|
||||
util_exec_command(cam, cam->conf->ptz_pan_left.c_str(), NULL);
|
||||
|
||||
} else if ((webui->post_cmd == "pan_right") &&
|
||||
} else if ((post_cmd == "pan_right") &&
|
||||
(cam->conf->ptz_pan_right != "")) {
|
||||
cam->frame_skip = cam->conf->ptz_wait;
|
||||
util_exec_command(cam, cam->conf->ptz_pan_right.c_str(), NULL);
|
||||
|
||||
} else if ((webui->post_cmd == "tilt_up") &&
|
||||
} else if ((post_cmd == "tilt_up") &&
|
||||
(cam->conf->ptz_tilt_up != "")) {
|
||||
cam->frame_skip = cam->conf->ptz_wait;
|
||||
util_exec_command(cam, cam->conf->ptz_tilt_up.c_str(), NULL);
|
||||
|
||||
} else if ((webui->post_cmd == "tilt_down") &&
|
||||
} else if ((post_cmd == "tilt_down") &&
|
||||
(cam->conf->ptz_tilt_down != "")) {
|
||||
cam->frame_skip = cam->conf->ptz_wait;
|
||||
util_exec_command(cam, cam->conf->ptz_tilt_down.c_str(), NULL);
|
||||
|
||||
} else if ((webui->post_cmd == "zoom_in") &&
|
||||
} else if ((post_cmd == "zoom_in") &&
|
||||
(cam->conf->ptz_zoom_in != "")) {
|
||||
cam->frame_skip = cam->conf->ptz_wait;
|
||||
util_exec_command(cam, cam->conf->ptz_zoom_in.c_str(), NULL);
|
||||
|
||||
} else if ((webui->post_cmd == "zoom_out") &&
|
||||
} else if ((post_cmd == "zoom_out") &&
|
||||
(cam->conf->ptz_zoom_out != "")) {
|
||||
cam->frame_skip = cam->conf->ptz_wait;
|
||||
util_exec_command(cam, cam->conf->ptz_zoom_out.c_str(), NULL);
|
||||
@@ -573,65 +595,189 @@ void webu_post_ptz(ctx_webui *webui)
|
||||
}
|
||||
|
||||
/* Process the actions from the webcontrol that the user requested */
|
||||
void webu_post_main(ctx_webui *webui)
|
||||
void cls_webu_post::process_actions()
|
||||
{
|
||||
parse_cmd();
|
||||
|
||||
webu_post_cmdindx(webui);
|
||||
|
||||
if (webui->post_cmd == "") {
|
||||
if (post_cmd == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (webui->post_cmd == "eventend") {
|
||||
webu_post_action_eventend(webui);
|
||||
if (post_cmd == "eventend") {
|
||||
action_eventend();
|
||||
|
||||
} else if (webui->post_cmd == "eventstart") {
|
||||
webu_post_action_eventstart(webui);
|
||||
} else if (post_cmd == "eventstart") {
|
||||
action_eventstart();
|
||||
|
||||
} else if (webui->post_cmd == "snapshot") {
|
||||
webu_post_action_snapshot(webui);
|
||||
} else if (post_cmd == "snapshot") {
|
||||
action_snapshot();
|
||||
|
||||
} else if (webui->post_cmd == "pause") {
|
||||
webu_post_action_pause(webui);
|
||||
} else if (post_cmd == "pause") {
|
||||
action_pause();
|
||||
|
||||
} else if (webui->post_cmd == "unpause") {
|
||||
webu_post_action_unpause(webui);
|
||||
} else if (post_cmd == "unpause") {
|
||||
action_unpause();
|
||||
|
||||
} else if (webui->post_cmd == "restart") {
|
||||
webu_post_action_restart(webui);
|
||||
} else if (post_cmd == "restart") {
|
||||
action_restart();
|
||||
|
||||
} else if (webui->post_cmd == "stop") {
|
||||
webu_post_action_stop(webui);
|
||||
} else if (post_cmd == "stop") {
|
||||
action_stop();
|
||||
|
||||
} else if (webui->post_cmd == "config_write") {
|
||||
webu_post_write_config(webui);
|
||||
} else if (post_cmd == "config_write") {
|
||||
write_config();
|
||||
|
||||
} else if (webui->post_cmd == "camera_add") {
|
||||
webu_post_cam_add(webui);
|
||||
} else if (post_cmd == "camera_add") {
|
||||
cam_add();
|
||||
|
||||
} else if (webui->post_cmd == "camera_delete") {
|
||||
webu_post_cam_delete(webui);
|
||||
} else if (post_cmd == "camera_delete") {
|
||||
cam_delete();
|
||||
|
||||
} else if (webui->post_cmd == "config") {
|
||||
webu_post_config(webui);
|
||||
} else if (post_cmd == "config") {
|
||||
config();
|
||||
|
||||
} else if (webui->post_cmd == "action_user") {
|
||||
webu_post_action_user(webui);
|
||||
} else if (post_cmd == "action_user") {
|
||||
action_user();
|
||||
|
||||
} else if (
|
||||
(webui->post_cmd == "pan_left") ||
|
||||
(webui->post_cmd == "pan_right") ||
|
||||
(webui->post_cmd == "tilt_up") ||
|
||||
(webui->post_cmd == "tilt_down") ||
|
||||
(webui->post_cmd == "zoom_in") ||
|
||||
(webui->post_cmd == "zoom_out")) {
|
||||
webu_post_ptz(webui);
|
||||
(post_cmd == "pan_left") ||
|
||||
(post_cmd == "pan_right") ||
|
||||
(post_cmd == "tilt_up") ||
|
||||
(post_cmd == "tilt_down") ||
|
||||
(post_cmd == "zoom_in") ||
|
||||
(post_cmd == "zoom_out")) {
|
||||
ptz();
|
||||
|
||||
} else {
|
||||
MOTPLS_LOG(INF, TYPE_STREAM, NO_ERRNO
|
||||
, _("Invalid action requested: command: >%s< camindx : >%d< ")
|
||||
, webui->post_cmd.c_str(), webui->camindx);
|
||||
, post_cmd.c_str(), webua->camindx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*Append more data on to an existing entry in the post info structure */
|
||||
void cls_webu_post::iterate_post_append(int indx
|
||||
, const char *data, size_t datasz)
|
||||
{
|
||||
post_info[indx].key_val = (char*)realloc(
|
||||
post_info[indx].key_val
|
||||
, post_info[indx].key_sz + datasz + 1);
|
||||
|
||||
memset(post_info[indx].key_val +
|
||||
post_info[indx].key_sz, 0, datasz + 1);
|
||||
|
||||
if (datasz > 0) {
|
||||
memcpy(post_info[indx].key_val +
|
||||
post_info[indx].key_sz, data, datasz);
|
||||
}
|
||||
|
||||
post_info[indx].key_sz += datasz;
|
||||
}
|
||||
|
||||
/*Create new entry in the post info structure */
|
||||
void cls_webu_post::iterate_post_new(const char *key
|
||||
, const char *data, size_t datasz)
|
||||
{
|
||||
int retcd;
|
||||
|
||||
post_sz++;
|
||||
if (post_sz == 1) {
|
||||
post_info = (ctx_key *)malloc(sizeof(ctx_key));
|
||||
} else {
|
||||
post_info = (ctx_key *)realloc(post_info
|
||||
, post_sz * sizeof(ctx_key));
|
||||
}
|
||||
|
||||
post_info[post_sz-1].key_nm = (char*)malloc(strlen(key)+1);
|
||||
retcd = snprintf(post_info[post_sz-1].key_nm, strlen(key)+1, "%s", key);
|
||||
|
||||
post_info[post_sz-1].key_val = (char*)malloc(datasz+1);
|
||||
memset(post_info[post_sz-1].key_val,0,datasz+1);
|
||||
if (datasz > 0) {
|
||||
memcpy(post_info[post_sz-1].key_val, data, datasz);
|
||||
}
|
||||
|
||||
post_info[post_sz-1].key_sz = datasz;
|
||||
|
||||
if (retcd < 0) {
|
||||
printf("Error processing post data\n");
|
||||
}
|
||||
}
|
||||
|
||||
mhdrslt cls_webu_post::iterate_post (const char *key, const char *data, size_t datasz)
|
||||
{
|
||||
int indx;
|
||||
|
||||
for (indx=0; indx < post_sz; indx++) {
|
||||
if (mystreq(post_info[indx].key_nm, key)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (indx < post_sz) {
|
||||
iterate_post_append(indx, data, datasz);
|
||||
} else {
|
||||
iterate_post_new(key, data, datasz);
|
||||
}
|
||||
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
mhdrslt cls_webu_post::processor_init()
|
||||
{
|
||||
post_processor = MHD_create_post_processor (webua->connection
|
||||
, WEBUI_POST_BFRSZ, webup_iterate_post, (void *)this);
|
||||
if (post_processor == NULL) {
|
||||
return MHD_NO;
|
||||
}
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
mhdrslt cls_webu_post::processor_start(const char *upload_data, size_t *upload_data_size)
|
||||
{
|
||||
mhdrslt retcd;
|
||||
|
||||
if (*upload_data_size != 0) {
|
||||
retcd = MHD_post_process (post_processor, upload_data, *upload_data_size);
|
||||
*upload_data_size = 0;
|
||||
} else {
|
||||
pthread_mutex_lock(&app->mutex_post);
|
||||
process_actions();
|
||||
pthread_mutex_unlock(&app->mutex_post);
|
||||
/* Send updated page back to user */
|
||||
webu_html = new cls_webu_html(webua);
|
||||
webu_html->main();
|
||||
delete webu_html;
|
||||
webu_html = nullptr;
|
||||
webua->mhd_send();
|
||||
retcd = MHD_YES;
|
||||
}
|
||||
return retcd;
|
||||
}
|
||||
|
||||
cls_webu_post::cls_webu_post(cls_webu_ans *p_webua)
|
||||
{
|
||||
app = p_webua->app;
|
||||
webu = p_webua->webu;
|
||||
webua = p_webua;
|
||||
|
||||
post_processor = nullptr;
|
||||
post_info = nullptr;
|
||||
post_sz = 0;
|
||||
|
||||
}
|
||||
|
||||
cls_webu_post::~cls_webu_post()
|
||||
{
|
||||
int indx;
|
||||
|
||||
if (post_processor != nullptr) {
|
||||
MHD_destroy_post_processor (post_processor);
|
||||
}
|
||||
|
||||
for (indx = 0; indx<post_sz; indx++) {
|
||||
myfree(&post_info[indx].key_nm);
|
||||
myfree(&post_info[indx].key_val);
|
||||
}
|
||||
myfree(&post_info);
|
||||
}
|
||||
@@ -18,7 +18,44 @@
|
||||
|
||||
#ifndef _INCLUDE_WEBU_POST_HPP_
|
||||
#define _INCLUDE_WEBU_POST_HPP_
|
||||
class cls_webu_post {
|
||||
public:
|
||||
cls_webu_post(cls_webu_ans *webua);
|
||||
~cls_webu_post();
|
||||
|
||||
void webu_post_main(ctx_webui *webui);
|
||||
mhdrslt iterate_post (const char *key, const char *data, size_t datasz);
|
||||
mhdrslt processor_init();
|
||||
mhdrslt processor_start(const char *upload_data, size_t *upload_data_size);
|
||||
|
||||
private:
|
||||
ctx_motapp *app;
|
||||
cls_webu *webu;
|
||||
cls_webu_ans *webua;
|
||||
cls_webu_html *webu_html;
|
||||
|
||||
std::string post_cmd;
|
||||
int post_sz; /* The number of entries in the post info */
|
||||
ctx_key *post_info; /* Structure of the entries provided from the post data */
|
||||
struct MHD_PostProcessor *post_processor; /* Processor for handling Post method connections */
|
||||
|
||||
void cam_add();
|
||||
void cam_delete();
|
||||
void parse_cmd();
|
||||
void iterate_post_append(int indx, const char *data, size_t datasz);
|
||||
void iterate_post_new(const char *key, const char *data, size_t datasz);
|
||||
void process_actions();
|
||||
void action_eventend();
|
||||
void action_eventstart();
|
||||
void action_snapshot();
|
||||
void action_pause();
|
||||
void action_unpause();
|
||||
void action_restart();
|
||||
void action_stop();
|
||||
void action_user();
|
||||
void write_config();
|
||||
void config();
|
||||
void ptz();
|
||||
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE_WEBU_POST_HPP_ */
|
||||
|
||||
1279
src/webu_stream.cpp
1279
src/webu_stream.cpp
File diff suppressed because it is too large
Load Diff
@@ -18,18 +18,36 @@
|
||||
|
||||
#ifndef _INCLUDE_WEBU_STREAM_HPP_
|
||||
#define _INCLUDE_WEBU_STREAM_HPP_
|
||||
class cls_webu_stream {
|
||||
public:
|
||||
cls_webu_stream(cls_webu_ans *webua);
|
||||
~cls_webu_stream();
|
||||
|
||||
void webu_stream_init(ctx_dev *cam);
|
||||
void webu_stream_deinit(ctx_dev *cam);
|
||||
void webu_stream_getimg(ctx_dev *cam);
|
||||
mhdrslt main();
|
||||
ssize_t mjpeg_response (char *buf, size_t max);
|
||||
|
||||
mhdrslt webu_stream_main(ctx_webui *webui);
|
||||
void webu_stream_delay(ctx_webui *webui);
|
||||
void webu_stream_checkbuffers(ctx_webui *webui);
|
||||
void webu_stream_img_sizes(ctx_webui *webui, ctx_dev *cam, int &img_w, int &img_h);
|
||||
void webu_stream_all_sizes(ctx_webui *webui);
|
||||
void webu_stream_all_buffers(ctx_webui *webui);
|
||||
void webu_stream_all_getimg(ctx_webui *webui);
|
||||
bool webu_stream_check_finish(ctx_webui *webui);
|
||||
private:
|
||||
ctx_motapp *app;
|
||||
cls_webu *webu;
|
||||
cls_webu_ans *webua;
|
||||
cls_webu_common *webuc;
|
||||
cls_webu_mpegts *webu_mpegts;
|
||||
|
||||
size_t stream_pos;
|
||||
|
||||
void mjpeg_all_img();
|
||||
void mjpeg_one_img();
|
||||
void static_all_img();
|
||||
void static_one_img();
|
||||
mhdrslt stream_static();
|
||||
mhdrslt stream_mjpeg();
|
||||
|
||||
int checks();
|
||||
bool all_ready();
|
||||
void all_cnct();
|
||||
void jpg_cnct();
|
||||
void ts_cnct();
|
||||
void set_cnct_type();
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE_WEBU_STREAM_HPP_ */
|
||||
|
||||
Reference in New Issue
Block a user