Qt 4.8 #if added
[mardrone] / mardrone / dronelib / video.cpp
index 0aa269b..0580a6d 100644 (file)
   !
   !
   *===================================================================*/
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #include "video.h"
+#include <QNetworkConfigurationManager>
+#include <QNetworkSession>
+#include <QList>
 #include <QGraphicsView>
+#include <QDateTime>
+#include <QDir>
+
+#ifdef QT_IOS
+#define NO_VIDEO
+#endif
 
 DroneVideo::DroneVideo()
 {
      droneHost.setAddress("192.168.1.1");
      initialized=false;
+     m_idleImage=NULL;
+     videoThread=NULL;
 }
 
-VideoThread::VideoThread(DroneVideo *parentp,QHostAddress host,QImage *_image)
+
+void DroneVideo::frameSeqUpdated()
 {
-    image=_image;
-    qDebug() << "videoThread::videoThread";
-    stopped=false;
-    parent=parentp;
-    videoSock=new QUdpSocket();
-    videoSock->bind(QHostAddress::Any,5555);
-    droneHost=host;
-    start();
+    emit frameSeqChanged();
+}
+
+QImage* DroneVideo::idleImage() { return m_idleImage; }
+void DroneVideo::setIdleImage(QImage *img)
+{
+    m_idleImage=img;
 
+    if(m_idleImage && image) {
+        QPainter p(image);
+        p.drawImage(0,0,*m_idleImage);
+        update(boundingRect());
+    }
 };
 
 void DroneVideo::paint(QPainter *painter,const QStyleOptionGraphicsItem *option,
@@ -57,10 +78,15 @@ void DroneVideo::paint(QPainter *painter,const QStyleOptionGraphicsItem *option,
             image->fill(0x5555);
         }
         QPainter p(image);
-        p.drawLine(0,0,image->width(),image->height());
-        p.drawLine(image->width(),0,0,image->height());
+        if(m_idleImage) {
+            p.drawImage(0,0,*m_idleImage);
+        } else {
+          p.drawLine(0,0,image->width(),image->height());
+          p.drawLine(image->width(),0,0,image->height());
+        }
         update(boundingRect());
         videoThread=new VideoThread(this,droneHost,image);
+        connect(videoThread,SIGNAL(frameSeqChanged()),this,SLOT(frameSeqUpdated()));
         initialized=true;
     } else
     painter->drawImage(boundingRect(),*image,image->rect());
@@ -72,6 +98,56 @@ QRectF DroneVideo::boundingRect() const
 }
 
 
+/*
+
+  VideoThread
+
+  */
+
+
+VideoThread::VideoThread(DroneVideo *parentp,QHostAddress host,QImage *_image)
+{
+    struct ip_mreq imreq;
+    QString my_ip;
+    my_ip="192.168.1.2";
+    image=_image;
+    qDebug() << "videoThread::videoThread";
+    stopped=false;
+    parent=parentp;
+    videoSock=new QUdpSocket();
+    if(!videoSock->bind(QHostAddress::Any,5555)) qDebug() << "VideoThread::VideoThread ** Cant Bind to port 5555 ***" << videoSock->errorString();
+    QList<QNetworkConfiguration> netconfs=QNetworkConfigurationManager().allConfigurations();
+    foreach (QNetworkConfiguration np,netconfs) {
+        qDebug() << "network Confifuration name " << np.name() << np.bearerName() << np.bearerTypeName();
+        QNetworkSession ns(np);
+        if(ns.interface().addressEntries().empty())
+            qDebug() << "network session " << ns.interface().humanReadableName() << "**NotConfig**";
+        else {
+            qDebug() << "network session " << ns.interface().humanReadableName() <<   ns.interface().addressEntries().first().ip();
+            // Ubuntu may give wlan0 as "Ethernet"
+            if((np.bearerName()==QString("WLAN")) || (ns.interface().humanReadableName()==QString("wlan0")) ) {
+               my_ip=ns.interface().addressEntries().first().ip().toString();
+               qDebug() << "My IP is " << my_ip;
+        }
+        }
+    }
+    // Qt 4.7.x
+    imreq.imr_multiaddr.s_addr=inet_addr("224.1.1.1");
+    imreq.imr_interface.s_addr=inet_addr(my_ip.toAscii());
+    setsockopt(videoSock->socketDescriptor(),IPPROTO_IP,IP_ADD_MEMBERSHIP,&imreq,sizeof(imreq));
+#if QT_VERSION >= 0x040800
+    // Qt 4.8
+    if(!videoSock->joinMulticastGroup(QHostAddress("224.1.1.1")))
+        qDebug() << "VideoThread::VideoThread can't join multicast Group 224.1.1.1" << videoSock->errorString();
+#endif
+    droneHost=host;
+    videoRec=FALSE;
+    videoFile=NULL;
+    start();
+
+};
+
+
 void VideoThread::run()
 {
 #define ACQ_WIDTH     320
@@ -90,6 +166,7 @@ void VideoThread::run()
     luma_only=FALSE;
     num_picture_decoded=0;
     /// Picture configuration
+#ifndef NO_VIDEO
     picture.format        = PIX_FMT_YUV420P;
     picture.width         = pictureWidth;
     picture.height        = pictureHeight;
@@ -102,7 +179,9 @@ void VideoThread::run()
     picture.cr_line_size  = pictureWidth / 2;
     picture.y_pad         = 0;
     picture.c_pad         = 0;
-    video_codec_open(&controller, (codec_type_t)UVLC_CODEC);
+
+    qDebug() << "video_codec_open=" << video_codec_open(&controller, (codec_type_t)codec_type);
+#endif
     //stateTimer->start(1000);
     qDebug() << "videoThread::run() initialized";
     sendVideoPort("AT");
@@ -126,6 +205,62 @@ void VideoThread::sendVideoPort(QString cmd)
     videoSock->writeDatagram(dgram.data(),dgram.size(),droneHost,5555);
 }
 
+unsigned int VideoThread::getFrameSeq()
+{
+    return frameSeq;
+}
+
+void VideoThread::setVideoRec(bool rec)
+{
+    qDebug() << "VideoThread::setVideoRec" <<  rec;
+    QDateTime fileDate=QDateTime::currentDateTime();
+    if(!videoRec && rec) {
+        frameSeq=0;
+        videoFileName="dronerec"+fileDate.toString("yyyyMMddhhmm");
+        qDebug() << "videoFileName=" <<  videoFileName;
+        emit frameSeqChanged();
+    }
+    videoRec=rec;
+    if(!videoRec && videoFile) { // Stop recording
+        videoFile->close();
+        videoFile->~QFile();
+        videoFile=NULL;
+        videoFileName="";
+    }
+
+
+}
+
+bool VideoThread::getVideoRec()
+{
+    return videoRec;
+}
+
+QString VideoThread::getVideoFileName()
+{
+    return videoFileName;
+}
+
+void VideoThread::setVideoFileName(QString name)
+{
+    videoFileName=name;
+}
+
+void VideoThread::setVideoPlay(bool play)
+{
+    if(!videoPlay && play) frameSeq=0;
+        videoPlay=true;
+        videoRec=false;
+}
+
+bool VideoThread::getVideoPlay()
+{
+    return videoPlay;
+}
+
+
+
+
 void VideoThread::videoDataReady()
 {
    qint64 l;
@@ -136,7 +271,13 @@ void VideoThread::videoDataReady()
    videoData.resize(videoSock->pendingDatagramSize ());
    l=videoSock->readDatagram(videoData.data(),videoData.size(),&host,&port);
 //   qDebug() << "videoThread::videoDataReady" <<" l=" << l << "from"  << host ;
+
+   if(videoRec && videoFile==NULL) {
+       // Open Video File
+   }
+
    decodeTransform(videoData);
+
 }
 
 void VideoThread::decodeTransform(QByteArray &videoData)
@@ -149,8 +290,27 @@ void VideoThread::decodeTransform(QByteArray &videoData)
     controller.in_stream.code    = 0;
 
     bool_t got_image = FALSE;
-    //qDebug() <<"VideoThread::decodeTransform";
-    video_decode_blockline( &controller, &picture, &got_image );
+    //qDebug() <<"VideoThread::decodeTransform" << controller.video_codec;
+#ifndef NO_VIDEO
+    if(controller.video_codec!=NULL)  video_decode_blockline( &controller, &picture, &got_image );
+    if(videoRec && !videoFile) {// Start recording
+        qDebug() << "Record Video to " << QDir::current().absolutePath()  << videoFileName+".yuv" << " at " << picture.width << "x" << picture.height;
+        videoFile=new QFile(videoFileName+".yuv");
+        videoFile->open(QIODevice::WriteOnly);
+        if(videoFile->error()!=QFile::NoError) {
+            qDebug() << "Can't open Video file " << videoFileName << ".yuv" << videoFile->errorString();
+            videoFile->~QFile();
+            videoFile=NULL;
+            videoRec=false;
+        }
+    }
+     if(!videoRec && videoFile) { // Stop recording
+         videoFile->close();
+         videoFile->~QFile();
+         videoFile=NULL;
+         videoFileName="";
+     }
+    //else qDebug() << "No video controller";
     //qDebug() <<"VideoThread::decodeTransform 2";
     //video_decode_picture( &controller, &picture, &stream, &got_image );
     if( got_image )
@@ -158,16 +318,23 @@ void VideoThread::decodeTransform(QByteArray &videoData)
           //  qDebug() <<"VideoThread::decodeTransform got image" << picture.width << picture.height << image->byteCount() << image->bytesPerLine();
           // we got one picture
           // out->size = 1;
+          frameSeq++;
           picture.complete     = 1;
           num_picture_decoded++;
+          if(videoFile && videoRec) {
+            videoFile->write((char*)picture.y_buf,picture.width*picture.height);
+            videoFile->write((char*)picture.cb_buf,picture.width*picture.height>>2);
+            videoFile->write((char*)picture.cr_buf,picture.width*picture.height>>2);
+          };
           if(image->depth()<24)
             vp_stages_YUV420P_to_RGB565(NULL,&picture,image->bits(),image->bytesPerLine());
           else
             vp_stages_YUV420P_to_ARGB32(NULL,&picture,image->bits(),image->bytesPerLine());
+          emit frameSeqChanged();
 
        //   qDebug() << "pic " << num_picture_decoded;
         }
-
+#endif
 
 };