Merge branch 'storageareas' of github.com:connortechnology/ZoneMinder into storageareas
This commit is contained in:
commit
055be6b613
|
@ -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();
|
||||
|
|
|
@ -1,51 +1,66 @@
|
|||
//
|
||||
// ZoneMinder Camera Class Implementation, $Date$, $Revision$
|
||||
// Copyright (C) 2001-2008 Philip Coombes
|
||||
//
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
//
|
||||
|
||||
#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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -41,8 +41,7 @@ struct LibvlcPrivateData
|
|||
ThreadData<bool> newImage;
|
||||
};
|
||||
|
||||
class LibvlcCamera : public Camera
|
||||
{
|
||||
class LibvlcCamera : public Camera {
|
||||
protected:
|
||||
std::string mPath;
|
||||
std::string mMethod;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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() :
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue