diff --git a/src/zm_camera.cpp b/src/zm_camera.cpp index f8c9fd6af..4759ddc1b 100644 --- a/src/zm_camera.cpp +++ b/src/zm_camera.cpp @@ -51,3 +51,8 @@ Camera::~Camera() { } +Monitor *Camera::getMonitor() { + if ( ! monitor ) + monitor = Monitor::Load( id, false, Monitor::QUERY ); + return monitor; +} diff --git a/src/zm_camera.h b/src/zm_camera.h index eb161b9f0..4d58d4ff1 100644 --- a/src/zm_camera.h +++ b/src/zm_camera.h @@ -25,6 +25,10 @@ #include "zm_image.h" +class Camera; + +#include "zm_monitor.h" + // // Abstract base class for cameras. This is intended just to express // common attributes @@ -32,56 +36,58 @@ class Camera { protected: - typedef enum { LOCAL_SRC, REMOTE_SRC, FILE_SRC, FFMPEG_SRC, LIBVLC_SRC, CURL_SRC } SourceType; + typedef enum { LOCAL_SRC, REMOTE_SRC, FILE_SRC, FFMPEG_SRC, LIBVLC_SRC, CURL_SRC } SourceType; - int id; - SourceType type; - unsigned int width; - unsigned int height; - unsigned int colours; - unsigned int subpixelorder; - unsigned int pixels; - unsigned int imagesize; - int brightness; - int hue; - int colour; - int contrast; - bool capture; - bool record_audio; + int id; // This is actually monitor id + Monitor * monitor; // Null on instantiation, set as soon as possible. + SourceType type; + unsigned int width; + unsigned int height; + unsigned int colours; + unsigned int subpixelorder; + unsigned int pixels; + unsigned int imagesize; + int brightness; + int hue; + int colour; + int contrast; + bool capture; + bool record_audio; public: - Camera( int p_id, SourceType p_type, int p_width, int p_height, int p_colours, int p_subpixelorder, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture, bool p_record_audio ); - virtual ~Camera(); + Camera( int p_id, SourceType p_type, int p_width, int p_height, int p_colours, int p_subpixelorder, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture, bool p_record_audio ); + virtual ~Camera(); - int getId() const { return( id ); } - SourceType Type() const { return( type ); } - bool IsLocal() const { return( type == LOCAL_SRC ); } - bool IsRemote() const { return( type == REMOTE_SRC ); } - bool IsFile() const { return( type == FILE_SRC ); } - bool IsFfmpeg() const { return( type == FFMPEG_SRC ); } - bool IsLibvlc() const { return( type == LIBVLC_SRC ); } - bool IscURL() const { return( type == CURL_SRC ); } - unsigned int Width() const { return( width ); } - unsigned int Height() const { return( height ); } - unsigned int Colours() const { return( colours ); } - unsigned int SubpixelOrder() const { return( subpixelorder ); } - unsigned int Pixels() const { return( pixels ); } - unsigned int ImageSize() const { return( imagesize ); } + int getId() const { return( id ); } + Monitor *getMonitor(); + SourceType Type() const { return( type ); } + bool IsLocal() const { return( type == LOCAL_SRC ); } + bool IsRemote() const { return( type == REMOTE_SRC ); } + bool IsFile() const { return( type == FILE_SRC ); } + bool IsFfmpeg() const { return( type == FFMPEG_SRC ); } + bool IsLibvlc() const { return( type == LIBVLC_SRC ); } + bool IscURL() const { return( type == CURL_SRC ); } + unsigned int Width() const { return( width ); } + unsigned int Height() const { return( height ); } + unsigned int Colours() const { return( colours ); } + unsigned int SubpixelOrder() const { return( subpixelorder ); } + unsigned int Pixels() const { return( pixels ); } + unsigned int ImageSize() const { return( imagesize ); } - virtual int Brightness( int/*p_brightness*/=-1 ) { return( -1 ); } - virtual int Hue( int/*p_hue*/=-1 ) { return( -1 ); } - virtual int Colour( int/*p_colour*/=-1 ) { return( -1 ); } - virtual int Contrast( int/*p_contrast*/=-1 ) { return( -1 ); } + virtual int Brightness( int/*p_brightness*/=-1 ) { return( -1 ); } + virtual int Hue( int/*p_hue*/=-1 ) { return( -1 ); } + virtual int Colour( int/*p_colour*/=-1 ) { return( -1 ); } + virtual int Contrast( int/*p_contrast*/=-1 ) { return( -1 ); } - bool CanCapture() const { return( capture ); } + bool CanCapture() const { return( capture ); } - bool SupportsNativeVideo() const { return( (type == FFMPEG_SRC )||(type == REMOTE_SRC)); } + bool SupportsNativeVideo() const { return( (type == FFMPEG_SRC )||(type == REMOTE_SRC)); } - virtual int PrimeCapture() { return( 0 ); } - virtual int PreCapture()=0; - virtual int Capture( Image &image )=0; - virtual int PostCapture()=0; - virtual int CaptureAndRecord( Image &image, bool recording, char* event_directory)=0; + virtual int PrimeCapture() { return( 0 ); } + virtual int PreCapture()=0; + virtual int Capture( Image &image )=0; + virtual int PostCapture()=0; + virtual int CaptureAndRecord( Image &image, bool recording, char* event_directory)=0; }; #endif // ZM_CAMERA_H diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index a6ca38e67..bef231c01 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -604,7 +604,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, bool recording, char* event_fi //Instantiate the video storage module Debug(3, "recording and ! wasRecording %s", event_file); - videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime); + videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime, this->getMonitor()->getOrientation() ); wasRecording = true; strcpy(oldDirectory, event_file); @@ -629,7 +629,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, bool recording, char* event_fi videoStore = NULL; } - videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime); + videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime, this->getMonitor()->getOrientation()); strcpy(oldDirectory, event_file); } diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index f5f7b3c84..8448d2dee 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -4399,3 +4399,15 @@ void Monitor::SingleImageZip( int scale) fprintf( stdout, "Content-Type: image/x-rgbz\r\n\r\n" ); fwrite( img_buffer, img_buffer_size, 1, stdout ); } +unsigned int Monitor::Colours() const { return( camera->Colours() ); } + unsigned int Monitor::SubpixelOrder() const { return( camera->SubpixelOrder() ); } + int Monitor::PrimeCapture() { + return( camera->PrimeCapture() ); + } + int Monitor::PreCapture() { + return( camera->PreCapture() ); + } + int Monitor::PostCapture() { + return( camera->PostCapture() ); + } + Monitor::Orientation Monitor::getOrientation()const { return orientation; } diff --git a/src/zm_monitor.h b/src/zm_monitor.h index 70f77ca4c..39f3dfa17 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -29,6 +29,7 @@ #include "zm_rgb.h" #include "zm_zone.h" #include "zm_event.h" +class Monitor; #include "zm_camera.h" #include "zm_storage.h" #include "zm_utils.h" @@ -326,6 +327,8 @@ protected: MonitorLink **linked_monitors; public: + Monitor( int p_id ); + // OurCheckAlarms seems to be unused. Check it on zm_monitor.cpp for more info. //bool OurCheckAlarms( Zone *zone, const Image *pImage ); Monitor( @@ -416,11 +419,12 @@ public: inline bool Exif() { return( embed_exif ); } + Orientation getOrientation()const; unsigned int Width() const { return width; } unsigned int Height() const { return height; } - unsigned int Colours() const { return( camera->Colours() ); } - unsigned int SubpixelOrder() const { return( camera->SubpixelOrder() ); } + unsigned int Colours() const; + unsigned int SubpixelOrder() const; int GetOptSaveJPEGs() const { return( savejpegspref ); } int GetOptVideoWriter() const { return( videowriterpref ); } @@ -454,16 +458,10 @@ public: int actionColour( int p_colour=-1 ); int actionContrast( int p_contrast=-1 ); - inline int PrimeCapture() { - return( camera->PrimeCapture() ); - } - inline int PreCapture() { - return( camera->PreCapture() ); - } + int PrimeCapture(); + int PreCapture(); int Capture(); - int PostCapture() { - return( camera->PostCapture() ); - } + int PostCapture(); unsigned int DetectMotion( const Image &comp_image, Event::StringSet &zoneSet ); // DetectBlack seems to be unused. Check it on zm_monitor.cpp for more info. diff --git a/src/zm_remote_camera_rtsp.cpp b/src/zm_remote_camera_rtsp.cpp index 5256b1de2..83cb341fe 100644 --- a/src/zm_remote_camera_rtsp.cpp +++ b/src/zm_remote_camera_rtsp.cpp @@ -499,7 +499,7 @@ int RemoteCameraRtsp::CaptureAndRecord( Image &image, bool recording, char* even if ( recording && !wasRecording ) { //Instantiate the video storage module - videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime); + videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime, this->getMonitor()->getOrientation() ); wasRecording = true; strcpy(oldDirectory, event_file); @@ -519,7 +519,7 @@ int RemoteCameraRtsp::CaptureAndRecord( Image &image, bool recording, char* even videoStore = NULL; } - videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime); + videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime, this->getMonitor()->getOrientation() ); strcpy( oldDirectory, event_file ); } diff --git a/src/zm_videostore.cpp b/src/zm_videostore.cpp index 8357ba5f7..64d8cb303 100644 --- a/src/zm_videostore.cpp +++ b/src/zm_videostore.cpp @@ -35,7 +35,9 @@ extern "C"{ VideoStore::VideoStore(const char *filename_in, const char *format_in, AVStream *input_st, AVStream *inpaud_st, - int64_t nStartTime) { + int64_t nStartTime, + Monitor::Orientation p_orientation +) { AVDictionary *pmetadata = NULL; int dsr; @@ -75,6 +77,11 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in, dsr = av_dict_set(&pmetadata, "title", "Zoneminder Security Recording", 0); if (dsr < 0) Warning("%s:%d: title set failed", __FILE__, __LINE__ ); + if ( p_orientation == Monitor::ROTATE_90 ) { + dsr = av_dict_set(&pmetadata, "rotate", "90", 0); + if (dsr < 0) Warning("%s:%d: title set failed", __FILE__, __LINE__ ); + } + oc->metadata = pmetadata; fmt = oc->oformat; diff --git a/src/zm_videostore.h b/src/zm_videostore.h index 0d72f42b6..6b2d3d8cc 100644 --- a/src/zm_videostore.h +++ b/src/zm_videostore.h @@ -5,6 +5,8 @@ #if HAVE_LIBAVCODEC +#include "zm_monitor.h" + class VideoStore { private: @@ -15,6 +17,8 @@ private: const char *filename; const char *format; + + Monitor::Orientation orientation; bool keyframeMessage; int keyframeSkipNumber; @@ -26,7 +30,7 @@ private: int64_t filter_in_rescale_delta_last; public: - VideoStore(const char *filename_in, const char *format_in, AVStream *input_st, AVStream *inpaud_st, int64_t nStartTime); + VideoStore(const char *filename_in, const char *format_in, AVStream *input_st, AVStream *inpaud_st, int64_t nStartTime, Monitor::Orientation p_orientation ); ~VideoStore(); int writeVideoFramePacket(AVPacket *pkt, AVStream *input_st);//, AVPacket *lastKeyframePkt);