Merge pull request #3314 from Carbenium/path-max

Fix Wformat for stringtf and convert path buffers depending on PATH_MAX to std::string
This commit is contained in:
Isaac Connor 2021-07-07 11:34:03 -04:00 committed by GitHub
commit b0cf3a4732
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 311 additions and 332 deletions

View File

@ -39,16 +39,15 @@ void zmLoadStaticConfig() {
// update the Config hash with those values
DIR *configSubFolder = opendir(ZM_CONFIG_SUBDIR);
if (configSubFolder) { // subfolder exists and is readable
char glob_pattern[PATH_MAX] = "";
snprintf(glob_pattern, sizeof(glob_pattern), "%s/*.conf", ZM_CONFIG_SUBDIR);
std::string glob_pattern = stringtf("%s/*.conf", ZM_CONFIG_SUBDIR);
glob_t pglob;
int glob_status = glob(glob_pattern, 0, nullptr, &pglob);
int glob_status = glob(glob_pattern.c_str(), 0, nullptr, &pglob);
if (glob_status != 0) {
if (glob_status < 0) {
Error("Can't glob '%s': %s", glob_pattern, strerror(errno));
Error("Can't glob '%s': %s", glob_pattern.c_str(), strerror(errno));
} else {
Debug(1, "Can't glob '%s': %d", glob_pattern, glob_status);
Debug(1, "Can't glob '%s': %d", glob_pattern.c_str(), glob_status);
}
} else {
for (unsigned int i = 0; i < pglob.gl_pathc; i++) {
@ -100,13 +99,10 @@ void zmLoadDBConfig() {
}
}
snprintf(staticConfig.capture_file_format, sizeof(staticConfig.capture_file_format), "%%s/%%0%dd-capture.jpg",
config.event_image_digits);
snprintf(staticConfig.analyse_file_format, sizeof(staticConfig.analyse_file_format), "%%s/%%0%dd-analyse.jpg",
config.event_image_digits);
snprintf(staticConfig.general_file_format, sizeof(staticConfig.general_file_format), "%%s/%%0%dd-%%s",
config.event_image_digits);
snprintf(staticConfig.video_file_format, sizeof(staticConfig.video_file_format), "%%s/%%s");
staticConfig.capture_file_format = stringtf("%%s/%%0%dd-capture.jpg", config.event_image_digits);
staticConfig.analyse_file_format = stringtf("%%s/%%0%dd-analyse.jpg", config.event_image_digits);
staticConfig.general_file_format = stringtf("%%s/%%0%dd-%%s", config.event_image_digits);
staticConfig.video_file_format = "%s/%s";
}
void process_configfile(char const *configFile) {

View File

@ -25,10 +25,6 @@
#include "zm_config_defines.h"
#include <string>
#if !defined(PATH_MAX)
#define PATH_MAX 1024
#endif
#define ZM_MAX_IMAGE_WIDTH 2048 // The largest image we imagine ever handling
#define ZM_MAX_IMAGE_HEIGHT 1536 // The largest image we imagine ever handling
#define ZM_MAX_IMAGE_COLOURS 4 // The largest image we imagine ever handling
@ -69,10 +65,10 @@ struct StaticConfig {
std::string PATH_LOGS;
std::string PATH_SWAP;
std::string PATH_ARP;
char capture_file_format[PATH_MAX];
char analyse_file_format[PATH_MAX];
char general_file_format[PATH_MAX];
char video_file_format[PATH_MAX];
std::string capture_file_format;
std::string analyse_file_format;
std::string general_file_format;
std::string video_file_format;
};
extern StaticConfig staticConfig;

View File

@ -466,7 +466,7 @@ void Event::AddFrame(Image *image,
if (image) {
if (save_jpegs & 1) {
std::string event_file = stringtf(staticConfig.capture_file_format, path.c_str(), frames);
std::string event_file = stringtf(staticConfig.capture_file_format.c_str(), path.c_str(), frames);
Debug(1, "Writing capture frame %d to %s", frames, event_file.c_str());
if (!WriteFrameImage(image, timestamp, event_file.c_str())) {
Error("Failed to write frame image");
@ -496,7 +496,7 @@ void Event::AddFrame(Image *image,
}
if (alarm_image and (save_jpegs & 2)) {
std::string event_file = stringtf(staticConfig.analyse_file_format, path.c_str(), frames);
std::string event_file = stringtf(staticConfig.analyse_file_format.c_str(), path.c_str(), frames);
Debug(1, "Writing analysis frame %d", frames);
if (!WriteFrameImage(alarm_image, timestamp, event_file.c_str(), true)) {
Error("Failed to write analysis frame image");

View File

@ -24,6 +24,7 @@
#include "zm_define.h"
#include "zm_storage.h"
#include "zm_time.h"
#include "zm_utils.h"
#include "zm_zone.h"
#include <map>
@ -128,18 +129,17 @@ class Event {
bool SetPath(Storage *storage);
public:
static const char *getSubPath(tm time) {
static char subpath[PATH_MAX] = "";
snprintf(subpath, sizeof(subpath), "%02d/%02d/%02d/%02d/%02d/%02d",
time.tm_year-100, time.tm_mon+1, time.tm_mday,
time.tm_hour, time.tm_min, time.tm_sec);
return subpath;
}
static const char *getSubPath(time_t *time) {
tm time_tm = {};
localtime_r(time, &time_tm);
return Event::getSubPath(time_tm);
}
static std::string getSubPath(tm time) {
std::string subpath = stringtf("%02d/%02d/%02d/%02d/%02d/%02d",
time.tm_year - 100, time.tm_mon + 1, time.tm_mday,
time.tm_hour, time.tm_min, time.tm_sec);
return subpath;
}
static std::string getSubPath(time_t *time) {
tm time_tm = {};
localtime_r(time, &time_tm);
return Event::getSubPath(time_tm);
}
const char* getEventFile() const {
return video_file.c_str();

View File

@ -44,7 +44,7 @@ constexpr Milliseconds EventStream::STREAM_PAUSE_WAIT;
bool EventStream::loadInitialEventData(int monitor_id, SystemTimePoint event_time) {
std::string sql = stringtf("SELECT `Id` FROM `Events` WHERE "
"`MonitorId` = %d AND unix_timestamp(`EndDateTime`) > %ld "
"ORDER BY `Id` ASC LIMIT 1", monitor_id, event_time);
"ORDER BY `Id` ASC LIMIT 1", monitor_id, std::chrono::system_clock::to_time_t(event_time));
MYSQL_RES *result = zmDbFetch(sql);
if (!result)
@ -145,7 +145,7 @@ bool EventStream::loadEventData(uint64_t event_id) {
event_data->duration = std::chrono::duration_cast<Microseconds>(event_data->end_time - event_data->start_time);
event_data->frames_duration =
std::chrono::duration_cast<Microseconds>(dbrow[5] ? FPSeconds(atof(dbrow[5])) : FPSeconds(0.0));
strncpy(event_data->video_file, dbrow[6], sizeof(event_data->video_file) - 1);
event_data->video_file = std::string(dbrow[6]);
std::string scheme_str = std::string(dbrow[7]);
if ( scheme_str == "Deep" ) {
event_data->scheme = Storage::DEEP;
@ -180,44 +180,41 @@ bool EventStream::loadEventData(uint64_t event_id) {
time_t start_time_t = std::chrono::system_clock::to_time_t(event_data->start_time);
localtime_r(&start_time_t, &event_time);
if ( storage_path[0] == '/' )
snprintf(event_data->path, sizeof(event_data->path),
"%s/%u/%02d/%02d/%02d/%02d/%02d/%02d",
storage_path, event_data->monitor_id,
event_time.tm_year-100, event_time.tm_mon+1, event_time.tm_mday,
event_time.tm_hour, event_time.tm_min, event_time.tm_sec);
else
snprintf(event_data->path, sizeof(event_data->path),
"%s/%s/%u/%02d/%02d/%02d/%02d/%02d/%02d",
staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id,
event_time.tm_year-100, event_time.tm_mon+1, event_time.tm_mday,
event_time.tm_hour, event_time.tm_min, event_time.tm_sec);
} else if ( event_data->scheme == Storage::MEDIUM ) {
if (storage_path[0] == '/') {
event_data->path = stringtf("%s/%u/%02d/%02d/%02d/%02d/%02d/%02d",
storage_path, event_data->monitor_id,
event_time.tm_year - 100, event_time.tm_mon + 1, event_time.tm_mday,
event_time.tm_hour, event_time.tm_min, event_time.tm_sec);
} else {
event_data->path = stringtf("%s/%s/%u/%02d/%02d/%02d/%02d/%02d/%02d",
staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id,
event_time.tm_year - 100, event_time.tm_mon + 1, event_time.tm_mday,
event_time.tm_hour, event_time.tm_min, event_time.tm_sec);
}
} else if (event_data->scheme == Storage::MEDIUM) {
tm event_time = {};
time_t start_time_t = std::chrono::system_clock::to_time_t(event_data->start_time);
localtime_r(&start_time_t, &event_time);
if ( storage_path[0] == '/' )
snprintf(event_data->path, sizeof(event_data->path),
"%s/%u/%04d-%02d-%02d/%" PRIu64,
storage_path, event_data->monitor_id,
event_time.tm_year+1900, event_time.tm_mon+1, event_time.tm_mday,
event_data->event_id);
else
snprintf(event_data->path, sizeof(event_data->path),
"%s/%s/%u/%04d-%02d-%02d/%" PRIu64,
staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id,
event_time.tm_year+1900, event_time.tm_mon+1, event_time.tm_mday,
event_data->event_id);
if (storage_path[0] == '/') {
event_data->path = stringtf("%s/%u/%04d-%02d-%02d/%" PRIu64,
storage_path, event_data->monitor_id,
event_time.tm_year + 1900, event_time.tm_mon + 1, event_time.tm_mday,
event_data->event_id);
} else {
event_data->path = stringtf("%s/%s/%u/%04d-%02d-%02d/%" PRIu64,
staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id,
event_time.tm_year + 1900, event_time.tm_mon + 1, event_time.tm_mday,
event_data->event_id);
}
} else {
if ( storage_path[0] == '/' )
snprintf(event_data->path, sizeof(event_data->path), "%s/%u/%" PRIu64,
storage_path, event_data->monitor_id, event_data->event_id);
else
snprintf(event_data->path, sizeof(event_data->path), "%s/%s/%u/%" PRIu64,
staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id,
event_data->event_id);
if (storage_path[0] == '/') {
event_data->path = stringtf("%s/%u/%" PRIu64, storage_path, event_data->monitor_id, event_data->event_id);
} else {
event_data->path = stringtf("%s/%s/%u/%" PRIu64,
staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id,
event_data->event_id);
}
}
double fps = 1.0;
@ -289,17 +286,17 @@ bool EventStream::loadEventData(uint64_t event_id) {
}
mysql_free_result(result);
if ( event_data->video_file[0] || (monitor->GetOptVideoWriter() > 0) ) {
if ( !event_data->video_file[0] ) {
snprintf(event_data->video_file, sizeof(event_data->video_file), "%" PRIu64 "-%s", event_data->event_id, "video.mp4");
if (!event_data->video_file.empty() || (monitor->GetOptVideoWriter() > 0)) {
if (event_data->video_file.empty()) {
event_data->video_file = stringtf("%" PRIu64 "-%s", event_data->event_id, "video.mp4");
}
std::string filepath = std::string(event_data->path) + "/" + std::string(event_data->video_file);
std::string filepath = event_data->path + "/" + event_data->video_file;
Debug(1, "Loading video file from %s", filepath.c_str());
if ( ffmpeg_input )
delete ffmpeg_input;
delete ffmpeg_input;
ffmpeg_input = new FFmpeg_Input();
if ( 0 > ffmpeg_input->Open(filepath.c_str()) ) {
if (ffmpeg_input->Open(filepath.c_str()) < 0) {
Warning("Unable to open ffmpeg_input %s", filepath.c_str());
delete ffmpeg_input;
ffmpeg_input = nullptr;
@ -690,32 +687,30 @@ bool EventStream::checkEventLoaded() {
} // void EventStream::checkEventLoaded()
Image * EventStream::getImage( ) {
static char filepath[PATH_MAX];
snprintf(filepath, sizeof(filepath), staticConfig.capture_file_format, event_data->path, curr_frame_id);
Debug(2, "EventStream::getImage path(%s) from %s frame(%ld) ", filepath, event_data->path, curr_frame_id);
Image *image = new Image(filepath);
std::string path = stringtf(staticConfig.capture_file_format.c_str(), event_data->path.c_str(), curr_frame_id);
Debug(2, "EventStream::getImage path(%s) from %s frame(%ld) ", path.c_str(), event_data->path.c_str(), curr_frame_id);
Image *image = new Image(path.c_str());
return image;
}
bool EventStream::sendFrame(Microseconds delta_us) {
Debug(2, "Sending frame %ld", curr_frame_id);
static char filepath[PATH_MAX];
static struct stat filestat;
std::string filepath;
struct stat filestat = {};
// This needs to be abstracted. If we are saving jpgs, then load the capture file.
// If we are only saving analysis frames, then send that.
if ( event_data->SaveJPEGs & 1 ) {
snprintf(filepath, sizeof(filepath), staticConfig.capture_file_format, event_data->path, curr_frame_id);
} else if ( event_data->SaveJPEGs & 2 ) {
snprintf(filepath, sizeof(filepath), staticConfig.analyse_file_format, event_data->path, curr_frame_id);
if ( stat(filepath, &filestat) < 0 ) {
Debug(1, "analyze file %s not found will try to stream from other", filepath);
snprintf(filepath, sizeof(filepath), staticConfig.capture_file_format, event_data->path, curr_frame_id);
if ( stat(filepath, &filestat) < 0 ) {
Debug(1, "capture file %s not found either", filepath);
filepath[0] = 0;
if (event_data->SaveJPEGs & 1) {
filepath = stringtf(staticConfig.capture_file_format.c_str(), event_data->path.c_str(), curr_frame_id);
} else if (event_data->SaveJPEGs & 2) {
filepath = stringtf(staticConfig.analyse_file_format.c_str(), event_data->path.c_str(), curr_frame_id);
if (stat(filepath.c_str(), &filestat) < 0) {
Debug(1, "analyze file %s not found will try to stream from other", filepath.c_str());
filepath = stringtf(staticConfig.capture_file_format.c_str(), event_data->path.c_str(), curr_frame_id);
if (stat(filepath.c_str(), &filestat) < 0) {
Debug(1, "capture file %s not found either", filepath.c_str());
filepath = "";
}
}
} else if ( !ffmpeg_input ) {
@ -724,7 +719,7 @@ bool EventStream::sendFrame(Microseconds delta_us) {
}
if ( type == STREAM_MPEG ) {
Image image(filepath);
Image image(filepath.c_str());
Image *send_image = prepareImage(&image);
@ -739,20 +734,20 @@ bool EventStream::sendFrame(Microseconds delta_us) {
config.mpeg_timed_frames,
delta_us.count() * 1000);
} else {
bool send_raw = (type == STREAM_JPEG) && ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE)) && filepath[0];
bool send_raw = (type == STREAM_JPEG) && ((scale >= ZM_SCALE_BASE) && (zoom == ZM_SCALE_BASE)) && !filepath.empty();
fprintf(stdout, "--" BOUNDARY "\r\n");
if ( send_raw ) {
if ( !send_file(filepath) ) {
Error("Can't send %s: %s", filepath, strerror(errno));
if (send_raw) {
if (!send_file(filepath)) {
Error("Can't send %s: %s", filepath.c_str(), strerror(errno));
return false;
}
} else {
Image *image = nullptr;
if ( filepath[0] ) {
image = new Image(filepath);
if (!filepath.empty()) {
image = new Image(filepath.c_str());
} else if ( ffmpeg_input ) {
// Get the frame from the mp4 input
FrameData *frame_data = &event_data->frames[curr_frame_id-1];
@ -1088,24 +1083,24 @@ void EventStream::runStream() {
closeComms();
} // end void EventStream::runStream()
bool EventStream::send_file(const char *filepath) {
bool EventStream::send_file(const std::string &filepath) {
static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE];
int img_buffer_size = 0;
uint8_t *img_buffer = temp_img_buffer;
FILE *fdj = nullptr;
fdj = fopen(filepath, "rb");
fdj = fopen(filepath.c_str(), "rb");
if ( !fdj ) {
Error("Can't open %s: %s", filepath, strerror(errno));
std::string error_message = stringtf("Can't open %s: %s", filepath, strerror(errno));
Error("Can't open %s: %s", filepath.c_str(), strerror(errno));
std::string error_message = stringtf("Can't open %s: %s", filepath.c_str(), strerror(errno));
return sendTextFrame(error_message.c_str());
}
#if HAVE_SENDFILE
static struct stat filestat;
if ( fstat(fileno(fdj), &filestat) < 0 ) {
fclose(fdj); /* Close the file handle */
Error("Failed getting information about file %s: %s", filepath, strerror(errno));
Error("Failed getting information about file %s: %s", filepath.c_str(), strerror(errno));
return false;
}
if ( !filestat.st_size ) {
@ -1134,7 +1129,7 @@ bool EventStream::send_file(const char *filepath) {
}
return send_buffer(img_buffer, img_buffer_size);
} // end bool EventStream::send_file(const char * filepath)
}
bool EventStream::send_buffer(uint8_t* buffer, int size) {
if ( 0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", size) ) {

View File

@ -56,10 +56,10 @@ class EventStream : public StreamBase {
SystemTimePoint end_time;
Microseconds duration;
Microseconds frames_duration;
char path[PATH_MAX];
std::string path;
int n_frames; // # of frame rows returned from database
FrameData *frames;
char video_file[PATH_MAX];
std::string video_file;
Storage::Schemes scheme;
int SaveJPEGs;
Monitor::Orientation Orientation;
@ -124,7 +124,7 @@ class EventStream : public StreamBase {
void runStream() override;
Image *getImage();
private:
bool send_file(const char *filepath);
bool send_file(const std::string &filepath);
bool send_buffer(uint8_t * buffer, int size);
Storage *storage;
FFmpeg_Input *ffmpeg_input;

View File

@ -29,32 +29,26 @@
#define RAW_BUFFER 512
#define PIPE_SIZE 1024*1024
void Fifo::file_create_if_missing(
const char * path,
bool is_fifo,
bool delete_fake_fifo
) {
static struct stat st;
if ( stat(path, &st) == 0 ) {
if ( (!is_fifo) || S_ISFIFO(st.st_mode) || !delete_fake_fifo )
void Fifo::file_create_if_missing(const std::string &path, bool is_fifo, bool delete_fake_fifo) {
struct stat st = {};
if (stat(path.c_str(), &st) == 0) {
if ((!is_fifo) || S_ISFIFO(st.st_mode) || !delete_fake_fifo)
return;
Debug(5, "Supposed to be a fifo pipe but isn't, unlinking: %s", path);
unlink(path);
Debug(5, "Supposed to be a fifo pipe but isn't, unlinking: %s", path.c_str());
unlink(path.c_str());
}
if (!is_fifo) {
Debug(5, "Creating non fifo file as requested: %s", path);
int fd = ::open(path, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
Debug(5, "Creating non fifo file as requested: %s", path.c_str());
int fd = ::open(path.c_str(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
::close(fd);
return;
}
Debug(5, "Making fifo file of: %s", path);
mkfifo(path, S_IRUSR|S_IWUSR);
Debug(5, "Making fifo file of: %s", path.c_str());
mkfifo(path.c_str(), S_IRUSR | S_IWUSR);
}
void Fifo::fifo_create_if_missing(
const char * path,
bool delete_fake_fifo
) {
void Fifo::fifo_create_if_missing(const std::string &path, bool delete_fake_fifo) {
file_create_if_missing(path, true, delete_fake_fifo);
}
@ -62,7 +56,8 @@ Fifo::~Fifo() {
close();
}
bool Fifo::open() {
fifo_create_if_missing(path.c_str());
fifo_create_if_missing(path);
if (!on_blocking_abort) {
if ( (outfile = fopen(path.c_str(), "wb")) == nullptr ) {
Error("Can't open %s for writing: %s", path.c_str(), strerror(errno));

View File

@ -32,11 +32,8 @@ class Fifo {
int raw_fd;
public:
static void file_create_if_missing(
const char * path,
bool is_fifo,
bool delete_fake_fifo = true
);
static void file_create_if_missing(const std::string &path, bool is_fifo, bool delete_fake_fifo = true);
static void fifo_create_if_missing(const std::string &path, bool delete_fake_fifo = true);
Fifo() :
on_blocking_abort(true),
@ -51,12 +48,6 @@ class Fifo {
{}
~Fifo();
static void fifo_create_if_missing(
const char * path,
bool delete_fake_fifo = true);
static bool writePacket(std::string filename, const ZMPacket &packet);
static bool write(std::string filename, uint8_t *data, size_t size);

View File

@ -28,7 +28,7 @@
#define RAW_BUFFER 512
static bool zm_fifodbg_inited = false;
FILE *zm_fifodbg_log_fd = nullptr;
char zm_fifodbg_log[PATH_MAX] = "";
std::string zm_fifodbg_log;
static bool zmFifoDbgOpen() {
if ( zm_fifodbg_log_fd )
@ -36,7 +36,7 @@ static bool zmFifoDbgOpen() {
zm_fifodbg_log_fd = nullptr;
signal(SIGPIPE, SIG_IGN);
Fifo::fifo_create_if_missing(zm_fifodbg_log);
int fd = open(zm_fifodbg_log, O_WRONLY|O_NONBLOCK|O_TRUNC);
int fd = open(zm_fifodbg_log.c_str(), O_WRONLY | O_NONBLOCK | O_TRUNC);
if ( fd < 0 )
return false;
int res = flock(fd, LOCK_EX | LOCK_NB);
@ -54,8 +54,7 @@ static bool zmFifoDbgOpen() {
int zmFifoDbgInit(Monitor *monitor) {
zm_fifodbg_inited = true;
snprintf(zm_fifodbg_log, sizeof(zm_fifodbg_log), "%s/dbgpipe-%u.log",
staticConfig.PATH_SOCKS.c_str(), monitor->Id());
zm_fifodbg_log = stringtf("%s/dbgpipe-%u.log", staticConfig.PATH_SOCKS.c_str(), monitor->Id());
zmFifoDbgOpen();
return 1;
}

View File

@ -29,9 +29,9 @@
#define RAW_BUFFER 512
bool FifoStream::sendRAWFrames() {
static unsigned char buffer[RAW_BUFFER];
int fd = open(stream_path, O_RDONLY);
int fd = open(stream_path.c_str(), O_RDONLY);
if ( fd < 0 ) {
Error("Can't open %s: %s", stream_path, strerror(errno));
Error("Can't open %s: %s", stream_path.c_str(), strerror(errno));
return false;
}
while ( (bytes_read = read(fd, buffer, RAW_BUFFER)) ) {
@ -56,9 +56,9 @@ bool FifoStream::sendRAWFrames() {
bool FifoStream::sendMJEGFrames() {
static unsigned char buffer[ZM_MAX_IMAGE_SIZE];
int fd = open(stream_path, O_RDONLY);
int fd = open(stream_path.c_str(), O_RDONLY);
if ( fd < 0 ) {
Error("Can't open %s: %s", stream_path, strerror(errno));
Error("Can't open %s: %s", stream_path.c_str(), strerror(errno));
return false;
}
total_read = 0;
@ -97,28 +97,26 @@ bool FifoStream::sendMJEGFrames() {
return true;
}
void FifoStream::setStreamStart(const char * path) {
stream_path = strdup(path);
void FifoStream::setStreamStart(const std::string &path) {
stream_path = path;
}
void FifoStream::setStreamStart(int monitor_id, const char * format) {
char diag_path[PATH_MAX];
void FifoStream::setStreamStart(int monitor_id, const char *format) {
std::string diag_path;
std::shared_ptr<Monitor> monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
if ( !strcmp(format, "reference") ) {
snprintf(diag_path, sizeof(diag_path), "%s/diagpipe-r-%u.jpg",
staticConfig.PATH_SOCKS.c_str(), monitor->Id());
if (!strcmp(format, "reference")) {
diag_path = stringtf("%s/diagpipe-r-%u.jpg", staticConfig.PATH_SOCKS.c_str(), monitor->Id());
stream_type = MJPEG;
} else if ( !strcmp(format, "delta") ) {
snprintf(diag_path, sizeof(diag_path), "%s/diagpipe-d-%u.jpg",
staticConfig.PATH_SOCKS.c_str(), monitor->Id());
} else if (!strcmp(format, "delta")) {
diag_path = stringtf("%s/diagpipe-d-%u.jpg", staticConfig.PATH_SOCKS.c_str(), monitor->Id());
stream_type = MJPEG;
} else {
if ( strcmp(format, "raw") ) {
if (strcmp(format, "raw")) {
Warning("Unknown or unspecified format. Defaulting to raw");
}
snprintf(diag_path, sizeof(diag_path), "%s/dbgpipe-%u.log",
staticConfig.PATH_SOCKS.c_str(), monitor->Id());
diag_path = stringtf("%s/dbgpipe-%u.log", staticConfig.PATH_SOCKS.c_str(), monitor->Id());
stream_type = RAW;
}
@ -126,46 +124,48 @@ void FifoStream::setStreamStart(int monitor_id, const char * format) {
}
void FifoStream::runStream() {
if ( stream_type == MJPEG ) {
if (stream_type == MJPEG) {
fprintf(stdout, "Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY "\r\n\r\n");
} else {
fprintf(stdout, "Content-Type: text/html\r\n\r\n");
}
/* only 1 person can read from a fifo at a time, so use a lock */
char lock_file[PATH_MAX];
snprintf(lock_file, sizeof(lock_file), "%s.rlock", stream_path);
std::string lock_file = stringtf("%s.rlock", stream_path.c_str());
Fifo::file_create_if_missing(lock_file, false);
Debug(1, "Locking %s", lock_file);
Debug(1, "Locking %s", lock_file.c_str());
int fd_lock = open(lock_file, O_RDONLY);
if ( fd_lock < 0 ) {
Error("Can't open %s: %s", lock_file, strerror(errno));
int fd_lock = open(lock_file.c_str(), O_RDONLY);
if (fd_lock < 0) {
Error("Can't open %s: %s", lock_file.c_str(), strerror(errno));
return;
}
int res = flock(fd_lock, LOCK_EX | LOCK_NB);
while ( (res < 0 and errno == EAGAIN) and (! zm_terminate) ) {
Warning("Flocking problem on %s: - %s", lock_file, strerror(errno));
while ((res < 0 and errno == EAGAIN) and (!zm_terminate)) {
Warning("Flocking problem on %s: - %s", lock_file.c_str(), strerror(errno));
sleep(1);
res = flock(fd_lock, LOCK_EX | LOCK_NB);
}
if ( res < 0 ) {
Error("Flocking problem on %d != %d %s: - %s", EAGAIN, res, lock_file, strerror(errno));
if (res < 0) {
Error("Flocking problem on %d != %d %s: - %s", EAGAIN, res, lock_file.c_str(), strerror(errno));
close(fd_lock);
return;
}
while ( !zm_terminate ) {
while (!zm_terminate) {
now = std::chrono::system_clock::now();
checkCommandQueue();
if ( stream_type == MJPEG ) {
if ( !sendMJEGFrames() )
if (stream_type == MJPEG) {
if (!sendMJEGFrames())
zm_terminate = true;
} else {
if ( !sendRAWFrames() )
if (!sendRAWFrames())
zm_terminate = true;
}
}
close(fd_lock);
}

View File

@ -25,15 +25,10 @@ class Monitor;
class FifoStream : public StreamBase {
private:
char * stream_path;
std::string stream_path;
int total_read;
int bytes_read;
unsigned int frame_count;
static void file_create_if_missing(
const char * path,
bool is_fifo,
bool delete_fake_fifo = true
);
protected:
typedef enum { UNKNOWN, MJPEG, RAW } StreamType;
@ -44,13 +39,13 @@ class FifoStream : public StreamBase {
public:
FifoStream() :
stream_path(nullptr),
total_read(0),
bytes_read(0),
frame_count(0),
stream_type(UNKNOWN)
{}
void setStreamStart(const char * path);
void setStreamStart(const std::string &path);
void setStreamStart(int monitor_id, const char * format);
void runStream() override;
};

View File

@ -48,20 +48,20 @@ FileCamera::FileCamera(
p_capture,
p_record_audio)
{
strncpy( path, p_path, sizeof(path)-1 );
if ( capture ) {
path = std::string(p_path);
if (capture) {
Initialise();
}
}
FileCamera::~FileCamera() {
if ( capture ) {
if (capture) {
Terminate();
}
}
void FileCamera::Initialise() {
if ( !path[0] ) {
if (path.empty()) {
Fatal("No path specified for file image");
}
}
@ -71,8 +71,8 @@ void FileCamera::Terminate() {
int FileCamera::PreCapture() {
struct stat statbuf = {};
if (stat(path, &statbuf) < 0) {
Error("Can't stat %s: %s", path, strerror(errno));
if (stat(path.c_str(), &statbuf) < 0) {
Error("Can't stat %s: %s", path.c_str(), strerror(errno));
return -1;
}
bytes += statbuf.st_size;

View File

@ -27,26 +27,19 @@
// accessed using a single file which contains the latest jpeg data
//
class FileCamera : public Camera {
protected:
char path[PATH_MAX];
public:
FileCamera(
const Monitor *monitor,
const char *p_path,
int p_width,
int p_height,
int p_colours,
int p_brightness,
int p_contrast,
int p_hue,
int p_colour,
bool p_capture,
bool p_record_audio
);
~FileCamera();
const char *Path() const { return path; }
public:
FileCamera(const Monitor *monitor,
const char *p_path,
int p_width,
int p_height,
int p_colours,
int p_brightness,
int p_contrast,
int p_hue,
int p_colour,
bool p_capture,
bool p_record_audio);
~FileCamera() override;
void Initialise();
void Terminate();
@ -54,6 +47,11 @@ public:
int Capture(std::shared_ptr<ZMPacket> &p) override;
int PostCapture() override;
int Close() override { return 0; };
const std::string &Path() const { return path; }
private:
std::string path;
};
#endif // ZM_FILE_CAMERA_H

View File

@ -933,7 +933,7 @@ bool Image::WriteRaw(const char *filename) const {
return true;
}
bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int p_subpixelorder) {
bool Image::ReadJpeg(const std::string &filename, unsigned int p_colours, unsigned int p_subpixelorder) {
unsigned int new_width, new_height, new_colours, new_subpixelorder;
struct jpeg_decompress_struct *cinfo = readjpg_dcinfo;
@ -946,8 +946,8 @@ bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int
}
FILE *infile;
if ( (infile = fopen(filename, "rb")) == nullptr ) {
Error("Can't open %s: %s", filename, strerror(errno));
if ( (infile = fopen(filename.c_str(), "rb")) == nullptr ) {
Error("Can't open %s: %s", filename.c_str(), strerror(errno));
return false;
}
@ -1060,24 +1060,24 @@ cinfo->out_color_space = JCS_RGB;
// Multiple calling formats to permit inclusion (or not) of non blocking, quality_override and timestamp (exif), with suitable defaults.
// Note quality=zero means default
bool Image::WriteJpeg(const char *filename, int quality_override) const {
bool Image::WriteJpeg(const std::string &filename, int quality_override) const {
return Image::WriteJpeg(filename, quality_override, {}, false);
}
bool Image::WriteJpeg(const char *filename) const {
bool Image::WriteJpeg(const std::string &filename) const {
return Image::WriteJpeg(filename, 0, {}, false);
}
bool Image::WriteJpeg(const char *filename, bool on_blocking_abort) const {
bool Image::WriteJpeg(const std::string &filename, bool on_blocking_abort) const {
return Image::WriteJpeg(filename, 0, {}, on_blocking_abort);
}
bool Image::WriteJpeg(const char *filename, SystemTimePoint timestamp) const {
bool Image::WriteJpeg(const std::string &filename, SystemTimePoint timestamp) const {
return Image::WriteJpeg(filename, 0, timestamp, false);
}
bool Image::WriteJpeg(const char *filename, int quality_override, SystemTimePoint timestamp) const {
bool Image::WriteJpeg(const std::string &filename, int quality_override, SystemTimePoint timestamp) const {
return Image::WriteJpeg(filename, quality_override, timestamp, false);
}
bool Image::WriteJpeg(const char *filename,
bool Image::WriteJpeg(const std::string &filename,
int quality_override,
SystemTimePoint timestamp,
bool on_blocking_abort) const {
@ -1114,17 +1114,17 @@ bool Image::WriteJpeg(const char *filename,
}
}
if ( !on_blocking_abort ) {
if ( (outfile = fopen(filename, "wb")) == nullptr ) {
Error("Can't open %s for writing: %s", filename, strerror(errno));
if (!on_blocking_abort) {
if ((outfile = fopen(filename.c_str(), "wb")) == nullptr) {
Error("Can't open %s for writing: %s", filename.c_str(), strerror(errno));
return false;
}
} else {
raw_fd = open(filename, O_WRONLY|O_NONBLOCK|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if ( raw_fd < 0 )
raw_fd = open(filename.c_str(), O_WRONLY | O_NONBLOCK | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (raw_fd < 0)
return false;
outfile = fdopen(raw_fd, "wb");
if ( outfile == nullptr ) {
if (outfile == nullptr) {
close(raw_fd);
return false;
}

View File

@ -233,14 +233,17 @@ class Image {
bool ReadRaw(const char *filename);
bool WriteRaw(const char *filename) const;
bool ReadJpeg(const char *filename, unsigned int p_colours, unsigned int p_subpixelorder);
bool ReadJpeg(const std::string &filename, unsigned int p_colours, unsigned int p_subpixelorder);
bool WriteJpeg(const char *filename) const;
bool WriteJpeg(const char *filename, bool on_blocking_abort) const;
bool WriteJpeg(const char *filename, int quality_override) const;
bool WriteJpeg(const char *filename, SystemTimePoint timestamp) const;
bool WriteJpeg(const char *filename, int quality_override, SystemTimePoint timestamp) const;
bool WriteJpeg(const char *filename, int quality_override, SystemTimePoint timestamp, bool on_blocking_abort) const;
bool WriteJpeg(const std::string &filename) const;
bool WriteJpeg(const std::string &filename, bool on_blocking_abort) const;
bool WriteJpeg(const std::string &filename, int quality_override) const;
bool WriteJpeg(const std::string &filename, SystemTimePoint timestamp) const;
bool WriteJpeg(const std::string &filename, int quality_override, SystemTimePoint timestamp) const;
bool WriteJpeg(const std::string &filename,
int quality_override,
SystemTimePoint timestamp,
bool on_blocking_abort) const;
bool DecodeJpeg(const JOCTET *inbuffer, int inbuffer_size, unsigned int p_colours, unsigned int p_subpixelorder);
bool EncodeJpeg(JOCTET *outbuffer, int *outbuffer_size, int quality_override=0) const;

View File

@ -37,13 +37,13 @@ void zm_jpeg_emit_silence(j_common_ptr cinfo, int msg_level) {
}
void zm_jpeg_error_exit(j_common_ptr cinfo) {
static char buffer[JMSG_LENGTH_MAX];
zm_error_ptr zmerr = (zm_error_ptr)cinfo->err;
zm_error_ptr zmerr = (zm_error_ptr) cinfo->err;
(zmerr->pub.format_message)(cinfo, buffer);
char buffer[JMSG_LENGTH_MAX];
zmerr->pub.format_message(cinfo, buffer);
Error("%s", buffer);
if ( ++jpeg_err_count == MAX_JPEG_ERRS ) {
if (++jpeg_err_count == MAX_JPEG_ERRS) {
Fatal("Maximum number (%d) of JPEG errors reached, exiting", jpeg_err_count);
}
@ -51,25 +51,25 @@ void zm_jpeg_error_exit(j_common_ptr cinfo) {
}
void zm_jpeg_emit_message(j_common_ptr cinfo, int msg_level) {
static char buffer[JMSG_LENGTH_MAX];
zm_error_ptr zmerr = (zm_error_ptr)cinfo->err;
char buffer[JMSG_LENGTH_MAX];
zm_error_ptr zmerr = (zm_error_ptr) cinfo->err;
if ( msg_level < 0 ) {
if (msg_level < 0) {
/* It's a warning message. Since corrupt files may generate many warnings,
* the policy implemented here is to show only the first warning,
* unless trace_level >= 3.
*/
if ( zmerr->pub.num_warnings == 0 || zmerr->pub.trace_level >= 3 ) {
(zmerr->pub.format_message)(cinfo, buffer);
if ( !strstr(buffer, "Corrupt JPEG data:") )
if (zmerr->pub.num_warnings == 0 || zmerr->pub.trace_level >= 3) {
zmerr->pub.format_message(cinfo, buffer);
if (!strstr(buffer, "Corrupt JPEG data:"))
Warning("%s", buffer);
}
/* Always count warnings in num_warnings. */
zmerr->pub.num_warnings++;
} else {
/* It's a trace message. Show it if trace_level >= msg_level. */
if ( zmerr->pub.trace_level >= msg_level ) {
(zmerr->pub.format_message)(cinfo, buffer);
if (zmerr->pub.trace_level >= msg_level) {
zmerr->pub.format_message(cinfo, buffer);
Debug(msg_level, "%s", buffer);
}
}

View File

@ -864,53 +864,56 @@ uint32_t LocalCamera::AutoSelectFormat(int p_colours) {
(test) ? (prefix yesString " " capability "\n") : (prefix noString " " capability "\n")
bool LocalCamera::GetCurrentSettings(
const char *device,
const std::string& device,
char *output,
int version,
bool verbose) {
output[0] = 0;
char *output_ptr = output;
char queryDevice[PATH_MAX] = "";
std::string queryDevice;
int devIndex = 0;
do {
if ( device ) {
strncpy(queryDevice, device, sizeof(queryDevice)-1);
if (!device.empty()) {
queryDevice = device;
} else {
sprintf(queryDevice, "/dev/video%d", devIndex);
queryDevice = stringtf("/dev/video%d", devIndex);
}
if ( (vid_fd = open(queryDevice, O_RDWR)) <= 0 ) {
if ( device ) {
Error("Failed to open video device %s: %s", queryDevice, strerror(errno));
if ( verbose )
if ((vid_fd = open(queryDevice.c_str(), O_RDWR)) <= 0) {
if (!device.empty()) {
Error("Failed to open video device %s: %s", queryDevice.c_str(), strerror(errno));
if (verbose) {
output_ptr += sprintf(output_ptr, "Error, failed to open video device %s: %s\n",
queryDevice, strerror(errno));
else
queryDevice.c_str(), strerror(errno));
} else {
output_ptr += sprintf(output_ptr, "error%d\n", errno);
}
return false;
} else {
return true;
}
}
if ( verbose ) {
output_ptr += sprintf(output_ptr, "Video Device: %s\n", queryDevice);
if (verbose) {
output_ptr += sprintf(output_ptr, "Video Device: %s\n", queryDevice.c_str());
} else {
output_ptr += sprintf(output_ptr, "d:%s|", queryDevice);
output_ptr += sprintf(output_ptr, "d:%s|", queryDevice.c_str());
}
if ( version == 2 ) {
struct v4l2_capability vid_cap;
if ( vidioctl(vid_fd, VIDIOC_QUERYCAP, &vid_cap) < 0 ) {
if (version == 2) {
v4l2_capability vid_cap = {};
if (vidioctl(vid_fd, VIDIOC_QUERYCAP, &vid_cap) < 0) {
Error("Failed to query video device: %s", strerror(errno));
if ( verbose ) {
if (verbose) {
output_ptr += sprintf(output_ptr, "Error, failed to query video capabilities %s: %s\n",
queryDevice, strerror(errno));
queryDevice.c_str(), strerror(errno));
} else {
output_ptr += sprintf(output_ptr, "error%d\n", errno);
}
if ( device )
if (!device.empty()) {
return false;
}
}
if ( verbose ) {
@ -953,7 +956,7 @@ bool LocalCamera::GetCurrentSettings(
output_ptr += sprintf(output_ptr, verbose ? " Standards:\n" : "S:");
struct v4l2_standard standard;
v4l2_standard standard = {};
int standardIndex = 0;
do {
memset(&standard, 0, sizeof(standard));
@ -981,10 +984,10 @@ bool LocalCamera::GetCurrentSettings(
*(output_ptr-1) = '|';
output_ptr += sprintf(output_ptr, verbose ? " Formats:\n" : "F:");
struct v4l2_fmtdesc format;
int formatIndex = 0;
do {
memset(&format, 0, sizeof(format));
v4l2_fmtdesc format = {};
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format.index = formatIndex;
@ -1025,9 +1028,9 @@ bool LocalCamera::GetCurrentSettings(
else
output_ptr += sprintf(output_ptr, "Crop Capabilities\n");
struct v4l2_cropcap cropcap;
memset(&cropcap, 0, sizeof(cropcap));
v4l2_cropcap cropcap = {};
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if ( vidioctl(vid_fd, VIDIOC_CROPCAP, &cropcap) < 0 ) {
if ( errno != EINVAL ) {
/* Failed querying crop capability, write error to the log and continue as if crop is not supported */
@ -1041,8 +1044,8 @@ bool LocalCamera::GetCurrentSettings(
output_ptr += sprintf(output_ptr, "B:%dx%d|", 0, 0);
}
} else {
struct v4l2_crop crop;
memset(&crop, 0, sizeof(crop));
v4l2_crop crop = {};
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if ( vidioctl(vid_fd, VIDIOC_G_CROP, &crop) < 0 ) {
@ -1159,8 +1162,9 @@ bool LocalCamera::GetCurrentSettings(
}
close(vid_fd);
if ( device )
if (!device.empty()) {
break;
}
} while ( ++devIndex < 32 );
return true;
}

View File

@ -123,7 +123,7 @@ public:
int Capture(std::shared_ptr<ZMPacket> &p) override;
int PostCapture() override;
int Close() override;
static bool GetCurrentSettings(const char *device, char *output, int version, bool verbose);
static bool GetCurrentSettings(const std::string &device, char *output, int version, bool verbose);
};
#endif // ZM_HAS_V4L

View File

@ -524,8 +524,8 @@ void Logger::logPrint(bool hex, const char *filepath, int line, int level, const
"INSERT INTO `Logs` "
"( `TimeKey`, `Component`, `ServerId`, `Pid`, `Level`, `Code`, `Message`, `File`, `Line` )"
" VALUES "
"( %ld.%06ld, '%s', %d, %d, %d, '%s', '%s', '%s', %d )",
now_sec, now_frac.count(), mId.c_str(), staticConfig.SERVER_ID, tid, level, classString,
"( %ld.%06" PRIi64 ", '%s', %d, %d, %d, '%s', '%s', '%s', %d )",
now_sec, static_cast<int64>(now_frac.count()), mId.c_str(), staticConfig.SERVER_ID, tid, level, classString,
escapedString.c_str(), file, line);
dbQueue.push(std::move(sql_string));
} else {

View File

@ -1184,8 +1184,7 @@ int Monitor::GetImage(int32_t index, int scale) {
image = image_buffer[index];
}
static char filename[PATH_MAX];
snprintf(filename, sizeof(filename), "Monitor%u.jpg", id);
std::string filename = stringtf("Monitor%u.jpg", id);
image->WriteJpeg(filename);
return 1;
}
@ -1506,20 +1505,20 @@ void Monitor::DumpZoneImage(const char *zone_string) {
zone_image->Outline(extra_colour, extra_zone);
}
static char filename[PATH_MAX];
snprintf(filename, sizeof(filename), "Zones%u.jpg", id);
std::string filename = stringtf("Zones%u.jpg", id);
zone_image->WriteJpeg(filename);
delete zone_image;
} // end void Monitor::DumpZoneImage(const char *zone_string)
void Monitor::DumpImage(Image *dump_image) const {
if ( image_count && !(image_count%10) ) {
static char filename[PATH_MAX];
static char new_filename[PATH_MAX];
snprintf(filename, sizeof(filename), "Monitor%u.jpg", id);
snprintf(new_filename, sizeof(new_filename), "Monitor%u-new.jpg", id);
if ( dump_image->WriteJpeg(new_filename) )
rename(new_filename, filename);
if (image_count && !(image_count % 10)) {
std::string filename = stringtf("Monitor%u.jpg", id);
std::string new_filename = stringtf("Monitor%u-new.jpg", id);
if (dump_image->WriteJpeg(new_filename)) {
rename(new_filename.c_str(), filename.c_str());
}
}
} // end void Monitor::DumpImage(Image *dump_image)
@ -2783,8 +2782,8 @@ unsigned int Monitor::DetectMotion(const Image &comp_image, Event::StringSet &zo
ref_image.Delta(comp_image, &delta_image);
if (config.record_diag_images) {
ref_image.WriteJpeg(diag_path_ref.c_str(), config.record_diag_images_fifo);
delta_image.WriteJpeg(diag_path_delta.c_str(), config.record_diag_images_fifo);
ref_image.WriteJpeg(diag_path_ref, config.record_diag_images_fifo);
delta_image.WriteJpeg(diag_path_delta, config.record_diag_images_fifo);
}
// Blank out all exclusion zones
@ -2932,7 +2931,7 @@ bool Monitor::DumpSettings(char *output, bool verbose) {
sprintf( output+strlen(output), "Path : %s\n", cam->Path().c_str() );
} else if ( camera->IsFile() ) {
FileCamera* cam = static_cast<FileCamera*>(camera.get());
sprintf( output+strlen(output), "Path : %s\n", cam->Path() );
sprintf( output+strlen(output), "Path : %s\n", cam->Path().c_str() );
}
else if ( camera->IsFfmpeg() ) {
FfmpegCamera* cam = static_cast<FfmpegCamera*>(camera.get());

View File

@ -320,7 +320,7 @@ void MonitorStream::processCommand(const CmdMsg *msg) {
//updateFrameRate(monitor->GetFPS());
} // end void MonitorStream::processCommand(const CmdMsg *msg)
bool MonitorStream::sendFrame(const char *filepath, SystemTimePoint timestamp) {
bool MonitorStream::sendFrame(const std::string &filepath, SystemTimePoint timestamp) {
bool send_raw = ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE));
if (
@ -330,19 +330,18 @@ bool MonitorStream::sendFrame(const char *filepath, SystemTimePoint timestamp) {
)
send_raw = false;
if ( !send_raw ) {
Image temp_image(filepath);
if (!send_raw) {
Image temp_image(filepath.c_str());
return sendFrame(&temp_image, timestamp);
} else {
int img_buffer_size = 0;
static unsigned char img_buffer[ZM_MAX_IMAGE_SIZE];
FILE *fdj = nullptr;
if ( (fdj = fopen(filepath, "r")) ) {
if (FILE *fdj = fopen(filepath.c_str(), "r")) {
img_buffer_size = fread(img_buffer, 1, sizeof(img_buffer), fdj);
fclose(fdj);
} else {
Error("Can't open %s: %s", filepath, strerror(errno));
Error("Can't open %s: %s", filepath.c_str(), strerror(errno));
return false;
}
@ -747,21 +746,13 @@ void MonitorStream::runStream() {
int temp_index = temp_write_index%temp_image_buffer_count;
Debug(2, "Storing frame %d", temp_index);
if ( !temp_image_buffer[temp_index].valid ) {
snprintf(
temp_image_buffer[temp_index].file_name,
sizeof(temp_image_buffer[0].file_name),
"%s/zmswap-i%05d.jpg",
swap_path.c_str(),
temp_index);
temp_image_buffer[temp_index].file_name = stringtf("%s/zmswap-i%05d.jpg", swap_path.c_str(), temp_index);
temp_image_buffer[temp_index].valid = true;
}
temp_image_buffer[temp_index].timestamp =
SystemTimePoint(zm::chrono::duration_cast<Microseconds>(monitor->shared_timestamps[index]));
monitor->image_buffer[index]->WriteJpeg(
temp_image_buffer[temp_index].file_name,
config.jpeg_file_quality
);
monitor->image_buffer[index]->WriteJpeg(temp_image_buffer[temp_index].file_name, config.jpeg_file_quality);
temp_write_index = MOD_ADD(temp_write_index, 1, temp_image_buffer_count);
if ( temp_write_index == temp_read_index ) {
// Go back to live viewing
@ -812,7 +803,7 @@ void MonitorStream::runStream() {
if ( buffered_playback ) {
Debug(1, "Cleaning swap files from %s", swap_path.c_str());
struct stat stat_buf;
struct stat stat_buf = {};
if ( stat(swap_path.c_str(), &stat_buf) < 0 ) {
if ( errno != ENOENT ) {
Error("Can't stat '%s': %s", swap_path.c_str(), strerror(errno));
@ -820,16 +811,15 @@ void MonitorStream::runStream() {
} else if ( !S_ISDIR(stat_buf.st_mode) ) {
Error("Swap image path '%s' is not a directory", swap_path.c_str());
} else {
char glob_pattern[PATH_MAX] = "";
snprintf(glob_pattern, sizeof(glob_pattern), "%s/*.*", swap_path.c_str());
std::string glob_pattern = stringtf("%s/*.*", swap_path.c_str());
glob_t pglob;
int glob_status = glob(glob_pattern, 0, 0, &pglob);
int glob_status = glob(glob_pattern.c_str(), 0, 0, &pglob);
if ( glob_status != 0 ) {
if ( glob_status < 0 ) {
Error("Can't glob '%s': %s", glob_pattern, strerror(errno));
Error("Can't glob '%s': %s", glob_pattern.c_str(), strerror(errno));
} else {
Debug(1, "Can't glob '%s': %d", glob_pattern, glob_status);
Debug(1, "Can't glob '%s': %d", glob_pattern.c_str(), glob_status);
}
} else {
for ( unsigned int i = 0; i < pglob.gl_pathc; i++ ) {

View File

@ -27,7 +27,7 @@ class MonitorStream : public StreamBase {
struct SwapImage {
bool valid = false;
SystemTimePoint timestamp;
char file_name[PATH_MAX] = "";
std::string file_name;
};
private:
@ -44,7 +44,7 @@ class MonitorStream : public StreamBase {
protected:
bool checkSwapPath(const char *path, bool create_path);
bool sendFrame(const char *filepath, SystemTimePoint timestamp);
bool sendFrame(const std::string &filepath, SystemTimePoint timestamp);
bool sendFrame(Image *image, SystemTimePoint timestamp);
void processCommand(const CmdMsg *msg) override;
void SingleImage(int scale=100);

View File

@ -22,6 +22,7 @@
#include "zm_config.h"
#include "zm_logger.h"
#include <array>
#include <cstdarg>
#include <cstring>
#include <fcntl.h> /* Definition of AT_* constants */
#include <sstream>
@ -116,6 +117,26 @@ std::string Join(const StringVector &values, const std::string &delim) {
return ss.str();
}
std::string stringtf(const char* format, ...) {
va_list args;
va_start(args, format);
va_list args2;
va_copy(args2, args);
int size = vsnprintf(nullptr, 0, format, args) + 1; // Extra space for '\0'
va_end(args);
if (size <= 0) {
throw std::runtime_error("Error during formatting.");
}
std::unique_ptr<char[]> buf(new char[size]);
vsnprintf(buf.get(), size, format, args2);
va_end(args2);
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
}
std::string ByteArrayToHexString(nonstd::span<const uint8> bytes) {
static constexpr char lowercase_table[] = "0123456789abcdef";
std::string buf;

View File

@ -61,16 +61,8 @@ inline bool StartsWith(const std::string &haystack, const std::string &needle) {
return (haystack.substr(0, needle.length()) == needle);
}
template<typename... Args>
std::string stringtf(const std::string &format, Args... args) {
int size = snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
if (size <= 0) {
throw std::runtime_error("Error during formatting.");
}
std::unique_ptr<char[]> buf(new char[size]);
snprintf(buf.get(), size, format.c_str(), args...);
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
}
__attribute__((format(printf, 1, 2)))
std::string stringtf(const char* format, ...);
std::string ByteArrayToHexString(nonstd::span<const uint8> bytes);

View File

@ -104,7 +104,8 @@ void Zone::Setup(
diag_path = stringtf("%s/diag-%d-poly.jpg",
monitor->getStorage()->Path(), id);
}
pg_image->WriteJpeg(diag_path.c_str(), config.record_diag_images_fifo);
pg_image->WriteJpeg(diag_path, config.record_diag_images_fifo);
}
} // end Zone::Setup
@ -232,8 +233,9 @@ bool Zone::CheckAlarms(const Image *delta_image) {
} */
std_alarmedpixels(diff_image, pg_image, &stats.alarm_pixels_, &pixel_diff_count);
if (config.record_diag_images)
diff_image->WriteJpeg(diag_path.c_str(), config.record_diag_images_fifo);
if (config.record_diag_images) {
diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo);
}
if (pixel_diff_count && stats.alarm_pixels_)
stats.pixel_diff_ = pixel_diff_count/stats.alarm_pixels_;
@ -316,8 +318,9 @@ bool Zone::CheckAlarms(const Image *delta_image) {
stats.alarm_filter_pixels_ = stats.alarm_pixels_;
}
if (config.record_diag_images)
diff_image->WriteJpeg(diag_path.c_str(), config.record_diag_images_fifo);
if (config.record_diag_images) {
diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo);
}
Debug(5, "Got %d filtered pixels, need %d -> %d",
stats.alarm_filter_pixels_, min_filter_pixels, max_filter_pixels);
@ -540,8 +543,9 @@ bool Zone::CheckAlarms(const Image *delta_image) {
}
}
if (config.record_diag_images)
diff_image->WriteJpeg(diag_path.c_str(), config.record_diag_images_fifo);
if (config.record_diag_images) {
diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo);
}
if (!stats.alarm_blobs_) {
stats.score_ = 0;
@ -592,8 +596,9 @@ bool Zone::CheckAlarms(const Image *delta_image) {
} // end if bs_count
} // end for i < WHITE
if (config.record_diag_images)
diff_image->WriteJpeg(diag_path.c_str(), config.record_diag_images_fifo);
if (config.record_diag_images) {
diff_image->WriteJpeg(diag_path, config.record_diag_images_fifo);
}
Debug(5, "Got %d blob pixels, %d blobs, need %d -> %d, %d -> %d",
stats.alarm_blob_pixels_, stats.alarm_blobs_, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs);