Use the power of smart pointers to manage Monitor instances

This commit is contained in:
Peter Keresztes Schmidt 2021-02-07 19:12:39 +01:00
parent a3dc48b55d
commit f43507dce0
41 changed files with 166 additions and 200 deletions

View File

@ -2,10 +2,8 @@
#include "zm_signal.h" #include "zm_signal.h"
AnalysisThread::AnalysisThread(Monitor *p_monitor) { AnalysisThread::AnalysisThread(std::shared_ptr<Monitor> monitor) :
monitor = p_monitor; monitor(std::move(monitor)), terminate(false) {}
terminate = false;
}
AnalysisThread::~AnalysisThread() { AnalysisThread::~AnalysisThread() {
Debug(2, "THREAD: deleteing analysis thread"); Debug(2, "THREAD: deleteing analysis thread");

View File

@ -3,14 +3,15 @@
#include "zm_monitor.h" #include "zm_monitor.h"
#include "zm_thread.h" #include "zm_thread.h"
#include <memory>
class AnalysisThread : public Thread { class AnalysisThread : public Thread {
private: private:
std::shared_ptr<Monitor> monitor;
bool terminate; bool terminate;
Monitor *monitor;
public: public:
explicit AnalysisThread(Monitor *); explicit AnalysisThread(std::shared_ptr<Monitor> monitor);
~AnalysisThread(); ~AnalysisThread();
int run(); int run();

View File

@ -22,7 +22,7 @@
#include "zm_monitor.h" #include "zm_monitor.h"
Camera::Camera( Camera::Camera(
unsigned int p_monitor_id, const Monitor *monitor,
SourceType p_type, SourceType p_type,
unsigned int p_width, unsigned int p_width,
unsigned int p_height, unsigned int p_height,
@ -35,8 +35,7 @@ Camera::Camera(
bool p_capture, bool p_capture,
bool p_record_audio bool p_record_audio
) : ) :
monitor_id(p_monitor_id), monitor(monitor),
monitor(nullptr),
type(p_type), type(p_type),
width(p_width), width(p_width),
height(p_height), height(p_height),
@ -62,7 +61,7 @@ Camera::Camera(
imagesize = height * linesize; imagesize = height * linesize;
Debug(2, "New camera id: %d width: %d line size: %d height: %d colours: %d subpixelorder: %d capture: %d", Debug(2, "New camera id: %d width: %d line size: %d height: %d colours: %d subpixelorder: %d capture: %d",
monitor_id, width, linesize, height, colours, subpixelorder, capture); monitor->Id(), width, linesize, height, colours, subpixelorder, capture);
} }
Camera::~Camera() { Camera::~Camera() {
@ -74,17 +73,6 @@ Camera::~Camera() {
} }
} }
Monitor *Camera::getMonitor() {
if ( ! monitor )
monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
return monitor;
}
void Camera::setMonitor(Monitor *p_monitor) {
monitor = p_monitor;
monitor_id = monitor->Id();
}
AVStream *Camera::get_VideoStream() { AVStream *Camera::get_VideoStream() {
if ( !mVideoStream ) { if ( !mVideoStream ) {
if ( !mFormatContext ) if ( !mFormatContext )

View File

@ -21,10 +21,10 @@
#define ZM_CAMERA_H #define ZM_CAMERA_H
#include "zm_image.h" #include "zm_image.h"
#include "zm_monitor.h"
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/types.h> #include <sys/types.h>
class Monitor;
class ZMPacket; class ZMPacket;
// //
@ -35,8 +35,7 @@ class Camera {
protected: protected:
typedef enum { LOCAL_SRC, REMOTE_SRC, FILE_SRC, FFMPEG_SRC, LIBVLC_SRC, CURL_SRC, VNC_SRC } SourceType; typedef enum { LOCAL_SRC, REMOTE_SRC, FILE_SRC, FFMPEG_SRC, LIBVLC_SRC, CURL_SRC, VNC_SRC } SourceType;
unsigned int monitor_id; const Monitor *monitor;
Monitor * monitor; // Null on instantiation, set as soon as possible.
SourceType type; SourceType type;
unsigned int width; unsigned int width;
unsigned int linesize; unsigned int linesize;
@ -62,7 +61,7 @@ protected:
public: public:
Camera( Camera(
unsigned int p_monitor_id, const Monitor* monitor,
SourceType p_type, SourceType p_type,
unsigned int p_width, unsigned int p_width,
unsigned int p_height, unsigned int p_height,
@ -77,9 +76,7 @@ public:
); );
virtual ~Camera(); virtual ~Camera();
unsigned int getId() const { return monitor_id; } unsigned int getId() const { return monitor->Id(); }
Monitor *getMonitor();
void setMonitor( Monitor *p_monitor );
SourceType Type() const { return type; } SourceType Type() const { return type; }
bool IsLocal() const { return type == LOCAL_SRC; } bool IsLocal() const { return type == LOCAL_SRC; }
bool IsRemote() const { return type == REMOTE_SRC; } bool IsRemote() const { return type == REMOTE_SRC; }

View File

@ -69,8 +69,8 @@ void bind_libcurl_symbols() {
*(void**) (&curl_easy_cleanup_f) = dlsym(curl_lib, "curl_easy_cleanup"); *(void**) (&curl_easy_cleanup_f) = dlsym(curl_lib, "curl_easy_cleanup");
} }
cURLCamera::cURLCamera( int p_id, const std::string &p_path, const std::string &p_user, const std::string &p_pass, unsigned int p_width, unsigned 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 ) : cURLCamera::cURLCamera( const Monitor* monitor, const std::string &p_path, const std::string &p_user, const std::string &p_pass, unsigned int p_width, unsigned 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 ) :
Camera( p_id, CURL_SRC, p_width, p_height, p_colours, ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours), p_brightness, p_contrast, p_hue, p_colour, p_capture, p_record_audio ), Camera( monitor, CURL_SRC, p_width, p_height, p_colours, ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours), p_brightness, p_contrast, p_hue, p_colour, p_capture, p_record_audio ),
mPath( p_path ), mUser( p_user ), mPass ( p_pass ), bTerminate( false ), bReset( false ), mode ( MODE_UNSET ) mPath( p_path ), mUser( p_user ), mPass ( p_pass ), bTerminate( false ), bReset( false ), mode ( MODE_UNSET )
{ {

View File

@ -61,7 +61,7 @@ protected:
pthread_cond_t request_complete_cond; pthread_cond_t request_complete_cond;
public: public:
cURLCamera( int p_id, const std::string &path, const std::string &username, const std::string &password, unsigned int p_width, unsigned 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 ); cURLCamera( const Monitor* monitor, const std::string &path, const std::string &username, const std::string &password, unsigned int p_width, unsigned 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 );
~cURLCamera(); ~cURLCamera();
const std::string &Path() const { return( mPath ); } const std::string &Path() const { return( mPath ); }

View File

@ -166,7 +166,6 @@ bool EventStream::loadEventData(uint64_t event_id) {
if ( !monitor ) { if ( !monitor ) {
monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY); monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY);
} else if ( monitor->Id() != event_data->monitor_id ) { } else if ( monitor->Id() != event_data->monitor_id ) {
delete monitor;
monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY); monitor = Monitor::Load(event_data->monitor_id, false, Monitor::QUERY);
} }
if ( !monitor ) { if ( !monitor ) {

View File

@ -115,10 +115,6 @@ class EventStream : public StreamBase {
delete event_data; delete event_data;
event_data = nullptr; event_data = nullptr;
} }
if ( monitor ) {
delete monitor;
monitor = nullptr;
}
if ( storage ) { if ( storage ) {
delete storage; delete storage;
storage = nullptr; storage = nullptr;

View File

@ -91,7 +91,7 @@ static enum AVPixelFormat find_fmt_by_hw_type(const enum AVHWDeviceType type) {
#endif #endif
FfmpegCamera::FfmpegCamera( FfmpegCamera::FfmpegCamera(
int p_id, const Monitor *monitor,
const std::string &p_path, const std::string &p_path,
const std::string &p_method, const std::string &p_method,
const std::string &p_options, const std::string &p_options,
@ -107,7 +107,7 @@ FfmpegCamera::FfmpegCamera(
const std::string &p_hwaccel_name, const std::string &p_hwaccel_name,
const std::string &p_hwaccel_device) : const std::string &p_hwaccel_device) :
Camera( Camera(
p_id, monitor,
FFMPEG_SRC, FFMPEG_SRC,
p_width, p_width,
p_height, p_height,

View File

@ -67,7 +67,7 @@ class FfmpegCamera : public Camera {
public: public:
FfmpegCamera( FfmpegCamera(
int p_id, const Monitor *monitor,
const std::string &path, const std::string &path,
const std::string &p_method, const std::string &p_method,
const std::string &p_options, const std::string &p_options,

View File

@ -204,7 +204,7 @@ void FifoStream::setStreamStart(const char * path) {
void FifoStream::setStreamStart(int monitor_id, const char * format) { void FifoStream::setStreamStart(int monitor_id, const char * format) {
char diag_path[PATH_MAX]; char diag_path[PATH_MAX];
Monitor * monitor = Monitor::Load(monitor_id, false, Monitor::QUERY); std::shared_ptr<Monitor> monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
if ( !strcmp(format, "reference") ) { if ( !strcmp(format, "reference") ) {
snprintf(diag_path, sizeof(diag_path), "%s/diagpipe-r-%d.jpg", snprintf(diag_path, sizeof(diag_path), "%s/diagpipe-r-%d.jpg",

View File

@ -23,7 +23,7 @@
#include <sys/stat.h> #include <sys/stat.h>
FileCamera::FileCamera( FileCamera::FileCamera(
int p_id, const Monitor *monitor,
const char *p_path, const char *p_path,
int p_width, int p_width,
int p_height, int p_height,
@ -35,7 +35,7 @@ FileCamera::FileCamera(
bool p_capture, bool p_capture,
bool p_record_audio) bool p_record_audio)
: Camera( : Camera(
p_id, monitor,
FILE_SRC, FILE_SRC,
p_width, p_width,
p_height, p_height,

View File

@ -32,7 +32,7 @@ protected:
public: public:
FileCamera( FileCamera(
int p_id, const Monitor *monitor,
const char *p_path, const char *p_path,
int p_width, int p_width,
int p_height, int p_height,

View File

@ -99,7 +99,7 @@ void LibvlcUnlockBuffer(void* opaque, void* picture, void *const *planes) {
} }
LibvlcCamera::LibvlcCamera( LibvlcCamera::LibvlcCamera(
int p_id, const Monitor *monitor,
const std::string &p_path, const std::string &p_path,
const std::string &p_method, const std::string &p_method,
const std::string &p_options, const std::string &p_options,
@ -114,7 +114,7 @@ LibvlcCamera::LibvlcCamera(
bool p_record_audio bool p_record_audio
) : ) :
Camera( Camera(
p_id, monitor,
LIBVLC_SRC, LIBVLC_SRC,
p_width, p_width,
p_height, p_height,

View File

@ -56,7 +56,7 @@ protected:
libvlc_media_player_t *mLibvlcMediaPlayer; libvlc_media_player_t *mLibvlcMediaPlayer;
public: public:
LibvlcCamera( int p_id, const std::string &path, const std::string &p_method, const std::string &p_options, 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 ); LibvlcCamera( const Monitor *monitor, const std::string &path, const std::string &p_method, const std::string &p_options, 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 );
~LibvlcCamera(); ~LibvlcCamera();
const std::string &Path() const { return mPath; } const std::string &Path() const { return mPath; }

View File

@ -63,7 +63,7 @@ static rfbCredential* GetCredentialsCallback(rfbClient* cl, int credentialType){
} }
VncCamera::VncCamera( VncCamera::VncCamera(
unsigned int p_monitor_id, const Monitor *monitor,
const std::string &host, const std::string &host,
const std::string &port, const std::string &port,
const std::string &user, const std::string &user,
@ -78,7 +78,7 @@ VncCamera::VncCamera(
bool p_capture, bool p_capture,
bool p_record_audio ) : bool p_record_audio ) :
Camera( Camera(
p_monitor_id, monitor,
VNC_SRC, VNC_SRC,
p_width, p_width,
p_height, p_height,

View File

@ -28,7 +28,7 @@ protected:
std::string mPass; std::string mPass;
public: public:
VncCamera( VncCamera(
unsigned int p_monitor_id, const Monitor *monitor,
const std::string &host, const std::string &host,
const std::string &port, const std::string &port,
const std::string &user, const std::string &user,

View File

@ -302,7 +302,7 @@ AVFrame **LocalCamera::capturePictures = nullptr;
LocalCamera *LocalCamera::last_camera = nullptr; LocalCamera *LocalCamera::last_camera = nullptr;
LocalCamera::LocalCamera( LocalCamera::LocalCamera(
int p_id, const Monitor *monitor,
const std::string &p_device, const std::string &p_device,
int p_channel, int p_channel,
int p_standard, int p_standard,
@ -320,7 +320,7 @@ LocalCamera::LocalCamera(
bool p_capture, bool p_capture,
bool p_record_audio, bool p_record_audio,
unsigned int p_extras) : unsigned int p_extras) :
Camera( p_id, LOCAL_SRC, p_width, p_height, p_colours, ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours), p_brightness, p_contrast, p_hue, p_colour, p_capture, p_record_audio ), Camera( monitor, LOCAL_SRC, p_width, p_height, p_colours, ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours), p_brightness, p_contrast, p_hue, p_colour, p_capture, p_record_audio ),
device( p_device ), device( p_device ),
channel( p_channel ), channel( p_channel ),
standard( p_standard ), standard( p_standard ),

View File

@ -114,7 +114,7 @@ protected:
public: public:
LocalCamera( LocalCamera(
int p_id, const Monitor *monitor,
const std::string &device, const std::string &device,
int p_channel, int p_channel,
int p_format, int p_format,

View File

@ -650,7 +650,7 @@ Camera * Monitor::getCamera() {
int extras = (deinterlacing>>24)&0xff; int extras = (deinterlacing>>24)&0xff;
camera = new LocalCamera( camera = new LocalCamera(
id, this,
device, device,
channel, channel,
format, format,
@ -672,7 +672,7 @@ Camera * Monitor::getCamera() {
} else if ( type == REMOTE ) { } else if ( type == REMOTE ) {
if ( protocol == "http" ) { if ( protocol == "http" ) {
camera = new RemoteCameraHttp( camera = new RemoteCameraHttp(
id, this,
method, method,
host, host,
port, port,
@ -691,7 +691,7 @@ Camera * Monitor::getCamera() {
#if HAVE_LIBAVFORMAT #if HAVE_LIBAVFORMAT
else if ( protocol == "rtsp" ) { else if ( protocol == "rtsp" ) {
camera = new RemoteCameraRtsp( camera = new RemoteCameraRtsp(
id, this,
method, method,
host, // Host host, // Host
port, // Port port, // Port
@ -714,7 +714,7 @@ Camera * Monitor::getCamera() {
} }
} else if ( type == FILE ) { } else if ( type == FILE ) {
camera = new FileCamera( camera = new FileCamera(
id, this,
path.c_str(), path.c_str(),
camera_width, camera_width,
camera_height, camera_height,
@ -729,7 +729,7 @@ Camera * Monitor::getCamera() {
} else if ( type == FFMPEG ) { } else if ( type == FFMPEG ) {
#if HAVE_LIBAVFORMAT #if HAVE_LIBAVFORMAT
camera = new FfmpegCamera( camera = new FfmpegCamera(
id, this,
path, path,
method, method,
options, options,
@ -748,7 +748,7 @@ Camera * Monitor::getCamera() {
#endif // HAVE_LIBAVFORMAT #endif // HAVE_LIBAVFORMAT
} else if ( type == NVSOCKET ) { } else if ( type == NVSOCKET ) {
camera = new RemoteCameraNVSocket( camera = new RemoteCameraNVSocket(
id, this,
host.c_str(), host.c_str(),
port.c_str(), port.c_str(),
path.c_str(), path.c_str(),
@ -765,7 +765,7 @@ Camera * Monitor::getCamera() {
} else if ( type == LIBVLC ) { } else if ( type == LIBVLC ) {
#if HAVE_LIBVLC #if HAVE_LIBVLC
camera = new LibvlcCamera( camera = new LibvlcCamera(
id, this,
path.c_str(), path.c_str(),
method, method,
options, options,
@ -785,7 +785,7 @@ Camera * Monitor::getCamera() {
} else if ( type == CURL ) { } else if ( type == CURL ) {
#if HAVE_LIBCURL #if HAVE_LIBCURL
camera = new cURLCamera( camera = new cURLCamera(
id, this,
path.c_str(), path.c_str(),
user.c_str(), user.c_str(),
pass.c_str(), pass.c_str(),
@ -805,7 +805,7 @@ Camera * Monitor::getCamera() {
} else if ( type == VNC ) { } else if ( type == VNC ) {
#if HAVE_LIBVNC #if HAVE_LIBVNC
camera = new VncCamera( camera = new VncCamera(
id, this,
host.c_str(), host.c_str(),
port.c_str(), port.c_str(),
user.c_str(), user.c_str(),
@ -825,11 +825,10 @@ Camera * Monitor::getCamera() {
#endif // HAVE_LIBVNC #endif // HAVE_LIBVNC
} // end if type } // end if type
camera->setMonitor(this);
return camera; return camera;
} // end Monitor::getCamera } // end Monitor::getCamera
Monitor *Monitor::Load(unsigned int p_id, bool load_zones, Purpose purpose) { std::shared_ptr<Monitor> Monitor::Load(unsigned int p_id, bool load_zones, Purpose purpose) {
std::string sql = load_monitor_sql + stringtf(" WHERE Id=%d", p_id); std::string sql = load_monitor_sql + stringtf(" WHERE Id=%d", p_id);
zmDbRow dbrow; zmDbRow dbrow;
@ -837,11 +836,12 @@ Monitor *Monitor::Load(unsigned int p_id, bool load_zones, Purpose purpose) {
Error("Can't use query result: %s", mysql_error(&dbconn)); Error("Can't use query result: %s", mysql_error(&dbconn));
return nullptr; return nullptr;
} }
Monitor *monitor = new Monitor();
std::shared_ptr<Monitor> monitor = std::make_shared<Monitor>();
monitor->Load(dbrow.mysql_row(), load_zones, purpose); monitor->Load(dbrow.mysql_row(), load_zones, purpose);
return monitor; return monitor;
} // end Monitor *Monitor::Load(unsigned int p_id, bool load_zones, Purpose purpose) }
bool Monitor::connect() { bool Monitor::connect() {
Debug(3, "Connecting to monitor. Purpose is %d", purpose); Debug(3, "Connecting to monitor. Purpose is %d", purpose);
@ -2376,36 +2376,37 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) {
} // end if p_linked_monitors } // end if p_linked_monitors
} // end void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) } // end void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors)
int Monitor::LoadMonitors(std::string sql, Monitor **&monitors, Purpose purpose) { std::vector<std::shared_ptr<Monitor>> Monitor::LoadMonitors(std::string sql, Purpose purpose) {
Debug(1, "Loading Monitors with %s", sql.c_str()); Debug(1, "Loading Monitors with %s", sql.c_str());
MYSQL_RES *result = zmDbFetch(sql.c_str()); MYSQL_RES *result = zmDbFetch(sql.c_str());
if ( !result ) { if (!result) {
Error("Can't load local monitors: %s", mysql_error(&dbconn)); Error("Can't load local monitors: %s", mysql_error(&dbconn));
return 0; return {};
} }
int n_monitors = mysql_num_rows(result); int n_monitors = mysql_num_rows(result);
Debug(1, "Got %d monitors", n_monitors); Debug(1, "Got %d monitors", n_monitors);
delete[] monitors;
monitors = new Monitor *[n_monitors]; std::vector<std::shared_ptr<Monitor>> monitors;
for( int i=0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++ ) { monitors.reserve(n_monitors);
monitors[i] = new Monitor();
monitors[i]->Load(dbrow, true, purpose); for (int i = 0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++) {
// need to load zones and set Purpose, 1, purpose); monitors.emplace_back();
monitors.back()->Load(dbrow, true, purpose);
} }
if ( mysql_errno(&dbconn) ) {
if (mysql_errno(&dbconn)) {
Error("Can't fetch row: %s", mysql_error(&dbconn)); Error("Can't fetch row: %s", mysql_error(&dbconn));
mysql_free_result(result); mysql_free_result(result);
return 0; return {};
} }
mysql_free_result(result); mysql_free_result(result);
return n_monitors; return monitors;
} // end int Monitor::LoadMonitors(std::string sql, Monitor **&monitors, Purpose purpose) }
#if ZM_HAS_V4L #if ZM_HAS_V4L
int Monitor::LoadLocalMonitors(const char *device, Monitor **&monitors, Purpose purpose) { std::vector<std::shared_ptr<Monitor>> Monitor::LoadLocalMonitors(const char *device, Purpose purpose) {
std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND `Type` = 'Local'"; std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND `Type` = 'Local'";
@ -2413,32 +2414,32 @@ int Monitor::LoadLocalMonitors(const char *device, Monitor **&monitors, Purpose
sql += " AND `Device`='" + std::string(device) + "'"; sql += " AND `Device`='" + std::string(device) + "'";
if ( staticConfig.SERVER_ID ) if ( staticConfig.SERVER_ID )
sql += stringtf(" AND `ServerId`=%d", staticConfig.SERVER_ID); sql += stringtf(" AND `ServerId`=%d", staticConfig.SERVER_ID);
return LoadMonitors(sql, monitors, purpose); return LoadMonitors(sql, purpose);
} // end int Monitor::LoadLocalMonitors(const char *device, Monitor **&monitors, Purpose purpose) }
#endif // ZM_HAS_V4L #endif // ZM_HAS_V4L
int Monitor::LoadRemoteMonitors(const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose) { std::vector<std::shared_ptr<Monitor>> Monitor::LoadRemoteMonitors(const char *protocol, const char *host, const char *port, const char *path, Purpose purpose) {
std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND `Type` = 'Remote'"; std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND `Type` = 'Remote'";
if ( staticConfig.SERVER_ID ) if ( staticConfig.SERVER_ID )
sql += stringtf(" AND `ServerId`=%d", staticConfig.SERVER_ID); sql += stringtf(" AND `ServerId`=%d", staticConfig.SERVER_ID);
if ( protocol ) if ( protocol )
sql += stringtf(" AND `Protocol` = '%s' AND `Host` = '%s' AND `Port` = '%s' AND `Path` = '%s'", protocol, host, port, path); sql += stringtf(" AND `Protocol` = '%s' AND `Host` = '%s' AND `Port` = '%s' AND `Path` = '%s'", protocol, host, port, path);
return LoadMonitors(sql, monitors, purpose); return LoadMonitors(sql, purpose);
} // end int Monitor::LoadRemoteMonitors }
int Monitor::LoadFileMonitors(const char *file, Monitor **&monitors, Purpose purpose) { std::vector<std::shared_ptr<Monitor>> Monitor::LoadFileMonitors(const char *file, Purpose purpose) {
std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND `Type` = 'File'"; std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND `Type` = 'File'";
if ( file[0] ) if ( file[0] )
sql += " AND `Path`='" + std::string(file) + "'"; sql += " AND `Path`='" + std::string(file) + "'";
if ( staticConfig.SERVER_ID ) { if ( staticConfig.SERVER_ID ) {
sql += stringtf(" AND `ServerId`=%d", staticConfig.SERVER_ID); sql += stringtf(" AND `ServerId`=%d", staticConfig.SERVER_ID);
} }
return LoadMonitors(sql, monitors, purpose); return LoadMonitors(sql, purpose);
} // end int Monitor::LoadFileMonitors }
#if HAVE_LIBAVFORMAT #if HAVE_LIBAVFORMAT
int Monitor::LoadFfmpegMonitors(const char *file, Monitor **&monitors, Purpose purpose) { std::vector<std::shared_ptr<Monitor>> Monitor::LoadFfmpegMonitors(const char *file, Purpose purpose) {
std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND `Type` = 'Ffmpeg'"; std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND `Type` = 'Ffmpeg'";
if ( file[0] ) if ( file[0] )
sql += " AND `Path` = '" + std::string(file) + "'"; sql += " AND `Path` = '" + std::string(file) + "'";
@ -2446,8 +2447,8 @@ int Monitor::LoadFfmpegMonitors(const char *file, Monitor **&monitors, Purpose p
if ( staticConfig.SERVER_ID ) { if ( staticConfig.SERVER_ID ) {
sql += stringtf(" AND `ServerId`=%d", staticConfig.SERVER_ID); sql += stringtf(" AND `ServerId`=%d", staticConfig.SERVER_ID);
} }
return LoadMonitors(sql, monitors, purpose); return LoadMonitors(sql, purpose);
} // end int Monitor::LoadFfmpegMonitors }
#endif // HAVE_LIBAVFORMAT #endif // HAVE_LIBAVFORMAT
/* Returns 0 on success, even if no new images are available (transient error) /* Returns 0 on success, even if no new images are available (transient error)

View File

@ -26,6 +26,7 @@
#include "zm_packet.h" #include "zm_packet.h"
#include "zm_packetqueue.h" #include "zm_packetqueue.h"
#include "zm_video.h" #include "zm_video.h"
#include <memory>
#include <sys/time.h> #include <sys/time.h>
#include <vector> #include <vector>
@ -532,16 +533,16 @@ public:
std::vector<Group *> Groups(); std::vector<Group *> Groups();
StringVector GroupNames(); StringVector GroupNames();
static int LoadMonitors(std::string sql, Monitor **&monitors, Purpose purpose); // Returns # of Monitors loaded, 0 on failure. static std::vector<std::shared_ptr<Monitor>> LoadMonitors(std::string sql, Purpose purpose); // Returns # of Monitors loaded, 0 on failure.
#if ZM_HAS_V4L #if ZM_HAS_V4L
static int LoadLocalMonitors(const char *device, Monitor **&monitors, Purpose purpose); static std::vector<std::shared_ptr<Monitor>> LoadLocalMonitors(const char *device, Purpose purpose);
#endif // ZM_HAS_V4L #endif // ZM_HAS_V4L
static int LoadRemoteMonitors(const char *protocol, const char *host, const char*port, const char*path, Monitor **&monitors, Purpose purpose); static std::vector<std::shared_ptr<Monitor>> LoadRemoteMonitors(const char *protocol, const char *host, const char*port, const char*path, Purpose purpose);
static int LoadFileMonitors(const char *file, Monitor **&monitors, Purpose purpose); static std::vector<std::shared_ptr<Monitor>> LoadFileMonitors(const char *file, Purpose purpose);
#if HAVE_LIBAVFORMAT #if HAVE_LIBAVFORMAT
static int LoadFfmpegMonitors(const char *file, Monitor **&monitors, Purpose purpose); static std::vector<std::shared_ptr<Monitor>> LoadFfmpegMonitors(const char *file, Purpose purpose);
#endif // HAVE_LIBAVFORMAT #endif // HAVE_LIBAVFORMAT
static Monitor *Load(unsigned int id, bool load_zones, Purpose purpose); static std::shared_ptr<Monitor> Load(unsigned int id, bool load_zones, Purpose purpose);
void Load(MYSQL_ROW dbrow, bool load_zones, Purpose purpose); void Load(MYSQL_ROW dbrow, bool load_zones, Purpose purpose);
//void writeStreamImage( Image *image, struct timeval *timestamp, int scale, int mag, int x, int y ); //void writeStreamImage( Image *image, struct timeval *timestamp, int scale, int mag, int x, int y );
//void StreamImages( int scale=100, int maxfps=10, time_t ttl=0, int msq_id=0 ); //void StreamImages( int scale=100, int maxfps=10, time_t ttl=0, int msq_id=0 );

View File

@ -24,7 +24,7 @@
#include <netdb.h> #include <netdb.h>
RemoteCamera::RemoteCamera( RemoteCamera::RemoteCamera(
unsigned int p_monitor_id, const Monitor *monitor,
const std::string &p_protocol, const std::string &p_protocol,
const std::string &p_host, const std::string &p_host,
const std::string &p_port, const std::string &p_port,
@ -39,7 +39,7 @@ RemoteCamera::RemoteCamera(
bool p_capture, bool p_capture,
bool p_record_audio bool p_record_audio
) : ) :
Camera( p_monitor_id, REMOTE_SRC, p_width, p_height, p_colours, ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours), p_brightness, p_contrast, p_hue, p_colour, p_capture, p_record_audio ), Camera( monitor, REMOTE_SRC, p_width, p_height, p_colours, ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours), p_brightness, p_contrast, p_hue, p_colour, p_capture, p_record_audio ),
protocol( p_protocol ), protocol( p_protocol ),
host( p_host ), host( p_host ),
port( p_port ), port( p_port ),

View File

@ -52,7 +52,7 @@ protected:
public: public:
RemoteCamera( RemoteCamera(
unsigned int p_monitor_id, const Monitor *monitor,
const std::string &p_proto, const std::string &p_proto,
const std::string &p_host, const std::string &p_host,
const std::string &p_port, const std::string &p_port,

View File

@ -42,7 +42,7 @@ static RegExpr *content_type_expr = nullptr;
#endif #endif
RemoteCameraHttp::RemoteCameraHttp( RemoteCameraHttp::RemoteCameraHttp(
unsigned int p_monitor_id, const Monitor *monitor,
const std::string &p_method, const std::string &p_method,
const std::string &p_host, const std::string &p_host,
const std::string &p_port, const std::string &p_port,
@ -56,7 +56,7 @@ RemoteCameraHttp::RemoteCameraHttp(
bool p_capture, bool p_capture,
bool p_record_audio ) : bool p_record_audio ) :
RemoteCamera( RemoteCamera(
p_monitor_id, monitor,
"http", "http",
p_host, p_host,
p_port, p_port,
@ -81,11 +81,11 @@ RemoteCameraHttp::RemoteCameraHttp(
else if ( p_method == "regexp" ) { else if ( p_method == "regexp" ) {
method = REGEXP; method = REGEXP;
} else } else
Fatal( "Unrecognised method '%s' when creating HTTP camera %d", p_method.c_str(), monitor_id ); Fatal("Unrecognised method '%s' when creating HTTP camera %d", p_method.c_str(), monitor->Id());
if ( capture ) { if ( capture ) {
Initialise(); Initialise();
} }
mVideoStream = NULL; mVideoStream = nullptr;
} }
RemoteCameraHttp::~RemoteCameraHttp() { RemoteCameraHttp::~RemoteCameraHttp() {
@ -156,7 +156,7 @@ int RemoteCameraHttp::Connect() {
addr = (struct sockaddr_in *)p->ai_addr; addr = (struct sockaddr_in *)p->ai_addr;
inet_ntop( AF_INET, &(addr->sin_addr), buf, INET6_ADDRSTRLEN ); inet_ntop( AF_INET, &(addr->sin_addr), buf, INET6_ADDRSTRLEN );
Warning("Can't connect to remote camera mid: %d at %s: %s", monitor_id, buf, strerror(errno) ); Warning("Can't connect to remote camera mid: %d at %s: %s", monitor->Id(), buf, strerror(errno));
continue; continue;
} }

View File

@ -42,7 +42,7 @@ protected:
public: public:
RemoteCameraHttp( RemoteCameraHttp(
unsigned int p_monitor_id, const Monitor *monitor,
const std::string &method, const std::string &method,
const std::string &host, const std::string &host,
const std::string &port, const std::string &port,

View File

@ -32,7 +32,7 @@
#endif #endif
RemoteCameraNVSocket::RemoteCameraNVSocket( RemoteCameraNVSocket::RemoteCameraNVSocket(
unsigned int p_monitor_id, const Monitor *monitor,
const std::string &p_host, const std::string &p_host,
const std::string &p_port, const std::string &p_port,
const std::string &p_path, const std::string &p_path,
@ -46,7 +46,7 @@ RemoteCameraNVSocket::RemoteCameraNVSocket(
bool p_capture, bool p_capture,
bool p_record_audio ) : bool p_record_audio ) :
RemoteCamera( RemoteCamera(
p_monitor_id, monitor,
"http", "http",
p_host, p_host,
p_port, p_port,
@ -115,7 +115,7 @@ int RemoteCameraNVSocket::Connect() {
close(sd); close(sd);
sd = -1; sd = -1;
Warning("Can't connect to socket mid: %d : %s", monitor_id, strerror(errno) ); Warning("Can't connect to socket mid: %d : %s", monitor->Id(), strerror(errno));
return -1; return -1;
} }

View File

@ -32,7 +32,7 @@ protected:
public: public:
RemoteCameraNVSocket( RemoteCameraNVSocket(
unsigned int p_monitor_id, const Monitor *monitor,
const std::string &host, const std::string &host,
const std::string &port, const std::string &port,
const std::string &path, const std::string &path,

View File

@ -25,7 +25,7 @@
#if HAVE_LIBAVFORMAT #if HAVE_LIBAVFORMAT
RemoteCameraRtsp::RemoteCameraRtsp( RemoteCameraRtsp::RemoteCameraRtsp(
unsigned int p_monitor_id, const Monitor *monitor,
const std::string &p_method, const std::string &p_method,
const std::string &p_host, const std::string &p_host,
const std::string &p_port, const std::string &p_port,
@ -41,7 +41,7 @@ RemoteCameraRtsp::RemoteCameraRtsp(
bool p_capture, bool p_capture,
bool p_record_audio ) : bool p_record_audio ) :
RemoteCamera( RemoteCamera(
p_monitor_id, "rtsp", monitor, "rtsp",
p_host, p_port, p_path, p_host, p_port, p_path,
p_width, p_height, p_colours, p_width, p_height, p_colours,
p_brightness, p_contrast, p_hue, p_colour, p_brightness, p_contrast, p_hue, p_colour,
@ -59,7 +59,7 @@ RemoteCameraRtsp::RemoteCameraRtsp(
else if ( p_method == "rtpRtspHttp" ) else if ( p_method == "rtpRtspHttp" )
method = RtspThread::RTP_RTSP_HTTP; method = RtspThread::RTP_RTSP_HTTP;
else else
Fatal("Unrecognised method '%s' when creating RTSP camera %d", p_method.c_str(), monitor_id); Fatal("Unrecognised method '%s' when creating RTSP camera %d", p_method.c_str(), monitor->Id());
if ( capture ) { if ( capture ) {
Initialise(); Initialise();
@ -113,7 +113,7 @@ void RemoteCameraRtsp::Terminate() {
} }
int RemoteCameraRtsp::Connect() { int RemoteCameraRtsp::Connect() {
rtspThread = new RtspThread(monitor_id, method, protocol, host, port, path, auth, rtsp_describe); rtspThread = new RtspThread(monitor->Id(), method, protocol, host, port, path, auth, rtsp_describe);
rtspThread->start(); rtspThread->start();

View File

@ -55,7 +55,7 @@ protected:
public: public:
RemoteCameraRtsp( RemoteCameraRtsp(
unsigned int p_monitor_id, const Monitor *monitor,
const std::string &method, const std::string &method,
const std::string &host, const std::string &host,
const std::string &port, const std::string &port,

View File

@ -27,12 +27,12 @@ static unsigned const samplingFrequencyTable[16] = {
// //
ADTS_ZoneMinderDeviceSource::ADTS_ZoneMinderDeviceSource( ADTS_ZoneMinderDeviceSource::ADTS_ZoneMinderDeviceSource(
UsageEnvironment& env, UsageEnvironment& env,
Monitor *monitor, std::shared_ptr<Monitor> monitor,
AVStream *stream, AVStream *stream,
unsigned int queueSize unsigned int queueSize
) )
: :
ZoneMinderDeviceSource(env, monitor, stream, queueSize), ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize),
samplingFrequencyIndex(0), samplingFrequencyIndex(0),
channels(stream->codecpar->channels) channels(stream->codecpar->channels)
{ {

View File

@ -24,18 +24,18 @@ class ADTS_ZoneMinderDeviceSource : public ZoneMinderDeviceSource {
public: public:
static ADTS_ZoneMinderDeviceSource* createNew( static ADTS_ZoneMinderDeviceSource* createNew(
UsageEnvironment& env, UsageEnvironment& env,
Monitor* monitor, std::shared_ptr<Monitor> monitor,
AVStream * stream, AVStream * stream,
unsigned int queueSize unsigned int queueSize
) { ) {
Debug(1, "m_stream %p codecpar %p channels %d", Debug(1, "m_stream %p codecpar %p channels %d",
stream, stream->codecpar, stream->codecpar->channels); stream, stream->codecpar, stream->codecpar->channels);
return new ADTS_ZoneMinderDeviceSource(env, monitor, stream, queueSize); return new ADTS_ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize);
}; };
protected: protected:
ADTS_ZoneMinderDeviceSource( ADTS_ZoneMinderDeviceSource(
UsageEnvironment& env, UsageEnvironment& env,
Monitor *monitor, std::shared_ptr<Monitor> monitor,
AVStream *stream, AVStream *stream,
unsigned int queueSize unsigned int queueSize
); );

View File

@ -18,13 +18,13 @@
#if HAVE_RTSP_SERVER #if HAVE_RTSP_SERVER
ZoneMinderDeviceSource::ZoneMinderDeviceSource( ZoneMinderDeviceSource::ZoneMinderDeviceSource(
UsageEnvironment& env, UsageEnvironment& env,
Monitor* monitor, std::shared_ptr<Monitor> monitor,
AVStream *stream, AVStream *stream,
unsigned int queueSize unsigned int queueSize
) : ) :
FramedSource(env), FramedSource(env),
m_stream(stream), m_stream(stream),
m_monitor(monitor), m_monitor(std::move(monitor)),
m_packetqueue(nullptr), m_packetqueue(nullptr),
m_packetqueue_it(nullptr), m_packetqueue_it(nullptr),
m_queueSize(queueSize) m_queueSize(queueSize)

View File

@ -26,7 +26,7 @@ class ZoneMinderDeviceSource: public FramedSource {
public: public:
static ZoneMinderDeviceSource* createNew( static ZoneMinderDeviceSource* createNew(
UsageEnvironment& env, UsageEnvironment& env,
Monitor* monitor, std::shared_ptr<Monitor> monitor,
AVStream * stream, AVStream * stream,
unsigned int queueSize unsigned int queueSize
) { ) {
@ -37,7 +37,7 @@ class ZoneMinderDeviceSource: public FramedSource {
int getHeight() { return m_monitor->Height(); }; int getHeight() { return m_monitor->Height(); };
protected: protected:
ZoneMinderDeviceSource(UsageEnvironment& env, Monitor* monitor, AVStream * stream, unsigned int queueSize); ZoneMinderDeviceSource(UsageEnvironment& env, std::shared_ptr<Monitor> monitor, AVStream * stream, unsigned int queueSize);
virtual ~ZoneMinderDeviceSource(); virtual ~ZoneMinderDeviceSource();
protected: protected:
@ -63,7 +63,7 @@ class ZoneMinderDeviceSource: public FramedSource {
std::list<NAL_Frame*> m_captureQueue; std::list<NAL_Frame*> m_captureQueue;
EventTriggerId m_eventTriggerId; EventTriggerId m_eventTriggerId;
AVStream *m_stream; AVStream *m_stream;
Monitor* m_monitor; std::shared_ptr<Monitor> m_monitor;
PacketQueue *m_packetqueue; PacketQueue *m_packetqueue;
std::list<ZMPacket *>::iterator *m_packetqueue_it; std::list<ZMPacket *>::iterator *m_packetqueue_it;

View File

@ -24,12 +24,12 @@
// //
H264_ZoneMinderDeviceSource::H264_ZoneMinderDeviceSource( H264_ZoneMinderDeviceSource::H264_ZoneMinderDeviceSource(
UsageEnvironment& env, UsageEnvironment& env,
Monitor *monitor, std::shared_ptr<Monitor> monitor,
AVStream *stream, AVStream *stream,
unsigned int queueSize, unsigned int queueSize,
bool repeatConfig, bool repeatConfig,
bool keepMarker) bool keepMarker)
: H26X_ZoneMinderDeviceSource(env, monitor, stream, queueSize, repeatConfig, keepMarker) : H26X_ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize, repeatConfig, keepMarker)
{ {
// extradata appears to simply be the SPS and PPS NAL's // extradata appears to simply be the SPS and PPS NAL's
this->splitFrames(m_stream->codecpar->extradata, m_stream->codecpar->extradata_size); this->splitFrames(m_stream->codecpar->extradata, m_stream->codecpar->extradata_size);
@ -89,12 +89,12 @@ std::list< std::pair<unsigned char*, size_t> > H264_ZoneMinderDeviceSource::spli
H265_ZoneMinderDeviceSource::H265_ZoneMinderDeviceSource( H265_ZoneMinderDeviceSource::H265_ZoneMinderDeviceSource(
UsageEnvironment& env, UsageEnvironment& env,
Monitor *monitor, std::shared_ptr<Monitor> monitor,
AVStream *stream, AVStream *stream,
unsigned int queueSize, unsigned int queueSize,
bool repeatConfig, bool repeatConfig,
bool keepMarker) bool keepMarker)
: H26X_ZoneMinderDeviceSource(env, monitor, stream, queueSize, repeatConfig, keepMarker) : H26X_ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize, repeatConfig, keepMarker)
{ {
// extradata appears to simply be the SPS and PPS NAL's // extradata appears to simply be the SPS and PPS NAL's
this->splitFrames(m_stream->codecpar->extradata, m_stream->codecpar->extradata_size); this->splitFrames(m_stream->codecpar->extradata, m_stream->codecpar->extradata_size);

View File

@ -23,13 +23,13 @@ class H26X_ZoneMinderDeviceSource : public ZoneMinderDeviceSource {
protected: protected:
H26X_ZoneMinderDeviceSource( H26X_ZoneMinderDeviceSource(
UsageEnvironment& env, UsageEnvironment& env,
Monitor *monitor, std::shared_ptr<Monitor> monitor,
AVStream *stream, AVStream *stream,
unsigned int queueSize, unsigned int queueSize,
bool repeatConfig, bool repeatConfig,
bool keepMarker) bool keepMarker)
: :
ZoneMinderDeviceSource(env, monitor, stream, queueSize), ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize),
m_repeatConfig(repeatConfig), m_repeatConfig(repeatConfig),
m_keepMarker(keepMarker), m_keepMarker(keepMarker),
m_frameType(0) { } m_frameType(0) { }
@ -51,18 +51,18 @@ class H264_ZoneMinderDeviceSource : public H26X_ZoneMinderDeviceSource {
public: public:
static H264_ZoneMinderDeviceSource* createNew( static H264_ZoneMinderDeviceSource* createNew(
UsageEnvironment& env, UsageEnvironment& env,
Monitor *monitor, std::shared_ptr<Monitor> monitor,
AVStream *stream, AVStream *stream,
unsigned int queueSize, unsigned int queueSize,
bool repeatConfig, bool repeatConfig,
bool keepMarker) { bool keepMarker) {
return new H264_ZoneMinderDeviceSource(env, monitor, stream, queueSize, repeatConfig, keepMarker); return new H264_ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize, repeatConfig, keepMarker);
} }
protected: protected:
H264_ZoneMinderDeviceSource( H264_ZoneMinderDeviceSource(
UsageEnvironment& env, UsageEnvironment& env,
Monitor *monitor, std::shared_ptr<Monitor> monitor,
AVStream *stream, AVStream *stream,
unsigned int queueSize, unsigned int queueSize,
bool repeatConfig, bool repeatConfig,
@ -76,18 +76,18 @@ class H265_ZoneMinderDeviceSource : public H26X_ZoneMinderDeviceSource {
public: public:
static H265_ZoneMinderDeviceSource* createNew( static H265_ZoneMinderDeviceSource* createNew(
UsageEnvironment& env, UsageEnvironment& env,
Monitor *monitor, std::shared_ptr<Monitor> monitor,
AVStream *stream, AVStream *stream,
unsigned int queueSize, unsigned int queueSize,
bool repeatConfig, bool repeatConfig,
bool keepMarker) { bool keepMarker) {
return new H265_ZoneMinderDeviceSource(env, monitor, stream, queueSize, repeatConfig, keepMarker); return new H265_ZoneMinderDeviceSource(env, std::move(monitor), stream, queueSize, repeatConfig, keepMarker);
} }
protected: protected:
H265_ZoneMinderDeviceSource( H265_ZoneMinderDeviceSource(
UsageEnvironment& env, UsageEnvironment& env,
Monitor *monitor, std::shared_ptr<Monitor> monitor,
AVStream *stream, AVStream *stream,
unsigned int queueSize, unsigned int queueSize,
bool repeatConfig, bool repeatConfig,

View File

@ -8,8 +8,8 @@
#if HAVE_RTSP_SERVER #if HAVE_RTSP_SERVER
#include <StreamReplicator.hh> #include <StreamReplicator.hh>
RTSPServerThread::RTSPServerThread(Monitor *p_monitor) : RTSPServerThread::RTSPServerThread(std::shared_ptr<Monitor> monitor) :
monitor(p_monitor), monitor(std::move(monitor)),
terminate(0) terminate(0)
{ {
//unsigned short rtsp_over_http_port = 0; //unsigned short rtsp_over_http_port = 0;

View File

@ -5,6 +5,7 @@
#include "zm_ffmpeg.h" #include "zm_ffmpeg.h"
#include "zm_thread.h" #include "zm_thread.h"
#include <list> #include <list>
#include <memory>
#if HAVE_RTSP_SERVER #if HAVE_RTSP_SERVER
#include <BasicUsageEnvironment.hh> #include <BasicUsageEnvironment.hh>
@ -14,7 +15,7 @@ class Monitor;
class RTSPServerThread : public Thread { class RTSPServerThread : public Thread {
private: private:
Monitor *monitor; std::shared_ptr<Monitor> monitor;
char terminate; char terminate;
TaskScheduler* scheduler; TaskScheduler* scheduler;
@ -25,7 +26,7 @@ class RTSPServerThread : public Thread {
std::list<FramedSource *> sources; std::list<FramedSource *> sources;
public: public:
explicit RTSPServerThread(Monitor *); explicit RTSPServerThread(std::shared_ptr<Monitor> monitor);
~RTSPServerThread(); ~RTSPServerThread();
void addStream(AVStream *, AVStream *); void addStream(AVStream *, AVStream *);
int run(); int run();

View File

@ -34,16 +34,10 @@ StreamBase::~StreamBase() {
} }
#endif #endif
closeComms(); closeComms();
if ( monitor ) {
delete monitor;
monitor = nullptr;
}
} }
bool StreamBase::loadMonitor(int p_monitor_id) { bool StreamBase::loadMonitor(int p_monitor_id) {
monitor_id = p_monitor_id; monitor_id = p_monitor_id;
if ( monitor )
delete monitor;
if ( !(monitor = Monitor::Load(monitor_id, false, Monitor::QUERY)) ) { if ( !(monitor = Monitor::Load(monitor_id, false, Monitor::QUERY)) ) {
Error("Unable to load monitor id %d for streaming", monitor_id); Error("Unable to load monitor id %d for streaming", monitor_id);

View File

@ -22,7 +22,7 @@
#include "zm_logger.h" #include "zm_logger.h"
#include "zm_mpeg.h" #include "zm_mpeg.h"
#include <memory>
#include <sys/un.h> #include <sys/un.h>
class Image; class Image;
@ -93,7 +93,7 @@ protected:
protected: protected:
int monitor_id; int monitor_id;
Monitor *monitor; std::shared_ptr<Monitor> monitor;
StreamType type; StreamType type;
const char *format; const char *format;

View File

@ -57,6 +57,7 @@ possible, this should run at more or less constant speed.
#include "zm_analysis_thread.h" #include "zm_analysis_thread.h"
#include "zm_camera.h" #include "zm_camera.h"
#include "zm_db.h" #include "zm_db.h"
#include "zm_define.h"
#include "zm_monitor.h" #include "zm_monitor.h"
#include "zm_rtsp_server_thread.h" #include "zm_rtsp_server_thread.h"
#include "zm_signal.h" #include "zm_signal.h"
@ -186,29 +187,26 @@ int main(int argc, char *argv[]) {
hwcaps_detect(); hwcaps_detect();
Monitor **monitors = nullptr; std::vector<std::shared_ptr<Monitor>> monitors;
int n_monitors = 0;
#if ZM_HAS_V4L #if ZM_HAS_V4L
if ( device[0] ) { if ( device[0] ) {
n_monitors = Monitor::LoadLocalMonitors(device, monitors, Monitor::CAPTURE); monitors = Monitor::LoadLocalMonitors(device, Monitor::CAPTURE);
} else } else
#endif // ZM_HAS_V4L #endif // ZM_HAS_V4L
if ( host[0] ) { if ( host[0] ) {
if ( !port ) if ( !port )
port = "80"; port = "80";
n_monitors = Monitor::LoadRemoteMonitors(protocol, host, port, path, monitors, Monitor::CAPTURE); monitors = Monitor::LoadRemoteMonitors(protocol, host, port, path, Monitor::CAPTURE);
} else if ( file[0] ) { } else if ( file[0] ) {
n_monitors = Monitor::LoadFileMonitors(file, monitors, Monitor::CAPTURE); monitors = Monitor::LoadFileMonitors(file, Monitor::CAPTURE);
} else { } else {
Monitor *monitor = Monitor::Load(monitor_id, true, Monitor::CAPTURE); std::shared_ptr<Monitor> monitor = Monitor::Load(monitor_id, true, Monitor::CAPTURE);
if ( monitor ) { if ( monitor ) {
monitors = new Monitor *[1]; monitors.push_back(monitor);
monitors[0] = monitor;
n_monitors = 1;
} }
} }
if ( !n_monitors ) { if (monitors.empty()) {
Error("No monitors found"); Error("No monitors found");
exit(-1); exit(-1);
} }
@ -232,17 +230,17 @@ int main(int argc, char *argv[]) {
while ( !zm_terminate ) { while ( !zm_terminate ) {
result = 0; result = 0;
static char sql[ZM_SQL_SML_BUFSIZ]; static char sql[ZM_SQL_SML_BUFSIZ];
for ( int i = 0; i < n_monitors; i++ ) { for (const std::shared_ptr<Monitor> &monitor : monitors) {
if ( ! monitors[i]->getCamera() ) { if (!monitor->getCamera()) {
} }
if ( ! monitors[i]->connect() ) { if (!monitor->connect()) {
} }
time_t now = (time_t)time(nullptr); time_t now = (time_t)time(nullptr);
monitors[i]->setStartupTime(now); monitor->setStartupTime(now);
snprintf(sql, sizeof(sql), snprintf(sql, sizeof(sql),
"INSERT INTO Monitor_Status (MonitorId,Status,CaptureFPS,AnalysisFPS) VALUES (%d, 'Running',0,0) ON DUPLICATE KEY UPDATE Status='Running',CaptureFPS=0,AnalysisFPS=0", "INSERT INTO Monitor_Status (MonitorId,Status,CaptureFPS,AnalysisFPS) VALUES (%d, 'Running',0,0) ON DUPLICATE KEY UPDATE Status='Running',CaptureFPS=0,AnalysisFPS=0",
monitors[i]->Id()); monitor->Id());
if ( mysql_query(&dbconn, sql) ) { if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn)); Error("Can't run query: %s", mysql_error(&dbconn));
} }
@ -263,10 +261,10 @@ int main(int argc, char *argv[]) {
} }
continue; continue;
} }
for ( int i = 0; i < n_monitors; i++ ) { for (std::shared_ptr<Monitor> &monitor : monitors) {
snprintf(sql, sizeof(sql), snprintf(sql, sizeof(sql),
"INSERT INTO Monitor_Status (MonitorId,Status) VALUES (%d, 'Connected') ON DUPLICATE KEY UPDATE Status='Connected'", "INSERT INTO Monitor_Status (MonitorId,Status) VALUES (%d, 'Connected') ON DUPLICATE KEY UPDATE Status='Connected'",
monitors[i]->Id()); monitor->Id());
if ( mysql_query(&dbconn, sql) ) { if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn)); Error("Can't run query: %s", mysql_error(&dbconn));
} }
@ -275,17 +273,17 @@ int main(int argc, char *argv[]) {
#if HAVE_RTSP_SERVER #if HAVE_RTSP_SERVER
RTSPServerThread ** rtsp_server_threads = nullptr; RTSPServerThread ** rtsp_server_threads = nullptr;
if ( config.min_rtsp_port and monitors[0]->RTSPServer() ) { if ( config.min_rtsp_port and monitors[0]->RTSPServer() ) {
rtsp_server_threads = new RTSPServerThread *[n_monitors]; rtsp_server_threads = new RTSPServerThread *[monitors.size()];
Debug(1, "Starting RTSP server because min_rtsp_port is set"); Debug(1, "Starting RTSP server because min_rtsp_port is set");
} else { } else {
Debug(1, "Not starting RTSP server because min_rtsp_port not set"); Debug(1, "Not starting RTSP server because min_rtsp_port not set");
} }
#endif #endif
AnalysisThread **analysis_threads = new AnalysisThread *[n_monitors]; AnalysisThread **analysis_threads = new AnalysisThread *[monitors.size()];
int *capture_delays = new int[n_monitors]; int *capture_delays = new int[monitors.size()];
int *alarm_capture_delays = new int[n_monitors]; int *alarm_capture_delays = new int[monitors.size()];
struct timeval * last_capture_times = new struct timeval[n_monitors]; struct timeval * last_capture_times = new struct timeval[monitors.size()];
for ( int i = 0; i < n_monitors; i++ ) { for (size_t i = 0; i < monitors.size(); i++) {
last_capture_times[i].tv_sec = last_capture_times[i].tv_usec = 0; last_capture_times[i].tv_sec = last_capture_times[i].tv_usec = 0;
capture_delays[i] = monitors[i]->GetCaptureDelay(); capture_delays[i] = monitors[i]->GetCaptureDelay();
alarm_capture_delays[i] = monitors[i]->GetAlarmCaptureDelay(); alarm_capture_delays[i] = monitors[i]->GetAlarmCaptureDelay();
@ -298,11 +296,11 @@ int main(int argc, char *argv[]) {
analysis_threads[i] = new AnalysisThread(monitors[i]); analysis_threads[i] = new AnalysisThread(monitors[i]);
analysis_threads[i]->start(); analysis_threads[i]->start();
} else { } else {
analysis_threads[i] = NULL; analysis_threads[i] = nullptr;
} }
#if HAVE_RTSP_SERVER #if HAVE_RTSP_SERVER
if ( rtsp_server_threads ) { if ( rtsp_server_threads ) {
for ( int i = 0; i < n_monitors; i++ ) { for (size_t i = 0; i < monitors.size(); i++) {
rtsp_server_threads[i] = new RTSPServerThread(monitors[i]); rtsp_server_threads[i] = new RTSPServerThread(monitors[i]);
Camera *camera = monitors[i]->getCamera(); Camera *camera = monitors[i]->getCamera();
rtsp_server_threads[i]->addStream(camera->get_VideoStream(), camera->get_AudioStream()); rtsp_server_threads[i]->addStream(camera->get_VideoStream(), camera->get_AudioStream());
@ -317,25 +315,24 @@ int main(int argc, char *argv[]) {
while ( !zm_terminate ) { while ( !zm_terminate ) {
//sigprocmask(SIG_BLOCK, &block_set, 0); //sigprocmask(SIG_BLOCK, &block_set, 0);
for ( int i = 0; i < n_monitors; i++ ) { for (size_t i = 0; i < monitors.size(); i++) {
monitors[i]->CheckAction(); monitors[i]->CheckAction();
if ( monitors[i]->PreCapture() < 0 ) { if ( monitors[i]->PreCapture() < 0 ) {
Error("Failed to pre-capture monitor %d %d (%d/%d)", Error("Failed to pre-capture monitor %d %d (%d/" SZFMTD ")",
monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors); monitors[i]->Id(), monitors[i]->Name(), i+1, monitors.size());
result = -1; result = -1;
break; break;
} }
if ( monitors[i]->Capture() < 0 ) { if ( monitors[i]->Capture() < 0 ) {
Error("Failed to capture image from monitor %d %s (%d/%d)", Error("Failed to capture image from monitor %d %s (%d/" SZFMTD ")",
monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors); monitors[i]->Id(), monitors[i]->Name(), i+1, monitors.size());
result = -1; result = -1;
break; break;
} }
if ( monitors[i]->PostCapture() < 0 ) { if ( monitors[i]->PostCapture() < 0 ) {
Error("Failed to post-capture monitor %d %s (%d/%d)", Error("Failed to post-capture monitor %d %s (%d/" SZFMTD ")",
monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors); monitors[i]->Id(), monitors[i]->Name(), i+1, monitors.size());
result = -1; result = -1;
break; break;
} }
@ -373,8 +370,8 @@ int main(int argc, char *argv[]) {
} }
if ( zm_reload ) { if ( zm_reload ) {
for ( int i = 0; i < n_monitors; i++ ) { for (std::shared_ptr<Monitor> &monitor : monitors) {
monitors[i]->Reload(); monitor->Reload();
} }
logTerm(); logTerm();
logInit(log_id_string); logInit(log_id_string);
@ -383,7 +380,7 @@ int main(int argc, char *argv[]) {
} // end while ! zm_terminate and connected } // end while ! zm_terminate and connected
// Killoff the analysis threads. Don't need them spinning while we try to reconnect // Killoff the analysis threads. Don't need them spinning while we try to reconnect
for ( int i = 0; i < n_monitors; i++ ) { for (size_t i = 0; i < monitors.size(); i++) {
if ( analysis_threads[i] ) { if ( analysis_threads[i] ) {
analysis_threads[i]->stop(); analysis_threads[i]->stop();
} }
@ -394,7 +391,7 @@ int main(int argc, char *argv[]) {
#endif #endif
} }
for ( int i = 0; i < n_monitors; i++ ) { for (size_t i = 0; i < monitors.size(); i++) {
monitors[i]->Close(); monitors[i]->Close();
// Killoff the analysis threads. Don't need them spinning while we try to reconnect // Killoff the analysis threads. Don't need them spinning while we try to reconnect
@ -435,18 +432,16 @@ int main(int argc, char *argv[]) {
Debug(1,"Updating Monitor status"); Debug(1,"Updating Monitor status");
for ( int i = 0; i < n_monitors; i++ ) { for (std::shared_ptr<Monitor> &monitor : monitors) {
static char sql[ZM_SQL_SML_BUFSIZ]; static char sql[ZM_SQL_SML_BUFSIZ];
snprintf(sql, sizeof(sql), snprintf(sql, sizeof(sql),
"INSERT INTO Monitor_Status (MonitorId,Status) VALUES (%d, 'Connected') ON DUPLICATE KEY UPDATE Status='NotRunning'", "INSERT INTO Monitor_Status (MonitorId,Status) VALUES (%d, 'Connected') ON DUPLICATE KEY UPDATE Status='NotRunning'",
monitors[i]->Id()); monitor->Id());
if ( mysql_query(&dbconn, sql) ) { if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn)); Error("Can't run query: %s", mysql_error(&dbconn));
} }
monitors[i]->disconnect(); monitor->disconnect();
delete monitors[i];
} }
delete [] monitors;
Image::Deinitialise(); Image::Deinitialise();
Debug(1,"terminating"); Debug(1,"terminating");

View File

@ -473,7 +473,7 @@ int main(int argc, char *argv[]) {
} // end if auth } // end if auth
if ( mon_id > 0 ) { if ( mon_id > 0 ) {
Monitor *monitor = Monitor::Load(mon_id, function&(ZMU_QUERY|ZMU_ZONES), Monitor::QUERY); std::shared_ptr<Monitor> monitor = Monitor::Load(mon_id, function&(ZMU_QUERY|ZMU_ZONES), Monitor::QUERY);
if ( !monitor ) { if ( !monitor ) {
Error("Unable to load monitor %d", mon_id); Error("Unable to load monitor %d", mon_id);
exit_zmu(-1); exit_zmu(-1);
@ -484,8 +484,6 @@ int main(int argc, char *argv[]) {
} }
if ( !monitor->connect() ) { if ( !monitor->connect() ) {
Error("Can't connect to capture daemon: %d %s", monitor->Id(), monitor->Name()); Error("Can't connect to capture daemon: %d %s", monitor->Id(), monitor->Name());
delete monitor;
monitor = nullptr;
exit_zmu(-1); exit_zmu(-1);
} }
@ -705,8 +703,6 @@ int main(int argc, char *argv[]) {
if ( !function ) { if ( !function ) {
Usage(); Usage();
} }
delete monitor;
monitor = nullptr;
} else { // non monitor functions } else { // non monitor functions
if ( function & ZMU_QUERY ) { if ( function & ZMU_QUERY ) {
#if ZM_HAS_V4L #if ZM_HAS_V4L
@ -745,7 +741,7 @@ int main(int argc, char *argv[]) {
int monitor_function = atoi(dbrow[1]); int monitor_function = atoi(dbrow[1]);
if ( !user || user->canAccess(monitor_id) ) { if ( !user || user->canAccess(monitor_id) ) {
if ( monitor_function > 1 ) { if ( monitor_function > 1 ) {
Monitor *monitor = Monitor::Load(monitor_id, false, Monitor::QUERY); std::shared_ptr<Monitor> monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
if ( monitor && monitor->connect() ) { if ( monitor && monitor->connect() ) {
struct timeval tv = monitor->GetTimestamp(); struct timeval tv = monitor->GetTimestamp();
printf( "%4d%5d%6d%9d%11ld.%02ld%6d%6d%8" PRIu64 "%8.2f\n", printf( "%4d%5d%6d%9d%11ld.%02ld%6d%6d%8" PRIu64 "%8.2f\n",
@ -759,7 +755,6 @@ int main(int argc, char *argv[]) {
monitor->GetLastEventId(), monitor->GetLastEventId(),
monitor->GetFPS() monitor->GetFPS()
); );
delete monitor;
} }
} else { } else {
struct timeval tv = { 0, 0 }; struct timeval tv = { 0, 0 };