@@ -27,11 +27,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <deque>
#include <array>
#include "Poco/Channel.h"
#include "rtp_ports_dispencer_detail.hpp"

namespace ZMB {

typedef std::vector<uint16_t> EvensArray;
typedef std::shared_ptr<EvensArray> EvensArrayPtr;

class RTPPortsDispencer;
class RTPPortsDispencerPV;

//---------------------------------------------------
/** RTP ports pair (even, odd).
@@ -42,30 +45,35 @@ class RTPPortPair
{
public:
//default ctor makes (0,0) which is invalid ports pair.
RTPPortPair();

RTPPortPair(uint16_t a_even, uint16_t a_odd);

RTPPortPair()
: even(0), odd(0) { tag.fill(0); }

RTPPortPair(uint16_t a_even, uint16_t a_odd)
: even(a_even), odd(a_odd) { }

//may be invalid in rare case(when no more ports available):w
bool valid() const {return 0 < (even & odd );}

//release the port number, it will be returned to dispencer
void reset();
void reset() { *this = RTPPortPair();}

//it will read 8 bytes exactly, last is guaranteed to be set to 0x00
void readTag(const char* tagMSg)
{ * static_cast<u_int64_t*> (tag.data()) = * static_cast<u_int64_t*>(tagMsg);
tag[--tag.size()] = 0x00; }

uint16_t even;
uint16_t odd;

//A tag may be set to show what this ports are used for
//the tag has this 8-bytes limitation for optimal comparison operations
//(re-interpreted as 64-bit interger)
std::array<char,8> tag;
std::array<char,sizeof(u_int64_t)> tag;

//may be invalid in rare case(when no more ports available):w
bool valid() const {return 0 < (even & odd );}
};
//---------------------------------------------------


class EvensArray;
typedef std::shared_ptr<EvensArray> EvensArrayPtr;


/** Ports pair dispencer.
The RTPPortPair will release it's port when last copy
of the RTPPortPair object is destroyed.
@@ -76,25 +84,19 @@ class RTPPortsDispencer
{
public:
//constructor with range:
RTPPortsDispencer(uint16_t rlow = 6000, uint16_t rhi = 8000,
Poco::Channel* logChannel = nullptr);
RTPPortsDispencer(uint16_t rlow = 6000, uint16_t rhi = 8000);
virtual ~RTPPortsDispencer();

std::pair<std::mutex*, SHP(RTPPortsDispencerPV)> getMutex();

/** The RTP pair may be optionally tagged. Only first 8 bytes are used.*/
RTPPortPair obtain(ZConstString use_tag = ZConstString(0, (size_t)0));

void release(const RTPPortPair& item);

//set current IP field
void set_destination_ip(const std::string& addr);

//get current IP field
std::string dest_ip() const;

//register already obtained port(elsewhere)
void bind(const RTPPortPair& item);
void release(const RTPPortPair& item);

//how much ports pairs available:
uint16_t available() const;

@@ -103,7 +105,7 @@ class RTPPortsDispencer
EvensArrayPtr get_tagged_ports(const ZConstString& tag) const;

private:
SHP(RTPPortsDispencerPV) pv;
RTPPortsDispencerPV pv;

};

@@ -0,0 +1,150 @@
#include <map>
#include <array>
#include <cassert>

namespace ZMB {


//----------------------------------------------------------

/** Map<uint16_t(even_port), uint16_t(odd_port)> */
typedef std::map<uint16_t, uint16_t> PortsMap;
//------

/** HashMap<uint64_t(char* tag), SHP(std::vector<uint16_t>) (even_port values list)> */
class TagsMap : public std::map<u_int64_t, EvensArrayPtr>
{
public:
typedef std::map<u_int64_t, EvensArrayPtr> base_type;

TagsMap() : base_type()
{

}

//return tagged ports array (or empty array)
EvensArrayPtr get_tagged_ports(const ZConstString& str_8bytes) const
{
u_int64_t num = 0;
assert(str_8bytes.size() >= 8);
num = * static_cast<u_int64_t*>(srt_8bytes.begin());

EvensArrayPtr array;
auto it = find(num);
array = (end() == it)? (*it).second : std::make_shared<EvensArray>();
return array;
}

//push tagged RTP even port
void tag(const ZConstString& str_8bytes, uint16_t even_port)
{
u_int64_t num = 0;
assert(str_8bytes.size() >= 8);
num = * static_cast<u_int64_t*>(srt_8bytes.begin());

EvensArrayPtr array;
auto it = find(num);
if (end() != it)
{//case tag already exists:
array = (*it).second;
}
else
{//case need to create tag:
operator[](num) = std::make_shared<EvensArray>();
}
array->push_back(even_port);
}
//erase whole tag:
void erase_tag(const ZConstString& str_8bytes)
{
u_int64_t num = 0;
assert(str_8bytes.size() >= 8);
num = * static_cast<u_int64_t*>(srt_8bytes.begin());

auto iter = find(num);
if (end() != iter)
{
erase(iter);
}
}

//erase one tagged port:
void remove_tagged_port(const ZConstString& str_8bytes, uint16_t port)
{
u_int64_t num = 0;
assert(str_8bytes.size() >= 8);
num = * static_cast<u_int64_t*>(srt_8bytes.begin());

auto it = find(num);
assert(num > 0 && end() != it); //avoid situations of improper user

auto arrayp = (*it).second;

auto array_iter = arrayp->begin();
for (auto& val : *arrayp)
{
if (port != val) { ++array_iter; continue; }
arrayp->erase(array_iter);
break;
}
}
};

//------

/** Keeps lists of used RTP/RTCP ports.*/
class RTPPortsDispencerPV
{
public:
RTPPortsDispencerPV(uint16_t rlow, uint16_t rhi)
: low(rlow), hi(rhi)
{
bool ok = true;
//insert (even, odd) pairs
for (uint16_t c = rlow; c < rhi && ok; c += 2)
{
m_free[c] = c + 1;
}
assert(ok);
}
~RTPPortsDispencerPV()
{
}

RTPPortPair obtain(ZConstString tag = ZConstString(0,(size_t)0))
{
uint16_t even = 0, odd = 0;
auto iter = m_free.begin();
if (m_free.end() == iter)
return RTPPortPair();
even = (*iter).first;
odd = (*iter).second;
//same as this->incref(even);
m_free.erase(iter);

if (nullptr != tag.begin())
{
m_tags.tag(tag, even);
}
return RTPPortPair(even, odd);
}

size_t available()
{
return m_free.size();
}

void release(const RTPPortPair& item)
{
m_tags.remove_tagged_port(ZConstString(item.tag.data(),item.tag.size()), item.even);
m_free[item.even] = item.odd;
}


/** Defaults to 127.0.0.1. Must be changed when needed. */
std::string d_server_ip;
TagsMap m_tags;
PortsMap m_free;
uint16_t low, hi;

};
@@ -27,22 +27,13 @@ namespace ZMB {

struct ClientID
{
ClientID(u_int32_t val = 0xffffffff)
{
client_id = val;
}
u_int32_t client_id;
u_int32_t client_id = 0xffffffff;
};

struct SurvlObjectID
{
SurvlObjectID()
{
ZUnsafeBuf zb(mem_accessor());
survlobj_id = 0xffffffff;
}
ClientID client_id;
u_int32_t survlobj_id;
u_int32_t survlobj_id = 0xffffffff;

ZUnsafeBuf mem_accessor() const {return ZUnsafeBuf((char*)this, sizeof(*this));}
};
@@ -57,7 +57,7 @@ LinkedTask* FuncNeu(LinkedTask* RootNodePtr)
}
return p;
}
void FuncDeleteNode(LinkedTask* RootNodePtr, LinkedTask* node_ptr)
static inline void FuncDeleteNode(LinkedTask* RootNodePtr, LinkedTask* node_ptr)
{
delete node_ptr;
RootNodePtr->utilPtr->counter.fetch_sub(1);
@@ -179,6 +179,17 @@ LinkedTask* LinkedTask::spawnChildNode(LinkedTask*& expelledChild)
return nullptr;
}

LinkedTask* LinkedTask::spawnChildNode()
{
LinkedTask* ptr = nullptr;
auto neu = spawnChildeNode(ptr);
if (nullptr != ptr)
{
ptr->utilPtr->deleteNode(ptr);
}
return neu;
}

size_t ForEachOnBranch(LinkedTask* head, std::function<void(LinkedTask*)> functor,
uint32_t skipCount)
{
@@ -81,6 +81,9 @@ class LinkedTask : public ZMBCommon::noncopyable
* @return new child node or NULL on caught exception.
*/
LinkedTask* spawnChildNode(LinkedTask*& expelledChild);

//same as previous, but it'll delete the old subtree if present
LinkedTask* spawnChildNode();

/** traverse to the last item on current tree level
* @return last item if exists, (this) otherwise. */

This file was deleted.

This file was deleted.

@@ -115,7 +115,7 @@ struct ZUnsafeBuf
* @return false if buffer overflow is possible. */
bool read(char** end_ptr, const ZConstString& data, char* start_pos = NULL);

//Copy with converting to network byte order, the data muyst be aligned.
//Copy with converting to network byte order, the data must be aligned.
bool read_htonl(u_int32_t** end_ptr, const ZConstString& data, u_int32_t* start_pos = NULL);
bool read_htons(u_int16_t** end_ptr, const ZConstString& data, u_int16_t* start_pos = NULL);

@@ -50,7 +50,7 @@ CentralWidget::~CentralWidget()
mg->clear();
}

void CentralWidget::pass_msg(const Json::Value& metadata, MByteArrayPtr msg)
void CentralWidget::pass_msg(const Json::Value& metadata, std::stringPtr msg)
{
if (metadata.type() == Json::objectValue && nullptr != metadata.find(CW_KW_OBJECT.begin(), CW_KW_OBJECT.end()))
{
@@ -62,7 +62,7 @@ void CentralWidget::pass_msg(const Json::Value& metadata, MByteArrayPtr msg)
SHP(TagViewWidget) CentralWidget::get_tab(ZConstString tag)
{
SHP(TagViewWidget) v;
MByteArray copy(tag.begin(), 0, tag.len);
std::string copy(tag.begin(), 0, tag.len);
auto iter = tagviews->find(copy);
if (iter.is_end())
{
@@ -80,14 +80,14 @@ SHP(TagViewWidget) CentralWidget::get_tab(ZConstString tag)

void CentralWidget::on_enter()
{
MByteArray addr = edit->text();
std::string addr = edit->text();
//split string of type 127.0.0.1:59000
auto str_list = addr.split(':');
if (str_list->size() == 2)
{

auto iter = str_list->begin();
const MByteArray& ip = *(iter);
const std::string& ip = *(iter);
++iter;
quint16 port = (*iter).toInt();

@@ -97,7 +97,7 @@ void CentralWidget::on_enter()
this, &CentralWidget::pass_msg, Qt::QueuedConnection);

QMetaObject::invokeMethod(udp.get(), "listen",Qt::QueuedConnection,
Q_ARG(MByteArray, ip), Q_ARG(quint16, port));
Q_ARG(std::string, ip), Q_ARG(quint16, port));
}

}
@@ -17,7 +17,7 @@ class TagViewWidget;


//Hash<QByteArray, SHP(SurvlObject)>
typedef LCDS::MapHnd<MByteArray, SHP(TagViewWidget)> HashViewers;
typedef LCDS::MapHnd<std::string, SHP(TagViewWidget)> HashViewers;


class CentralWidget : public QWidget,
@@ -41,11 +41,11 @@ public slots:
//on address enter:
void on_enter();

void pass_msg(const Json::Value& metadata, MByteArrayPtr msg);
void pass_msg(const Json::Value& metadata, std::stringPtr msg);

private:

MByteArray temp;
std::string temp;
QTabWidget* tabs;
SHP(HashViewers) tagviews;
LeechLair<CentralWidget, LogsGrabber, float/*fps*/> udp_lair;
@@ -47,15 +47,15 @@ const QJsonObject& LoggerSettings::get_settings() const
return settings;
}

void LoggerSettings::set_disk_write(bool onoff, MByteArray path)
void LoggerSettings::set_disk_write(bool onoff, std::string path)
{
QJsonObject disk_o;
disk_o["logsdir"] = path.empty()? QDir::currentPath() : path.to_qstring();
disk_o["status"] = QJsonValue(onoff);
settings["disk"] = QJsonValue(disk_o);
}

MByteArray LoggerSettings::logs_dirname() const
std::string LoggerSettings::logs_dirname() const
{
auto jo = settings["disk"].toObject();
return jo["logsdir"].toString();
@@ -72,10 +72,10 @@ bool LoggerSettings::disk_write_enabled() const
}


SHP(QFile) LoggerSettings::make_logfile(const MByteArray& tag)
SHP(QFile) LoggerSettings::make_logfile(const std::string& tag)
{
QDateTime tm = QDateTime::currentDateTime();
MByteArray fname = logs_dirname();
std::string fname = logs_dirname();
fname += "/log_";
fname += tag;
fname += "_";
@@ -17,14 +17,14 @@ class LoggerSettings : public QObject

static LoggerSettings* instance();
const QJsonObject& get_settings() const;
MByteArray logs_dirname() const;
std::string logs_dirname() const;

int rowsmax() const;

void set_disk_write(bool onoff, MByteArray path = "");
void set_disk_write(bool onoff, std::string path = "");
bool disk_write_enabled() const;

SHP(QFile) make_logfile(const MByteArray& tag);
SHP(QFile) make_logfile(const std::string& tag);

signals:
void runtime_block_feeds();
@@ -13,7 +13,7 @@
LogsGrabber::LogsGrabber(std::shared_ptr<QThread> work_thread, float fps, QObject* parent)
: QObject(parent), ProcLeech<CentralWidget>(work_thread, fps)
{
qRegisterMetaType<MByteArrayPtr>("MByteArrayPtr");
qRegisterMetaType<std::stringPtr>("std::stringPtr");
m_port = 0;
z_sub_sock = 0;
memset(addr_to_connect, 0x00, sizeof(addr_to_connect));
@@ -42,7 +42,7 @@ LogsGrabber::~LogsGrabber()
}
}

void LogsGrabber::listen(const MByteArray& srv, quint16 port)
void LogsGrabber::listen(const std::string& srv, quint16 port)
{
QMutexLocker lk(&mut);
m_srv = srv.toStdString();
@@ -61,8 +61,8 @@ void LogsGrabber::listen(const MByteArray& srv, quint16 port)
{
zsocket_destroy(keep.czctx(), z_sub_sock);
z_sub_sock = 0;
MByteArray msg(__PRETTY_FUNCTION__);
msg += MByteArray("FAILED zsocket_connect()");
std::string msg(__PRETTY_FUNCTION__);
msg += std::string("FAILED zsocket_connect()");
std::cout << msg.data() << std::endl;
emit sig_error(msg);
}
@@ -28,19 +28,19 @@ class LogsGrabber : public QObject,
virtual ~LogsGrabber();

signals:
void message(Json::Value metadata, MByteArrayPtr msg);
void sig_error(MByteArray err);
void message(Json::Value metadata, std::stringPtr msg);
void sig_error(std::string err);


public slots:

void listen(const MByteArray& srv, quint16 port);
void listen(const std::string& srv, quint16 port);

void proc();

private:
MByteArray name;
MByteArray buf;
std::string name;
std::string buf;

Json::Reader jreader;

@@ -19,7 +19,7 @@ class ErrorCheck : public QObject

public slots:
void on_writer_error(std::shared_ptr<ZMBCommon::GenericStreamWriter> writer,
std::shared_ptr<MByteArray> msg)
std::shared_ptr<std::string> msg)
{
qDebug() << "Error occured: " << msg->data();
QApplication::quit();
@@ -16,7 +16,7 @@
#include "logsgrabber.h"


TagViewWidget::TagViewWidget(const MByteArray& selection_tag,
TagViewWidget::TagViewWidget(const std::string& selection_tag,
int rows_limit,
QWidget *parent)
: QWidget(parent), tag(selection_tag)
@@ -47,7 +47,7 @@ TagViewWidget::~TagViewWidget()
dump_file();
}

const MByteArray& TagViewWidget::gettag() const
const std::string& TagViewWidget::gettag() const
{
return tag;
}
@@ -68,9 +68,9 @@ void TagViewWidget::check_limit_dumpfile()
rows_cnt = 0;
}
}
MByteArray make_date_time(const QJsonObject& jo)
std::string make_date_time(const QJsonObject& jo)
{
MByteArray tm;
std::string tm;
tm += jo["date"].toString();
tm += " ";
tm += jo["timezone"].toString();
@@ -82,9 +82,9 @@ MByteArray make_date_time(const QJsonObject& jo)
return tm;
}

MByteArray make_date_time(const Json::Value& jo)
std::string make_date_time(const Json::Value& jo)
{
MByteArray tm;
std::string tm;
tm += jo["date"].asCString();
tm += " ";
tm += jo["timezone"].asCString();
@@ -98,7 +98,7 @@ MByteArray make_date_time(const Json::Value& jo)



void TagViewWidget::post(const Json::Value& metadata, MByteArrayPtr msg)
void TagViewWidget::post(const Json::Value& metadata, std::stringPtr msg)
{
QMutexLocker lk(&mut);
if (nullptr != metadata.find(CW_KW_OBJECT.begin(), CW_KW_OBJECT.end())
@@ -19,12 +19,12 @@ class TagViewWidget : public QWidget
{
Q_OBJECT
public:
explicit TagViewWidget(const MByteArray& selection_tag,
explicit TagViewWidget(const std::string& selection_tag,
int rows_limit = 2500,
QWidget *parent = 0);
virtual ~TagViewWidget();

const MByteArray& gettag() const;
const std::string& gettag() const;



@@ -33,22 +33,22 @@ class TagViewWidget : public QWidget
public slots:

//select by tag:
void post(const Json::Value& metadata, MByteArrayPtr msg);
void post(const Json::Value& metadata, std::stringPtr msg);

private:
void check_limit_dumpfile();
void dump_file();

QMutex mut;
MByteArray tag;
std::string tag;
QLabel* queryLabel;
QLineEdit* queryEdit;
QTextEdit* textEdit;
int d_max_rows;
int rows_cnt;

// static const int time_col_width = 24;
// MByteArray time_col_text;
// std::string time_col_text;
};

#endif // TAGVIEWWIDGET_H
@@ -422,8 +422,8 @@ class MovementDetector
mode = DetectionMode::FULL_FRAME;
}

typedef std::map<ZMBCommon::MByteArray, std::vector<glm::ivec2>> LinesMap;
typedef std::pair<ZMBCommon::MByteArray, std::vector<glm::ivec2>> NamedLine;
typedef std::map<std::string, std::vector<glm::ivec2>> LinesMap;
typedef std::pair<std::string, std::vector<glm::ivec2>> NamedLine;

void detect(const ZMB::MImage& frame)
{
@@ -488,7 +488,7 @@ class MovementDetector
std::shared_ptr<CVBGS::MOG2Algo> full_frame_mog2;
std::map<ZMB::MRegion, std::shared_ptr<CVBGS::MOG2Algo>> rect_zones_map;

std::map<ZMBCommon::MByteArray/*name*/, std::vector<glm::ivec2>/*convex hull*/>
std::map<std::string/*name*/, std::vector<glm::ivec2>/*convex hull*/>
ignored_polygonal_zones_map,
interest_polygonal_zones_map;
cv::Mat enabled_detection_mask;
@@ -14,12 +14,12 @@ Json::Value jvalue_from_file(bool &ok, const ZConstString& fname)
char _buf [1024];
ZUnsafeBuf buf(_buf, sizeof(_buf));
buf.fill(0);
ZMBCommon::MByteArray text;
std::string text;
std::ifstream in;
in.open(fname.begin());

for (size_t bytes_read = 0; !in.eof() && in.good();
text += ZConstString(buf.begin(), bytes_read))
text += std::string(buf.begin(), bytes_read))
{
bytes_read = in.readsome(buf.begin(), buf.size());
if (0 == bytes_read)
@@ -123,9 +123,9 @@ bool SurvlObj::create(const Json::Value* config_object)
**/
ZConstString fs_loc(ZMB::SURV_CAM_PARAMS_FS, entity_cfg);
ZConstString item_name(ZMB::SURV_CAM_PARAMS_NAME, entity_cfg);
ZMBCommon::MByteArray np = fs_loc;
std::string np = fs_loc;
np += ZMFS::FSLocation::dir_path_sep;
np += item_name;
np += std::string(item_name.begin(), item_name.size());
auto znp = np.get_const_str();
//(*entity_cfg)["fs"] = path;
entity_cfg->operator [](ZMB::SURV_CAM_PARAMS_FS.begin()) =