From bc0b499697c32f44d03697c3babe00e1951fa6f1 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 20 Sep 2016 14:10:37 -0400 Subject: [PATCH 1/4] update zm_create.sql.in to match the update scripts --- db/zm_create.sql.in | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index a93437cda..21a4d4cc1 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -328,22 +328,22 @@ CREATE TABLE `Monitors` ( `Type` enum('Local','Remote','File','Ffmpeg','Libvlc','cURL') NOT NULL default 'Local', `Function` enum('None','Monitor','Modect','Record','Mocord','Nodect') NOT NULL default 'Monitor', `Enabled` tinyint(3) unsigned NOT NULL default '1', - `LinkedMonitors` varchar(255) NOT NULL default '', + `LinkedMonitors` varchar(255), `Triggers` set('X10') NOT NULL default '', `Device` tinytext NOT NULL default '', `Channel` tinyint(3) unsigned NOT NULL default '0', `Format` int(10) unsigned NOT NULL default '0', `V4LMultiBuffer` tinyint(1) unsigned, `V4LCapturesPerFrame` tinyint(3) unsigned, - `Protocol` varchar(16) NOT NULL default '', + `Protocol` varchar(16), `Method` varchar(16) NOT NULL default '', - `Host` varchar(64) NOT NULL default '', + `Host` varchar(64), `Port` varchar(8) NOT NULL default '', `SubPath` varchar(64) NOT NULL default '', `Path` varchar(255) NOT NULL default '', - `Options` varchar(255) not null default '', - `User` varchar(64) NOT NULL default '', - `Pass` varchar(64) NOT NULL default '', + `Options` varchar(255), + `User` varchar(64), + `Pass` varchar(64), `Width` smallint(5) unsigned NOT NULL default '0', `Height` smallint(5) unsigned NOT NULL default '0', `Colours` tinyint(3) unsigned NOT NULL default '1', @@ -354,13 +354,13 @@ CREATE TABLE `Monitors` ( `VideoWriter` TINYINT NOT NULL DEFAULT '0', `EncoderParameters` TEXT NOT NULL, `RecordAudio` TINYINT NOT NULL DEFAULT '0', - `RTSPDescribe` tinyint(1) unsigned NOT NULL default '0', + `RTSPDescribe` tinyint(1) unsigned, `Brightness` mediumint(7) NOT NULL default '-1', `Contrast` mediumint(7) NOT NULL default '-1', `Hue` mediumint(7) NOT NULL default '-1', `Colour` mediumint(7) NOT NULL default '-1', `EventPrefix` varchar(32) NOT NULL default 'Event-', - `LabelFormat` varchar(64) NOT NULL default '%N - %y/%m/%d %H:%M:%S', + `LabelFormat` varchar(64) default '%N - %y/%m/%d %H:%M:%S', `LabelX` smallint(5) unsigned NOT NULL default '0', `LabelY` smallint(5) unsigned NOT NULL default '0', `LabelSize` smallint(5) unsigned NOT NULL DEFAULT '1', @@ -381,14 +381,14 @@ CREATE TABLE `Monitors` ( `RefBlendPerc` tinyint(3) unsigned NOT NULL default '6', `AlarmRefBlendPerc` tinyint(3) unsigned NOT NULL default '6', `Controllable` tinyint(3) unsigned NOT NULL default '0', - `ControlId` int(10) unsigned NOT NULL default '0', + `ControlId` int(10) unsigned, `ControlDevice` varchar(255) default NULL, `ControlAddress` varchar(255) default NULL, `AutoStopTimeout` decimal(5,2) default NULL, `TrackMotion` tinyint(3) unsigned NOT NULL default '0', - `TrackDelay` smallint(5) unsigned NOT NULL default '0', + `TrackDelay` smallint(5) unsigned, `ReturnLocation` tinyint(3) NOT NULL default '-1', - `ReturnDelay` smallint(5) unsigned NOT NULL default '0', + `ReturnDelay` smallint(5) unsigned, `DefaultView` enum('Events','Control') NOT NULL default 'Events', `DefaultRate` smallint(5) unsigned NOT NULL default '100', `DefaultScale` smallint(5) unsigned NOT NULL default '100', @@ -477,7 +477,7 @@ CREATE TABLE `Users` ( `Id` int(10) unsigned NOT NULL auto_increment, `Username` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', `Password` varchar(64) NOT NULL default '', - `Language` varchar(8) NOT NULL default '', + `Language` varchar(8), `Enabled` tinyint(3) unsigned NOT NULL default '1', `Stream` enum('None','View') NOT NULL default 'None', `Events` enum('None','View','Edit') NOT NULL default 'None', @@ -486,8 +486,8 @@ CREATE TABLE `Users` ( `Groups` enum('None','View','Edit') NOT NULL default 'None', `Devices` enum('None','View','Edit') NOT NULL default 'None', `System` enum('None','View','Edit') NOT NULL default 'None', - `MaxBandwidth` varchar(16) NOT NULL default '', - `MonitorIds` tinytext NOT NULL, + `MaxBandwidth` varchar(16), + `MonitorIds` tinytext, PRIMARY KEY (`Id`), UNIQUE KEY `UC_Username` (`Username`) ) ENGINE=@ZM_MYSQL_ENGINE@; From f40c8d0da876f78dc687cb26605871c4885d92af Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 20 Sep 2016 15:54:37 -0400 Subject: [PATCH 2/4] contains due to glob --- scripts/zmaudit.pl.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index ca4430c22..b1004d81d 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -206,11 +206,11 @@ MAIN: while( $loop ) { Debug( "Checking day dir $day_dir" ); ( $day_dir ) = ( $day_dir =~ /^(.*)$/ ); # De-taint if ( ! chdir( $day_dir ) ) { - Error( "Can't chdir to '$$Storage{Path}/$monitor_dir/$day_dir': $!" ); + Error( "Can't chdir to '$$Storage{Path}/$day_dir': $!" ); next; } if ( ! opendir( DIR, '.' ) ) { - Error( "Can't open directory $$Storage{Path}/$monitor_dir/'$day_dir': $!" ); + Error( "Can't open directory '$$Storage{Path}/$day_dir': $!" ); next; } my @event_links = sort { $b <=> $a } grep { -l $_ } readdir( DIR ); @@ -237,7 +237,7 @@ MAIN: while( $loop ) { Debug( "Checking link $event_link points to $event_path " ); my $Event = $fs_events->{$event} = new ZoneMinder::Event(); $$Event{Id} = $event; - $$Event{Path} = join('/', $Storage->Path(), $monitor_dir,$day_dir,$event_path); + $$Event{Path} = join('/', $Storage->Path(), $day_dir,$event_path); $Event->MonitorId( $monitor_dir ); $Event->StorageId( $Storage->Id() ); } # event path exists From 364a80fb94a821039ff18826f2adcaf97415fa9c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 20 Sep 2016 15:55:28 -0400 Subject: [PATCH 3/4] don't output jpeg header unless there is some kind of success --- web/views/image.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/web/views/image.php b/web/views/image.php index 17de2ec81..bce07e765 100644 --- a/web/views/image.php +++ b/web/views/image.php @@ -39,8 +39,6 @@ if ( !canView( 'Events' ) ) { require_once('includes/Event.php'); require_once('includes/Frame.php'); -header( 'Content-type: image/jpeg' ); - // Compatibility for PHP 5.4 if (!function_exists('imagescale')) { function imagescale($image, $new_width, $new_height = -1, $mode = 0) { @@ -85,6 +83,10 @@ if ( empty($_REQUEST['path']) ) { $retval = 0; exec( $command, $output, $retval ); Debug("Retval: $retval, output: " . implode("\n", $output)); + if ( ! file_exists( $path ) ) { + header("HTTP/1.0 404 Not Found"); + Fatal("Can't create frame images from video for this event (".$Event->DefaultVideo() ); + } } else { header("HTTP/1.0 404 Not Found"); Fatal("Can't create frame images from video becuase there is no video file for this event (".$Event->DefaultVideo() ); @@ -138,6 +140,8 @@ if( !empty($_REQUEST['height']) ) { } +header( 'Content-type: image/jpeg' ); + if ( $errorText ) { Error( $errorText ); } else { @@ -167,13 +171,8 @@ if ( $errorText ) { # Slight optimisation, thumbnails always specify width and height, so we can cache them. $scaled_path = preg_replace('/\.jpg$/', "-${width}x${height}.jpg", $path ); - if ( file_exists( $scaled_path ) ) { - Debug( "Using cached scaled image at $scaled_path."); - if ( ! readfile( $scaled_path ) ) { - Error("No bytes read from scaled image". $scaled_path ); - } - } else { - Debug( "Cached scaled image does not exist at $scaled_path. Creating it"); + if ( ! file_exists( $scaled_path ) or ! readfile( $scaled_path ) ) { + Debug( "Cached scaled image does not exist at $scaled_path or is no good.. Creating it"); ob_start(); if ( ! $i ) $i = imagecreatefromjpeg( $path ); From 19a60b01da16e23fa87500a693f8cf6655099c77 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 20 Sep 2016 16:59:43 -0400 Subject: [PATCH 4/4] maybe fixes, maybe big memleaks --- src/zm_ffmpeg_camera.cpp | 9 +++++---- src/zm_packetqueue.cpp | 14 +++++++++++--- src/zm_packetqueue.h | 1 + src/zm_videostore.cpp | 20 +++++++++++++++++--- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index d04aca2db..bd72ae3a9 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -167,7 +167,7 @@ int FfmpegCamera::Capture( Image &image ) Error( "Unable to read packet from stream %d: error %d \"%s\".", packet.stream_index, avResult, errbuf ); return( -1 ); } - Debug( 5, "Got packet from stream %d", packet.stream_index ); + Debug( 5, "Got packet from stream %d dts (%d) pts(%d)", packet.stream_index, packet.pts, packet.dts ); // What about audio stream? Maybe someday we could do sound detection... if ( packet.stream_index == mVideoStreamId ) { #if LIBAVCODEC_VERSION_CHECK(52, 23, 0, 23, 0) @@ -290,7 +290,6 @@ int FfmpegCamera::OpenFfmpeg() { Debug ( 1, "Opened input" ); Info( "Stream open %s", mPath.c_str() ); - startTime=av_gettime();//FIXME here or after find_Stream_info //FIXME can speed up initial analysis but need sensible parameters... //mFormatContext->probesize = 32; @@ -305,6 +304,7 @@ int FfmpegCamera::OpenFfmpeg() { #endif Fatal( "Unable to find stream info from %s due to: %s", mPath.c_str(), strerror(errno) ); + startTime=av_gettime();//FIXME here or after find_Stream_info Debug ( 1, "Got stream info" ); // Find first video stream present @@ -584,7 +584,7 @@ Debug(5, "After av_read_frame (%d)", ret ); Error( "Unable to read packet from stream %d: error %d \"%s\".", packet->stream_index, ret, errbuf ); return( -1 ); } - Debug( 5, "Got packet from stream %d", packet->stream_index ); + Debug( 4, "Got packet from stream %d dts (%d) pts(%d)", packet->stream_index, packet->dts, packet->pts ); //Video recording if ( recording ) { @@ -636,7 +636,7 @@ Debug(5, "After av_read_frame (%d)", ret ); while ( ( queued_packet = packetqueue.popPacket() ) ) { packet_count += 1; //Write the packet to our video store - Debug(2, "Writing queued packet stream: %d KEY %d", queued_packet->stream_index, packet->flags & AV_PKT_FLAG_KEY ); + Debug(2, "Writing queued packet stream: %d KEY %d, remaining (%d)", queued_packet->stream_index, packet->flags & AV_PKT_FLAG_KEY, packetqueue.size() ); if ( queued_packet->stream_index == mVideoStreamId ) { ret = videoStore->writeVideoFramePacket( queued_packet, mFormatContext->streams[mVideoStreamId]); } else if ( queued_packet->stream_index == mAudioStreamId ) { @@ -748,6 +748,7 @@ Debug(5, "After av_read_frame (%d)", ret ); Debug( 3, "Some other stream index %d", packet->stream_index ); #endif } + if ( videoStore ) zm_av_unref_packet( packet ); } // end while ! frameComplete return (frameCount); diff --git a/src/zm_packetqueue.cpp b/src/zm_packetqueue.cpp index 42a74af98..5758e8871 100644 --- a/src/zm_packetqueue.cpp +++ b/src/zm_packetqueue.cpp @@ -37,10 +37,14 @@ bool zm_packetqueue::queuePacket( AVPacket* packet ) { //AVPacket *input_ref = (AVPacket *)av_malloc(sizeof(AVPacket)); //if ( av_packet_ref( input_ref, packet ) < 0 ) { - //free(input_ref); - //return false; - //} + if ( av_packet_ref( packet, packet ) < 0 ) { +Error("error refing packet"); + //av_free_packet(input_ref); + return false; + } + pktQueue.push( packet ); + //pktQueue.push( input_ref ); return true; } @@ -66,3 +70,7 @@ void zm_packetqueue::clearQueue() { zm_av_unref_packet( packet ); } } + +unsigned int zm_packetqueue::size() { + return pktQueue.size(); +} diff --git a/src/zm_packetqueue.h b/src/zm_packetqueue.h index f79502996..60a9620a4 100644 --- a/src/zm_packetqueue.h +++ b/src/zm_packetqueue.h @@ -38,6 +38,7 @@ public: bool popVideoPacket(AVPacket* packet); bool popAudioPacket(AVPacket* packet); void clearQueue( ); + unsigned int size(); private: std::queue pktQueue; diff --git a/src/zm_videostore.cpp b/src/zm_videostore.cpp index 311318a90..95dc9dd7f 100644 --- a/src/zm_videostore.cpp +++ b/src/zm_videostore.cpp @@ -274,6 +274,7 @@ Debug(2, "Have audio_output_context"); startDts = 0; filter_in_rescale_delta_last = AV_NOPTS_VALUE; + // now - when streaming started startTime=av_gettime()-nStartTime;//oc->start_time; Info("VideoStore startTime=%d\n",startTime); } // VideoStore::VideoStore @@ -342,26 +343,39 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt, AVStream *input_video_stre Debug(2, "writeVideoFrame init_packet"); av_init_packet(&opkt); +if ( 1 ) { + if ( ! startPts ) { + //never gets set, so the first packet can set it. + startPts = ipkt->pts; + } //Scale the PTS of the outgoing packet to be the correct time base if (ipkt->pts != AV_NOPTS_VALUE) { - opkt.pts = av_rescale_q(ipkt->pts-startPts, input_video_stream->time_base, video_stream->time_base) - ost_tb_start_time; + opkt.pts = av_rescale_q(ipkt->pts-startPts, input_video_stream->time_base, video_stream->time_base); + //- ost_tb_start_time; Debug(3, "opkt.pts = %d from ipkt->pts(%d) - startPts(%d), input->time_base(%d) video_stream->time-base(%d)", opkt.pts, ipkt->pts, startPts, input_video_stream->time_base, video_stream->time_base ); } else { + Debug(3, "opkt.pts = undef"); opkt.pts = AV_NOPTS_VALUE; } + if ( ! startDts ) { + startDts = input_video_stream->cur_dts; +} //Scale the DTS of the outgoing packet to be the correct time base if(ipkt->dts == AV_NOPTS_VALUE) { opkt.dts = av_rescale_q(input_video_stream->cur_dts-startDts, AV_TIME_BASE_Q, video_stream->time_base); - Debug(3, "opkt.dts = %d from input_video_stream->cur_dts(%d) - startDts(%d), video_stream->time-base(%d)", opkt.dts, input_video_stream->cur_dts, startDts, video_stream->time_base ); + Debug(3, "opkt.dts = %d from input_video_stream->cur_dts(%d) - startDts(%d), video_stream->time-base(%d)", opkt.dts, input_video_stream->cur_dts, startDts, video_stream->time_base ); } else { opkt.dts = av_rescale_q(ipkt->dts-startDts, input_video_stream->time_base, video_stream->time_base); Debug(3, "opkt.dts = %d from ipkt->dts(%d) - startDts(%d), video_stream->time-base(%d)", opkt.dts, ipkt->dts, startDts, video_stream->time_base ); } - opkt.dts -= ost_tb_start_time; + //opkt.dts -= ost_tb_start_time; opkt.duration = av_rescale_q(ipkt->duration, input_video_stream->time_base, video_stream->time_base); +} else { + av_packet_rescale_ts( &opkt, input_video_stream->time_base, video_stream->time_base ); +} opkt.flags = ipkt->flags; opkt.pos=-1;