Merge branch 'storageareas' of github.com:connortechnology/ZoneMinder into storageareas

This commit is contained in:
Isaac Connor 2018-05-07 10:14:04 -07:00
commit 055be6b613
8 changed files with 163 additions and 92 deletions

View File

@ -302,7 +302,7 @@ sub run {
if ( ! ( $secs_count % 60 ) ) {
Debug("Connecting");
while ( (!$zm_terminate) and !($dbh and $dbh->ping()) ) {
Warning("Not connected to db ($dbh)".($dbh?" ping(".$dbh->ping().")":''). " errstr($DBI::errstr). Reconnecting");
Warning("Not connected to db ($dbh)".($dbh?" ping(".$dbh->ping().")":''). ($DBI::errstr?" errstr($DBI::errstr)":'').' Reconnecting');
$dbh = zmDbConnect();
}
my @cpuload = CpuLoad();

View File

@ -20,32 +20,47 @@
#include "zm.h"
#include "zm_camera.h"
Camera::Camera( unsigned int p_monitor_id, SourceType p_type, unsigned int p_width, unsigned int p_height, int p_colours, int p_subpixelorder, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture, bool p_record_audio ) :
monitor_id( p_monitor_id ),
type( p_type ),
width( p_width),
height( p_height ),
colours( p_colours ),
subpixelorder( p_subpixelorder ),
brightness( p_brightness ),
hue( p_hue ),
colour( p_colour ),
contrast( p_contrast ),
capture( p_capture ),
record_audio( p_record_audio )
Camera::Camera(
unsigned int p_monitor_id,
SourceType p_type,
unsigned int p_width,
unsigned int p_height,
int p_colours,
int p_subpixelorder,
int p_brightness,
int p_contrast,
int p_hue,
int p_colour,
bool p_capture,
bool p_record_audio
) :
monitor_id(p_monitor_id),
type(p_type),
width(p_width),
height(p_height),
colours(p_colours),
subpixelorder(p_subpixelorder),
brightness(p_brightness),
hue(p_hue),
colour(p_colour),
contrast(p_contrast),
capture(p_capture),
record_audio(p_record_audio),
bytes(0)
{
pixels = width * height;
imagesize = pixels * colours;
Debug(2,"New camera id: %d width: %d height: %d colours: %d subpixelorder: %d capture: %d",monitor_id,width,height,colours,subpixelorder,capture);
Debug(2,"New camera id: %d width: %d height: %d colours: %d subpixelorder: %d capture: %d",
monitor_id,width,height,colours,subpixelorder,capture);
/* Because many loops are unrolled and work on 16 colours/time or 4 pixels/time, we have to meet requirements */
if((colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB32) && (imagesize % 64) != 0) {
if ( (colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB32) && (imagesize % 64) != 0 ) {
Fatal("Image size is not multiples of 64");
} else if(colours == ZM_COLOUR_RGB24 && ((imagesize % 64) != 0 || (imagesize % 12) != 0)) {
} else if ( colours == ZM_COLOUR_RGB24 && ((imagesize % 64) != 0 || (imagesize % 12) != 0) ) {
Fatal("Image size is not multiples of 12 and 64");
}
monitor = NULL;
monitor = NULL;
}
Camera::~Camera() {
@ -53,11 +68,11 @@ Camera::~Camera() {
Monitor *Camera::getMonitor() {
if ( ! monitor )
monitor = Monitor::Load( monitor_id, false, Monitor::QUERY );
monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
return monitor;
}
void Camera::setMonitor( Monitor *p_monitor ) {
void Camera::setMonitor(Monitor *p_monitor) {
monitor = p_monitor;
monitor_id = monitor->Id();
}

View File

@ -69,7 +69,7 @@ Event::Event(
untimedEvent = true;
start_time = now;
} else if ( start_time.tv_sec > now.tv_sec ) {
Error("StartTime in the future %d.%d > %d.%d",
Error("StartTime in the future %u.%u > %u.%u",
start_time.tv_sec, start_time.tv_usec, now.tv_sec, now.tv_usec
);
start_time = now;

View File

@ -18,6 +18,7 @@
*/
#include "zm.h"
#include "zm_signal.h"
#include "zm_libvlc_camera.h"
#if HAVE_LIBVLC
@ -39,7 +40,7 @@ void LibvlcUnlockBuffer(void* opaque, void* picture, void *const *planes) {
LibvlcPrivateData* data = reinterpret_cast<LibvlcPrivateData*>(opaque);
bool newFrame = false;
for( uint32_t i = 0; i < data->bufferSize; i++ ) {
for( unsigned int i=0; i < data->bufferSize; i++ ) {
if ( data->buffer[i] != data->prevBuffer[i] ) {
newFrame = true;
break;
@ -56,11 +57,38 @@ void LibvlcUnlockBuffer(void* opaque, void* picture, void *const *planes) {
}
}
LibvlcCamera::LibvlcCamera( int p_id, const std::string &p_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 ) :
Camera( p_id, LIBVLC_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 ),
mMethod( p_method ),
mOptions( p_options )
LibvlcCamera::LibvlcCamera(
int p_id,
const std::string &p_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
) :
Camera(
p_id,
LIBVLC_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),
mMethod(p_method),
mOptions(p_options)
{
mLibvlcInstance = NULL;
mLibvlcMedia = NULL;
@ -70,15 +98,15 @@ LibvlcCamera::LibvlcCamera( int p_id, const std::string &p_path, const std::stri
mOptArgV = NULL;
/* Has to be located inside the constructor so other components such as zma will receive correct colours and subpixel order */
if(colours == ZM_COLOUR_RGB32) {
if ( colours == ZM_COLOUR_RGB32 ) {
subpixelorder = ZM_SUBPIX_ORDER_BGRA;
mTargetChroma = "RV32";
mBpp = 4;
} else if(colours == ZM_COLOUR_RGB24) {
} else if ( colours == ZM_COLOUR_RGB24 ) {
subpixelorder = ZM_SUBPIX_ORDER_BGR;
mTargetChroma = "RV24";
mBpp = 3;
} else if(colours == ZM_COLOUR_GRAY8) {
} else if ( colours == ZM_COLOUR_GRAY8 ) {
subpixelorder = ZM_SUBPIX_ORDER_NONE;
mTargetChroma = "GREY";
mBpp = 1;
@ -118,11 +146,13 @@ void LibvlcCamera::Initialise() {
void LibvlcCamera::Terminate() {
libvlc_media_player_stop(mLibvlcMediaPlayer);
if(mLibvlcData.buffer != NULL) {
if ( mLibvlcData.buffer ) {
zm_freealigned(mLibvlcData.buffer);
mLibvlcData.buffer = NULL;
}
if(mLibvlcData.prevBuffer != NULL) {
if ( mLibvlcData.prevBuffer ) {
zm_freealigned(mLibvlcData.prevBuffer);
mLibvlcData.prevBuffer = NULL;
}
}
@ -139,6 +169,8 @@ int LibvlcCamera::PrimeCapture() {
else if ( Method() == "rtpRtspHttp" )
opVect.push_back("--rtsp-http");
opVect.push_back("--no-audio");
if ( opVect.size() > 0 ) {
mOptArgV = new char*[opVect.size()];
Debug(2, "Number of Options: %d",opVect.size());
@ -149,17 +181,23 @@ int LibvlcCamera::PrimeCapture() {
}
}
mLibvlcInstance = libvlc_new (opVect.size(), (const char* const*)mOptArgV);
if ( mLibvlcInstance == NULL )
Fatal("Unable to create libvlc instance due to: %s", libvlc_errmsg());
mLibvlcInstance = libvlc_new(opVect.size(), (const char* const*)mOptArgV);
if ( mLibvlcInstance == NULL ) {
Error("Unable to create libvlc instance due to: %s", libvlc_errmsg());
return -1;
}
mLibvlcMedia = libvlc_media_new_location(mLibvlcInstance, mPath.c_str());
if(mLibvlcMedia == NULL)
Fatal("Unable to open input %s due to: %s", mPath.c_str(), libvlc_errmsg());
if ( mLibvlcMedia == NULL ) {
Error("Unable to open input %s due to: %s", mPath.c_str(), libvlc_errmsg());
return -1;
}
mLibvlcMediaPlayer = libvlc_media_player_new_from_media(mLibvlcMedia);
if(mLibvlcMediaPlayer == NULL)
Fatal("Unable to create player for %s due to: %s", mPath.c_str(), libvlc_errmsg());
if ( mLibvlcMediaPlayer == NULL ) {
Error("Unable to create player for %s due to: %s", mPath.c_str(), libvlc_errmsg());
return -1;
}
libvlc_video_set_format(mLibvlcMediaPlayer, mTargetChroma.c_str(), width, height, width * mBpp);
libvlc_video_set_callbacks(mLibvlcMediaPlayer, &LibvlcLockBuffer, &LibvlcUnlockBuffer, NULL, &mLibvlcData);
@ -177,13 +215,18 @@ int LibvlcCamera::PrimeCapture() {
}
int LibvlcCamera::PreCapture() {
return(0);
return 0;
}
// Should not return -1 as cancels capture. Always wait for image if available.
int LibvlcCamera::Capture( Image &image ) {
while(!mLibvlcData.newImage.getValueImmediate())
int LibvlcCamera::Capture(Image &image) {
// newImage is a mutex/condition based flag to tell us when there is an image available
while( !mLibvlcData.newImage.getValueImmediate() ) {
if (zm_terminate)
return 0;
mLibvlcData.newImage.getUpdatedValue(1);
}
mLibvlcData.mutex.lock();
image.Assign(width, height, colours, subpixelorder, mLibvlcData.buffer, width * height * mBpp);
@ -193,13 +236,12 @@ int LibvlcCamera::Capture( Image &image ) {
return 1;
}
// Should not return -1 as cancels capture. Always wait for image if available.
int LibvlcCamera::CaptureAndRecord(Image &image, timeval recording, char* event_directory) {
return (0);
return 0;
}
int LibvlcCamera::PostCapture() {
return(0);
return 0;
}
#endif // HAVE_LIBVLC

View File

@ -41,8 +41,7 @@ struct LibvlcPrivateData
ThreadData<bool> newImage;
};
class LibvlcCamera : public Camera
{
class LibvlcCamera : public Camera {
protected:
std::string mPath;
std::string mMethod;

View File

@ -330,7 +330,7 @@ bool MonitorStream::sendFrame(const char *filepath, struct timeval *timestamp) {
fprintf(stdout, "Content-Length: %d\r\n", img_buffer_size);
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
if ( ! zm_terminate )
Error("Unable to send stream frame: %s", strerror(errno));
Warning("Unable to send stream frame: %s", strerror(errno));
return false;
}
fputs("\r\n\r\n", stdout);
@ -407,7 +407,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
if ( !zm_terminate ){
// If the pipe was closed, we will get signalled SIGPIPE to exit, which will set zm_terminate
Error("Unable to send stream frame: %s", strerror(errno));
Warning("Unable to send stream frame: %s", strerror(errno));
}
return false;
}

View File

@ -142,31 +142,29 @@ template <class T> const T ThreadData<T>::getValue() const {
mMutex.lock();
const T valueCopy = mValue;
mMutex.unlock();
return( valueCopy );
return valueCopy;
}
template <class T> T ThreadData<T>::setValue( const T value ) {
template <class T> T ThreadData<T>::setValue(const T value) {
mMutex.lock();
const T valueCopy = mValue = value;
mMutex.unlock();
return( valueCopy );
return valueCopy;
}
template <class T> const T ThreadData<T>::getUpdatedValue() const {
Debug( 8, "Waiting for value update, %p", this );
Debug(8, "Waiting for value update, %p", this);
mMutex.lock();
mChanged = false;
//do {
mCondition.wait();
//} while ( !mChanged );
mCondition.wait();
const T valueCopy = mValue;
mMutex.unlock();
Debug( 9, "Got value update, %p", this );
return( valueCopy );
Debug(9, "Got value update, %p", this);
return valueCopy;
}
template <class T> const T ThreadData<T>::getUpdatedValue( double secs ) const {
Debug( 8, "Waiting for value update, %.2f secs, %p", secs, this );
template <class T> const T ThreadData<T>::getUpdatedValue(double secs) const {
Debug(8, "Waiting for value update, %.2f secs, %p", secs, this);
mMutex.lock();
mChanged = false;
//do {
@ -174,41 +172,41 @@ template <class T> const T ThreadData<T>::getUpdatedValue( double secs ) const {
//} while ( !mChanged );
const T valueCopy = mValue;
mMutex.unlock();
Debug( 9, "Got value update, %p", this );
return( valueCopy );
Debug(9, "Got value update, %p", this );
return valueCopy;
}
template <class T> const T ThreadData<T>::getUpdatedValue( int secs ) const {
Debug( 8, "Waiting for value update, %d secs, %p", secs, this );
template <class T> const T ThreadData<T>::getUpdatedValue(int secs) const {
Debug(8, "Waiting for value update, %d secs, %p", secs, this);
mMutex.lock();
mChanged = false;
//do {
mCondition.wait( secs );
mCondition.wait(secs);
//} while ( !mChanged );
const T valueCopy = mValue;
mMutex.unlock();
Debug( 9, "Got value update, %p", this );
return( valueCopy );
Debug(9, "Got value update, %p", this);
return valueCopy;
}
template <class T> void ThreadData<T>::updateValueSignal( const T value ) {
Debug( 8, "Updating value with signal, %p", this );
template <class T> void ThreadData<T>::updateValueSignal(const T value) {
Debug(8, "Updating value with signal, %p", this);
mMutex.lock();
mValue = value;
mChanged = true;
mCondition.signal();
mMutex.unlock();
Debug( 9, "Updated value, %p", this );
Debug(9, "Updated value, %p", this);
}
template <class T> void ThreadData<T>::updateValueBroadcast( const T value ) {
Debug( 8, "Updating value with broadcast, %p", this );
Debug(8, "Updating value with broadcast, %p", this);
mMutex.lock();
mValue = value;
mChanged = true;
mCondition.broadcast();
mMutex.unlock();
Debug( 9, "Updated value, %p", this );
Debug(9, "Updated value, %p", this);
}
Thread::Thread() :

View File

@ -30,20 +30,37 @@ class HostController extends AppController {
));
}
function getAuthHash() {
if ( $zmOptAuth == '1' ) {
require_once '../../../includes/auth.php';
$this->set(array(
'auth_hash' => generateAuthHash(ZM_AUTH_HASH_IPS),
'_serialize' => array('auth_hash')
) );
} else {
$this->set(array(
'auth_hash' => '',
'_serialize' => array('auth_hash')
) );
function getCredentials() {
// ignore debug warnings from other functions
$this->view='Json';
$credentials = "";
$appendPassword = 0;
$this->loadModel('Config');
$isZmAuth = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH')))['Config']['Value'];
if ($isZmAuth) {
$zmAuthRelay = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_RELAY')))['Config']['Value'];
if ($zmAuthRelay == 'hashed') {
$zmAuthHashIps= $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_IPS')))['Config']['Value'];
$credentials = 'auth='.generateAuthHash($zmAuthHashIps);
}
elseif ($zmAuthRelay == 'plain') {
// user will need to append the store password here
$credentials = "user=".$this->Session->read('user.Username')."&pass=";
$appendPassword = 1;
}
elseif ($zmAuthRelay == 'none') {
$credentials = "user=".$this->Session->read('user.Username');
}
}
}
$this->set(array(
'credentials'=> $credentials,
'append_password'=>$appendPassword,
'_serialize' => array('credentials', 'append_password')
) );
}
// If $mid is set, only return disk usage for that monitor
// Else, return an array of total disk usage, and per-monitor