Merge branch 'feature-h264-videostorage'

This commit is contained in:
Isaac Connor 2017-05-16 13:37:24 -04:00
commit eef5e5cd90
5 changed files with 95 additions and 24 deletions

View File

@ -1,7 +1,20 @@
ZoneMinder
==========
ZoneMinder H264 Patch
[![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)
[![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` ;
```
All documentation for ZoneMinder is now online at https://zoneminder.readthedocs.org

View File

@ -420,6 +420,35 @@ sub generateVideo
return( 1 );
}
# Returns an image absolute path for given event and frame
# Optionally an analyse image path may be returned if an analyse image exists
# If neither capture nor analyse image exists it will try to extract a frame from .mp4 file if exists
# An empty string is returned if no one from methods above works
sub generateImage
{
my $event = shift;
my $frame = shift;
my $analyse = do { @_ ? shift : 0 }; # don't return analyse image by default
my $capture_image_path = sprintf("%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg", getEventPath($event), $frame->{FrameId});
my $analyse_image_path = sprintf("%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-analyse.jpg", getEventPath($event), $frame->{FrameId}) if $analyse;
my $video_path = sprintf("%s/%d-video.mp4", getEventPath($event), $event->{Id});
my $image_path = "";
# check if the image file exists. If the file doesn't exist and we use H264 try to extract it from .mp4 video
if ( $analyse && -r $analyse_image_path ) {
$image_path = $analyse_image_path;
} elsif ( -r $capture_image_path ) {
$image_path = $capture_image_path;
} elsif ( -e $video_path ) {
if ( !system("ffmpeg -y -v 0 -i ".$video_path." -vf 'select=gte(n\\,".$frame->{FrameId}."),setpts=PTS-STARTPTS' -vframes 1 -f image2 ".$capture_image_path) ) {
$image_path = $capture_image_path;
}
}
return $image_path;
}
sub uploadArchFile
{
my $filter = shift;
@ -623,7 +652,7 @@ sub substituteTags
}
# Do we need the image information too?
my $need_images = $text =~ /%(?:EPI1|EPIM|EI1|EIM)%/;
my $need_images = $text =~ /%(?:EPI1|EPIM|EI1|EIM|EI1A|EIMA)%/;
my $first_alarm_frame;
my $max_alarm_frame;
my $max_alarm_score = 0;
@ -684,17 +713,16 @@ sub substituteTags
$text =~ s/%EPIM%/$url?view=frame&mid=$event->{MonitorId}&eid=$event->{Id}&fid=$max_alarm_frame->{FrameId}/g;
if ( $attachments_ref && $text =~ s/%EI1%//g )
{
my $path = generateImage( $event, $first_alarm_frame);
if ( -e $path ) {
push( @$attachments_ref,
{
type=>"image/jpeg",
path=>sprintf(
"%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg",
getEventPath( $event ),
$first_alarm_frame->{FrameId}
)
path=>$path
}
);
}
}
if ( $attachments_ref && $text =~ s/%EIM%//g )
{
# Don't attach the same image twice
@ -702,19 +730,48 @@ sub substituteTags
|| ($first_alarm_frame->{FrameId} != $max_alarm_frame->{FrameId} )
)
{
my $path = generateImage( $event, $max_alarm_frame);
if ( -e $path ) {
push( @$attachments_ref,
{
type=>"image/jpeg",
path=>sprintf(
"%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg",
getEventPath( $event ),
$max_alarm_frame->{FrameId}
)
path=>$path
}
);
}
}
}
if ( $attachments_ref && $text =~ s/%EI1A%//g )
{
my $path = generateImage( $event, $first_alarm_frame, "analyse" );
if ( -e $path ) {
push( @$attachments_ref,
{
type=>"image/jpeg",
path=>$path
}
);
}
}
if ( $attachments_ref && $text =~ s/%EIMA%//g )
{
# Don't attach the same image twice
if ( !@$attachments_ref
|| ($first_alarm_frame->{FrameId} != $max_alarm_frame->{FrameId} )
)
{
my $path = generateImage( $event, $max_alarm_frame, "analyse");
if ( -e $path ) {
push( @$attachments_ref,
{
type=>"image/jpeg",
path=>$path
}
);
}
}
}
}
if ( $attachments_ref && $Config{ZM_OPT_FFMPEG} )
{
if ( $text =~ s/%EV%//g )
@ -1007,4 +1064,3 @@ sub executeCommand
}
return( 1 );
}

View File

@ -311,7 +311,6 @@ int cURLCamera::CaptureAndRecord( Image &image, struct timeval recording, char*
return( 0 );
}
size_t cURLCamera::data_callback(void *buffer, size_t size, size_t nmemb, void *userdata) {
lock();
@ -331,8 +330,6 @@ size_t cURLCamera::data_callback(void *buffer, size_t size, size_t nmemb, void *
return size*nmemb;
}
size_t cURLCamera::header_callback( void *buffer, size_t size, size_t nmemb, void *userdata) {
std::string header;
header.assign((const char*)buffer, size*nmemb);

View File

@ -2865,7 +2865,6 @@ int Monitor::Capture() {
}
}
if ( capture_image->Size() > camera->ImageSize() ) {
Error( "Captured image %d does not match expected size %d check width, height and colour depth",capture_image->Size(),camera->ImageSize() );
return( -1 );

View File

@ -42,6 +42,12 @@
#cmakedefine HAVE_GNUTLS_GNUTLS_H 1
#cmakedefine HAVE_LIBMYSQLCLIENT 1
#cmakedefine HAVE_MYSQL_H 1
#cmakedefine HAVE_LIBX264 1
#cmakedefine HAVE_X264_H 1
#cmakedefine HAVE_LIBMP4V2 1
#cmakedefine HAVE_MP4V2_MP4V2_H 1
#cmakedefine HAVE_MP4V2_H 1
#cmakedefine HAVE_MP4_H 1
#cmakedefine HAVE_LIBAVFORMAT 1
#cmakedefine HAVE_LIBAVFORMAT_AVFORMAT_H 1
#cmakedefine HAVE_LIBAVCODEC 1