Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

mxcpcSimpleMxPEGViewer.cpp

00001 //           ///          //                                        Mx clientSDK
00002 //          /////        ////                    Mx Crossplatform Client Library
00003 //         /// XXX     XXX ///
00004 //        ///    XXX XXX    ///     $RCSfile: mxcpcSimpleMxPEGViewer.cpp,v $
00005 //       ///       XXX       ///     $Revision: 1.10 $
00006 //      ///      XXX XXX      ///     $Date: 2006/01/18 17:24:59 $
00007 //     ////    XXX     XXX    ////     $Author: cvs-kai $
00008 //    ////                     ////
00009 //   ////  M  O  B  O  T  I  X  ////////////////////////////////////////////////
00010 //  //// Security Vision Systems //////////////////////////////////////////////
00011 //                                                                          //
00012 //  Copyright (C) 2005 - 2006, MOBOTIX AG, Germany                         //
00013 //  This software is made available under the BSD licence. Please refer   //
00014 //  to the file LICENCE.TXT contained in this distribution for details.  //
00015 //                                                                      //
00016 //  /////////////////////////////////////////////////////////////////////
00017 
00018 
00019 
00020 #include <mxcpcSimpleMxPEGViewer.h>
00021 #include <mxcpcMxPEGCodecFactory.h>
00022 #include <mxcpcAsynchronousCameraLiveMxPEGFastStream.h>
00023 #include <mxcpcBufferedMxPEGVideoRenderer.h>
00024 #include <mxcpcFramewiseMxPEGDecoder.h>
00025 #include <mxcpcFramewiseMxPEGScanDecoderSoftwareOnly.h>
00026 #include <mxcpcAuthenticationDialog.h>
00027 #include <mxcpcMessageDialog.h>
00028 #include <mxcpc_namespace.h>
00029 
00030 #include <QTimer>
00031 #include <QMenu>
00032 #include <QMouseEvent>
00033 
00034 
00035 
00036 /*!
00037  *  \param codec_factory
00038  *  will be used by the viewer when instantiating <tt>MxPEG</tt> decoding
00039  *  facilities. The viewer assumes ownership over the codec factory.
00040  *
00041  *  \param connection_timeout
00042  *  The timeout value specified will be added to the frame cycle time
00043  *  <tt>T = 1/framerate</tt> when engaging the stream connection watchdog
00044  *  timer.
00045  */
00046 mxcpcSimpleMxPEGViewer
00047  ::mxcpcSimpleMxPEGViewer(QWidget *parent,
00048                           mxcpcMxPEGCodecFactory *codec_factory,
00049                           const QString& window_title_prefix,
00050                           int connection_timeout)
00051     : mxcpcVideoDisplay(parent)                               {
00052 
00053   WindowTitlePrefix = window_title_prefix;
00054   setWindowTitle(window_title_prefix);
00055   resize(640, 480);
00056   setAutoBufferSwap(false);
00057   
00058   CodecFactory = codec_factory;
00059   
00060   Decoder    = 0;   // viewer starts in disconnected state;
00061   FastStream = 0;
00062   Renderer   = 0;
00063   
00064   ConnectionWatchdogTimer = new QTimer(this);
00065   QObject::connect(ConnectionWatchdogTimer, SIGNAL(timeout(void)),
00066                    this, SLOT(processWatchdog(void)));
00067   LastDrawnFrame = 0;
00068   ConnectionTimeout = connection_timeout;
00069   if(ConnectionTimeout < 0) ConnectionTimeout = 2000;
00070   
00071   Menu = new QMenu(this);
00072   
00073   AuthenticationDialog = new mxcpcAuthenticationDialog();
00074   AuthenticationDialog->setWindowTitle(QString("Authentication"));
00075   MessageDialog = new mxcpcMessageDialog();
00076 
00077   FramerateMeasureInterval = -1;   // don't measure framerates
00078 }
00079        
00080 
00081 mxcpcSimpleMxPEGViewer::~mxcpcSimpleMxPEGViewer() {
00082 
00083   delete AuthenticationDialog;
00084   delete MessageDialog;
00085   
00086   delete Decoder;
00087   
00088   delete CodecFactory;
00089 }
00090 
00091 
00092 
00093 /*! 
00094  *  If the viewer was already streaming, the old stream source is disconected
00095  *  properly.
00096  */
00097 void mxcpcSimpleMxPEGViewer
00098       ::playCameraLiveFastStream(
00099           const mxcpcIPAddress& camera_ip,
00100           int camera_port,
00101           const mxcpcProxyConfiguration& camera_proxy_configuration,
00102           float fps
00103         )                                                            {
00104 
00105   mxcpcAsynchronousCameraLiveMxPEGFastStream *fast_stream;
00106   QString window_title;
00107   int timeout;
00108   char txt[100];
00109   
00110   if(fps < 0.0f) fps = 4.0f;
00111   
00112   // disconnect a potentially established connection
00113   stop();
00114   
00115   // set up new decoding facility...
00116   FastStream 
00117    = fast_stream = new mxcpcAsynchronousCameraLiveMxPEGFastStream(
00118                          camera_ip,
00119                          camera_port,
00120                          camera_proxy_configuration,
00121                          fps
00122                        );
00123   Renderer = new mxcpcBufferedMxPEGVideoRenderer(this);
00124   Decoder = new mxcpcFramewiseMxPEGDecoder(
00125                  fast_stream,
00126                  Renderer,
00127                  CodecFactory->newFramewiseMxPEGScanDecoder()
00128                 );
00129                 
00130   QObject::connect(fast_stream, SIGNAL(bytesAvailable(void)),
00131                    this, SLOT(processIncoming(void)));
00132   QObject::connect(fast_stream, SIGNAL(authenticationRequest(QString)),
00133                    AuthenticationDialog, SLOT(openDialog(const QString&)));
00134   QObject::connect(AuthenticationDialog, 
00135                    SIGNAL(authenticationCommitted(QString, QString)),
00136                    fast_stream,
00137                    SLOT(processAuthentication(const QString&, const QString&)));
00138   QObject::connect(AuthenticationDialog, 
00139                    SIGNAL(authenticationCancelled(void)),
00140                    fast_stream,
00141                    SLOT(processAuthenticationCancellation(void)));
00142   QObject::connect(Renderer, SIGNAL(framerateMeasured(float)),
00143                    this, SLOT(processMeasuredFramerate(float)));
00144                    
00145   window_title = WindowTitlePrefix 
00146                   + QString(" - Camera ")
00147                   + QString::number(camera_ip.getIP1()) + QString(".")
00148                   + QString::number(camera_ip.getIP2()) + QString(".")
00149                   + QString::number(camera_ip.getIP3()) + QString(".")
00150                   + QString::number(camera_ip.getIP4())
00151                   + QString(" @ ");
00152   if(fps != 0.0f) {
00153     if(fps < 1.0f) std::sprintf(txt, "%.2f", fps);
00154     else           std::sprintf(txt, "%.0f", fps);
00155     window_title += QString(txt) + QString("fps");
00156   }
00157   else { 
00158     window_title += QString("Maximum Framerate");
00159   }
00160   setWindowTitle(window_title);
00161   
00162   LastDrawnFrame = Renderer->getFrameCount();
00163   if(fps != 0.0f)
00164    timeout = (int)((float)ConnectionTimeout + 1000.0f/fps);
00165   else
00166    timeout = ConnectionTimeout;
00167   ConnectionWatchdogTimer->start(timeout);
00168   
00169   MessageDialog->hide();
00170   
00171   if(FramerateMeasureInterval >= 0)
00172    Renderer->setFramerateMeasureModeEnabled(true, FramerateMeasureInterval);
00173   else
00174    Renderer->setFramerateMeasureModeEnabled(false);
00175 }
00176 
00177 
00178 /*!
00179  *  If the viewer is currently not connected to any stream source, the method
00180  *  has no effect.
00181  */
00182 void mxcpcSimpleMxPEGViewer::stop(void) {
00183   
00184   // disconnect a potentially established connection
00185   delete Decoder;   // signal wiring to and from the authentication dialog
00186                     // will implicitly be disconnected
00187   Decoder    = 0;
00188   FastStream = 0;
00189   Renderer   = 0;
00190   ConnectionWatchdogTimer->stop();
00191   
00192   setWindowTitle(WindowTitlePrefix);
00193   updateGL();
00194 }
00195 
00196 
00197 void mxcpcSimpleMxPEGViewer::addMenuItem(const QString& item_text,
00198                                          const QObject *receiver, 
00199                                          const char *slot)        {
00200 
00201   Menu->addAction(item_text, receiver, slot);
00202 }
00203 
00204 
00205 void mxcpcSimpleMxPEGViewer::addMenuSeparator(void) {
00206 
00207   Menu->addSeparator();
00208 }
00209 
00210 
00211 /*!
00212  *   Per default, the framerate measure mode is disabled.
00213  */
00214 void mxcpcSimpleMxPEGViewer
00215       ::setFramerateMeasureModeEnabled(bool enabled, int measure_interval_ms) {
00216 
00217   if(!enabled) FramerateMeasureInterval = -1;
00218   else {
00219     FramerateMeasureInterval = measure_interval_ms;
00220     if(FramerateMeasureInterval < 0) FramerateMeasureInterval = 10000;   // 10s
00221    
00222   }            
00223   
00224   if(Renderer) {
00225     if(FramerateMeasureInterval >= 0)
00226      Renderer->setFramerateMeasureModeEnabled(true, FramerateMeasureInterval);
00227     else
00228      Renderer->setFramerateMeasureModeEnabled(false); 
00229   }
00230 }
00231 
00232 
00233 void mxcpcSimpleMxPEGViewer::paintGL(void) {
00234  
00235   //if(Decoder && !AuthenticationDialog->isVisible()) return;
00236  
00237   glClearColor(0.0f,
00238                0.0f,
00239                0.5f,
00240                0.0f);
00241   glClear(GL_COLOR_BUFFER_BIT);
00242  
00243   // restore GL base state...
00244   glClearColor(0.0f,
00245                0.0f,
00246                0.0f,
00247                0.0f);
00248 }
00249 
00250 
00251 void mxcpcSimpleMxPEGViewer::resizeGL(int width, int height) {
00252         
00253   glViewport(0, 0, width, height);
00254   
00255   glMatrixMode(GL_PROJECTION);
00256   glLoadIdentity();
00257   glOrtho((GLdouble)0.0, (GLdouble)width,
00258           (GLdouble)height, (GLdouble)0.0,
00259           (GLdouble)-1.0, (GLdouble)1.0);
00260   glMatrixMode(GL_MODELVIEW);
00261 }
00262 
00263 
00264 void mxcpcSimpleMxPEGViewer::mousePressEvent(QMouseEvent *e) {
00265   
00266   if(e->button() == Qt::RightButton) {
00267     
00268     Menu->popup(e->globalPos());
00269   }
00270 }
00271 
00272 
00273 void mxcpcSimpleMxPEGViewer::processIncoming(void) {
00274 
00275   if(!Decoder) return;   // just be safe
00276   
00277   while(Decoder->decode(2048))
00278    ;
00279 }
00280 
00281 
00282 void mxcpcSimpleMxPEGViewer::processWatchdog(void) {
00283 
00284   int frame_count;
00285   
00286   if(!Decoder) return;   // just be safe
00287   
00288   frame_count = Renderer->getFrameCount();
00289   if((frame_count == LastDrawnFrame)
00290      && !FastStream->wasAuthenticationDialogRaised()) {
00291     MessageDialog->setMessage(QString("Notification"),
00292                               QString("Stream connection timed out!"));
00293     MessageDialog->openDialog();
00294     mxcpc::sendStatusMsg("mxcpcSimpleMxPEGViewer : "
00295                          "stream connection timed out - disconnecting...");
00296     stop();
00297   }
00298   else
00299    LastDrawnFrame = frame_count;
00300 }
00301 
00302 
00303 void mxcpcSimpleMxPEGViewer::processMeasuredFramerate(float fps) {
00304   
00305   char txt[100];
00306   
00307   std::sprintf(txt, "SimpleMxPEGViewer : current effective framerate : %.2f",
00308                fps);
00309   mxcpc::sendStatusMsg(txt);
00310   
00311   emit framerateMeasured(fps);
00312 }
00313 

Generated on Mon Jan 30 15:13:08 2006 for mxcpc by  doxygen 1.4.4