Initial work on adding cURL to zoneminder

pull/297/head
Kfir Itzhak 2013-11-04 16:52:21 +02:00
parent 9d5ac7ae8c
commit 8e96df7643
6 changed files with 240 additions and 2 deletions

View File

@ -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',

View File

@ -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;

132
src/zm_curl_camera.cpp Normal file
View File

@ -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

70
src/zm_curl_camera.h Normal file
View File

@ -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

View File

@ -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
{

View File

@ -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
}
?>