Merge branch 'master' into storageareas
This commit is contained in:
commit
a515041e14
19
README.md
19
README.md
|
@ -1,20 +1,7 @@
|
|||
ZoneMinder H264 Patch
|
||||
ZoneMinder
|
||||
==========
|
||||
|
||||
[![Build Status](https://travis-ci.org/ZoneMinder/ZoneMinder.png?branch=feature-h264-videostorage)](https://travis-ci.org/ZoneMinder/ZoneMinder) [![Bountysource](https://api.bountysource.com/badge/team?team_id=204&style=bounties_received)](https://www.bountysource.com/teams/zoneminder/issues?utm_source=ZoneMinder&utm_medium=shield&utm_campaign=bounties_received)
|
||||
|
||||
##Feature-h264-videostorage Branch Details
|
||||
This branch supports direct recording of h264 cameras into MP4 format uisng the h264 Passthrough option, but only with FFMPEG Monitors currently. It also provides h264 encoding for any other monitor type. If you encounter any issues, please open an issue on GitHub and attach it to the h264 milestone. But do remember this is bleeding edge so it will have problems.
|
||||
Thanks to @chriswiggins and @mastertheknife for their work, @SteveGilvarry is now maintaining this branch and welcomes any assistance.
|
||||
|
||||
**The following SQL changes are required, these will be merged to zmupdate once we are ready to merge this branch to master.**
|
||||
```
|
||||
ALTER TABLE `Monitors` ADD `SaveJPEGs` TINYINT NOT NULL DEFAULT '3' AFTER `Deinterlacing` ,
|
||||
ADD `VideoWriter` TINYINT NOT NULL DEFAULT '0' AFTER `SaveJPEGs` ,
|
||||
ADD `EncoderParameters` TEXT NOT NULL AFTER `VideoWriter` ,
|
||||
ADD `RecordAudio` TINYINT NOT NULL DEFAULT '0' AFTER `EncoderParameters` ;
|
||||
|
||||
ALTER TABLE `Events` ADD `DefaultVideo` VARCHAR( 64 ) NOT NULL AFTER `AlarmFrames` ;
|
||||
```
|
||||
[![Build Status](https://travis-ci.org/ZoneMinder/ZoneMinder.png)](https://travis-ci.org/ZoneMinder/ZoneMinder) [![Bountysource](https://api.bountysource.com/badge/team?team_id=204&style=bounties_received)](https://www.bountysource.com/teams/zoneminder/issues?utm_source=ZoneMinder&utm_medium=shield&utm_campaign=bounties_received)
|
||||
|
||||
All documentation for ZoneMinder is now online at https://zoneminder.readthedocs.org
|
||||
|
||||
|
|
|
@ -354,7 +354,7 @@ CREATE TABLE `Monitors` (
|
|||
`Deinterlacing` int(10) unsigned NOT NULL default '0',
|
||||
`SaveJPEGs` TINYINT NOT NULL DEFAULT '3' ,
|
||||
`VideoWriter` TINYINT NOT NULL DEFAULT '0',
|
||||
`EncoderParameters` TEXT NOT NULL,
|
||||
`EncoderParameters` TEXT,
|
||||
`RecordAudio` TINYINT NOT NULL DEFAULT '0',
|
||||
`RTSPDescribe` tinyint(1) unsigned,
|
||||
`Brightness` mediumint(7) NOT NULL default '-1',
|
||||
|
|
|
@ -71,3 +71,27 @@ SET @s = (SELECT IF(
|
|||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
--
|
||||
-- The following alters various columns to allow NULLs
|
||||
--
|
||||
|
||||
ALTER TABLE Monitors MODIFY Host varchar(64);
|
||||
ALTER TABLE Monitors MODIFY LabelFormat varchar(64);
|
||||
ALTER TABLE Monitors MODIFY LinkedMonitors varchar(255);
|
||||
ALTER TABLE Monitors MODIFY Options varchar(255);
|
||||
ALTER TABLE Monitors MODIFY Protocol varchar(16);
|
||||
ALTER TABLE Monitors MODIFY User varchar(64);
|
||||
ALTER TABLE Monitors MODIFY Pass varchar(64);
|
||||
ALTER TABLE Monitors MODIFY RTSPDescribe tinyint(1) unsigned;
|
||||
ALTER TABLE Monitors MODIFY ControlId int(10) unsigned;
|
||||
ALTER TABLE Monitors MODIFY TrackDelay smallint(5) unsigned;
|
||||
ALTER TABLE Monitors MODIFY ReturnDelay smallint(5) unsigned;
|
||||
ALTER TABLE Monitors MODIFY EncoderParameters TEXT;
|
||||
ALTER TABLE Monitors MODIFY Path varchar(255);
|
||||
ALTER TABLE Monitors MODIFY V4LMultiBuffer tinyint(1) unsigned;
|
||||
|
||||
ALTER TABLE Users MODIFY MonitorIds tinytext;
|
||||
ALTER TABLE Users MODIFY Language varchar(8);
|
||||
ALTER TABLE Users MODIFY MaxBandwidth varchar(16);
|
||||
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
Alias /zm /usr/share/zoneminder/www
|
||||
|
||||
<IfModule mod_fcgid.c>
|
||||
<Directory /usr/share/zoneminder/www>
|
||||
Options -Indexes +ExecCGI
|
||||
AllowOverride All
|
||||
AddHandler fcgid-script .php
|
||||
FCGIWrapper /usr/bin/php5-cgi
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
<Directory /usr/share/zoneminder/www>
|
||||
Options -Indexes +ExecCGI
|
||||
AllowOverride All
|
||||
AddHandler fcgid-script .php
|
||||
FCGIWrapper /usr/bin/php5-cgi
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
</IfModule>
|
||||
<IfModule mod_php5.c>
|
||||
<Directory /usr/share/zoneminder/www>
|
||||
Options -Indexes +FollowSymLinks
|
||||
<IfModule mod_dir.c>
|
||||
DirectoryIndex index.php
|
||||
</IfModule>
|
||||
</Directory>
|
||||
<Directory /usr/share/zoneminder/www>
|
||||
Options -Indexes +FollowSymLinks
|
||||
<IfModule mod_dir.c>
|
||||
DirectoryIndex index.php
|
||||
</IfModule>
|
||||
</Directory>
|
||||
</IfModule>
|
||||
|
|
|
@ -6,7 +6,7 @@ Build-Depends: debhelper (>= 9), cmake
|
|||
, libphp-serialization-perl
|
||||
, libgnutls28-dev | libgnutls-dev
|
||||
, libmysqlclient-dev | libmariadbclient-dev
|
||||
, libjpeg-dev
|
||||
, libjpeg8-dev | libjpeg-dev
|
||||
, libpcre3-dev
|
||||
, libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev
|
||||
, libavdevice-dev
|
||||
|
|
|
@ -29,7 +29,7 @@ override_dh_auto_install:
|
|||
install -D -m 0644 debian/apache.conf $(INSTDIR)/etc/zm/apache.conf
|
||||
rm -f $(INSTDIR)/usr/share/zoneminder/www/api/lib/Cake/LICENSE.txt
|
||||
rm -f $(INSTDIR)/usr/share/zoneminder/www/api/.gitignore
|
||||
rm -rf $(INSTDIR)/usr/share/zoneminder/www/api/lib/Cake/Test
|
||||
rm -rf $(INSTDIR)/usr/share/zoneminder/www/api/lib/Cake/Test
|
||||
|
||||
override_dh_auto_test:
|
||||
# do not run tests...
|
||||
|
|
|
@ -187,7 +187,7 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
|
|||
snprintf( video_file, sizeof(video_file), video_file_format, path, video_name );
|
||||
|
||||
/* X264 MP4 video writer */
|
||||
if(monitor->GetOptVideoWriter() == 1) {
|
||||
if ( monitor->GetOptVideoWriter() == Monitor::X264ENCODE ) {
|
||||
#if ZM_HAVE_VIDEOWRITER_X264MP4
|
||||
videowriter = new X264MP4Writer(video_file, monitor->Width(), monitor->Height(), monitor->Colours(), monitor->SubpixelOrder(), monitor->GetOptEncoderParams());
|
||||
#else
|
||||
|
@ -195,8 +195,7 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
|
|||
#endif
|
||||
}
|
||||
|
||||
if(videowriter != NULL) {
|
||||
|
||||
if ( videowriter != NULL ) {
|
||||
/* Open the video stream */
|
||||
int nRet = videowriter->Open();
|
||||
if(nRet != 0) {
|
||||
|
@ -207,9 +206,10 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
|
|||
|
||||
snprintf( timecodes_name, sizeof(timecodes_name), "%d-%s", id, "video.timecodes" );
|
||||
snprintf( timecodes_file, sizeof(timecodes_file), video_file_format, path, timecodes_name );
|
||||
|
||||
/* Create timecodes file */
|
||||
timecodes_fd = fopen(timecodes_file, "wb");
|
||||
if(timecodes_fd == NULL) {
|
||||
if ( timecodes_fd == NULL ) {
|
||||
Error("Failed creating timecodes file");
|
||||
}
|
||||
}
|
||||
|
@ -353,12 +353,12 @@ void Event::updateNotes( const StringSetMap &newNoteSetMap ) {
|
|||
noteSet.insert( newNote );
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
} // end if ( noteSetMap.size() == 0
|
||||
} // end if newNoteSetupMap.size() > 0
|
||||
} // end for
|
||||
} // end if ( noteSetMap.size() == 0
|
||||
} // end if newNoteSetupMap.size() > 0
|
||||
} // end foreach newNoteSetMap
|
||||
} // end if have old notes
|
||||
} // end if have new notes
|
||||
|
||||
if ( update ) {
|
||||
std::string notes;
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
#define MAP_LOCKED 0
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
std::vector<std::string> split(const std::string &s, char delim) {
|
||||
std::vector<std::string> elems;
|
||||
std::stringstream ss(s);
|
||||
|
@ -71,7 +70,6 @@ std::vector<std::string> split(const std::string &s, char delim) {
|
|||
}
|
||||
return elems;
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
Monitor::MonitorLink::MonitorLink( int p_id, const char *p_name ) : id( p_id ) {
|
||||
strncpy( name, p_name, sizeof(name) );
|
||||
|
@ -1228,7 +1226,7 @@ bool Monitor::Analyse() {
|
|||
}
|
||||
shared_data->action &= ~RESUME;
|
||||
}
|
||||
} // end ifshared_data->action
|
||||
} // end if shared_data->action
|
||||
|
||||
if ( auto_resume_time && (now.tv_sec >= auto_resume_time) ) {
|
||||
Info( "Auto resuming at count %d", image_count );
|
||||
|
|
|
@ -163,7 +163,7 @@ protected:
|
|||
typedef struct {
|
||||
uint32_t size;
|
||||
char event_file[4096];
|
||||
timeval recording; // used as both bool and a pointer to the timestamp when recording should begin
|
||||
timeval recording; // used as both bool and a pointer to the timestamp when recording should begin
|
||||
//uint32_t frameNumber;
|
||||
} VideoStoreData;
|
||||
|
||||
|
@ -222,19 +222,19 @@ protected:
|
|||
|
||||
protected:
|
||||
// These are read from the DB and thereafter remain unchanged
|
||||
unsigned int id;
|
||||
char name[64];
|
||||
unsigned int server_id; // Id of the Server object
|
||||
unsigned int storage_id; // Id of the Storage Object, which currently will just provide a path, but in future may do more.
|
||||
Function function; // What the monitor is doing
|
||||
bool enabled; // Whether the monitor is enabled or asleep
|
||||
unsigned int width; // Normally the same as the camera, but not if partly rotated
|
||||
unsigned int height; // Normally the same as the camera, but not if partly rotated
|
||||
bool v4l_multi_buffer;
|
||||
unsigned int v4l_captures_per_frame;
|
||||
Orientation orientation; // Whether the image has to be rotated at all
|
||||
unsigned int deinterlacing;
|
||||
bool videoRecording;
|
||||
unsigned int id;
|
||||
char name[64];
|
||||
unsigned int server_id; // Id of the Server object
|
||||
unsigned int storage_id; // Id of the Storage Object, which currently will just provide a path, but in future may do more.
|
||||
Function function; // What the monitor is doing
|
||||
bool enabled; // Whether the monitor is enabled or asleep
|
||||
unsigned int width; // Normally the same as the camera, but not if partly rotated
|
||||
unsigned int height; // Normally the same as the camera, but not if partly rotated
|
||||
bool v4l_multi_buffer;
|
||||
unsigned int v4l_captures_per_frame;
|
||||
Orientation orientation; // Whether the image has to be rotated at all
|
||||
unsigned int deinterlacing;
|
||||
bool videoRecording;
|
||||
|
||||
int savejpegspref;
|
||||
VideoWriter videowriter;
|
||||
|
|
|
@ -48,18 +48,16 @@ RemoteCamera::RemoteCamera(
|
|||
path = '/'+path;
|
||||
}
|
||||
|
||||
RemoteCamera::~RemoteCamera()
|
||||
{
|
||||
if(hp != NULL) {
|
||||
freeaddrinfo(hp);
|
||||
hp = NULL;
|
||||
}
|
||||
RemoteCamera::~RemoteCamera() {
|
||||
if ( hp != NULL ) {
|
||||
freeaddrinfo(hp);
|
||||
hp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteCamera::Initialise()
|
||||
{
|
||||
if( protocol.empty() )
|
||||
Fatal( "No protocol specified for remote camera" );
|
||||
void RemoteCamera::Initialise() {
|
||||
if( protocol.empty() )
|
||||
Fatal( "No protocol specified for remote camera" );
|
||||
|
||||
if( host.empty() )
|
||||
Fatal( "No host specified for remote camera" );
|
||||
|
@ -71,21 +69,19 @@ void RemoteCamera::Initialise()
|
|||
//Fatal( "No path specified for remote camera" );
|
||||
|
||||
// Cache as much as we can to speed things up
|
||||
std::string::size_type authIndex = host.rfind( '@' );
|
||||
std::string::size_type authIndex = host.rfind( '@' );
|
||||
|
||||
if ( authIndex != std::string::npos )
|
||||
{
|
||||
auth = host.substr( 0, authIndex );
|
||||
host.erase( 0, authIndex+1 );
|
||||
auth64 = base64Encode( auth );
|
||||
if ( authIndex != std::string::npos ) {
|
||||
auth = host.substr( 0, authIndex );
|
||||
host.erase( 0, authIndex+1 );
|
||||
auth64 = base64Encode( auth );
|
||||
|
||||
authIndex = auth.rfind( ':' );
|
||||
username = auth.substr(0,authIndex);
|
||||
password = auth.substr( authIndex+1, auth.length() );
|
||||
authIndex = auth.rfind( ':' );
|
||||
username = auth.substr(0,authIndex);
|
||||
password = auth.substr( authIndex+1, auth.length() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mNeedAuth = false;
|
||||
mNeedAuth = false;
|
||||
mAuthenticator = new zm::Authenticator(username,password);
|
||||
|
||||
struct addrinfo hints;
|
||||
|
@ -93,10 +89,8 @@ void RemoteCamera::Initialise()
|
|||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
int ret = getaddrinfo(host.c_str(), port.c_str(), &hints, &hp);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
Fatal( "Can't getaddrinfo(%s port %s): %s", host.c_str(), port.c_str(), gai_strerror(ret) );
|
||||
}
|
||||
int ret = getaddrinfo(host.c_str(), port.c_str(), &hints, &hp);
|
||||
if ( ret != 0 ) {
|
||||
Fatal( "Can't getaddrinfo(%s port %s): %s", host.c_str(), port.c_str(), gai_strerror(ret) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,8 +31,7 @@
|
|||
// Class representing 'http' cameras, i.e. those which are
|
||||
// accessed over a network connection using http
|
||||
//
|
||||
class RemoteCameraHttp : public RemoteCamera
|
||||
{
|
||||
class RemoteCameraHttp : public RemoteCamera {
|
||||
protected:
|
||||
std::string request;
|
||||
struct timeval timeout;
|
||||
|
|
|
@ -45,8 +45,7 @@ RemoteCameraRtsp::RemoteCameraRtsp( unsigned int p_monitor_id, const std::string
|
|||
else
|
||||
Fatal( "Unrecognised method '%s' when creating RTSP camera %d", p_method.c_str(), monitor_id );
|
||||
|
||||
if ( capture )
|
||||
{
|
||||
if ( capture ) {
|
||||
Initialise();
|
||||
}
|
||||
|
||||
|
@ -76,36 +75,30 @@ RemoteCameraRtsp::RemoteCameraRtsp( unsigned int p_monitor_id, const std::string
|
|||
} else {
|
||||
Panic("Unexpected colours: %d",colours);
|
||||
}
|
||||
|
||||
}
|
||||
} // end RemoteCameraRtsp::RemoteCameraRtsp(...)
|
||||
|
||||
RemoteCameraRtsp::~RemoteCameraRtsp()
|
||||
{
|
||||
RemoteCameraRtsp::~RemoteCameraRtsp() {
|
||||
av_frame_free( &mFrame );
|
||||
av_frame_free( &mRawFrame );
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if ( mConvertContext )
|
||||
{
|
||||
if ( mConvertContext ) {
|
||||
sws_freeContext( mConvertContext );
|
||||
mConvertContext = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( mCodecContext )
|
||||
{
|
||||
if ( mCodecContext ) {
|
||||
avcodec_close( mCodecContext );
|
||||
mCodecContext = NULL; // Freed by avformat_free_context in the destructor of RtspThread class
|
||||
}
|
||||
|
||||
if ( capture )
|
||||
{
|
||||
if ( capture ) {
|
||||
Terminate();
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteCameraRtsp::Initialise()
|
||||
{
|
||||
void RemoteCameraRtsp::Initialise() {
|
||||
RemoteCamera::Initialise();
|
||||
|
||||
int max_size = width*height*colours;
|
||||
|
@ -124,13 +117,11 @@ void RemoteCameraRtsp::Initialise()
|
|||
Connect();
|
||||
}
|
||||
|
||||
void RemoteCameraRtsp::Terminate()
|
||||
{
|
||||
void RemoteCameraRtsp::Terminate() {
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
int RemoteCameraRtsp::Connect()
|
||||
{
|
||||
int RemoteCameraRtsp::Connect() {
|
||||
rtspThread = new RtspThread( monitor_id, method, protocol, host, port, path, auth, rtsp_describe );
|
||||
|
||||
rtspThread->start();
|
||||
|
@ -138,10 +129,8 @@ int RemoteCameraRtsp::Connect()
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
int RemoteCameraRtsp::Disconnect()
|
||||
{
|
||||
if ( rtspThread )
|
||||
{
|
||||
int RemoteCameraRtsp::Disconnect() {
|
||||
if ( rtspThread ) {
|
||||
rtspThread->stop();
|
||||
rtspThread->join();
|
||||
delete rtspThread;
|
||||
|
@ -150,11 +139,9 @@ int RemoteCameraRtsp::Disconnect()
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
int RemoteCameraRtsp::PrimeCapture()
|
||||
{
|
||||
int RemoteCameraRtsp::PrimeCapture() {
|
||||
Debug( 2, "Waiting for sources" );
|
||||
for ( int i = 0; i < 100 && !rtspThread->hasSources(); i++ )
|
||||
{
|
||||
for ( int i = 0; i < 100 && !rtspThread->hasSources(); i++ ) {
|
||||
usleep( 100000 );
|
||||
}
|
||||
if ( !rtspThread->hasSources() )
|
||||
|
@ -241,7 +228,7 @@ int RemoteCameraRtsp::PrimeCapture()
|
|||
int pSize = avpicture_get_size( imagePixFormat, width, height );
|
||||
#endif
|
||||
|
||||
if( (unsigned int)pSize != imagesize) {
|
||||
if ( (unsigned int)pSize != imagesize ) {
|
||||
Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
|
||||
}
|
||||
/*
|
||||
|
@ -265,8 +252,7 @@ int RemoteCameraRtsp::PrimeCapture()
|
|||
int RemoteCameraRtsp::PreCapture() {
|
||||
if ( !rtspThread->isRunning() )
|
||||
return( -1 );
|
||||
if ( !rtspThread->hasSources() )
|
||||
{
|
||||
if ( !rtspThread->hasSources() ) {
|
||||
Error( "Cannot precapture, no RTP sources" );
|
||||
return( -1 );
|
||||
}
|
||||
|
@ -303,25 +289,20 @@ int RemoteCameraRtsp::Capture( Image &image ) {
|
|||
int nalType = (buffer.head()[3] & 0x1f);
|
||||
|
||||
// SPS The SPS NAL unit contains parameters that apply to a series of consecutive coded video pictures
|
||||
if(nalType == 7)
|
||||
{
|
||||
if(nalType == 7) {
|
||||
lastSps = buffer;
|
||||
continue;
|
||||
}
|
||||
} else if(nalType == 8) {
|
||||
// PPS The PPS NAL unit contains parameters that apply to the decoding of one or more individual pictures inside a coded video sequence
|
||||
else if(nalType == 8)
|
||||
{
|
||||
lastPps = buffer;
|
||||
continue;
|
||||
}
|
||||
} else if(nalType == 5) {
|
||||
// IDR
|
||||
else if(nalType == 5)
|
||||
{
|
||||
buffer += lastSps;
|
||||
buffer += lastPps;
|
||||
}
|
||||
} else {
|
||||
Debug(3, "Not an h264 packet");
|
||||
} else {
|
||||
Debug(3, "Not an h264 packet");
|
||||
}
|
||||
|
||||
av_init_packet( &packet );
|
||||
|
@ -382,7 +363,7 @@ int RemoteCameraRtsp::Capture( Image &image ) {
|
|||
} // end while true
|
||||
|
||||
// can never get here.
|
||||
return (0) ;
|
||||
return (0);
|
||||
}
|
||||
|
||||
//Function to handle capture and store
|
||||
|
@ -392,7 +373,6 @@ int RemoteCameraRtsp::CaptureAndRecord(Image &image, timeval recording, char* ev
|
|||
uint8_t* directbuffer;
|
||||
int frameComplete = false;
|
||||
|
||||
|
||||
while ( true ) {
|
||||
|
||||
// WHY Are we clearing it? Might be something good in it.
|
||||
|
@ -450,14 +430,12 @@ int RemoteCameraRtsp::CaptureAndRecord(Image &image, timeval recording, char* ev
|
|||
if(nalType == 7) {
|
||||
lastSps = buffer;
|
||||
continue;
|
||||
}
|
||||
} else if(nalType == 8) {
|
||||
// PPS
|
||||
else if(nalType == 8) {
|
||||
lastPps = buffer;
|
||||
continue;
|
||||
}
|
||||
} else if(nalType == 5) {
|
||||
// IDR
|
||||
else if(nalType == 5) {
|
||||
buffer += lastSps;
|
||||
buffer += lastPps;
|
||||
}
|
||||
|
@ -525,14 +503,14 @@ int RemoteCameraRtsp::CaptureAndRecord(Image &image, timeval recording, char* ev
|
|||
#if HAVE_LIBSWSCALE
|
||||
// Why are we re-scaling after writing out the packet?
|
||||
if ( mConvertContext == NULL ) {
|
||||
mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL );
|
||||
mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL );
|
||||
|
||||
if ( mConvertContext == NULL )
|
||||
Fatal( "Unable to create conversion context");
|
||||
if ( mConvertContext == NULL )
|
||||
Fatal( "Unable to create conversion context");
|
||||
}
|
||||
|
||||
if ( sws_scale( mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mCodecContext->height, mFrame->data, mFrame->linesize ) < 0 )
|
||||
Fatal( "Unable to convert raw format %u to target format %u at frame %d", mCodecContext->pix_fmt, imagePixFormat, frameCount );
|
||||
Fatal( "Unable to convert raw format %u to target format %u at frame %d", mCodecContext->pix_fmt, imagePixFormat, frameCount );
|
||||
#else // HAVE_LIBSWSCALE
|
||||
Fatal( "You must compile ffmpeg with the --enable-swscale option to use RTSP cameras" );
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
|
|
|
@ -70,7 +70,11 @@ X264MP4Writer::X264MP4Writer(const char* p_path, const unsigned int p_width, con
|
|||
|
||||
/* Calculate the image sizes. We will need this for parameter checking */
|
||||
zm_imgsize = colours * width * height;
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
codec_imgsize = av_image_get_buffer_size( codec_pf, width, height, 1 );
|
||||
#else
|
||||
codec_imgsize = avpicture_get_size( codec_pf, width, height);
|
||||
#endif
|
||||
if(!codec_imgsize) {
|
||||
Error("Failed calculating codec pixel format image size");
|
||||
}
|
||||
|
|
1568
src/zm_zone.cpp
1568
src/zm_zone.cpp
File diff suppressed because it is too large
Load Diff
|
@ -94,7 +94,10 @@ class ImageComponent extends Component {
|
|||
// Take the StartTime of an Event and return
|
||||
// the path to its location on the filesystem
|
||||
public function getEventPath( $event ) {
|
||||
return $event['Event']['MonitorId'].'/'.strftime( "%y/%m/%d/%H/%M/%S", strtotime($event['Event']['StartTime']) );
|
||||
}
|
||||
if ( $config['ZM_USE_DEEP_STORAGE'] == 1 )
|
||||
return $event['Event']['MonitorId'].'/'.strftime( "%y/%m/%d/%H/%M/%S", strtotime($event['Event']['StartTime']) );
|
||||
else
|
||||
return $event['Event']['MonitorId'].'/'.$event['Event']['Id'];
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
//
|
||||
|
||||
require_once( 'includes/Server.php');
|
||||
require_once( 'includes/Storage.php');
|
||||
|
||||
if ( !canView( 'Monitors' ) ) {
|
||||
$view = "error";
|
||||
|
@ -29,7 +28,6 @@ if ( !canView( 'Monitors' ) ) {
|
|||
$tabs = array();
|
||||
$tabs["general"] = translate('General');
|
||||
$tabs["source"] = translate('Source');
|
||||
$tabs["storage"] = translate('Storage');
|
||||
$tabs["timestamp"] = translate('Timestamp');
|
||||
$tabs["buffers"] = translate('Buffers');
|
||||
if ( ZM_OPT_CONTROL && canView( 'Control' ) )
|
||||
|
@ -137,7 +135,6 @@ if ( ! empty($_REQUEST['mid']) ) {
|
|||
'V4LMultiBuffer' => '',
|
||||
'V4LCapturesPerFrame' => 1,
|
||||
'ServerId' => $Server['Id'],
|
||||
'StorageId' => '0',
|
||||
) );
|
||||
} # end if $_REQUEST['dupID']
|
||||
} # end if $_REQUEST['mid']
|
||||
|
@ -519,7 +516,6 @@ if ( $tab != 'general' ) {
|
|||
?>
|
||||
<input type="hidden" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name) ?>"/>
|
||||
<input type="hidden" name="newMonitor[ServerId]" value="<?php echo validHtmlStr($monitor->ServerId() ) ?>"/>
|
||||
<input type="hidden" name="newMonitor[StorageId]" value="<?= validHtmlStr($monitor->StorageId() ) ?>"/>
|
||||
<input type="hidden" name="newMonitor[Type]" value="<?php echo validHtmlStr($monitor->Type) ?>"/>
|
||||
<input type="hidden" name="newMonitor[Function]" value="<?php echo validHtmlStr($monitor->Function) ?>"/>
|
||||
<input type="hidden" name="newMonitor[Enabled]" value="<?php echo validHtmlStr($monitor->Enabled) ?>"/>
|
||||
|
@ -682,17 +678,6 @@ switch ( $tab )
|
|||
$servers[$server_obj->Id()] = $server_obj->Name();
|
||||
}
|
||||
echo htmlSelect( "newMonitor[ServerId]", $servers, $monitor->ServerId() );
|
||||
?>
|
||||
</td></tr>
|
||||
<tr><td><?php echo translate('StorageArea') ?></td><td>
|
||||
<?php
|
||||
$storage_areas = array(0=>'Default');
|
||||
$result = dbQuery( 'SELECT * FROM Storage ORDER BY Name');
|
||||
$results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Storage' );
|
||||
foreach ( $results as $row => $storage_obj ) {
|
||||
$storage_areas[$storage_obj->Id] = $storage_obj->Name();
|
||||
}
|
||||
echo htmlSelect( "newMonitor[StorageId]", $storage_areas, $monitor->StorageId() );
|
||||
?>
|
||||
</td></tr>
|
||||
<tr><td><?php echo translate('SourceType') ?></td><td><?php echo htmlSelect( "newMonitor[Type]", $sourceTypes, $monitor->Type() ); ?></td></tr>
|
||||
|
|
Loading…
Reference in New Issue