Initial work on adding cURL to zoneminder
parent
9d5ac7ae8c
commit
8e96df7643
|
@ -327,6 +327,8 @@ CREATE TABLE `Monitors` (
|
|||
`Port` varchar(8) NOT NULL default '',
|
||||
`SubPath` varchar(64) NOT NULL default '',
|
||||
`Path` varchar(255) NOT NULL default '',
|
||||
`User` varchar(64) NOT NULL default '',
|
||||
`Pass` varchar(64) NOT NULL default '',
|
||||
`Width` smallint(5) unsigned NOT NULL default '0',
|
||||
`Height` smallint(5) unsigned NOT NULL default '0',
|
||||
`Colours` tinyint(3) unsigned NOT NULL default '1',
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
class Camera
|
||||
{
|
||||
protected:
|
||||
typedef enum { LOCAL_SRC, REMOTE_SRC, FILE_SRC, FFMPEG_SRC } SourceType;
|
||||
typedef enum { LOCAL_SRC, REMOTE_SRC, FILE_SRC, FFMPEG_SRC, CURL_SRC } SourceType;
|
||||
|
||||
int id;
|
||||
SourceType type;
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
//
|
||||
// ZoneMinder cURL Camera Class Implementation, $Date: 2009-01-16 12:18:50 +0000 (Fri, 16 Jan 2009) $, $Revision: 2713 $
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
|
||||
#include "zm.h"
|
||||
|
||||
#if HAVE_LIBCURL
|
||||
|
||||
static FILE* curldebugfile = NULL; // Remove later
|
||||
|
||||
#include "zm_curl_camera.h"
|
||||
|
||||
cURLCamera::cURLCamera( int p_id, const std::string &p_path, const std::string &p_username, const std::string &p_password, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) :
|
||||
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 ),
|
||||
mPath( p_path ), mUsername
|
||||
{
|
||||
if ( capture )
|
||||
{
|
||||
Initialise();
|
||||
c = curl_easy_init();
|
||||
if(c == NULL) {
|
||||
Fatal("Failed getting easy handle from libcurl");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cURLCamera::~cURLCamera()
|
||||
{
|
||||
if ( capture )
|
||||
{
|
||||
if(c != NULL) {
|
||||
curl_easy_cleanup(c);
|
||||
c = NULL;
|
||||
}
|
||||
Terminate();
|
||||
}
|
||||
}
|
||||
|
||||
void cURLCamera::Initialise()
|
||||
{
|
||||
ret = curl_global_init(CURL_GLOBAL_ALL | CURL_GLOBAL_ACK_EINTR);
|
||||
if(ret != CURLE_OK) {
|
||||
Fatal("libcurl initialization failed. error %d: ", curl_easy_strerror(ret));
|
||||
}
|
||||
|
||||
Debug(2,"libcurl version: %s",curl_version());
|
||||
|
||||
curldebugfile = fopen("/tmp/curl_debug.log","w"); // Remove later
|
||||
}
|
||||
|
||||
void cURLCamera::Terminate()
|
||||
{
|
||||
curl_global_cleanup();
|
||||
|
||||
fclose(curldebugfile); // Remove later
|
||||
}
|
||||
|
||||
int cURLCamera::PrimeCapture()
|
||||
{
|
||||
Info( "Priming capture from %s", mPath.c_str() );
|
||||
|
||||
/* Temporary */
|
||||
curl_easy_setopt(c, CURLOPT_VERBOSE, 1);
|
||||
curl_easy_setopt(c, CURLOPT_STDERR, curldebugfile);
|
||||
|
||||
ret = curl_easy_setopt(c, CURLOPT_URL, mPath.c_str());
|
||||
if(ret != CURLE_OK)
|
||||
Fatal("Failed setting libcurl URL. error %d: ", curl_easy_strerror(ret));
|
||||
|
||||
ret = curl_easy_setopt(c, CURLOPT_HEADERFUNCTION, header_callback);
|
||||
if(ret != CURLE_OK)
|
||||
Fatal("Failed setting libcurl header callback function. error %d: ", curl_easy_strerror(ret));
|
||||
|
||||
ret = curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, data_callback);
|
||||
if(ret != CURLE_OK)
|
||||
Fatal("Failed setting libcurl header callback function. error %d: ", curl_easy_strerror(ret));
|
||||
|
||||
ret = curl_easy_setopt(c, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
|
||||
if(ret != CURLE_OK)
|
||||
Warning("Failed setting libcurl acceptable http authenication methods. error %d: ", curl_easy_strerror(ret));
|
||||
}
|
||||
|
||||
int cURLCamera::PreCapture()
|
||||
{
|
||||
// Nothing to do here
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int cURLCamera::Capture( Image &image )
|
||||
{
|
||||
uint8_t* directbuffer;
|
||||
bool frameComplete = false;
|
||||
|
||||
/* Request a writeable buffer of the target image */
|
||||
directbuffer = image.WriteBuffer(width, height, colours, subpixelorder);
|
||||
if(directbuffer == NULL) {
|
||||
Error("Failed requesting writeable buffer for the captured image.");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
success = curl_easy_perform(easyhandle);
|
||||
|
||||
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int cURLCamera::PostCapture()
|
||||
{
|
||||
// Nothing to do here
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
size_t cURLCamera::data_callback(void *buffer, size_t size, size_t nmemb, void *userdata);
|
||||
size_t cURLCamera::header_callback( void *buffer, size_t size, size_t nmemb, void *userdata);.
|
||||
|
||||
#endif // HAVE_LIBCURL
|
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// ZoneMinder cURL Class Interface, $Date: 2008-07-25 10:33:23 +0100 (Fri, 25 Jul 2008) $, $Revision: 2611 $
|
||||
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
|
||||
#ifndef ZM_CURL_CAMERA_H
|
||||
#define ZM_CURL_CAMERA_H
|
||||
|
||||
#include "zm_camera.h"
|
||||
#include "zm_ffmpeg.h"
|
||||
#include "zm_buffer.h"
|
||||
#include "zm_regexp.h"
|
||||
#include "zm_utils.h"
|
||||
|
||||
#if HAVE_CURL_CURL_H
|
||||
#include <curl/curl.h>
|
||||
#endif
|
||||
|
||||
//
|
||||
// Class representing 'remote' cameras, i.e. those which are
|
||||
// accessed over a network connection.
|
||||
//
|
||||
class cURLCamera : public Camera
|
||||
{
|
||||
protected:
|
||||
std::string mPath;
|
||||
std::string mUser;
|
||||
std::string mPass;
|
||||
curl* c = NULL;
|
||||
|
||||
public:
|
||||
cURLCamera( int p_id, const std::string &path, const std::string &username, const std::string &password, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture );
|
||||
~cURLCamera();
|
||||
|
||||
const std::string &Path() const { return( mPath ); }
|
||||
const std::string &Username() const { return( mUser ); }
|
||||
const std::string &Password() const { return( mPass ); }
|
||||
|
||||
void Initialise();
|
||||
void Terminate();
|
||||
|
||||
int PrimeCapture();
|
||||
int PreCapture();
|
||||
int Capture( Image &image );
|
||||
int PostCapture();
|
||||
|
||||
size_t data_callback(void *buffer, size_t size, size_t nmemb, void *userdata);
|
||||
size_t header_callback( void *buffer, size_t size, size_t nmemb, void *userdata);.
|
||||
int debug_callback(CURL* handle, curl_infotype type, char* str, size_t strsize, void* data);
|
||||
|
||||
private:
|
||||
int ret;
|
||||
|
||||
};
|
||||
|
||||
#endif // ZM_CURL_CAMERA_H
|
|
@ -2404,7 +2404,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
|
|||
Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose )
|
||||
{
|
||||
static char sql[ZM_SQL_MED_BUFSIZ];
|
||||
snprintf( sql, sizeof(sql), "select Id, Name, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = %d", id );
|
||||
snprintf( sql, sizeof(sql), "select Id, Name, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Protocol, Method, Host, Port, Path, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = %d", id );
|
||||
if ( mysql_query( &dbconn, sql ) )
|
||||
{
|
||||
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||
|
@ -2440,6 +2440,8 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose )
|
|||
std::string host = dbrow[col]; col++;
|
||||
std::string port = dbrow[col]; col++;
|
||||
std::string path = dbrow[col]; col++;
|
||||
std::string user = dbrow[col]; col++;
|
||||
std::string pass = dbrow[col]; col++;
|
||||
|
||||
int width = atoi(dbrow[col]); col++;
|
||||
int height = atoi(dbrow[col]); col++;
|
||||
|
@ -2588,6 +2590,27 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose )
|
|||
#else // HAVE_LIBAVFORMAT
|
||||
Fatal( "You must have ffmpeg libraries installed to use ffmpeg cameras for monitor %d", id );
|
||||
#endif // HAVE_LIBAVFORMAT
|
||||
}
|
||||
else if ( type == "cURL" )
|
||||
{
|
||||
#if HAVE_LIBCURL
|
||||
camera = new cURLCamera(
|
||||
id,
|
||||
path.c_str(),
|
||||
user.c_str(),
|
||||
pass.c_str(),
|
||||
cam_width,
|
||||
cam_height,
|
||||
colours,
|
||||
brightness,
|
||||
contrast,
|
||||
hue,
|
||||
colour,
|
||||
purpose==CAPTURE
|
||||
);
|
||||
#else // HAVE_LIBCURL
|
||||
Fatal( "You must have libcurl installed to use ffmpeg cameras for monitor %d", id );
|
||||
#endif // HAVE_LIBCURL
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -64,6 +64,8 @@ else
|
|||
'Host' => "",
|
||||
'Path' => "",
|
||||
'Port' => "80",
|
||||
'User' => "",
|
||||
'Pass' => "",
|
||||
'Colours' => 3,
|
||||
'Palette' => 0,
|
||||
'Width' => "320",
|
||||
|
@ -174,6 +176,7 @@ $sourceTypes = array(
|
|||
'Remote' => $SLANG['Remote'],
|
||||
'File' => $SLANG['File'],
|
||||
'Ffmpeg' => $SLANG['Ffmpeg'],
|
||||
'cURL' => $SLANG['cURL'],
|
||||
);
|
||||
if ( !ZM_HAS_V4L )
|
||||
unset($sourceTypes['Local']);
|
||||
|
@ -684,6 +687,14 @@ switch ( $tab )
|
|||
{
|
||||
?>
|
||||
<tr><td><?= $SLANG['SourcePath'] ?></td><td><input type="text" name="newMonitor[Path]" value="<?= validHtmlStr($newMonitor['Path']) ?>" size="36"/></td></tr>
|
||||
<?php
|
||||
}
|
||||
elseif ( $newMonitor['Type'] == "cURL" )
|
||||
{
|
||||
?>
|
||||
<tr><td><?= "Address" ?></td><td><input type="text" name="newMonitor[Path]" value="<?= validHtmlStr($newMonitor['Path']) ?>" size="36"/></td></tr>
|
||||
<tr><td><?= "Username" ?></td><td><input type="text" name="newMonitor[User]" value="<?= validHtmlStr($newMonitor['User']) ?>" size="12"/></td></tr>
|
||||
<tr><td><?= "Password" ?></td><td><input type="text" name="newMonitor[Pass]" value="<?= validHtmlStr($newMonitor['Pass']) ?>" size="12"/></td></tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
|
Loading…
Reference in New Issue