Merge pull request #1045 from knnniggett/knnniggett-new_rtsp_describe

enable/disable RTSP Describe Header
This commit is contained in:
Isaac Connor 2015-08-31 10:35:15 -04:00
commit f107b905d7
12 changed files with 88 additions and 31 deletions

View File

@ -4,7 +4,7 @@
#
cmake_minimum_required (VERSION 2.6)
project (zoneminder)
set(zoneminder_VERSION "1.28.105")
set(zoneminder_VERSION "1.28.106")
# make API version a minor of ZM version
set(zoneminder_API_VERSION "${zoneminder_VERSION}.1")

View File

@ -341,6 +341,7 @@ CREATE TABLE `Monitors` (
`Palette` int(10) unsigned NOT NULL default '0',
`Orientation` enum('0','90','180','270','hori','vert') NOT NULL default '0',
`Deinterlacing` int(10) unsigned NOT NULL default '0',
`RTSPDescribe` tinyint(1) unsigned NOT NULL default '0',
`Brightness` mediumint(7) NOT NULL default '-1',
`Contrast` mediumint(7) NOT NULL default '-1',
`Hue` mediumint(7) NOT NULL default '-1',

21
db/zm_update-1.28.106.sql Normal file
View File

@ -0,0 +1,21 @@
--
-- This updates a 1.28.105 database to 1.28.106
--
--
-- Add Monitor RTSPDescribe field
-- Used to enable or disable processing of the remote camera RTSP DESCRIBE response header
--
SET @s = (SELECT IF(
(SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'Monitors'
AND table_schema = DATABASE()
AND column_name = 'RTSPDescribe'
) > 0,
"SELECT 'Column RTSPDescribe already exists in Monitors'",
"ALTER TABLE `Monitors` ADD `RTSPDescribe` tinyint(1) unsigned NOT NULL default '0' AFTER `Deinterlacing`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -2224,11 +2224,11 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
static char sql[ZM_SQL_MED_BUFSIZ];
if ( !protocol )
{
strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'", sizeof(sql) );
strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'", sizeof(sql) );
}
else
{
snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote' and Protocol = '%s' and Host = '%s' and Port = '%s' and Path = '%s'", protocol, host, port, path );
snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote' and Protocol = '%s' and Host = '%s' and Port = '%s' and Path = '%s'", protocol, host, port, path );
}
if ( mysql_query( &dbconn, sql ) )
{
@ -2267,7 +2267,8 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
int colours = atoi(dbrow[col]); col++;
/* int palette = atoi(dbrow[col]); */ col++;
Orientation orientation = (Orientation)atoi(dbrow[col]); col++;
unsigned int deinterlacing = atoi(dbrow[col]); col++;
unsigned int deinterlacing = atoi(dbrow[col]); col++;
bool rtsp_describe = (*dbrow[col] != '0'); col++;
int brightness = atoi(dbrow[col]); col++;
int contrast = atoi(dbrow[col]); col++;
int hue = atoi(dbrow[col]); col++;
@ -2332,6 +2333,7 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
path, // Path
cam_width,
cam_height,
rtsp_describe,
colours,
brightness,
contrast,
@ -2699,7 +2701,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, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", id );
snprintf( sql, sizeof(sql), "select Id, Name, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", id );
if ( mysql_query( &dbconn, sql ) )
{
Error( "Can't run query: %s", mysql_error( &dbconn ) );
@ -2766,6 +2768,7 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame );
int palette = atoi(dbrow[col]); col++;
Orientation orientation = (Orientation)atoi(dbrow[col]); col++;
unsigned int deinterlacing = atoi(dbrow[col]); col++;
bool rtsp_describe = (*dbrow[col] != '0'); col++;
int brightness = atoi(dbrow[col]); col++;
int contrast = atoi(dbrow[col]); col++;
int hue = atoi(dbrow[col]); col++;
@ -2867,6 +2870,7 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame );
path.c_str(),
cam_width,
cam_height,
rtsp_describe,
colours,
brightness,
contrast,

View File

@ -28,9 +28,10 @@
#include <sys/types.h>
#include <sys/socket.h>
RemoteCameraRtsp::RemoteCameraRtsp( int p_id, const std::string &p_method, const std::string &p_host, const std::string &p_port, const std::string &p_path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) :
RemoteCameraRtsp::RemoteCameraRtsp( int p_id, const std::string &p_method, const std::string &p_host, const std::string &p_port, const std::string &p_path, int p_width, int p_height, bool p_rtsp_describe, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) :
RemoteCamera( p_id, "rtsp", p_host, p_port, p_path, p_width, p_height, p_colours, p_brightness, p_contrast, p_hue, p_colour, p_capture ),
rtspThread( 0 )
rtspThread( 0 ),
rtsp_describe( p_rtsp_describe )
{
if ( p_method == "rtpUni" )
method = RtspThread::RTP_UNICAST;
@ -125,7 +126,7 @@ void RemoteCameraRtsp::Terminate()
int RemoteCameraRtsp::Connect()
{
rtspThread = new RtspThread( id, method, protocol, host, port, path, auth );
rtspThread = new RtspThread( id, method, protocol, host, port, path, auth, rtsp_describe );
rtspThread->start();

View File

@ -40,10 +40,11 @@ protected:
int rtsp_sd;
int rtp_sd;
int rtcp_sd;
bool rtsp_describe;
Buffer buffer;
Buffer lastSps;
Buffer lastPps;
Buffer lastSps;
Buffer lastPps;
RtspThread::RtspMethod method;
@ -66,18 +67,19 @@ protected:
#endif
public:
RemoteCameraRtsp( int p_id, const std::string &method, const std::string &host, const std::string &port, const std::string &path, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture );
RemoteCameraRtsp( int p_id, const std::string &method, const std::string &host, const std::string &port, const std::string &path, int p_width, int p_height, bool p_rtsp_describe, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture );
~RemoteCameraRtsp();
void Initialise();
void Terminate();
int Connect();
int Disconnect();
int Connect();
int Disconnect();
int PrimeCapture();
int PreCapture();
int Capture( Image &image );
int PostCapture();
};
#endif // ZM_REMOTE_CAMERA_RTSP_H

View File

@ -167,13 +167,14 @@ void RtspThread::releasePorts( int port )
smAssignedPorts.erase( port );
}
RtspThread::RtspThread( int id, RtspMethod method, const std::string &protocol, const std::string &host, const std::string &port, const std::string &path, const std::string &auth) :
RtspThread::RtspThread( int id, RtspMethod method, const std::string &protocol, const std::string &host, const std::string &port, const std::string &path, const std::string &auth, bool rtsp_describe) :
mId( id ),
mMethod( method ),
mProtocol( protocol ),
mHost( host ),
mPort( port ),
mPath( path ),
mRtspDescribe( rtsp_describe ),
mSessDesc( 0 ),
mFormatContext( 0 ),
mSeq( 0 ),
@ -382,20 +383,23 @@ int RtspThread::run()
if( sdpStart == std::string::npos )
return( -1 );
std::string DescHeader = response.substr( 0,sdpStart );
Debug( 1, "Processing DESCRIBE response header '%s'", DescHeader.c_str() );
if ( mRtspDescribe )
{
std::string DescHeader = response.substr( 0,sdpStart );
Debug( 1, "Processing DESCRIBE response header '%s'", DescHeader.c_str() );
lines = split( DescHeader, "\r\n" );
for ( size_t i = 0; i < lines.size(); i++ )
{
// If the device sends us a url value for Content-Base in the response header, we should use that instead
if ( ( lines[i].size() > 13 ) && ( lines[i].substr( 0, 13 ) == "Content-Base:" ) )
{
mUrl = trimSpaces( lines[i].substr( 13 ) );
Info("Received new Content-Base in DESCRIBE response header. Updated device Url to: '%s'", mUrl.c_str() );
break;
}
}
lines = split( DescHeader, "\r\n" );
for ( size_t i = 0; i < lines.size(); i++ )
{
// If the device sends us a url value for Content-Base in the response header, we should use that instead
if ( ( lines[i].size() > 13 ) && ( lines[i].substr( 0, 13 ) == "Content-Base:" ) )
{
mUrl = trimSpaces( lines[i].substr( 13 ) );
Info("Received new Content-Base in DESCRIBE response header. Updated device Url to: '%s'", mUrl.c_str() );
break;
}
}
}
sdpStart += endOfHeaders.length();

View File

@ -50,6 +50,7 @@ private:
private:
int mId;
bool mRtspDescribe;
RtspMethod mMethod;
std::string mProtocol;
std::string mHost;
@ -95,7 +96,7 @@ private:
void checkAuthResponse(std::string &response);
public:
RtspThread( int id, RtspMethod method, const std::string &protocol, const std::string &host, const std::string &port, const std::string &path, const std::string &auth);
RtspThread( int id, RtspMethod method, const std::string &protocol, const std::string &host, const std::string &port, const std::string &path, const std::string &auth, bool rtsp_describe );
~RtspThread();
public:

View File

@ -1 +1 @@
1.28.105
1.28.106

View File

@ -445,7 +445,8 @@ if ( !empty($action) )
'TrackMotion' => 'toggle',
'Enabled' => 'toggle',
'DoNativeMotDet' => 'toggle',
'Exif' => 'toggle'
'Exif' => 'toggle',
'RTSPDescribe' => 'toggle',
);
$columns = getTableColumns( 'Monitors' );

View File

@ -256,6 +256,7 @@ $SLANG = array(
'DefaultScale' => 'Default Scale',
'DefaultView' => 'Default View',
'Deinterlacing' => 'Deinterlacing',
'RTSPDescribe' => 'Use RTSP Response Media URL',
'Delay' => 'Delay',
'DeleteAndNext' => 'Delete &amp; Next',
'DeleteAndPrev' => 'Delete &amp; Prev',
@ -903,7 +904,13 @@ $OLANG = array(
'OPTIONS_EXIF' => array(
'Help' => "Enable this option to embed EXIF data into each jpeg frame."
),
'OPTIONS_RTSPDESCRIBE' => array(
'Help' => "Sometimes, during the intial RTSP handshake, the camera will send an updated media URL. ".
"Enable this option to tell ZoneMinder to use this URL. Disable this option to ignore the ".
"value from the camera and use the value as entered in the monitor configuration~~~~".
"Generally this should be enabled. However, there are cases where the camera can get its".
"own URL incorrect, such as when the camera is streaming through a firewall"
),
// 'LANG_DEFAULT' => array(
// 'Prompt' => "This is a new prompt for this option",

View File

@ -78,6 +78,7 @@ if ( ! empty($_REQUEST['mid']) ) {
'Height' => "240",
'Orientation' => "0",
'Deinterlacing' => 0,
'RTSPDescribe' => 0,
'LabelFormat' => '%N - %d/%m/%y %H:%M:%S',
'LabelX' => 0,
'LabelY' => 0,
@ -563,6 +564,12 @@ if ( $tab != 'source' )
<input type="hidden" name="newMonitor[Deinterlacing]" value="<?php echo validHtmlStr($newMonitor['Deinterlacing']) ?>"/>
<?php
}
if ( $tab != 'source' || ($newMonitor['Type'] != 'Remote' && $newMonitor['Protocol'] != 'RTSP'))
{
?>
<input type="hidden" name="newMonitor[RTSPDescribe]" value="<?php echo validHtmlStr($newMonitor['RTSPDescribe']) ?>"/>
<?php
}
if ( $tab != 'timestamp' )
{
?>
@ -823,6 +830,14 @@ switch ( $tab )
<?php
}
?>
<?php
if ( $newMonitor['Type'] == "Remote" )
{
?>
<tr><td><?php echo translate('RTSPDescribe') ?>&nbsp;(<?php echo makePopupLink( '?view=optionhelp&amp;option=OPTIONS_RTSPDESCRIBE', 'zmOptionHelp', 'optionhelp', '?' ) ?>) </td><td><input type="checkbox" name="newMonitor[RTSPDescribe]" value="1"<?php if ( !empty($newMonitor['RTSPDescribe']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<?php
}
?>
<?php
break;
}