add mjpeg support
This commit is contained in:
parent
bafdf1fdfc
commit
56bb2205d8
|
@ -386,7 +386,7 @@ CREATE TABLE `Monitors` (
|
||||||
`SaveJPEGs` TINYINT NOT NULL DEFAULT '3' ,
|
`SaveJPEGs` TINYINT NOT NULL DEFAULT '3' ,
|
||||||
`VideoWriter` TINYINT NOT NULL DEFAULT '0',
|
`VideoWriter` TINYINT NOT NULL DEFAULT '0',
|
||||||
`OutputCodec` enum('h264','mjpeg','mpeg1','mpeg2'),
|
`OutputCodec` enum('h264','mjpeg','mpeg1','mpeg2'),
|
||||||
`OutputContainer` enum('mp4','mkv'),
|
`OutputContainer` enum('auto','mp4','mkv'),
|
||||||
`EncoderParameters` TEXT,
|
`EncoderParameters` TEXT,
|
||||||
`RecordAudio` TINYINT NOT NULL DEFAULT '0',
|
`RecordAudio` TINYINT NOT NULL DEFAULT '0',
|
||||||
`RTSPDescribe` tinyint(1) unsigned,
|
`RTSPDescribe` tinyint(1) unsigned,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
ALTER TABLE `Monitors` MODIFY `OutputCodec` enum('h264','mjpeg','mpeg1','mpeg2')
|
ALTER TABLE `Monitors` MODIFY `OutputCodec` enum('h264','mjpeg','mpeg1','mpeg2') default 'h264';
|
||||||
|
ALTER TABLE `Monitors` MODIFY `OutputContainer` enum('auto','mp4','mkv') default 'auto';
|
||||||
|
|
||||||
SET @s = (SELECT IF(
|
SET @s = (SELECT IF(
|
||||||
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
@ -6,7 +7,7 @@ SET @s = (SELECT IF(
|
||||||
AND column_name = 'SaveJPEGs'
|
AND column_name = 'SaveJPEGs'
|
||||||
) > 0,
|
) > 0,
|
||||||
"SELECT 'Column SaveJPEGs already exists in Events'",
|
"SELECT 'Column SaveJPEGs already exists in Events'",
|
||||||
"ALTER TABLE `Eventss` ADD `SaveJPEGs` TINYINT AFTER `DefaultVideo`"
|
"ALTER TABLE `Events` ADD `SaveJPEGs` TINYINT AFTER `DefaultVideo`"
|
||||||
));
|
));
|
||||||
|
|
||||||
PREPARE stmt FROM @s;
|
PREPARE stmt FROM @s;
|
||||||
|
|
|
@ -167,7 +167,16 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
|
||||||
/* Save as video */
|
/* Save as video */
|
||||||
|
|
||||||
if ( monitor->GetOptVideoWriter() != 0 ) {
|
if ( monitor->GetOptVideoWriter() != 0 ) {
|
||||||
snprintf( video_name, sizeof(video_name), "%d-%s", id, "video.mp4" );
|
std::string container = monitor->OutputContainer();
|
||||||
|
if ( container == "auto" || container == "" ) {
|
||||||
|
if ( monitor->OutputCodec() == "h264" ) {
|
||||||
|
container = "mp4";
|
||||||
|
} else {
|
||||||
|
container = "mkv";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf( video_name, sizeof(video_name), "%d-%s.%s", id, "video", container.c_str() );
|
||||||
snprintf( video_file, sizeof(video_file), staticConfig.video_file_format, path, video_name );
|
snprintf( video_file, sizeof(video_file), staticConfig.video_file_format, path, video_name );
|
||||||
Debug(1,"Writing video file to %s", video_file );
|
Debug(1,"Writing video file to %s", video_file );
|
||||||
videowriter = NULL;
|
videowriter = NULL;
|
||||||
|
|
|
@ -243,6 +243,8 @@ Monitor::Monitor(
|
||||||
int p_savejpegs,
|
int p_savejpegs,
|
||||||
VideoWriter p_videowriter,
|
VideoWriter p_videowriter,
|
||||||
std::string p_encoderparams,
|
std::string p_encoderparams,
|
||||||
|
std::string p_output_codec,
|
||||||
|
std::string p_output_container,
|
||||||
bool p_record_audio,
|
bool p_record_audio,
|
||||||
const char *p_event_prefix,
|
const char *p_event_prefix,
|
||||||
const char *p_label_format,
|
const char *p_label_format,
|
||||||
|
@ -282,6 +284,8 @@ Monitor::Monitor(
|
||||||
savejpegspref( p_savejpegs ),
|
savejpegspref( p_savejpegs ),
|
||||||
videowriter( p_videowriter ),
|
videowriter( p_videowriter ),
|
||||||
encoderparams( p_encoderparams ),
|
encoderparams( p_encoderparams ),
|
||||||
|
output_codec( p_output_codec ),
|
||||||
|
output_container( p_output_container ),
|
||||||
record_audio( p_record_audio ),
|
record_audio( p_record_audio ),
|
||||||
label_coord( p_label_coord ),
|
label_coord( p_label_coord ),
|
||||||
label_size( p_label_size ),
|
label_size( p_label_size ),
|
||||||
|
@ -1781,7 +1785,7 @@ void Monitor::ReloadLinkedMonitors( const char *p_linked_monitors ) {
|
||||||
|
|
||||||
#if ZM_HAS_V4L
|
#if ZM_HAS_V4L
|
||||||
int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose ) {
|
int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose ) {
|
||||||
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Function != 'None' and Type = 'Local'";
|
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, OutputCodec, OutputContainer, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Function != 'None' and Type = 'Local'";
|
||||||
;
|
;
|
||||||
if ( device[0] ) {
|
if ( device[0] ) {
|
||||||
sql += " AND Device='";
|
sql += " AND Device='";
|
||||||
|
@ -1846,6 +1850,8 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
|
||||||
int savejpegs = atoi(dbrow[col]); col++;
|
int savejpegs = atoi(dbrow[col]); col++;
|
||||||
VideoWriter videowriter = (VideoWriter)atoi(dbrow[col]); col++;
|
VideoWriter videowriter = (VideoWriter)atoi(dbrow[col]); col++;
|
||||||
std::string encoderparams = dbrow[col] ? dbrow[col] : ""; col++;
|
std::string encoderparams = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
|
std::string output_codec = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
|
std::string output_container = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
bool record_audio = (*dbrow[col] != '0'); col++;
|
bool record_audio = (*dbrow[col] != '0'); col++;
|
||||||
|
|
||||||
int brightness = atoi(dbrow[col]); col++;
|
int brightness = atoi(dbrow[col]); col++;
|
||||||
|
@ -1923,6 +1929,8 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
|
||||||
savejpegs,
|
savejpegs,
|
||||||
videowriter,
|
videowriter,
|
||||||
encoderparams,
|
encoderparams,
|
||||||
|
output_codec,
|
||||||
|
output_container,
|
||||||
record_audio,
|
record_audio,
|
||||||
event_prefix,
|
event_prefix,
|
||||||
label_format,
|
label_format,
|
||||||
|
@ -1970,7 +1978,7 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
|
||||||
#endif // ZM_HAS_V4L
|
#endif // ZM_HAS_V4L
|
||||||
|
|
||||||
int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose ) {
|
int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose ) {
|
||||||
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'";
|
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, OutputCodec, OutputContainer, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'";
|
||||||
if ( staticConfig.SERVER_ID ) {
|
if ( staticConfig.SERVER_ID ) {
|
||||||
sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID );
|
sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID );
|
||||||
}
|
}
|
||||||
|
@ -2016,6 +2024,8 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
|
||||||
int savejpegs = atoi(dbrow[col]); col++;
|
int savejpegs = atoi(dbrow[col]); col++;
|
||||||
VideoWriter videowriter = (VideoWriter)atoi(dbrow[col]); col++;
|
VideoWriter videowriter = (VideoWriter)atoi(dbrow[col]); col++;
|
||||||
std::string encoderparams = dbrow[col] ? dbrow[col] : ""; col++;
|
std::string encoderparams = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
|
std::string output_codec = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
|
std::string output_container = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
bool record_audio = (*dbrow[col] != '0'); col++;
|
bool record_audio = (*dbrow[col] != '0'); col++;
|
||||||
|
|
||||||
int brightness = atoi(dbrow[col]); col++;
|
int brightness = atoi(dbrow[col]); col++;
|
||||||
|
@ -2107,6 +2117,8 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
|
||||||
savejpegs,
|
savejpegs,
|
||||||
videowriter,
|
videowriter,
|
||||||
encoderparams,
|
encoderparams,
|
||||||
|
output_codec,
|
||||||
|
output_container,
|
||||||
record_audio,
|
record_audio,
|
||||||
event_prefix,
|
event_prefix,
|
||||||
label_format,
|
label_format,
|
||||||
|
@ -2153,7 +2165,7 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
|
||||||
}
|
}
|
||||||
|
|
||||||
int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose ) {
|
int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose ) {
|
||||||
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'File'";
|
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, OutputCodec, OutputContainer, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'File'";
|
||||||
if ( file[0] ) {
|
if ( file[0] ) {
|
||||||
sql += " AND Path='";
|
sql += " AND Path='";
|
||||||
sql += file;
|
sql += file;
|
||||||
|
@ -2195,6 +2207,8 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu
|
||||||
int savejpegs = atoi(dbrow[col]); col++;
|
int savejpegs = atoi(dbrow[col]); col++;
|
||||||
VideoWriter videowriter = (VideoWriter)atoi(dbrow[col]); col++;
|
VideoWriter videowriter = (VideoWriter)atoi(dbrow[col]); col++;
|
||||||
std::string encoderparams = dbrow[col]; col++;
|
std::string encoderparams = dbrow[col]; col++;
|
||||||
|
std::string output_codec = dbrow[col]; col++;
|
||||||
|
std::string output_container = dbrow[col]; col++;
|
||||||
bool record_audio = (*dbrow[col] != '0'); col++;
|
bool record_audio = (*dbrow[col] != '0'); col++;
|
||||||
|
|
||||||
int brightness = atoi(dbrow[col]); col++;
|
int brightness = atoi(dbrow[col]); col++;
|
||||||
|
@ -2256,6 +2270,8 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu
|
||||||
savejpegs,
|
savejpegs,
|
||||||
videowriter,
|
videowriter,
|
||||||
encoderparams,
|
encoderparams,
|
||||||
|
output_codec,
|
||||||
|
output_container,
|
||||||
record_audio,
|
record_audio,
|
||||||
event_prefix,
|
event_prefix,
|
||||||
label_format,
|
label_format,
|
||||||
|
@ -2303,7 +2319,7 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu
|
||||||
|
|
||||||
#if HAVE_LIBAVFORMAT
|
#if HAVE_LIBAVFORMAT
|
||||||
int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose purpose ) {
|
int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose purpose ) {
|
||||||
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Method, Options, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Ffmpeg'";
|
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Method, Options, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, OutputCodec, OutputContainer, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Ffmpeg'";
|
||||||
if ( file[0] ) {
|
if ( file[0] ) {
|
||||||
sql += " AND Path = '";
|
sql += " AND Path = '";
|
||||||
sql += file;
|
sql += file;
|
||||||
|
@ -2348,6 +2364,8 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
|
||||||
int savejpegs = atoi(dbrow[col]); col++;
|
int savejpegs = atoi(dbrow[col]); col++;
|
||||||
VideoWriter videowriter = (VideoWriter)atoi(dbrow[col]); col++;
|
VideoWriter videowriter = (VideoWriter)atoi(dbrow[col]); col++;
|
||||||
std::string encoderparams = dbrow[col] ? dbrow[col] : ""; col++;
|
std::string encoderparams = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
|
std::string output_codec = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
|
std::string output_container = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
bool record_audio = (*dbrow[col] != '0'); col++;
|
bool record_audio = (*dbrow[col] != '0'); col++;
|
||||||
|
|
||||||
int brightness = atoi(dbrow[col]); col++;
|
int brightness = atoi(dbrow[col]); col++;
|
||||||
|
@ -2415,6 +2433,8 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
|
||||||
savejpegs,
|
savejpegs,
|
||||||
videowriter,
|
videowriter,
|
||||||
encoderparams,
|
encoderparams,
|
||||||
|
output_codec,
|
||||||
|
output_container,
|
||||||
record_audio,
|
record_audio,
|
||||||
event_prefix,
|
event_prefix,
|
||||||
label_format,
|
label_format,
|
||||||
|
@ -2463,7 +2483,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
|
||||||
#endif // HAVE_LIBAVFORMAT
|
#endif // HAVE_LIBAVFORMAT
|
||||||
|
|
||||||
Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose ) {
|
Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose ) {
|
||||||
std::string sql = stringtf( "select Id, Name, ServerId, StorageId, 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, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", p_id );
|
std::string sql = stringtf( "select Id, Name, ServerId, StorageId, 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, SaveJPEGs, VideoWriter, EncoderParameters, OutputCodec, OutputContainer, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", p_id );
|
||||||
|
|
||||||
zmDbRow dbrow;
|
zmDbRow dbrow;
|
||||||
if ( ! dbrow.fetch( sql.c_str() ) ) {
|
if ( ! dbrow.fetch( sql.c_str() ) ) {
|
||||||
|
@ -2523,7 +2543,9 @@ Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose ) {
|
||||||
bool rtsp_describe = (dbrow[col] && *dbrow[col] != '0'); col++;
|
bool rtsp_describe = (dbrow[col] && *dbrow[col] != '0'); col++;
|
||||||
int savejpegs = atoi(dbrow[col]); col++;
|
int savejpegs = atoi(dbrow[col]); col++;
|
||||||
VideoWriter videowriter = (VideoWriter)atoi(dbrow[col]); col++;
|
VideoWriter videowriter = (VideoWriter)atoi(dbrow[col]); col++;
|
||||||
std::string encoderparams = dbrow[col] ? dbrow[col] : ""; col++;
|
std::string encoderparams = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
|
std::string output_codec = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
|
std::string output_container = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
bool record_audio = (*dbrow[col] != '0'); col++;
|
bool record_audio = (*dbrow[col] != '0'); col++;
|
||||||
|
|
||||||
int brightness = atoi(dbrow[col]); col++;
|
int brightness = atoi(dbrow[col]); col++;
|
||||||
|
@ -2742,6 +2764,8 @@ Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose ) {
|
||||||
savejpegs,
|
savejpegs,
|
||||||
videowriter,
|
videowriter,
|
||||||
encoderparams,
|
encoderparams,
|
||||||
|
output_codec,
|
||||||
|
output_container,
|
||||||
record_audio,
|
record_audio,
|
||||||
event_prefix,
|
event_prefix,
|
||||||
label_format,
|
label_format,
|
||||||
|
|
|
@ -166,6 +166,8 @@ protected:
|
||||||
VideoStore *videoStore;
|
VideoStore *videoStore;
|
||||||
zm_packetqueue packetqueue;
|
zm_packetqueue packetqueue;
|
||||||
Mutex mutex;
|
Mutex mutex;
|
||||||
|
std::string output_codec;
|
||||||
|
std::string output_container;
|
||||||
|
|
||||||
class MonitorLink {
|
class MonitorLink {
|
||||||
protected:
|
protected:
|
||||||
|
@ -346,6 +348,8 @@ public:
|
||||||
int p_savejpegs,
|
int p_savejpegs,
|
||||||
VideoWriter p_videowriter,
|
VideoWriter p_videowriter,
|
||||||
std::string p_encoderparams,
|
std::string p_encoderparams,
|
||||||
|
std::string p_output_codec,
|
||||||
|
std::string p_output_container,
|
||||||
bool p_record_audio,
|
bool p_record_audio,
|
||||||
const char *p_event_prefix,
|
const char *p_event_prefix,
|
||||||
const char *p_label_format,
|
const char *p_label_format,
|
||||||
|
@ -431,6 +435,8 @@ public:
|
||||||
VideoWriter GetOptVideoWriter() const { return( videowriter ); }
|
VideoWriter GetOptVideoWriter() const { return( videowriter ); }
|
||||||
const std::vector<EncoderParameter_t>* GetOptEncoderParams() const { return( &encoderparamsvec ); }
|
const std::vector<EncoderParameter_t>* GetOptEncoderParams() const { return( &encoderparamsvec ); }
|
||||||
const std::string &GetEncoderOptions() const { return( encoderparams ); }
|
const std::string &GetEncoderOptions() const { return( encoderparams ); }
|
||||||
|
const std::string &OutputCodec() const { return output_codec; }
|
||||||
|
const std::string &OutputContainer() const { return output_container; }
|
||||||
|
|
||||||
uint32_t GetLastEventId() const { return shared_data->last_event_id; }
|
uint32_t GetLastEventId() const { return shared_data->last_event_id; }
|
||||||
uint32_t GetVideoWriterEventId() const { return video_store_data->current_event; }
|
uint32_t GetVideoWriterEventId() const { return video_store_data->current_event; }
|
||||||
|
|
|
@ -129,78 +129,95 @@ Debug(2,"About to copy aparames");
|
||||||
Error("Could not allocate in frame");
|
Error("Could not allocate in frame");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
video_out_codec = avcodec_find_encoder_by_name("h264_omx");
|
video_out_ctx = avcodec_alloc_context3( video_out_codec );
|
||||||
if ( ! video_out_codec ) {
|
// Don't have an input stream, so need to tell it what we are sending it, or are transcoding
|
||||||
Debug(1, "Didn't find omx");
|
video_out_ctx->width = monitor->Width();
|
||||||
video_out_codec = avcodec_find_encoder(AV_CODEC_ID_H264);
|
video_out_ctx->height = monitor->Height();
|
||||||
}
|
video_out_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||||
if ( !video_out_codec ) {
|
|
||||||
Fatal("Could not find codec for H264");
|
|
||||||
}
|
|
||||||
Debug(2, "Have video out codec");
|
|
||||||
|
|
||||||
video_out_ctx = avcodec_alloc_context3( video_out_codec );
|
if ( monitor->OutputCodec() == "mjpeg" ) {
|
||||||
// Don't have an input stream, so need to tell it what we are sending it, or are transcoding
|
video_out_codec = avcodec_find_encoder_by_name("mjpeg");
|
||||||
video_out_ctx->width = monitor->Width();
|
|
||||||
video_out_ctx->height = monitor->Height();
|
|
||||||
video_out_ctx->codec_id = AV_CODEC_ID_H264;
|
|
||||||
video_out_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
|
|
||||||
//video_in_ctx->sample_aspect_ratio;
|
|
||||||
/* take first format from list of supported formats */
|
|
||||||
//video_out_ctx->pix_fmt = video_out_codec->pix_fmts[0];
|
|
||||||
video_out_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
|
|
||||||
/* video time_base can be set to whatever is handy and supported by encoder */
|
|
||||||
video_out_ctx->time_base = (AVRational){1, 1000000}; // microseconds as base frame rate
|
|
||||||
video_out_ctx->framerate = (AVRational){0,1}; // Unknown framerate
|
|
||||||
video_out_ctx->gop_size = 12;
|
|
||||||
video_out_ctx->bit_rate = 4000000;
|
|
||||||
video_out_ctx->qmin = 10;
|
|
||||||
video_out_ctx->qmax = 51;
|
|
||||||
video_out_ctx->qcompress = 0.6;
|
|
||||||
|
|
||||||
AVDictionary *opts = 0;
|
|
||||||
std::string Options = monitor->GetEncoderOptions();
|
|
||||||
ret = av_dict_parse_string(&opts, Options.c_str(), "=", ",#\n", 0);
|
|
||||||
if ( ret < 0 ) {
|
|
||||||
Warning("Could not parse ffmpeg encoder options list '%s'\n", Options.c_str());
|
|
||||||
} else {
|
|
||||||
AVDictionaryEntry *e = NULL;
|
|
||||||
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
|
|
||||||
Debug( 3, "Encoder Option %s=%s", e->key, e->value );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! av_dict_get( opts, "preset", NULL, 0 ) ) {
|
|
||||||
Debug(2,"Setting preset to superfast");
|
|
||||||
av_dict_set( &opts, "preset", "superfast", 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (ret = avcodec_open2(video_out_ctx, video_out_codec, &opts)) < 0 ) {
|
|
||||||
Warning("Can't open video codec (%s)! %s, trying h264",
|
|
||||||
video_out_codec->name,
|
|
||||||
av_make_error_string(ret).c_str()
|
|
||||||
);
|
|
||||||
video_out_codec = avcodec_find_encoder_by_name("h264");
|
|
||||||
if ( ! video_out_codec ) {
|
if ( ! video_out_codec ) {
|
||||||
Error("Can't find h264 encoder");
|
Debug(1, "Didn't find omx");
|
||||||
video_out_codec = avcodec_find_encoder_by_name("libx264");
|
video_out_codec = avcodec_find_encoder(AV_CODEC_ID_MJPEG);
|
||||||
|
}
|
||||||
|
video_out_ctx->codec_id = video_out_codec->id;
|
||||||
|
video_out_ctx->pix_fmt = AV_PIX_FMT_YUVJ422P;
|
||||||
|
|
||||||
|
} else if ( monitor->OutputCodec() == "h264" ) {
|
||||||
|
video_out_codec = avcodec_find_encoder_by_name("h264_omx");
|
||||||
|
if ( ! video_out_codec ) {
|
||||||
|
Debug(1, "Didn't find omx");
|
||||||
|
video_out_codec = avcodec_find_encoder(AV_CODEC_ID_H264);
|
||||||
|
}
|
||||||
|
if ( !video_out_codec ) {
|
||||||
|
Fatal("Could not find codec for H264");
|
||||||
|
}
|
||||||
|
Debug(2, "Have video out codec");
|
||||||
|
|
||||||
|
video_out_ctx->codec_id = AV_CODEC_ID_H264;
|
||||||
|
//video_in_ctx->sample_aspect_ratio;
|
||||||
|
/* take first format from list of supported formats */
|
||||||
|
//video_out_ctx->pix_fmt = video_out_codec->pix_fmts[0];
|
||||||
|
video_out_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||||
|
/* video time_base can be set to whatever is handy and supported by encoder */
|
||||||
|
video_out_ctx->time_base = (AVRational){1, 1000000}; // microseconds as base frame rate
|
||||||
|
video_out_ctx->framerate = (AVRational){0,1}; // Unknown framerate
|
||||||
|
video_out_ctx->gop_size = 12;
|
||||||
|
video_out_ctx->bit_rate = 4000000;
|
||||||
|
video_out_ctx->qmin = 10;
|
||||||
|
video_out_ctx->qmax = 51;
|
||||||
|
video_out_ctx->qcompress = 0.6;
|
||||||
|
|
||||||
|
AVDictionary *opts = 0;
|
||||||
|
std::string Options = monitor->GetEncoderOptions();
|
||||||
|
ret = av_dict_parse_string(&opts, Options.c_str(), "=", ",#\n", 0);
|
||||||
|
if ( ret < 0 ) {
|
||||||
|
Warning("Could not parse ffmpeg encoder options list '%s'\n", Options.c_str());
|
||||||
|
} else {
|
||||||
|
AVDictionaryEntry *e = NULL;
|
||||||
|
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
|
||||||
|
Debug( 3, "Encoder Option %s=%s", e->key, e->value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! av_dict_get( opts, "preset", NULL, 0 ) ) {
|
||||||
|
Debug(2,"Setting preset to ultrafast");
|
||||||
|
av_dict_set( &opts, "preset", "ultrafast", 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ret = avcodec_open2(video_out_ctx, video_out_codec, &opts)) < 0 ) {
|
||||||
|
Warning("Can't open video codec (%s)! %s, trying h264",
|
||||||
|
video_out_codec->name,
|
||||||
|
av_make_error_string(ret).c_str()
|
||||||
|
);
|
||||||
|
video_out_codec = avcodec_find_encoder_by_name("h264");
|
||||||
if ( ! video_out_codec ) {
|
if ( ! video_out_codec ) {
|
||||||
Error("Can't find libx264 encoder");
|
Error("Can't find h264 encoder");
|
||||||
|
video_out_codec = avcodec_find_encoder_by_name("libx264");
|
||||||
|
if ( ! video_out_codec ) {
|
||||||
|
Error("Can't find libx264 encoder");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( (ret = avcodec_open2(video_out_ctx, video_out_codec, &opts)) < 0 ) {
|
||||||
|
Error("Can't open video codec (%s)! %s",
|
||||||
|
video_out_codec->name,
|
||||||
|
av_make_error_string(ret).c_str() );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( (ret = avcodec_open2(video_out_ctx, video_out_codec, &opts)) < 0 ) {
|
AVDictionaryEntry *e = NULL;
|
||||||
Error("Can't open video codec (%s)! %s",
|
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
|
||||||
video_out_codec->name,
|
Warning( "Encoder Option %s not recognized by ffmpeg codec", e->key);
|
||||||
av_make_error_string(ret).c_str() );
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
av_dict_free(&opts);
|
||||||
AVDictionaryEntry *e = NULL;
|
if ( !video_out_ctx->codec_tag ) {
|
||||||
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
|
video_out_ctx->codec_tag =
|
||||||
Warning( "Encoder Option %s not recognized by ffmpeg codec", e->key);
|
av_codec_get_tag(oc->oformat->codec_tag, AV_CODEC_ID_H264 );
|
||||||
}
|
Debug(2, "No codec_tag, setting to %d", video_out_ctx->codec_tag);
|
||||||
av_dict_free(&opts);
|
}
|
||||||
|
}// end if codec == h264
|
||||||
|
|
||||||
swscale.SetDefaults(
|
swscale.SetDefaults(
|
||||||
video_in_ctx->pix_fmt,
|
video_in_ctx->pix_fmt,
|
||||||
|
@ -210,11 +227,6 @@ Debug(2,"About to copy aparames");
|
||||||
);
|
);
|
||||||
} // end if copying or trasncoding
|
} // end if copying or trasncoding
|
||||||
|
|
||||||
if ( !video_out_ctx->codec_tag ) {
|
|
||||||
video_out_ctx->codec_tag =
|
|
||||||
av_codec_get_tag(oc->oformat->codec_tag, AV_CODEC_ID_H264 );
|
|
||||||
Debug(2, "No codec_tag, setting to %d", video_out_ctx->codec_tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
video_out_stream = avformat_new_stream(oc, video_out_codec);
|
video_out_stream = avformat_new_stream(oc, video_out_codec);
|
||||||
if ( !video_out_stream ) {
|
if ( !video_out_stream ) {
|
||||||
|
|
|
@ -326,7 +326,7 @@ function changeGroup( e, depth ) {
|
||||||
}
|
}
|
||||||
function changeMonitor( e ) {
|
function changeMonitor( e ) {
|
||||||
var monitor_id = e.value;
|
var monitor_id = e.value;
|
||||||
Cookie.write( 'zmMonitorId', monitor_id, { duration: 10*365 } );
|
Cookie.write( 'MonitorId', monitor_id, { duration: 10*365 } );
|
||||||
window.location = window.location;
|
window.location = window.location;
|
||||||
}
|
}
|
||||||
function changeFilter( e ) {
|
function changeFilter( e ) {
|
||||||
|
|
|
@ -97,12 +97,17 @@ $groupSql = Group::get_group_sql( $group_id );
|
||||||
$monitors_dropdown[$monitors[$i]['Id']] = $monitors[$i]['Name'];
|
$monitors_dropdown[$monitors[$i]['Id']] = $monitors[$i]['Name'];
|
||||||
if ( $monitors[$i]['Id'] == $monitor_id ) {
|
if ( $monitors[$i]['Id'] == $monitor_id ) {
|
||||||
$found_selected_monitor = true;
|
$found_selected_monitor = true;
|
||||||
|
} else {
|
||||||
|
Warning("didn't find monitor $monitor_id " . $monitors[$i]['Id'] );
|
||||||
}
|
}
|
||||||
}
|
} // end foreach monitor
|
||||||
if ( ! $found_selected_monitor ) {
|
if ( ! $found_selected_monitor ) {
|
||||||
$monitor_id = '';
|
$monitor_id = '';
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
Warning("Monitor id not specified");
|
||||||
|
} // end if a monitor was specified
|
||||||
|
|
||||||
for ( $i = 0; $i < count($monitors); $i++ ) {
|
for ( $i = 0; $i < count($monitors); $i++ ) {
|
||||||
if ( !visibleMonitor( $monitors[$i]['Id'] ) ) {
|
if ( !visibleMonitor( $monitors[$i]['Id'] ) ) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -114,7 +119,7 @@ $groupSql = Group::get_group_sql( $group_id );
|
||||||
}
|
}
|
||||||
$displayMonitors[] = $monitors[$i];
|
$displayMonitors[] = $monitors[$i];
|
||||||
}
|
}
|
||||||
echo htmlSelect( 'MonitorId', $monitors_dropdown, $monitor_id, array('onchange'=>'changeMonitor(this);') );
|
echo htmlSelect( 'MonitorId', $monitors_dropdown, $monitor_id, array('onchange'=>'changeFilter(this);') );
|
||||||
?>
|
?>
|
||||||
</span>
|
</span>
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -74,6 +74,10 @@ if ( ( ! $replayMode ) or ( ! $replayModes[$replayMode] ) ) {
|
||||||
$replayMode = 'none';
|
$replayMode = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$video_tag = false;
|
||||||
|
if ( $Event->DefaultVideo() and ( 'mp4' == pathinfo($Event->DefaultVideo(), PATHINFO_EXTENSION) ) ) {
|
||||||
|
$video_tag = true;
|
||||||
|
}
|
||||||
// videojs zoomrotate only when direct recording
|
// videojs zoomrotate only when direct recording
|
||||||
$Zoom = 1;
|
$Zoom = 1;
|
||||||
$Rotation = 0;
|
$Rotation = 0;
|
||||||
|
@ -150,7 +154,7 @@ if ( $Event->SaveJPEGs() & 3 ) { // Analysis or Jpegs
|
||||||
<div id="exportEvent"><a href="#" onclick="exportEvent();"><?php echo translate('Export') ?></a></div>
|
<div id="exportEvent"><a href="#" onclick="exportEvent();"><?php echo translate('Export') ?></a></div>
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
if ( $Event->DefaultVideo() ) {
|
if ( $video_tag ) {
|
||||||
?>
|
?>
|
||||||
<div id="eventVideo" class="">
|
<div id="eventVideo" class="">
|
||||||
<div id="videoFeed">
|
<div id="videoFeed">
|
||||||
|
@ -170,7 +174,7 @@ if ( $Event->DefaultVideo() ) {
|
||||||
<?php
|
<?php
|
||||||
} // end if DefaultVideo
|
} // end if DefaultVideo
|
||||||
?>
|
?>
|
||||||
<?php if (!$Event->DefaultVideo()) { ?>
|
<?php if ( !$video_tag ) { ?>
|
||||||
<div id="imageFeed">
|
<div id="imageFeed">
|
||||||
<?php
|
<?php
|
||||||
if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
|
if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
|
||||||
|
|
Loading…
Reference in New Issue