00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00038
00039
00040
00041
00042
00043
00044
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;
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;
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
00095
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
00113 stop();
00114
00115
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
00180
00181
00182 void mxcpcSimpleMxPEGViewer::stop(void) {
00183
00184
00185 delete Decoder;
00186
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
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;
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
00236
00237 glClearColor(0.0f,
00238 0.0f,
00239 0.5f,
00240 0.0f);
00241 glClear(GL_COLOR_BUFFER_BIT);
00242
00243
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;
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;
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