Переглянути джерело

add grpc_h264,for mp4 transfer.

yuchuli 3 роки тому
батько
коміт
68bdae87d2
62 змінених файлів з 7292 додано та 10 видалено
  1. 2 0
      src/driver/driver_camera_ioctl/driver_camera_ioctl.pro
  2. 59 0
      src/driver/driver_cloud_grpc_client_h264/driver_cloud_grpc_client_h264.pro
  3. 48 0
      src/driver/driver_cloud_grpc_client_h264/driver_cloud_grpc_client_h264.yaml
  4. 686 0
      src/driver/driver_cloud_grpc_client_h264/grpcclient.cpp
  5. 139 0
      src/driver/driver_cloud_grpc_client_h264/grpcclient.h
  6. 67 0
      src/driver/driver_cloud_grpc_client_h264/main.cpp
  7. 4 0
      src/driver/driver_cloud_grpc_client_h264/prototocpp.txt
  8. 64 0
      src/driver/driver_cloud_grpc_server_h264/clientime.cpp
  9. 40 0
      src/driver/driver_cloud_grpc_server_h264/clientime.h
  10. 224 0
      src/driver/driver_cloud_grpc_server_h264/cumsgbuffer.cpp
  11. 73 0
      src/driver/driver_cloud_grpc_server_h264/cumsgbuffer.h
  12. 59 0
      src/driver/driver_cloud_grpc_server_h264/driver_cloud_grpc_server_h264.pro
  13. 216 0
      src/driver/driver_cloud_grpc_server_h264/main.cpp
  14. 171 0
      src/driver/driver_cloud_grpc_server_h264/pcmsgbuffer.cpp
  15. 66 0
      src/driver/driver_cloud_grpc_server_h264/pcmsgbuffer.h
  16. 114 0
      src/driver/driver_cloud_grpc_server_h264/picbuf.cpp
  17. 45 0
      src/driver/driver_cloud_grpc_server_h264/picbuf.h
  18. 15 7
      src/driver/driver_h264_dec/main.cpp
  19. 1 1
      src/driver/driver_h264_enc/driver_h264_enc.pro
  20. 2 1
      src/driver/driver_h264_enc/main.cpp
  21. 341 0
      src/tool/RemoteCtrl_h264/BaiDuMap.html
  22. 11 0
      src/tool/RemoteCtrl_h264/RemoteCtrl.xml
  23. 139 0
      src/tool/RemoteCtrl_h264/RemoteCtrl_h264.pro
  24. BIN
      src/tool/RemoteCtrl_h264/car.png
  25. 256 0
      src/tool/RemoteCtrl_h264/dialogbigpic.cpp
  26. 70 0
      src/tool/RemoteCtrl_h264/dialogbigpic.h
  27. 19 0
      src/tool/RemoteCtrl_h264/dialogbigpic.ui
  28. 104 0
      src/tool/RemoteCtrl_h264/dialogpic.cpp
  29. 49 0
      src/tool/RemoteCtrl_h264/dialogpic.h
  30. 19 0
      src/tool/RemoteCtrl_h264/dialogpic.ui
  31. 78 0
      src/tool/RemoteCtrl_h264/dialogsetpassword.cpp
  32. 39 0
      src/tool/RemoteCtrl_h264/dialogsetpassword.h
  33. 97 0
      src/tool/RemoteCtrl_h264/dialogsetpassword.ui
  34. 54 0
      src/tool/RemoteCtrl_h264/dialogsetting.cpp
  35. 33 0
      src/tool/RemoteCtrl_h264/dialogsetting.h
  36. 137 0
      src/tool/RemoteCtrl_h264/dialogsetting.ui
  37. 31 0
      src/tool/RemoteCtrl_h264/driver_cloud_grpc_pc.yaml
  38. 594 0
      src/tool/RemoteCtrl_h264/grpcpc.cpp
  39. 129 0
      src/tool/RemoteCtrl_h264/grpcpc.h
  40. 155 0
      src/tool/RemoteCtrl_h264/ivpicsave.cpp
  41. 44 0
      src/tool/RemoteCtrl_h264/ivpicsave.h
  42. 111 0
      src/tool/RemoteCtrl_h264/ivpicview.cpp
  43. 40 0
      src/tool/RemoteCtrl_h264/ivpicview.h
  44. 25 0
      src/tool/RemoteCtrl_h264/ivview.cpp
  45. 34 0
      src/tool/RemoteCtrl_h264/ivview.h
  46. 161 0
      src/tool/RemoteCtrl_h264/joyreadthread.cpp
  47. 39 0
      src/tool/RemoteCtrl_h264/joyreadthread.h
  48. 76 0
      src/tool/RemoteCtrl_h264/main.cpp
  49. 955 0
      src/tool/RemoteCtrl_h264/mainwindow.cpp
  50. 209 0
      src/tool/RemoteCtrl_h264/mainwindow.h
  51. 523 0
      src/tool/RemoteCtrl_h264/mainwindow.ui
  52. 120 0
      src/tool/RemoteCtrl_h264/myview.cpp
  53. 35 0
      src/tool/RemoteCtrl_h264/myview.h
  54. 2 0
      src/tool/RemoteCtrl_h264/pos.txt
  55. 16 0
      src/tool/RemoteCtrl_h264/pos_def.h
  56. BIN
      src/tool/RemoteCtrl_h264/remotectrl.png
  57. 5 0
      src/tool/RemoteCtrl_h264/remotectrl.qrc
  58. 143 0
      src/tool/RemoteCtrl_h264/remotectrlini.cpp
  59. 53 0
      src/tool/RemoteCtrl_h264/remotectrlini.h
  60. 199 0
      src/tool/RemoteCtrl_h264/speed.cpp
  61. 51 0
      src/tool/RemoteCtrl_h264/speed.h
  62. 1 1
      src/tool/picview_civetweb/main.cpp

+ 2 - 0
src/driver/driver_camera_ioctl/driver_camera_ioctl.pro

@@ -41,6 +41,8 @@ INCLUDEPATH += /home/linaro/opencv3
 #    DEFINES += USE_OPENCV4
 #}
 
+INCLUDEPATH += /usr/include/x86_64-linux-gnu
+
 
 DEFINES += USE_OPENCV4
 

+ 59 - 0
src/driver/driver_cloud_grpc_client_h264/driver_cloud_grpc_client_h264.pro

@@ -0,0 +1,59 @@
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+QMAKE_LFLAGS += -no-pie
+
+# The following define makes your compiler emit warnings if you use
+# any Qt feature that has been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+system(protoc -I=./../../include/proto3 --cpp_out=./../../include/msgtype   ./../../include/proto3/uploadthreadmsg.proto)
+
+# You can also make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+        ../../include/msgtype/cloud.pb.cc \
+    ../../include/msgtype/uploadthreadmsg.pb.cc \
+        main.cpp \
+    grpcclient.cpp \
+    uploadthreadmsg.grpc.pb.cc
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+!include(../../../include/common.pri ) {
+    error( "Couldn't find the common.pri file!" )
+}
+
+!include(../../../include/ivprotobuf.pri ) {
+    error( "Couldn't find the ivprotobuf.pri file!" )
+}
+
+!include(../../../include/ivboost.pri ) {
+    error( "Couldn't find the ivboost.pri file!" )
+}
+
+!include(../../../include/ivgrpc.pri ) {
+    error( "Couldn't find the ivgrpc.pri file!" )
+}
+
+!include(../../../include/ivyaml-cpp.pri ) {
+    error( "Couldn't find the ivyaml-cpp.pri file!" )
+}
+
+
+
+HEADERS += \
+    ../../include/msgtype/cloud.pb.h \
+    ../../include/msgtype/uploadthreadmsg.pb.h \
+    grpcclient.h \
+    uploadthreadmsg.grpc.pb.h

+ 48 - 0
src/driver/driver_cloud_grpc_client_h264/driver_cloud_grpc_client_h264.yaml

@@ -0,0 +1,48 @@
+server : 47.96.250.93
+port : 50051
+uploadinterval : 100
+skip : 2  # 1 no skip 2 skip 50%  3 skip %66
+
+VIN : AAAAAAAAAAAAAAAAA
+queryMD5 : 5d41402abc4b2a76b9719d911017c592
+ctrlMD5  : 5d41402abc4b2a76b9719d911017c592
+
+
+uploadmessage:
+  usbpic:
+    msgname: compresspic
+    buffersize: 10000000
+    buffercount: 1
+  hcp2_gpsimu:
+    msgname: hcp2_gpsimu
+    buffersize: 100000
+    buffercount: 1
+
+#  tracemap:
+#    msgname: tracemap
+#    buffersize: 10000000
+#    buffercount: 1
+
+  simpletrace:
+    msgname: simpletrace
+    buffersize: 10000000
+    buffercount: 1
+    bimportant: true
+    keeptime: 3000
+
+ctrlmessage:
+  xodrsrc:
+    msgname: xodrsrc
+    buffersize: 1000
+    buffercount: 1
+  xodrreq:
+    msgname: xodrreq
+    buffersize: 1000
+    buffercount: 1
+  remotectrl:
+    msgname: remotectrl
+    buffersize: 10000
+    buffercount: 1
+
+
+

+ 686 - 0
src/driver/driver_cloud_grpc_client_h264/grpcclient.cpp

@@ -0,0 +1,686 @@
+#include "grpcclient.h"
+
+grpcclient * ggrpcclient;
+
+void ListenData(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+    ggrpcclient->UpdateData(strdata,nSize,strmemname);
+
+}
+
+void ListenPicData(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+    ggrpcclient->UpdatePicData(strdata,nSize,strmemname);
+
+}
+
+
+grpcclient::grpcclient(std::string stryamlpath)
+{
+    ggrpcclient = this;
+    dec_yaml(stryamlpath.data());
+
+
+    mstrpicmsgname[0] = "h264front";
+    mstrpicmsgname[1] = "h264rear";
+    mstrpicmsgname[2] = "h264left";
+    mstrpicmsgname[3] = "h264right";
+
+    unsigned int i;
+    for(i=0;i<mvectormsgunit.size();i++)
+    {
+        mvectormsgunit[i].mpa = iv::modulecomm::RegisterRecv(mvectormsgunit[i].mstrmsgname,ListenData);
+    }
+
+    for(i=0;i<mvectorctrlmsgunit.size();i++)
+    {
+        mvectorctrlmsgunit[i].mpa = iv::modulecomm::RegisterSend(mvectorctrlmsgunit[i].mstrmsgname,mvectorctrlmsgunit[i].mnBufferSize,
+                                                                 mvectorctrlmsgunit[i].mnBufferCount);
+    }
+
+    for(i=0;i<NUM_CAM;i++)
+    {
+        mpaPic[i] = iv::modulecomm::RegisterRecv(mstrpicmsgname[i].data(),ListenPicData);
+    }
+
+
+    for(i=0;i<NUM_CAM;i++)
+    {
+        unsigned int j;
+        for(j=0;j<NUM_THREAD_PERCAM;j++)
+        {
+            mpThread[i*NUM_THREAD_PERCAM + j] = new std::thread(&grpcclient::threadpicupload,this,i);
+        }
+    }
+
+    for(i=0;i<NUM_CAM;i++)
+    {
+        mpicbuf[i].mnSkipBase = mnskip;
+    }
+
+}
+
+grpcclient::~grpcclient()
+{
+    std::cout<<" enter ~grpcclient"<<std::endl;
+    mbPicUpload = false;
+
+    requestInterruption();
+    while(this->isFinished() == false)
+    {
+
+    }
+
+    std::cout<<"now join grpcclient thread"<<std::endl;
+
+    unsigned int i;
+    for(i=0;i<NUM_CAM;i++)
+    {
+        unsigned int j;
+        for(j=0;j<NUM_THREAD_PERCAM;j++)
+        {
+            mpThread[i*NUM_THREAD_PERCAM + j]->join();
+        }
+    }
+
+    for(i=0;i<mvectorctrlmsgunit.size();i++)
+    {
+        iv::modulecomm::Unregister(mvectorctrlmsgunit[i].mpa);
+    }
+
+    for(i=0;i<mvectormsgunit.size();i++)
+    {
+        iv::modulecomm::Unregister(mvectormsgunit[i].mpa);
+    }
+
+    std::cout<<"complete ~grpcclient"<<std::endl;
+
+}
+
+void grpcclient::run()
+{
+    int nsize = mvectormsgunit.size();
+    int i;
+
+    int ninterval = atoi(gstruploadinterval.data());
+    if(ninterval<=0)ninterval = 100;
+
+    QTime xTime;
+    xTime.start();
+    int nlastsend = xTime.elapsed();
+
+    std::string target_str = gstrserverip+":";
+    target_str = target_str + gstrserverport ;//std::to_string()
+    auto cargs = grpc::ChannelArguments();
+    cargs.SetMaxReceiveMessageSize(1024 * 1024 * 1024); // 1 GB
+    cargs.SetMaxSendMessageSize(1024 * 1024 * 1024);
+
+    std::shared_ptr<Channel> channel = grpc::CreateCustomChannel(
+             target_str, grpc::InsecureChannelCredentials(),cargs);
+
+    std::unique_ptr<iv::UploadThread::Stub> stub_ = iv::UploadThread::NewStub(channel);
+
+
+    iv::UploadRequestThread request;
+
+    int nid = 0;
+
+    // Container for the data we expect from the server.
+    iv::UploadReplyThread reply;
+
+    gpr_timespec timespec;
+      timespec.tv_sec = 30;//设置阻塞时间为2秒
+      timespec.tv_nsec = 0;
+      timespec.clock_type = GPR_TIMESPAN;
+
+ //   ClientContext context;
+
+    std::vector<qint64> xvectorlatency;
+
+
+    while(!QThread::isInterruptionRequested())
+    {
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+        if((xTime.elapsed()-nlastsend)<ninterval)
+        {
+            continue;
+        }
+
+            bool bImportant = false;
+            int nkeeptime = 0;
+            iv::cloud::cloudmsg xmsg;
+            xmsg.set_xtime(QDateTime::currentMSecsSinceEpoch());
+            gMutexMsg.lock();
+            for(i=0;i<nsize;i++)
+            {
+                if(mvectormsgunit[i].mbRefresh)
+                {
+                    mvectormsgunit[i].mbRefresh = false;
+                    if(mvectormsgunit[i].mbImportant)
+                    {
+                        bImportant = true;
+                    }
+                    if(mvectormsgunit[i].mnkeeptime > nkeeptime)
+                    {
+                        nkeeptime = mvectormsgunit[i].mnkeeptime;
+                    }
+                    iv::cloud::cloudunit xcloudunit;
+                    xcloudunit.set_msgname(mvectormsgunit[i].mstrmsgname);
+                    xcloudunit.set_data(mvectormsgunit[i].mpstrmsgdata.get(),mvectormsgunit[i].mndatasize);
+                    iv::cloud::cloudunit * pcu = xmsg.add_xclouddata();
+                    pcu->CopyFrom(xcloudunit);
+                }
+
+            }
+            gMutexMsg.unlock();
+
+            int nbytesize = xmsg.ByteSize();
+            char * strbuf = new char[nbytesize];
+            std::shared_ptr<char> pstrbuf;
+            pstrbuf.reset(strbuf);
+            if(xmsg.SerializeToArray(strbuf,nbytesize))
+            {
+
+                ClientContext context ;
+                context.set_deadline(timespec);
+                qint64 time1 = QDateTime::currentMSecsSinceEpoch();
+
+
+
+                request.set_id(nid);
+                request.set_ntime(time1);
+                request.set_strquerymd5(gstrqueryMD5);
+                request.set_strctrlmd5(gstrctrlMD5);
+                request.set_strvin(gstrVIN);
+                request.set_xdata(strbuf,nbytesize);
+                request.set_kepptime(nkeeptime);
+                request.set_bimportant(bImportant);
+                request.set_nsendtime(QDateTime::currentMSecsSinceEpoch());
+                request.set_nlatency(CalcLateny(xvectorlatency));
+                nid++;
+
+                nlastsend = xTime.elapsed();
+                // The actual RPC.
+                Status status = stub_->uploaddata(&context, request, &reply);
+                if (status.ok()) {
+//                    std::cout<<"  data size is "<<nbytesize<<std::endl;
+//                    std::cout<<nid<<" upload successfully"<<std::endl;
+                    xvectorlatency.push_back((QDateTime::currentMSecsSinceEpoch() - reply.nreqsendtime()));
+                    while(xvectorlatency.size()>10)xvectorlatency.erase(xvectorlatency.begin());
+                    if(reply.nres() == 1)
+                    {
+                        iv::cloud::cloudmsg xmsg;
+                        if(xmsg.ParseFromArray(reply.xdata().data(),reply.xdata().size()))
+                        {
+                            sharectrlmsg(&xmsg);
+                        }
+                    }
+                } else {
+                  std::cout << status.error_code() << ": " << status.error_message()
+                            << std::endl;
+                  std::cout<<"RPC failed"<<std::endl;
+                  if(status.error_code() == 4)
+                  {
+                      std::cout<<" RPC Exceed Time, Create New stub_"<<std::endl;
+                      channel = grpc::CreateCustomChannel(
+                               target_str, grpc::InsecureChannelCredentials(),cargs);
+
+                      stub_ = iv::UploadThread::NewStub(channel);
+                  }
+                  std::this_thread::sleep_for(std::chrono::milliseconds(300));
+
+                }
+
+            }
+
+
+    }
+
+    std::cout<<" grpcclient:run complete."<<std::endl;
+}
+
+
+void grpcclient::dec_yaml(const char * stryamlpath)
+{
+
+    YAML::Node config;
+    try
+    {
+        config = YAML::LoadFile(stryamlpath);
+    }
+    catch(YAML::BadFile e)
+    {
+        qDebug("load error.");
+        return;
+    }
+
+    std::vector<std::string> vecmodulename;
+
+
+    if(config["server"])
+    {
+        gstrserverip = config["server"].as<std::string>();
+    }
+    if(config["port"])
+    {
+        gstrserverport = config["port"].as<std::string>();
+    }
+    if(config["uploadinterval"])
+    {
+        gstruploadinterval = config["uploadinterval"].as<std::string>();
+    }
+    if(config["skip"])
+    {
+        std::string strskip = config["skip"].as<std::string>();
+        mnskip = atoi(strskip.data());
+        if(mnskip<1)mnskip = 1;
+    }
+
+    if(config["VIN"])
+    {
+        gstrVIN = config["VIN"].as<std::string>();
+    }
+
+    if(config["queryMD5"])
+    {
+        gstrqueryMD5 = config["queryMD5"].as<std::string>();
+    }
+    else
+    {
+        return;
+    }
+
+    if(config["ctrlMD5"])
+    {
+        gstrctrlMD5 = config["ctrlMD5"].as<std::string>();
+    }
+
+
+    std::string strmsgname;
+
+    if(config["uploadmessage"])
+    {
+
+        for(YAML::const_iterator it= config["uploadmessage"].begin(); it != config["uploadmessage"].end();++it)
+        {
+            std::string strtitle = it->first.as<std::string>();
+            std::cout<<strtitle<<std::endl;
+
+            if(config["uploadmessage"][strtitle]["msgname"]&&config["uploadmessage"][strtitle]["buffersize"]&&config["uploadmessage"][strtitle]["buffercount"])
+            {
+                iv::msgunit xmu;
+                strmsgname = config["uploadmessage"][strtitle]["msgname"].as<std::string>();
+                strncpy(xmu.mstrmsgname,strmsgname.data(),255);
+                xmu.mnBufferSize = config["uploadmessage"][strtitle]["buffersize"].as<int>();
+                xmu.mnBufferCount = config["uploadmessage"][strtitle]["buffercount"].as<int>();
+                if(config["uploadmessage"][strtitle]["bimportant"])
+                {
+                   std::string strimportant =    config["uploadmessage"][strtitle]["bimportant"].as<std::string>();
+                   if(strimportant == "true")
+                   {
+                       xmu.mbImportant = true;
+                   }
+                }
+                if(config["uploadmessage"][strtitle]["keeptime"])
+                {
+                   std::string strkeep =    config["uploadmessage"][strtitle]["keeptime"].as<std::string>();
+                   xmu.mnkeeptime = atoi(strkeep.data());
+                }
+                mvectormsgunit.push_back(xmu);
+            }
+        }
+    }
+    else
+    {
+
+
+    }
+
+    if(!config["ctrlMD5"])
+    {
+       return;
+    }
+
+    if(config["ctrlmessage"])
+    {
+        std::string strnodename = "ctrlmessage";
+        for(YAML::const_iterator it= config[strnodename].begin(); it != config[strnodename].end();++it)
+        {
+            std::string strtitle = it->first.as<std::string>();
+            std::cout<<strtitle<<std::endl;
+
+            if(config[strnodename][strtitle]["msgname"]&&config[strnodename][strtitle]["buffersize"]&&config[strnodename][strtitle]["buffercount"])
+            {
+                iv::msgunit xmu;
+                strmsgname = config[strnodename][strtitle]["msgname"].as<std::string>();
+                strncpy(xmu.mstrmsgname,strmsgname.data(),255);
+                xmu.mnBufferSize = config[strnodename][strtitle]["buffersize"].as<int>();
+                xmu.mnBufferCount = config[strnodename][strtitle]["buffercount"].as<int>();
+                mvectorctrlmsgunit.push_back(xmu);
+            }
+        }
+    }
+    else
+    {
+
+    }
+
+    return;
+
+}
+
+void grpcclient::sharectrlmsg(iv::cloud::cloudmsg * pxmsg)
+{
+    int i;
+    int nsize = pxmsg->xclouddata_size();
+    for(i=0;i<nsize;i++)
+    {
+        int j;
+        int nquerysize = mvectorctrlmsgunit.size();
+        for(j=0;j<nquerysize;j++)
+        {
+            if(strncmp(pxmsg->xclouddata(i).msgname().data(), mvectorctrlmsgunit[j].mstrmsgname,255) == 0)
+            {
+ //               qDebug("size is %d ",pxmsg->xclouddata(i).data().size());
+                iv::modulecomm::ModuleSendMsg(mvectorctrlmsgunit[j].mpa,pxmsg->xclouddata(i).data().data(),pxmsg->xclouddata(i).data().size());
+                break;
+            }
+        }
+    }
+}
+
+void grpcclient::UpdateData(const char *strdata, const unsigned int nSize, const char *strmemname)
+{
+    int nsize = mvectormsgunit.size();
+    int i;
+    for(i=0;i<nsize;i++)
+    {
+        if(strncmp(strmemname,mvectormsgunit[i].mstrmsgname,255) == 0)
+        {
+            gMutexMsg.lock();
+            char * strtem = new char[nSize];
+            memcpy(strtem,strdata,nSize);
+            mvectormsgunit[i].mpstrmsgdata.reset(strtem);
+            mvectormsgunit[i].mndatasize = nSize;
+            mvectormsgunit[i].mbRefresh = true;
+            gMutexMsg.unlock();
+            break;
+        }
+    }
+}
+
+void grpcclient::UpdatePicData(const char *strdata, const unsigned int nSize, const char *strmemname)
+{
+    int npos = -1;
+
+    unsigned int i;
+    for(i=0;i<NUM_CAM;i++)
+    {
+        if(strncmp(strmemname,mstrpicmsgname[i].data(),255) == 0)
+        {
+            npos = i;
+            break;
+        }
+    }
+
+    if(npos<0)
+    {
+        std::cout<<"grpcclient::UpdatePicData not found pic. msg name is "<<strmemname<<std::endl;
+        return;
+    }
+
+    if(npos>= NUM_CAM)
+    {
+        std::cout<<"Camera count is "<<NUM_CAM<<" NOW camear is "<<npos<<std::endl;
+        return;
+    }
+
+    if(nSize<5)return;
+    iv::h264frame xframe;
+    if((strdata[4] == 0x27)||(strdata[4] == 0x47)||(strdata[4] == 0x67))
+    {
+        xframe.mbIframe = true;
+    }
+    else
+    {
+        xframe.mbIframe = false;
+    }
+
+    if(mpicbuf[npos].mbRecvIFrame == false)
+    {
+      if(xframe.mbIframe == false)
+      {
+          return;
+      }
+      else
+      {
+          mpicbuf[npos].mbRecvIFrame = true;
+      }
+    }
+
+    xframe.mpstrframedata = std::shared_ptr<char>(new char[nSize]);
+    xframe.mDataSize = nSize;
+    memcpy(xframe.mpstrframedata.get(),strdata,nSize);
+
+    iv::threadpicunit * ppicbuf = &mpicbuf[npos];
+    ppicbuf->mMutex.lock();
+    ppicbuf->mnMsgTime = QDateTime::currentMSecsSinceEpoch();
+    ppicbuf->mbRefresh = true;
+
+    if(ppicbuf->mvectorframe.size()>=NUM_FRAMEBUFFSIZE)
+    {
+        while((ppicbuf->mvectorframe.size()>=NUM_FRAMEBUFFSIZE)||((ppicbuf->mvectorframe.size()>0)&&(ppicbuf->mvectorframe.size()<NUM_FRAMEBUFFSIZE)&&(ppicbuf->mvectorframe[0].mbIframe == false)))
+        {
+            ppicbuf->mvectorframe.erase(ppicbuf->mvectorframe.begin()+0);
+        }
+        if(ppicbuf->mvectorframe.size() == 0)
+        {
+            std::cout<<" Reset SPS Iframe Mark."<<std::endl;
+            ppicbuf->mbRecvIFrame = false;
+        }
+    }
+    ppicbuf->mvectorframe.push_back(xframe);
+
+//    mpicbuf[npos].mpstrmsgdata = std::shared_ptr<char>(new char[nSize]);
+//    mpicbuf[npos].mDataSize = nSize;
+//    memcpy(mpicbuf[npos].mpstrmsgdata.get(),strdata,nSize);
+    ppicbuf->mMutex.unlock();
+    ppicbuf->mwc.wakeAll();
+}
+
+
+void grpcclient::threadpicupload(int nCamPos)
+{
+    std::cout<<"thread cam "<<nCamPos<<"run"<<std::endl;
+    int nsize = mvectormsgunit.size();
+    int i;
+
+    int ninterval = atoi(gstruploadinterval.data());
+    if(ninterval<=0)ninterval = 100;
+
+    QTime xTime;
+    xTime.start();
+    int nlastsend = xTime.elapsed();
+
+    std::string target_str = gstrserverip+":";
+    target_str = target_str + gstrserverport ;//std::to_string()
+    auto cargs = grpc::ChannelArguments();
+    cargs.SetMaxReceiveMessageSize(1024 * 1024 * 1024); // 1 GB
+    cargs.SetMaxSendMessageSize(1024 * 1024 * 1024);
+
+    std::shared_ptr<Channel> channel = grpc::CreateCustomChannel(
+             target_str, grpc::InsecureChannelCredentials(),cargs);
+
+    std::unique_ptr<iv::UploadThread::Stub> stub_ = iv::UploadThread::NewStub(channel);
+
+
+    iv::PicUpRequestThread request;
+
+    int nid = 0;
+
+    // Container for the data we expect from the server.
+    iv::PicUpReplyThread reply;
+
+    gpr_timespec timespec;
+      timespec.tv_sec = 30;//设置阻塞时间为2秒
+      timespec.tv_nsec = 0;
+      timespec.clock_type = GPR_TIMESPAN;
+
+ //   ClientContext context;
+
+    while(mbPicUpload)
+    {
+        std::shared_ptr<char> pstr_ptr;
+        if((nCamPos<0)||(nCamPos >= NUM_CAM))
+        {
+            std::cout<<"Cam Pos Error. "<<"Pos: "<<nCamPos<<" TOTAL:"<<NUM_CAM<<std::endl;
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            continue;
+        }
+
+        bool bUpdate = false;
+        qint64 nMsgTime = 0;
+        int nSize = 0;
+        qint64 npiclatency;
+        int nSkipBase = 1;
+        int nCount;
+
+        if(mpicbuf[nCamPos].mvectorframe.size() == 0)
+        {
+            mpicbuf[nCamPos].mWaitMutex.lock();
+            mpicbuf[nCamPos].mwc.wait(&mpicbuf[nCamPos].mWaitMutex,100);
+            mpicbuf[nCamPos].mWaitMutex.unlock();
+
+        }
+        mpicbuf[nCamPos].mMutex.lock();
+//        bUpdate = mpicbuf[nCamPos].mbRefresh;
+        if(mpicbuf[nCamPos].mvectorframe.size() > 0)bUpdate = true;
+        if(bUpdate == true)
+        {
+            nMsgTime = mpicbuf[nCamPos].mnMsgTime;
+
+            mpicbuf[nCamPos].mbRefresh = false;
+            const int npacmax = 10;
+            int npaccount = mpicbuf[nCamPos].mvectorframe.size();
+            if(npaccount > npacmax)npaccount = npacmax;
+            int nalldatasize = 0;
+            int j;
+            for(j=0;j<npaccount;j++)
+            {
+                nalldatasize = nalldatasize + mpicbuf[nCamPos].mvectorframe[j].mDataSize;
+            }
+            int nsendpacsize = (npacmax + 1)*sizeof(int) + nalldatasize;
+            pstr_ptr = std::shared_ptr<char>(new char[nsendpacsize]);
+            int * pnpacheader = (int *)pstr_ptr.get();
+            *pnpacheader = npaccount;
+            for(j=0;j<npaccount;j++)
+            {
+                *(pnpacheader+j+1) = mpicbuf[nCamPos].mvectorframe[j].mDataSize;
+            }
+            std::cout<<"pac count "<<npaccount<<std::endl;
+            char * pstrvalue = (char * )pstr_ptr.get();
+            pstrvalue = pstrvalue + (npacmax + 1)*sizeof(int);
+            for(j=0;j<npaccount;j++)
+            {
+                memcpy(pstrvalue,mpicbuf[nCamPos].mvectorframe[j].mpstrframedata.get(),mpicbuf[nCamPos].mvectorframe[j].mDataSize);
+                pstrvalue = pstrvalue + mpicbuf[nCamPos].mvectorframe[j].mDataSize;
+            }
+            for(j=0;j<npaccount;j++)mpicbuf[nCamPos].mvectorframe.erase(mpicbuf[nCamPos].mvectorframe.begin());
+            nSize = nsendpacsize;
+//            pstr_ptr = mpicbuf[nCamPos].mvectorframe[0].mpstrframedata;
+//            nSize = mpicbuf[nCamPos].mvectorframe[0].mDataSize;
+//            mpicbuf[nCamPos].mvectorframe.erase(mpicbuf[nCamPos].mvectorframe.begin());
+//            pstr_ptr = mpicbuf[nCamPos].mpstrmsgdata;
+//            nSize = mpicbuf[nCamPos].mDataSize;
+            npiclatency = CalcLateny(mpicbuf[nCamPos].mvectorlatency);
+            nSkipBase = mpicbuf[nCamPos].mnSkipBase;
+            nCount = mpicbuf[nCamPos].mnCount;
+            mpicbuf[nCamPos].mnCount++;
+//            if(npiclatency >  500)
+//            {
+//                if(mpicbuf[nCamPos].mnSkipBase<30)mpicbuf[nCamPos].mnSkipBase++;
+//            }
+//            else
+//            {
+//                if(npiclatency<300)
+//                    if(mpicbuf[nCamPos].mnSkipBase > mpicbuf[nCamPos].mnDefSkipBase)mpicbuf[nCamPos].mnSkipBase--;
+//            }
+            std::cout<<"upload "<<nMsgTime<<"  latency:  "<<npiclatency<<" skip param: "<<nSkipBase<<std::endl;
+        }
+        mpicbuf[nCamPos].mMutex.unlock();
+//        if(bUpdate == false)
+//        {
+// //           std::this_thread::sleep_for(std::chrono::milliseconds(10));
+//            continue;
+//        }
+
+//        if(nCount%nSkipBase != 0)
+//        {
+//            continue;
+//        }
+
+
+
+        ClientContext context ;
+        context.set_deadline(timespec);
+        qint64 time1 = QDateTime::currentMSecsSinceEpoch();
+
+        request.set_npictime(nMsgTime);
+        request.set_ncampos(nCamPos);
+        request.set_strvin(gstrVIN);
+        request.set_xdata(pstr_ptr.get(),nSize);
+        request.set_nlatency(npiclatency);
+        nid++;
+
+        nlastsend = xTime.elapsed();
+        // The actual RPC.
+        Status status = stub_->uploadpic(&context, request, &reply);
+        if (status.ok()) {
+
+            qint64 nlaten = QDateTime::currentMSecsSinceEpoch() - time1;
+            mpicbuf[nCamPos].mMutex.lock();
+            mpicbuf[nCamPos].mvectorlatency.push_back(nlaten);
+            while(mpicbuf[nCamPos].mvectorlatency.size()>10)mpicbuf[nCamPos].mvectorlatency.erase(mpicbuf[nCamPos].mvectorlatency.begin());
+            mpicbuf[nCamPos].mMutex.unlock();
+            if(reply.nres() == 1)
+            {
+//                iv::cloud::cloudmsg xmsg;
+//                if(xmsg.ParseFromArray(reply.xdata().data(),reply.xdata().size()))
+//                {
+//                    sharectrlmsg(&xmsg);
+//                }
+            }
+        } else {
+          std::cout << status.error_code() << ": " << status.error_message()
+                    << std::endl;
+          std::cout<<"RPC failed"<<std::endl;
+          if(status.error_code() == 4)
+          {
+              std::cout<<nCamPos<<" RPC Exceed Time, Create New stub_"<<std::endl;
+              channel = grpc::CreateCustomChannel(
+                       target_str, grpc::InsecureChannelCredentials(),cargs);
+
+              stub_ = iv::UploadThread::NewStub(channel);
+          }
+          std::this_thread::sleep_for(std::chrono::milliseconds(900));
+
+        }
+
+
+    }
+
+    std::cout<<"threadpicupload cam pos: "<<nCamPos<<" exit."<<std::endl;
+}
+
+qint64 grpcclient::CalcLateny(std::vector<qint64> &xvectorlatency)
+{
+    if(xvectorlatency.size() == 0)return 1000;
+    unsigned int i;
+    qint64 nLatencyTotal = 0;
+    for(i=0;i<xvectorlatency.size();i++)
+    {
+        nLatencyTotal = nLatencyTotal + xvectorlatency[i];
+    }
+    qint64 nLatencyAvg = nLatencyTotal/xvectorlatency.size();
+    return nLatencyAvg;
+}

+ 139 - 0
src/driver/driver_cloud_grpc_client_h264/grpcclient.h

@@ -0,0 +1,139 @@
+#ifndef GRPCCLIENT_H
+#define GRPCCLIENT_H
+
+#include <QThread>
+
+#include <yaml-cpp/yaml.h>
+
+#include <QDateTime>
+
+#include <iostream>
+
+#include <vector>
+
+#include <memory>
+
+#include <QMutex>
+#include <QWaitCondition>
+
+#include <thread>
+
+#include "modulecomm.h"
+
+#include "cloud.pb.h"
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+
+
+#include "uploadthreadmsg.grpc.pb.h"
+
+#define NUM_CAM 4
+#define NUM_THREAD_PERCAM 1
+#define NUM_FRAMEBUFFSIZE 30
+
+namespace iv {
+struct msgunit
+{
+    char mstrmsgname[256];
+    int mnBufferSize = 10000;
+    int mnBufferCount = 1;
+    void * mpa;
+    std::shared_ptr<char> mpstrmsgdata;
+    int mndatasize = 0;
+    bool mbRefresh = false;
+    bool mbImportant = false;
+    int mnkeeptime = 100;
+
+};
+
+
+struct  h264frame
+{
+    bool mbIframe = false;   //if SPS, is true
+    std::shared_ptr<char> mpstrframedata;
+    int mDataSize;
+};
+
+struct  threadpicunit
+{
+     std::vector<h264frame> mvectorframe;
+     bool mbRefresh = false;
+     qint64 mnMsgTime;
+     std::shared_ptr<char> mpstrmsgdata;
+     int mDataSize;
+     QMutex mWaitMutex;
+     QWaitCondition mwc;
+     QMutex mMutex;
+     std::vector<qint64> mvectorlatency;
+     int mnSkipBase = 2;
+     int mnDefSkipBase = 1;
+     int mnCount = 0;
+     bool mbRecvIFrame = false;
+};
+}
+
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Status;
+
+class grpcclient : public QThread
+{
+public:
+    grpcclient(std::string stryamlpath);
+    ~grpcclient();
+
+private:
+    std::string gstrserverip = "127.0.0.1";//111.33.136.149";//"0.0.0.0";//"192.168.14.98";// "123.57.212.138";
+    std::string gstrserverport = "50051";//"9000";
+    std::string gstruploadinterval = "1000";
+    void * gpa;
+    QMutex gMutexMsg;
+    std::thread * guploadthread;
+
+
+
+
+    std::vector<iv::msgunit> mvectormsgunit;
+
+    std::vector<iv::msgunit> mvectorctrlmsgunit;
+
+
+    std::string gstrVIN = "AAAAAAAAAAAAAAAAA";
+    std::string gstrqueryMD5 = "5d41402abc4b2a76b9719d911017c591";//"5d41402abc4b2a76b9719d911017c592";
+    std::string gstrctrlMD5 = "5d41402abc4b2a76b9719d911017c591";
+
+
+
+    int gindex = 0;
+public:
+    void UpdateData(const char * strdata,const unsigned int nSize,const char * strmemname);
+    void UpdatePicData(const char * strdata,const unsigned int nSize,const char * strmemname);
+private:
+    void run();
+    void dec_yaml(const char * stryamlpath);
+    void sharectrlmsg(iv::cloud::cloudmsg * pxmsg);
+
+private:
+    void threadpicupload(int nCamPos);
+
+    iv::threadpicunit mpicbuf[NUM_CAM];
+
+    void * mpaPic[NUM_CAM];
+    std::string mstrpicmsgname[NUM_CAM];
+
+    std::thread * mpThread[NUM_CAM * NUM_THREAD_PERCAM];
+
+    bool mbPicUpload = true;
+
+    qint64 CalcLateny(std::vector<qint64> & xvectorlatency);
+
+    int mnskip = 2;
+
+};
+
+#endif // GRPCCLIENT_H

+ 67 - 0
src/driver/driver_cloud_grpc_client_h264/main.cpp

@@ -0,0 +1,67 @@
+#include <QCoreApplication>
+
+#include <signal.h>
+
+#include "grpcclient.h"
+
+#include "ivversion.h"
+#include "ivexit.h"
+#include "ivbacktrace.h"
+
+static QCoreApplication * gApp;
+
+static grpcclient * gpgrpcclient;
+
+void ExitFunc()
+{
+//    gApp->quit();
+    delete gpgrpcclient;
+    std::cout<<"driver_cloud_grpc_thread exit."<<std::endl;
+    gApp->quit();
+}
+
+void signal_handler(int sig)
+{
+    if(sig == SIGINT)
+    {
+        ExitFunc();
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    showversion("driver_cloud_grpc_client");
+
+    RegisterIVBackTrace();
+
+
+
+    QCoreApplication a(argc, argv);
+    gApp = &a;
+
+ //   std::thread * ptest = new std::thread(test);
+
+ //   return a.exec();
+
+    char stryamlpath[256];
+    if(argc<2)
+    {
+        snprintf(stryamlpath,255,"driver_cloud_grpc_client_h264.yaml");
+//        strncpy(stryamlpath,abs_ymlpath,255);
+    }
+    else
+    {
+        strncpy(stryamlpath,argv[1],255);
+    }
+//    dec_yaml(stryamlpath);
+
+    grpcclient * pgrpcclient = new grpcclient(stryamlpath);
+    pgrpcclient->start();
+    gpgrpcclient = pgrpcclient;
+
+    signal(SIGINT,signal_handler);
+
+    iv::ivexit::RegIVExitCall(ExitFunc);
+
+    return a.exec();
+}

+ 4 - 0
src/driver/driver_cloud_grpc_client_h264/prototocpp.txt

@@ -0,0 +1,4 @@
+protoc -I=./../../include/proto3 --plugin=protoc-gen-grpc=/home/yuchuli/git/grpc-framework/build2/grpc_cpp_plugin --grpc_out=. ./../../include/proto3/uploadthreadmsg.proto
+
+protoc -I=./../../include/proto3 --cpp_out=./../../include/msgtype   ./../../include/proto3/uploadthreadmsg.proto
+

+ 64 - 0
src/driver/driver_cloud_grpc_server_h264/clientime.cpp

@@ -0,0 +1,64 @@
+#include "clientime.h"
+
+clientime::clientime()
+{
+
+}
+
+iv::clientinfo * clientime::FindClientInfo(std::string strclientid)
+{
+    unsigned int i;
+    bool bFind = false;
+    unsigned int nPos= 0;
+    for(i=0;i<mvectorclient.size();i++)
+    {
+        if(strclientid == mvectorclient[i].mstrclientid)
+        {
+            bFind = true;
+            nPos = i;
+            break;
+        }
+    }
+    if(bFind)
+    {
+        return &mvectorclient[nPos];
+    }
+
+    iv::clientinfo xclient;
+    xclient.mstrclientid = strclientid;
+    for(i=0;i<CAM_NUM;i++)
+    {
+        xclient.mnCamLastTime[i] = 0;
+    }
+    mvectorclient.push_back(xclient);
+    return &mvectorclient[mvectorclient.size() -1];
+
+}
+
+int clientime::SetClientCamLastTime(std::string strclientid, int nCamPos, qint64 nLastTime)
+{
+    if((nCamPos<0)||(nCamPos >= CAM_NUM))
+    {
+        return -1;
+    }
+
+    mMutex.lock();
+    iv::clientinfo * pclient = FindClientInfo(strclientid);
+    pclient->mnCamLastTime[nCamPos] = nLastTime;
+    mMutex.unlock();
+    return 0;
+}
+
+int clientime::GetClientCamLastTime(std::string strclientid, int nCamPos, qint64 &nLastTime)
+{
+    if((nCamPos<0)||(nCamPos >= CAM_NUM))
+    {
+        return -1;
+    }
+    mMutex.lock();
+    iv::clientinfo * pclient = FindClientInfo(strclientid);
+    nLastTime = pclient->mnCamLastTime[nCamPos];
+    mMutex.unlock();
+    return 0;
+
+}

+ 40 - 0
src/driver/driver_cloud_grpc_server_h264/clientime.h

@@ -0,0 +1,40 @@
+#ifndef CLIENTIME_H
+#define CLIENTIME_H
+
+#include <string>
+#include <vector>
+#include <QThread>
+#include <QMutex>
+
+#ifndef CAM_NUM
+#define  CAM_NUM 4
+#endif
+
+namespace  iv {
+
+struct clientinfo
+{
+  std::string mstrclientid;
+  qint64 mnCamLastTime[CAM_NUM];
+};
+}
+
+
+class clientime
+{
+public:
+    clientime();
+
+private:
+    std::vector<iv::clientinfo> mvectorclient;
+    QMutex mMutex;
+
+private:
+    inline iv::clientinfo * FindClientInfo(std::string strclientid);
+
+public:
+    int GetClientCamLastTime(std::string strclientid,int nCamPos,qint64 & nLastTime);
+    int SetClientCamLastTime(std::string strclientid,int nCamPos,qint64 nLastTime);
+};
+
+#endif // CLIENTIME_H

+ 224 - 0
src/driver/driver_cloud_grpc_server_h264/cumsgbuffer.cpp

@@ -0,0 +1,224 @@
+#include "cumsgbuffer.h"
+
+cumsgbuffer::cumsgbuffer()
+{
+
+}
+
+void cumsgbuffer::addmsg(int id, qint64 ntime, std::string strVIN, std::string strqueryMD5, std::string strctrlMD5, std::vector<char> *pxdata,bool bImportant,int nkeeptime)
+{
+    qDebug("ntime is %lld",ntime);
+    mMutex.lock();
+    iv::cumsg * pmsg = 0;
+    int nsize = mvectormsg.size();
+    int i;
+    for(i=0;i<nsize;i++)
+    {
+        if(strncmp(mvectormsg[i].strVIN.data(),strVIN.data(),255) == 0)
+        {
+            pmsg = &mvectormsg[i];
+            break;
+        }
+    }
+    if(pmsg == 0)
+    {
+        iv::cumsg cmsg;
+        cmsg.id = id;
+        cmsg.ntime = ntime;
+        cmsg.strVIN = strVIN;
+        cmsg.strqueryMD5 = strqueryMD5;
+        cmsg.strctrlMD5 = strctrlMD5;
+        if(pxdata->size() > 0)
+        {
+            cmsg.xdata.resize(pxdata->size());
+            memcpy(cmsg.xdata.data(),pxdata->data(),pxdata->size());
+        }
+        cmsg.mlastuptime = QDateTime::currentMSecsSinceEpoch();
+        cmsg.mbImportant = bImportant;
+        cmsg.mkeeptime = nkeeptime;
+        cmsg.mbhavequery = false;
+        mvectormsg.push_back(cmsg);
+        mMutex.unlock();
+        return;
+    }
+
+    if((pmsg->mbImportant != true)||(pmsg->mbhavequery)||((QDateTime::currentMSecsSinceEpoch() - pmsg->mlastuptime)>=pmsg->mkeeptime))
+    {
+        pmsg->id = id;
+        pmsg->ntime = ntime;
+        pmsg->mbImportant = bImportant;
+        pmsg->mbhavequery = false;
+        pmsg->mlastuptime = QDateTime::currentMSecsSinceEpoch();
+        pmsg->mkeeptime = nkeeptime;
+        pmsg->strqueryMD5 = strqueryMD5;
+        pmsg->strctrlMD5 = strctrlMD5;
+        pmsg->xdata.clear();
+        if(pxdata->size()>0)
+        {
+            pmsg->xdata.resize(pxdata->size());
+            memcpy(pmsg->xdata.data(),pxdata->data(),pxdata->size());
+        }
+    }
+
+    mMutex.unlock();
+}
+
+
+int cumsgbuffer::getmsg(std::string strVIN,std::string strqueryMD5, qint64 nlasttime, int &id, qint64 &ntime,   std::vector<char> *pxdata)
+{
+    mMutex.lock();
+    iv::cumsg * pmsg = 0;
+    int nsize = mvectormsg.size();
+    int i;
+    for(i=0;i<nsize;i++)
+    {
+        if(strncmp(mvectormsg[i].strVIN.data(),strVIN.data(),255) == 0)
+        {
+            pmsg = &mvectormsg[i];
+            break;
+        }
+    }
+
+    if(pmsg == 0)
+    {
+        std::cout<<" no this vin data"<<std::endl;;
+        mMutex.unlock();
+        return -1;
+    }
+
+    if(strqueryMD5 != pmsg->strqueryMD5)
+    {
+        std::cout<<" query error."<<std::endl;
+        mMutex.unlock();
+        return -2;
+    }
+    pmsg->mbhavequery = true;
+    if(nlasttime == pmsg->ntime)
+    {
+        mMutex.unlock();
+        return 0;
+    }
+    id = pmsg->id;
+    ntime = pmsg->ntime;
+    pxdata->clear();
+    int ndatasize = pmsg->xdata.size();
+    pxdata->resize(ndatasize);
+    memcpy(pxdata->data(),pmsg->xdata.data(),ndatasize);
+    mMutex.unlock();
+    return 1;
+}
+
+void cumsgbuffer::addPicData(std::string strVIN, const char *strdata, const unsigned int ndatasize,
+                             qint64 npictime, int nCamPos,qint64 nLatency)
+{
+    if(ndatasize<5)return;
+    mMutex.lock();
+    iv::cumsg * pmsg = 0;
+    int nsize = mvectormsg.size();
+    int i;
+    for(i=0;i<nsize;i++)
+    {
+        if(strncmp(mvectormsg[i].strVIN.data(),strVIN.data(),255) == 0)
+        {
+            pmsg = &mvectormsg[i];
+            break;
+        }
+    }
+    if(pmsg == 0)
+    {
+        std::cout<<" Not Found buf. Need Data Prepare."<<std::endl;
+    }
+    else
+    {
+        if((nCamPos<0)||(nCamPos>= CAM_NUM))
+        {
+            std::cout<<"Camera Postion error . nCamPos = "<<nCamPos<<std::endl;
+        }
+        else
+        {
+            iv::PicData xPicData;
+            xPicData.mdata_ptr = std::shared_ptr<char>(new char[ndatasize]);
+            memcpy(xPicData.mdata_ptr.get(),strdata,ndatasize);
+            xPicData.mdatasize = ndatasize;
+            xPicData.mnMsgTime = npictime;
+            if((strdata[4] == 0x27)||(strdata[4] == 0x47)||(strdata[4] == 0x67))
+            {
+                xPicData.mbSPSFrame = true;
+            }
+            pmsg->mpicbuf[nCamPos].AddData(xPicData);
+            pmsg->mpicbuf[nCamPos].SetLatency(nLatency);
+        }
+    }
+
+//    std::cout<<" add data. "<<npictime<<"size: "<<ndatasize<<std::endl;
+
+    mMutex.unlock();
+}
+
+int cumsgbuffer::getPicData(std::string strVIN, std::string strqueryMD5,std::shared_ptr<char> &pdata_ptr,
+                            unsigned int &ndatasize,std::string strclientid, int nCamPos,qint64 & nPicTime,qint64 & nPicLatency,int & nFrameRate)
+{
+    mMutex.lock();
+    iv::cumsg * pmsg = 0;
+    int nsize = mvectormsg.size();
+    int i;
+    for(i=0;i<nsize;i++)
+    {
+        if(strncmp(mvectormsg[i].strVIN.data(),strVIN.data(),255) == 0)
+        {
+            pmsg = &mvectormsg[i];
+            break;
+        }
+    }
+
+    if(pmsg == 0)
+    {
+        std::cout<<" no this vin data"<<std::endl;;
+        mMutex.unlock();
+        return -1;
+    }
+
+    if(strqueryMD5 != pmsg->strqueryMD5)
+    {
+        std::cout<<" query error."<<std::endl;
+        mMutex.unlock();
+        return -2;
+    }
+
+    if((nCamPos<0)||(nCamPos>= CAM_NUM))
+    {
+        std::cout<<"cumsgbuffer::getPicData Camera Postion error . nCamPos = "<<nCamPos<<std::endl;
+        mMutex.unlock();
+        return -3;
+    }
+
+    qint64 nLastPicTime = 0;
+
+    if(mclienttime.GetClientCamLastTime(strclientid,nCamPos,nLastPicTime) < 0)
+    {
+        std::cout<<"cumsgbuffer::getPicData Can't Get Camera LastTime"<<std::endl;
+        mMutex.unlock();
+        return -4;
+    }
+
+    iv::PicData xPicData;
+    int nrtn = pmsg->mpicbuf[nCamPos].GetData(nLastPicTime,xPicData);
+    if(nrtn == 1)
+    {
+        pdata_ptr = xPicData.mdata_ptr;
+        ndatasize = xPicData.mdatasize;
+        nPicTime = nLastPicTime;
+    }
+
+    nPicLatency = pmsg->mpicbuf[nCamPos].GetLatency();
+    nFrameRate = pmsg->mpicbuf[nCamPos].GetFrameRate();
+
+    mclienttime.SetClientCamLastTime(strclientid,nCamPos,nLastPicTime);
+
+
+    mMutex.unlock();
+
+//    std::cout<<" query ntrn : "<<nrtn<<std::endl;
+    return nrtn;
+}
+

+ 73 - 0
src/driver/driver_cloud_grpc_server_h264/cumsgbuffer.h

@@ -0,0 +1,73 @@
+#ifndef CUMSGBUFFER_H
+#define CUMSGBUFFER_H
+
+#include <QDateTime>
+#include <QMutex>
+#include <string>
+#include <iostream>
+#include <vector>
+
+#include <memory>
+
+#include <picbuf.h>
+#include "clientime.h"
+
+#ifndef CAM_NUM
+#define CAM_NUM 4
+#endif
+
+namespace iv {
+struct cumsg
+{
+
+public:
+
+    int id;
+    qint64 ntime;
+    std::string strVIN;
+    std::string strqueryMD5;
+    std::string strctrlMD5;
+    std::vector<char> xdata;
+    qint64 mlastuptime;  //更新时间
+    bool mbImportant = false;
+    int mkeeptime;
+    bool mbhavequery = false;
+    PicBuf mpicbuf[CAM_NUM];
+};
+}
+
+class cumsgbuffer
+{
+public:
+    cumsgbuffer();
+
+private:
+    std::vector<iv::cumsg> mvectormsg;
+    clientime mclienttime;
+
+    QMutex mMutex;
+
+public:
+    void addmsg(int id,qint64 ntime,std::string strVIN,std::string strqueryMD5,
+                std::string strctrlMD5,std::vector<char> * pxdata,bool bImportant,int nkeeptime);
+
+
+    //if no new msg return 0
+    // -1 no this vin
+    // -2 queryMD5 error
+    int getmsg(std::string strVIN,std::string strqueryMD5,qint64 nlasttime, int & id,qint64 & ntime,
+                std::vector<char> * pxdata);
+
+
+    void addPicData(std::string strVIN,const char * strdata,const unsigned int ndatasize,qint64 npictime,int nCamPos,qint64 nLatency);
+
+    int getPicData(std::string strVIN,std::string strqueryMD5,std::shared_ptr<char> & pdata_ptr,unsigned int & ndatasize,
+                   std::string strclientid,int nCamPos,qint64 & nPicTime,qint64 & nPicLatency,int & nFrameRate);
+
+
+
+
+
+};
+
+#endif // CUMSGBUFFER_H

+ 59 - 0
src/driver/driver_cloud_grpc_server_h264/driver_cloud_grpc_server_h264.pro

@@ -0,0 +1,59 @@
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+QMAKE_LFLAGS += -no-pie
+
+
+# The following define makes your compiler emit warnings if you use
+# any Qt feature that has been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+        ../../include/msgtype/uploadthreadmsg.pb.cc \
+        ../driver_cloud_grpc_thread/uploadthreadmsg.grpc.pb.cc \
+        cumsgbuffer.cpp \
+        main.cpp \
+        pcmsgbuffer.cpp \
+        picbuf.cpp \
+    clientime.cpp
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+!include(../../../include/common.pri ) {
+    error( "Couldn't find the common.pri file!" )
+}
+
+!include(../../../include/ivprotobuf.pri ) {
+    error( "Couldn't find the ivprotobuf.pri file!" )
+}
+
+!include(../../../include/ivboost.pri ) {
+    error( "Couldn't find the ivboost.pri file!" )
+}
+
+!include(../../../include/ivgrpc.pri ) {
+    error( "Couldn't find the ivgrpc.pri file!" )
+}
+
+
+INCLUDEPATH += $$PWD/../driver_cloud_grpc_thread
+
+HEADERS += \
+    ../../include/msgtype/uploadthreadmsg.pb.h \
+    ../driver_cloud_grpc_thread/uploadthreadmsg.grpc.pb.h \
+    cumsgbuffer.h \
+    pcmsgbuffer.h  \
+    picbuf.h \
+    clientime.h

+ 216 - 0
src/driver/driver_cloud_grpc_server_h264/main.cpp

@@ -0,0 +1,216 @@
+#include <QCoreApplication>
+#include <QDateTime>
+#include <iostream>
+#include <vector>
+
+#include "cumsgbuffer.h"
+#include "pcmsgbuffer.h"
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+#include <grpcpp/health_check_service_interface.h>
+#include <grpcpp/ext/proto_server_reflection_plugin.h>
+
+#include "uploadthreadmsg.grpc.pb.h"
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::Status;
+
+
+
+#include <QDateTime>
+
+
+
+
+
+
+static cumsgbuffer gcumsgbuf;
+static pcmsgbuffer gpcmsgbuf;
+
+
+// Logic and data behind the server's behavior.
+class UploadServiceImpl final : public iv::UploadThread::Service {
+  Status uploaddata(ServerContext* context, const iv::UploadRequestThread* request,
+                  iv::UploadReplyThread* reply) override {
+
+    std::vector<char> xvectordata;
+    qDebug("size is %d",request->xdata().size());
+    if(request->xdata().size()>0)
+    {
+
+        xvectordata.resize(request->xdata().size());
+        memcpy(xvectordata.data(),request->xdata().data(),request->xdata().size());
+    }
+
+    gcumsgbuf.addmsg(request->id(),request->ntime(),request->strvin(),request->strquerymd5(),request->strctrlmd5(),
+                     &xvectordata,request->bimportant(),request->kepptime());
+
+ //   std::string strVIN,strctrlMD5;
+    int id;
+    qint64 ntime;
+
+    std::vector<char > xvectorctrldata;
+
+    int nres = gpcmsgbuf.getmsg(request->strvin(),request->strctrlmd5(),id,ntime,&xvectorctrldata);
+
+    reply->set_nres(nres);
+    reply->set_nreqsendtime(request->nsendtime());
+
+    if(nres == 1)
+    {
+
+        reply->set_xdata(xvectorctrldata.data(),xvectorctrldata.size());
+    }
+
+
+
+//    char * strdata = new char[10000000];
+//    qint64 time = QDateTime::currentMSecsSinceEpoch();
+//    memcpy(strdata,&time,8);
+//    reply->set_data(strdata,10000000);
+//    delete strdata;
+    return Status::OK;
+  }
+
+  Status queryctrl(ServerContext* context, const iv::queryReqThread* request,
+                  iv::queryReplyThread* reply) override {
+
+      int id;
+      qint64 ntime;
+      std::vector<char > xvectorquerydata;
+
+      std::vector<char> xvectordata;
+      if(request->xdata().size()>0)
+      {
+          xvectordata.resize(request->xdata().size());
+          memcpy(xvectordata.data(),request->xdata().data(),request->xdata().size());
+          gpcmsgbuf.addmsg(request->id(),request->ntime(),request->strvin(),request->strctrlmd5(),&xvectordata,
+                                     request->bimportant(),request->kepptime());
+      }
+
+
+
+      int nres = gcumsgbuf.getmsg(request->strvin(),request->strquerymd5(),request->nlasttime(),id,ntime,&xvectorquerydata);
+
+      reply->set_nres(nres);
+      if(nres > 0)
+      {
+          reply->set_xdata(xvectorquerydata.data(),xvectorquerydata.size());
+          reply->set_id(id);
+          reply->set_ntime(ntime);
+      }
+
+      return Status::OK;
+
+
+  }
+
+  Status uploadpic(ServerContext* context, const iv::PicUpRequestThread* request,
+                  iv::PicUpReplyThread* reply) override {
+      gcumsgbuf.addPicData(request->strvin(),request->xdata().data(),
+                           request->xdata().size(),request->npictime(),request->ncampos(),request->nlatency());
+      reply->set_nres(0);
+      reply->set_npicsendtime(request->npictime());
+
+
+      return Status::OK;
+
+  }
+
+  Status querypic(grpc::ServerContext *context, const iv::PicDownReqThread *request, iv::PicDownReplyThread *response) override {
+
+        std::shared_ptr<char> pstr_data;
+        unsigned int ndatasize;
+        qint64 nPicTime = request->npicquerytime() ;
+        qint64 nPicLatency;
+        int nFrameRate;
+        int nres =gcumsgbuf.getPicData(request->strvin(),request->strquerymd5(),pstr_data,ndatasize,request->strclientid(), request->ncampos(),nPicTime,
+                                       nPicLatency,nFrameRate);
+ //       std::cout<<" reply pic : "<<nres<<std::endl;
+        response->set_nres(nres);
+        if(nres == 1)
+        {
+            response->set_ncampos(request->ncampos());
+            response->set_npictime(nPicTime);
+            response->set_xdata(pstr_data.get(),ndatasize);
+            response->set_npicframerate(nFrameRate);
+            response->set_npicuplatency(nPicLatency);
+        }
+
+        return Status::OK;
+  }
+
+//  Status ctrl(ServerContext* context, const iv::ctrlreq* request,
+//                  iv::ctrlReply * reply) override {
+
+//      std::vector<char> xvectordata;
+//      if(request->data().size()>0)
+//      {
+//          xvectordata.resize(request->data().size());
+//          memcpy(xvectordata.data(),request->data().data(),request->data().size());
+//      }
+
+//      int nid = gpcmsgbuf.addmsg(request->id(),request->ntime(),request->strvin(),request->strctrlmd5(),&xvectordata,
+//                                 request->bimportant(),request->kepptime());
+
+//      reply->set_nsendid(nid);
+
+
+//      return Status::OK;
+
+
+//  }
+
+
+};
+
+void RunServer() {
+  std::string server_address("0.0.0.0:50051");
+  UploadServiceImpl service;
+
+  grpc::EnableDefaultHealthCheckService(true);
+//  grpc::reflection::InitProtoReflectionServerBuilderPlugin();
+  ServerBuilder builder;
+  // Listen on the given address without any authentication mechanism.
+  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+
+  builder.SetMaxReceiveMessageSize(300000000);
+ // builder.SetMaxMessageSize(100000000);
+
+
+//  builder.SetMaxSendMessageSize(100000000);
+  // Register "service" as the instance through which we'll communicate with
+  // clients. In this case it corresponds to an *synchronous* service.
+  builder.RegisterService(&service);
+  // Finally assemble the server.
+  std::unique_ptr<Server> server(builder.BuildAndStart());
+  std::cout << "Server listening on " << server_address << std::endl;
+
+  // Wait for the server to shutdown. Note that some other thread must be
+  // responsible for shutting down the server for this call to ever return.
+  server->Wait();
+}
+
+
+
+
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+    gpcmsgbuf.start();
+
+    RunServer();
+
+
+
+
+    return a.exec();
+}

+ 171 - 0
src/driver/driver_cloud_grpc_server_h264/pcmsgbuffer.cpp

@@ -0,0 +1,171 @@
+#include "pcmsgbuffer.h"
+
+pcmsgbuffer::pcmsgbuffer()
+{
+
+}
+
+void pcmsgbuffer::run()
+{
+    while(!QThread::isInterruptionRequested())
+    {
+        mMutex.lock();
+        qint64 nowtime = QDateTime::currentMSecsSinceEpoch();
+        int i;
+        for(i=0;i<mvectorpcmsgstate.size();i++)
+        {
+            if((nowtime - mvectorpcmsgstate[i].nsendtime) > OVERTIME)
+            {
+                mvectorpcmsgstate.erase(mvectorpcmsgstate.begin() + i);
+                i--;
+            }
+        }
+        mMutex.unlock();
+        msleep(100);
+    }
+}
+
+unsigned int pcmsgbuffer::addmsg(int id, qint64 ntime, std::string strVIN, std::string strctrlMD5, std::vector<char> *pxdata,bool bImportant,int nkeeptime)
+{
+    unsigned int nrtn;
+    mMutex.lock();
+    iv::pcmsg * pmsg = 0;
+    int nsize = mvectormsg.size();
+    int i;
+    for(i=0;i<nsize;i++)
+    {
+        if(strncmp(mvectormsg[i].strVIN.data(),strVIN.data(),255) == 0)
+        {
+            pmsg = &mvectormsg[i];
+            break;
+        }
+    }
+    if(pmsg == 0)
+    {
+        iv::pcmsg cmsg;
+        cmsg.id = id;
+        cmsg.ntime = ntime;
+        cmsg.strVIN = strVIN;
+        cmsg.strctrlMD5 = strctrlMD5;
+        if(pxdata->size() > 0)
+        {
+            cmsg.xdata.resize(pxdata->size());
+            memcpy(cmsg.xdata.data(),pxdata->data(),pxdata->size());
+        }
+        cmsg.mlastuptime = QDateTime::currentMSecsSinceEpoch();
+        cmsg.nsendid = muid;
+        cmsg.mbImportant = bImportant;
+        cmsg.mkeeptime = nkeeptime;
+        nrtn = muid;
+        muid++;
+        mvectormsg.push_back(cmsg);
+        iv::pcmsgstate xpms;xpms.nsendid = cmsg.nsendid;
+        xpms.nsendtime = QDateTime::currentMSecsSinceEpoch();
+        mvectorpcmsgstate.push_back(xpms);
+        mMutex.unlock();
+        return nrtn;
+    }
+
+    if((pmsg->mbImportant != true)||((QDateTime::currentMSecsSinceEpoch() - pmsg->mlastuptime)>=pmsg->mkeeptime))
+    {
+        changesendstate(pmsg->nsendid,-2);
+        pmsg->mbImportant = bImportant;
+        pmsg->mkeeptime = nkeeptime;
+        pmsg->id = id;
+        pmsg->ntime = ntime;
+        pmsg->strctrlMD5 = strctrlMD5;
+        pmsg->xdata.clear();
+        pmsg->nsendid = muid;
+ //       cmsg.mlastuptime = QDateTime::currentMSecsSinceEpoch();
+        nrtn = muid;
+        iv::pcmsgstate xpms;xpms.nsendid = pmsg->nsendid;
+        pmsg->mlastuptime = QDateTime::currentMSecsSinceEpoch();
+        mvectorpcmsgstate.push_back(xpms);
+        muid++;
+        if(pxdata->size()>0)
+        {
+            pmsg->xdata.resize(pxdata->size());
+            memcpy(pmsg->xdata.data(),pxdata->data(),pxdata->size());
+        }
+    }
+
+
+    mMutex.unlock();
+    return nrtn;
+}
+
+int pcmsgbuffer::getmsg(std::string strVIN, std::string strctrlMD5, int &id, qint64 &ntime, std::vector<char> *pxdata)
+{
+    mMutex.lock();
+    iv::pcmsg * pmsg = 0;
+    int nsize = mvectormsg.size();
+    int i;
+    int npos;
+    for(i=0;i<nsize;i++)
+    {
+        if(strncmp(mvectormsg[i].strVIN.data(),strVIN.data(),255) == 0)
+        {
+            pmsg = &mvectormsg[i];
+            npos = i;
+            break;
+        }
+    }
+
+    if(pmsg == 0)
+    {
+        std::cout<<" no this vin data"<<std::endl;;
+        mMutex.unlock();
+        return 0;
+    }
+    if(strctrlMD5 != pmsg->strctrlMD5)
+    {
+        std::cout<<" ctrl error."<<std::endl;
+        changesendstate(pmsg->nsendid,-1);
+        mMutex.unlock();
+        return -2;
+    }
+
+    id = pmsg->id;
+    ntime = pmsg->ntime;
+    pxdata->clear();
+    int ndatasize = pmsg->xdata.size();
+    pxdata->resize(ndatasize);
+    memcpy(pxdata->data(),pmsg->xdata.data(),ndatasize);
+    changesendstate(pmsg->nsendid,1);
+
+    mvectormsg.erase(mvectormsg.begin()+npos);
+    mMutex.unlock();
+    return 1;
+}
+
+void pcmsgbuffer::changesendstate(int nsendid, int nstate)
+{
+    int nstatesize = mvectorpcmsgstate.size();
+    int i;
+    for(i=0;i<nstatesize;i++)
+    {
+        if(nsendid == mvectorpcmsgstate[i].nsendid)
+        {
+            mvectorpcmsgstate[i].nstate = nstate; //Send OK
+            break;
+        }
+    }
+}
+
+int pcmsgbuffer::querysendstate(int nsendid)
+{
+    int nrtn = -2;
+    mMutex.lock();
+    int nstatesize = mvectorpcmsgstate.size();
+    int i;
+    for(i=0;i<nstatesize;i++)
+    {
+        if(nsendid == mvectorpcmsgstate[i].nsendid)
+        {
+            nrtn = mvectorpcmsgstate[i].nstate;
+            break;
+        }
+    }
+    mMutex.unlock();
+    return nrtn;
+}

+ 66 - 0
src/driver/driver_cloud_grpc_server_h264/pcmsgbuffer.h

@@ -0,0 +1,66 @@
+#ifndef PCMSGBUFFER_H
+#define PCMSGBUFFER_H
+
+#include <QDateTime>
+#include <QMutex>
+#include <string>
+#include <iostream>
+
+#include <QThread>
+
+namespace iv {
+struct pcmsg
+{
+    int id;
+    qint64 ntime;
+    std::string strVIN;
+    std::string strctrlMD5;
+    std::vector<char> xdata;
+    qint64 mlastuptime;  //更新时间
+    unsigned int nsendid; //send id
+    bool mbImportant = false;
+    int mkeeptime;
+    bool mbhavequery = false;
+};
+}
+
+namespace  iv {
+struct pcmsgstate
+{
+    qint64 nsendtime;
+    unsigned int nsendid;
+    int nstate = 0; //0 wait send 1 send ok -1 md5 error -2 timeout.
+};
+}
+
+class pcmsgbuffer:public QThread
+{
+public:
+    pcmsgbuffer();
+
+private:
+    std::vector<iv::pcmsg> mvectormsg;
+    std::vector<iv::pcmsgstate> mvectorpcmsgstate;
+    QMutex mMutex;
+    const int OVERTIME = 60000; //60 seconds
+    unsigned int muid = 0;
+
+public:
+
+    unsigned int addmsg(int id,qint64 ntime,std::string strVIN,
+                std::string strctrlMD5,std::vector<char> * pxdata,bool bImportant,int nkeeptime);
+
+    //if no new msg return 0
+    // -2 queryMD5 error
+    int getmsg(std::string strVIN,std::string strctrlMD5,int & id,qint64 & ntime,
+                std::vector<char> * pxdata);
+
+    int querysendstate(int nsendid);
+private:
+    void changesendstate(int nsendid,int nstate);
+
+private:
+    void run();
+};
+
+#endif // PCMSGBUFFER_H

+ 114 - 0
src/driver/driver_cloud_grpc_server_h264/picbuf.cpp

@@ -0,0 +1,114 @@
+#include "picbuf.h"
+
+#include <iostream>
+
+PicBuf::PicBuf()
+{
+
+}
+
+void PicBuf::AddData(iv::PicData xPicData)
+{
+ //   std::cout<<"pic time is "<<xPicData.mnMsgTime<<std::endl;
+    qint64 xsecond = QDateTime::currentMSecsSinceEpoch()/1000;
+    mnFrameSecondCount++;
+    if(xsecond != mnSecondTime)
+    {
+        mnSecondTime = xsecond;
+        mnFrameRate = mnFrameSecondCount;
+        mnFrameSecondCount = 0;
+        std::cout<<"pic framefate: "<<mnFrameRate<<std::endl;
+
+    }
+    mMutexBuf.lock();
+
+
+    if(mvectordata_ptr.size() == 0)
+    {
+        mvectordata_ptr.push_back(xPicData);
+        mLastBufTime = xPicData.mnMsgTime;
+        mMutexBuf.unlock();
+        return;
+    }
+
+
+    mvectordata_ptr.push_back(xPicData);
+    mLastBufTime = xPicData.mnMsgTime;
+
+    int i;
+    bool bRemove = false;
+    for(i=0;i<(int)(mvectordata_ptr.size());i++)
+    {
+        if(abs(mLastBufTime - mvectordata_ptr.at(i).mnMsgTime) > mBufTime)
+        {
+            bRemove = true;
+            mvectordata_ptr.erase(mvectordata_ptr.begin() + i);
+            i--;
+        }
+
+    }
+    if(bRemove)
+    {
+        while(mvectordata_ptr.size()>0)
+        {
+            if(mvectordata_ptr[0].mbSPSFrame)break;
+            mvectordata_ptr.erase(mvectordata_ptr.begin());
+        }
+    }
+
+    mMutexBuf.unlock();
+}
+
+int PicBuf::GetData(qint64 &nLastTime, iv::PicData &xPicData)
+{
+    int nrtn = 0;
+    mMutexBuf.lock();
+    if(nLastTime > mLastBufTime)
+    {
+        nLastTime = mLastBufTime;
+        mMutexBuf.unlock();
+        return 0;
+    }
+
+    unsigned int i;
+    for(i=0;i<mvectordata_ptr.size();i++)
+    {
+        if(mvectordata_ptr.at(i).mnMsgTime > (mLastBufTime - mnReceiveBufTime ))
+        {
+            break; //becuase in this time Data not complete.
+        }
+        if(mvectordata_ptr.at(i).mnMsgTime > nLastTime)
+        {
+            nLastTime = mvectordata_ptr.at(i).mnMsgTime;
+            xPicData = mvectordata_ptr.at(i);
+            nrtn = 1;
+            break;
+        }
+    }
+    mMutexBuf.unlock();
+//    if(nrtn == 0)std::cout<<" no data. "<<std::endl;
+    return nrtn;
+}
+
+PicBuf::PicBuf(const PicBuf &other)
+{
+    mvectordata_ptr = other.mvectordata_ptr;
+    mBufTime = other.mBufTime;
+    mnReceiveBufTime = other.mnReceiveBufTime;
+    mLastBufTime = other.mLastBufTime;
+}
+
+int PicBuf::GetFrameRate()
+{
+    return mnFrameRate;
+}
+
+void PicBuf::SetLatency(qint64 nlatency)
+{
+    mnUpLatency = nlatency;
+}
+
+qint64 PicBuf::GetLatency()
+{
+    return mnUpLatency;
+}

+ 45 - 0
src/driver/driver_cloud_grpc_server_h264/picbuf.h

@@ -0,0 +1,45 @@
+#ifndef PICBUF_H
+#define PICBUF_H
+
+#include <memory>
+#include <vector>
+#include <QMutex>
+#include <QDateTime>
+
+namespace iv {
+struct PicData
+{
+public:
+    qint64 mnMsgTime;
+    std::shared_ptr<char> mdata_ptr;
+    unsigned int mdatasize;
+    bool mbSPSFrame = false;
+};
+
+}
+
+class PicBuf
+{
+private:
+    std::vector<iv::PicData> mvectordata_ptr;
+    qint64 mBufTime = 1500;
+    qint64 mnReceiveBufTime = 0;
+    qint64 mLastBufTime = 0;
+    QMutex mMutexBuf;
+
+private:
+    int mnFrameRate = 0;
+    qint64 mnSecondTime = 0;   //Time  Second.
+    int mnFrameSecondCount =0; //Last Second Receive message
+    qint64 mnUpLatency = 1000;
+public:
+    PicBuf();
+    PicBuf(const PicBuf & other);
+    void AddData(iv::PicData xPicData);
+    int GetData(qint64 & nLastTime,iv::PicData & xPicData);  //0 No Data  1 Have Data
+    int GetFrameRate();
+    void SetLatency(qint64 nlatency);
+    qint64 GetLatency();
+};
+
+#endif // PICBUF_H

+ 15 - 7
src/driver/driver_h264_dec/main.cpp

@@ -68,9 +68,17 @@ void ListenFrame(const char * strdata,const unsigned int nSize,const unsigned in
 
     if(gbStartRecv == false)return;
 
+//    char strout[1000];
+//    memcpy(strout,strdata,100);
+//    char strprint[1000];
+//    sprintf(strprint,"%02x %02x %02x %02x %02x %02x %02x %02x",strout[0],strout[1],
+//            strout[2],strout[3],strout[4],strout[5],strout[6],strout[7]);
+//    std::cout<<strprint<<std::endl;
+
+
     if(bStart == false)
     {
-        if(strdata[4] == 0x27)
+        if((strdata[4] == 0x27)||(strdata[4] == 0x67))
         {
             std::cout<<" SPS Size "<<nSize<<std::endl;
             bStart = true;
@@ -90,12 +98,12 @@ void ListenFrame(const char * strdata,const unsigned int nSize,const unsigned in
 
 
 
-    char strout[1000];
-    memcpy(strout,strdata,100);
-    char strprint[1000];
-    sprintf(strprint,"%02x %02x %02x %02x %02x %02x %02x %02x",strout[0],strout[1],
-            strout[2],strout[3],strout[4],strout[5],strout[6],strout[7]);
-    std::cout<<strprint<<std::endl;
+//    char strout[1000];
+//    memcpy(strout,strdata,100);
+//    char strprint[1000];
+//    sprintf(strprint,"%02x %02x %02x %02x %02x %02x %02x %02x",strout[0],strout[1],
+//            strout[2],strout[3],strout[4],strout[5],strout[6],strout[7]);
+//    std::cout<<strprint<<std::endl;
 
 }
 

+ 1 - 1
src/driver/driver_h264_enc/driver_h264_enc.pro

@@ -35,7 +35,7 @@ SOURCES += main.cpp \
     ../../include/msgtype/rawpic.pb.cc
 
 
-DEFINES += USE_QSV
+#DEFINES += USE_QSV
 
 
 if(contains(DEFINES,USE_QSV)){

+ 2 - 1
src/driver/driver_h264_enc/main.cpp

@@ -128,6 +128,7 @@ void ThreadEnc()
 #ifndef USE_QSV
     av_register_all();
 
+
    codec = avcodec_find_encoder(AV_CODEC_ID_H264);// avcodec_find_encoder_by_name("h264");
 #endif
 
@@ -344,7 +345,7 @@ int main(int argc, char *argv[])
     gnheight = atoi(gstrheight);
 
     void * pa = iv::modulecomm::RegisterRecv("picfront",Listenpic);
-    gpaout = iv::modulecomm::RegisterSend("h264frame",1000000,1);
+    gpaout = iv::modulecomm::RegisterSend("h264front",1000000,1);
     std::thread * pthreadenc = new std::thread(ThreadEnc);
     return a.exec();
 }

+ 341 - 0
src/tool/RemoteCtrl_h264/BaiDuMap.html

@@ -0,0 +1,341 @@
+
+
+<!DOCTYPE html>
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
+    <style type="text/css">
+        body, html, #allmap {
+            width: 100%;
+            height: 100%;
+            overflow: hidden;
+            margin: 0;
+            font-family: "微软雅黑";
+        }
+    </style>
+    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=EVi8PXiYpKBGvBr7tgGMzcbdwzWWNf2o"></script>
+
+    
+    <title>野火GPS地图</title>
+</head>
+<body>
+    <div id="allmap"></div>
+
+
+
+</body>
+</html>
+
+
+
+<script type="text/javascript">
+    try {
+
+   
+    // 百度地图API功能
+    var map = new BMap.Map("allmap");            // 创建Map实例
+
+    //添加拖拽和缩放功能
+    map.enableScrollWheelZoom(true);
+    map.enableDragging();   
+
+    //添加控件和比例尺
+    var top_right_control = new BMap.ScaleControl({ anchor: BMAP_ANCHOR_BOTTOM_LEFT });// 左下角,添加比例尺
+    var top_right_navigation = new BMap.NavigationControl({ anchor: BMAP_ANCHOR_BOTTOM_LEFT });  //左下角,添加默认缩放平移控件
+
+    map.addControl(top_right_control);
+    map.addControl(top_right_navigation);
+
+
+    //添加地图类型
+    var mapType1 = new BMap.MapTypeControl({ mapTypes: [BMAP_NORMAL_MAP, BMAP_HYBRID_MAP] });
+    var mapType2 = new BMap.MapTypeControl({ anchor: BMAP_ANCHOR_TOP_LEFT });
+
+    //添加地图类型和缩略图
+   
+    map.addControl(mapType1);          //2D图,卫星图
+    map.addControl(mapType2);          //左上角,默认地图控件
+
+    var drawtrail = 0;
+
+    var grotation = 0;
+
+
+    //创建点
+    //map.clearOverlays();
+    var point = new BMap.Point(117.355, 39.066);
+    var markerCur = new BMap.Marker(point);
+    var markerObj = new BMap.Marker(point);
+    var havepointlast = 0;
+    var pointlast = new BMap.Point(116,39);
+    var pointobj = new BMap.Point(116,39);
+    var bobjset = 0;
+    var gtracelist = []; 
+    var gtraceraw = [];
+    var tracenow = 0;
+    var tracenum = 0;
+    map.centerAndZoom(point, 18);
+    var convertor = new BMap.Convertor();
+    var polylineTrace;
+/*
+    var polylineTrace =new BMap.Polyline(gtracelist, {
+    enableEditing: false,//是否启用线编辑,默认为false
+    enableClicking: false,//是否响应点击事件,默认为true
+    strokeWeight:'4',//折线的宽度,以像素为单位
+    strokeOpacity: 0.8,//折线的透明度,取值范围0 - 1
+    strokeColor:"red" //折线颜色
+    });*/
+    //var marker = new BMap.Marker(point);  // 创建标注
+    //map.addOverlay(marker);               // 将标注添加到地图中
+    
+    //根据IP定位城市
+    function myFun(result) {
+        var cityName = result.name;
+        map.setCenter(cityName);
+    }
+    var myCity = new BMap.LocalCity();
+    myCity.get(myFun);
+
+	var icon = new BMap.Icon('car.png',new BMap.Size(15,30));
+        icon.imageSize = new BMap.Size(15,30);
+        icon.anchor = new BMap.Size(8,15);
+        
+
+    //showalert(testmsg);
+
+    //对传入的经纬度进行标注:纬度,经度
+   // var Latt = 116.404;
+   // var Lott = 39.915;
+
+   // theLocation(Latt, Lott);
+   // testAlert();
+
+    function SetDrawTrail(x)
+   {
+	
+	if(x == 1)drawtrail = 1;
+	else drawtrail = 0;
+   }    
+
+
+    function clear()
+    {
+	gtracelist = [];
+    }
+
+   
+        // 用经纬度设置地图中心点
+    function objLocation(Longitude,Latitude) {
+
+        var gpsPoint = new BMap.Point(Longitude, Latitude);
+
+	var pointArr = [];
+	pointArr.push(gpsPoint);
+        convertor.translate(pointArr, 1, 5, translateCallbackobj)
+        //gps坐标纠偏
+ //       BMap.Convertor.translate(gpsPoint, 0, translateCallbackobj);     //真实经纬度转成百度坐标
+
+
+    }
+
+    // 用经纬度设置地图中心点
+    function theLocation(Longitude,Latitude,rotation) {
+        
+        grotation = rotation;
+        var gpsPoint = new BMap.Point(Longitude, Latitude);
+
+        //gps坐标纠偏
+
+
+var pointArr = [];
+pointArr.push(gpsPoint);
+        convertor.translate(pointArr, 1, 5, translateCallback)
+//convertor.translate(gpsPoint, 0, translateCallback);     //真实经纬度转成百度坐标
+ //       BMap.Convertor.translate(gpsPoint, 0, translateCallback);     //真实经纬度转成百度坐标
+
+
+            //map.clearOverlays();
+            //var new_point = new BMap.Point(Longitude,Latitude );
+            //var marker = new BMap.Marker(new_point);  // 创建标注
+            //map.addOverlay(marker);              // 将标注添加到地图中
+            //map.panTo(new_point);
+            //marker.setAnimation(BMAP_ANIMATION_BOUNCE); //跳动的动画
+
+    }
+
+
+function settrace(numlist,num2list)                    //仅把qt传来的数组转换成可用的list
+{
+    //alert(numlist);
+    var num_list,num2_list;                         //以下为格式转换,分割成可用的数组
+    num_list = numlist.substring(1,numlist.length-1);
+    num2_list = num2list.substring(1,num2list.length-1);
+    num_list = num_list.split(",");
+    num2_list = num2_list.split(",");
+    //alert("the num_list is: "+num_list[0]+" "+num_list[1]);
+
+    
+    gtraceraw = [];
+    gtracelist = [];
+    for(i=0;i<num_list.length;i++)
+    {
+        point= new BMap.Point(num_list[i],num2_list[i]);
+        gtraceraw.push(point);                                  
+    }
+    tracenum = num_list.length;
+    tracenow = 0;
+
+    setTimeout("converttrace()", 30);// 调用画轨迹的函数
+
+    
+}
+
+function converttrace() 
+{
+    var tracelist = [];     //为轨迹做准备,把所有的点扔里面,但不对每个点标注
+    var index = 0;
+    for(i=tracenow;i<tracenum;i++)
+    {
+	tracelist.push(gtraceraw[i]);
+	index++;
+	if(index>=10)break;
+    }
+    if(index>0)
+    {
+	
+        convertor.translate(tracelist, 1,5,translateCallbacktrace);     //真实经纬度转成百度坐标
+     }
+
+}
+
+
+translateCallbacktrace = function (data){
+      if(data.status == 0) {
+        for (var i = 0; i < data.points.length; i++) {
+	gtracelist.push(data.points[i]);
+        }
+	tracenow = tracenow + data.points.length;
+      }
+
+    map.removeOverlay(polylineTrace);
+    polylineTrace =new BMap.Polyline(gtracelist, {
+    enableEditing: false,//是否启用线编辑,默认为false
+    enableClicking: false,//是否响应点击事件,默认为true
+    strokeWeight:'4',//折线的宽度,以像素为单位
+    strokeOpacity: 0.8,//折线的透明度,取值范围0 - 1
+    strokeColor:"red" //折线颜色
+    });
+    map.addOverlay(polylineTrace);          //增加折线
+      setTimeout("converttrace()", 250);// 调用画轨迹的函数
+	
+}
+
+
+
+
+    // 用经纬度设置地图中心点
+    function testAlert(msg) {
+
+        var str = new String;
+        str =  msg.toString()
+       // str = "test"
+
+        alert(str);
+    }
+
+    function enableZoomDrag()
+    {
+        //添加拖拽和缩放功能
+        map.enableScrollWheelZoom(true);
+        map.enableDragging();
+    }
+
+        //坐标转换完之后的回调函数
+    translateCallbackmap = function (point) {
+
+	gtracelist.push(point);       
+ //       map.setCenter(point);
+      //  marker.setAnimation(BMAP_ANIMATION_BOUNCE); //跳动的动画
+    }
+
+        //坐标转换完之后的回调函数
+    translateCallbacktr = function (point) {
+
+	gtracelist.push(point);       
+ //       map.setCenter(point);
+      //  marker.setAnimation(BMAP_ANIMATION_BOUNCE); //跳动的动画
+    }
+
+    //坐标转换完之后的回调函数
+    translateCallbackobj = function (data) {
+	if(data.status === 0) {
+         var point = data.points[0];
+	pointobj = point;
+	bobjset = 1;
+ //       map.clearOverlays();
+	map.removeOverlay(markerObj);
+        markerObj = new BMap.Marker(point);
+
+        map.addOverlay(markerObj);
+	}
+
+ //       map.setCenter(point);
+      //  marker.setAnimation(BMAP_ANIMATION_BOUNCE); //跳动的动画
+    }
+
+
+    //坐标转换完之后的回调函数
+    translateCallback = function (data) {
+
+if(data.status === 0) {
+         var point = data.points[0]
+        map.removeOverlay(markerCur);
+        markerCur = new BMap.Marker(point);
+        if(havepointlast == 1)
+	{
+		if(drawtrail == 1)
+		{
+		var line = new BMap.Polyline([pointlast, point], {strokeColor: "green", strokeWeight: 1, strokeOpacity: 1});
+		map.addOverlay(line);  
+		line.disableMassClear();
+		}
+	}
+        pointlast = point;
+        havepointlast = 1;
+
+	markerCur.setOffset(-30,-30);
+	markerCur.setIcon(icon); 
+	markerCur.setShadow(icon) 
+	markerCur.setRotation(grotation);
+        map.addOverlay(markerCur);
+        map.setCenter(point);
+      }
+//	return;
+//        map.clearOverlays();
+
+/*
+	if(bobjset == 1)
+	{
+		map.removeOverlay(markerObj);
+        	markerObj = new BMap.Marker(pointobj);
+
+        	map.addOverlay(markerObj);
+	}
+
+*/
+
+      //  marker.setAnimation(BMAP_ANIMATION_BOUNCE); //跳动的动画
+    }
+
+    } catch (e) {
+
+        alert("地图加载失败,请检查网络!");
+
+    }
+
+   
+</script>
+
+
+

+ 11 - 0
src/tool/RemoteCtrl_h264/RemoteCtrl.xml

@@ -0,0 +1,11 @@
+<xml>	
+	<node name="RemoteCtrl">
+		<param name="gpsimu" value="hcp2_gpsimu" />
+		<param name="PicFront" value="picfront" />
+		<param name="PicRear" value="picrear" />
+		<param name="PicLeft" value="picleft" />
+		<param name="PicRight" value="picright" />
+		<param name="joypath" value="/dev/input/js0" />
+		<param name="yamlpath" value="./driver_cloud_grpc_pc.yaml" />
+	</node>
+</xml>

+ 139 - 0
src/tool/RemoteCtrl_h264/RemoteCtrl_h264.pro

@@ -0,0 +1,139 @@
+
+
+!include(../../../include/common.pri ) {
+    error( "Couldn't find the common.pri file!" )
+}
+
+
+contains(QMAKE_HOST.arch, aarch64){
+    QT       += core gui  xml #webenginewidgets    #AGX
+    DEFINES += NVIDIA_AGX
+}else{
+    QT       += core gui  xml network  #webenginewidgets    #x86
+}
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+
+system(protoc -I=./../../include/proto3 --cpp_out=./../../include/msgtype   ./../../include/proto3/uploadthreadmsg.proto)
+# The following define makes your compiler emit warnings if you use
+# any Qt feature that has been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+    ../../common/common/getinterface/get_interface.cpp \
+    ../../common/common/md5/md5_encode.cpp \
+    ../../include/msgtype/gps.pb.cc \
+    ../../include/msgtype/gpsimu.pb.cc \
+    ../../include/msgtype/imu.pb.cc \
+    ../../include/msgtype/plugmsg.pb.cc \
+    ../../include/msgtype/rawpic.pb.cc \
+    ../../include/msgtype/remotectrl.pb.cc \
+    ../../plugin/common/pluginapp.cpp \
+    dialogbigpic.cpp \
+    dialogsetpassword.cpp \
+    dialogsetting.cpp \
+    ivpicview.cpp \
+    ivview.cpp \
+    joyreadthread.cpp \
+    main.cpp \
+    mainwindow.cpp \
+    myview.cpp \
+    remotectrlini.cpp \
+    speed.cpp \
+    ../../driver/driver_cloud_grpc_thread/uploadthreadmsg.grpc.pb.cc \
+    ../../include/msgtype/cloud.pb.cc \
+    dialogpic.cpp \
+    ivpicsave.cpp \
+    ../../include/msgtype/uploadthreadmsg.pb.cc \
+    grpcpc.cpp
+
+HEADERS += \
+    ../../common/common/getinterface/get_interface.h \
+    ../../common/common/md5/md5_encode.h \
+    ../../include/msgtype/gps.pb.h \
+    ../../include/msgtype/gpsimu.pb.h \
+    ../../include/msgtype/imu.pb.h \
+    ../../include/msgtype/plugmsg.pb.h \
+    ../../include/msgtype/rawpic.pb.h \
+    ../../include/msgtype/remotectrl.pb.h \
+    ../../plugin/common/pluginapp.h \
+    dialogbigpic.h \
+    dialogsetpassword.h \
+    dialogsetting.h \
+    ivpicview.h \
+    ivview.h \
+    joyreadthread.h \
+    mainwindow.h \
+    myview.h \
+    pos_def.h \
+    remotectrlini.h \
+    speed.h \
+    ../../driver/driver_cloud_grpc_thread/uploadthreadmsg.grpc.pb.h \
+    ../../include/msgtype/cloud.pb.h \
+    dialogpic.h \
+    ivpicsave.h \
+    ../../include/msgtype/uploadthreadmsg.pb.h \
+    grpcpc.h
+
+FORMS += \
+    dialogbigpic.ui \
+    dialogsetpassword.ui \
+    dialogsetting.ui \
+    mainwindow.ui \
+    dialogpic.ui
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+INCLUDEPATH += /usr/include/opencv4
+
+
+
+INCLUDEPATH += $$PWD/../../driver/driver_cloud_grpc_thread
+
+INCLUDEPATH += $$PWD/../../plugin/common
+
+
+LIBS += -lprotobuf -lyaml-cpp
+
+
+LIBS += -lopencv_highgui -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -lopencv_video  -lopencv_videoio -lpthread #-lopencv_shape
+
+
+#INCLUDEPATH += $$PWD/../../../include/
+#LIBS += -L$$PWD/../../../bin/ -lxmlparam -lmodulecomm -livbacktrace #-livlog -livfault
+
+INCLUDEPATH += $$PWD/../../../thirdpartylib/AGX/qtwebenginewidgets/include/include     # If AGX, Need this line,if x86 please comment this line
+
+contains(QMAKE_HOST.arch, aarch64){
+    LIBS += -lQt5WebEngineWidgets  # If AGX, sudo apt-get install libqt5webenginewidgets5, If x86 comment this line
+}
+
+LIBS += -lQt5WebEngineWidgets
+
+RESOURCES += \
+    remotectrl.qrc
+
+LIBS += -lboost_system
+
+INCLUDEPATH += $$PWD/../../../thirdpartylib/grpc/include
+
+LIBS += -L$$PWD/../../../thirdpartylib/grpc/lib
+
+
+LIBS += -lgrpc++_unsecure -lgrpc++_reflection -labsl_raw_hash_set -labsl_hashtablez_sampler -labsl_exponential_biased -labsl_hash -labsl_bad_variant_access -labsl_city -labsl_status -labsl_cord -labsl_str_format_internal -labsl_synchronization -labsl_graphcycles_internal -labsl_symbolize -labsl_demangle_internal -labsl_stacktrace -labsl_debugging_internal -labsl_malloc_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_bad_optional_access -labsl_raw_logging_internal -labsl_log_severity
+
+INCLUDEPATH += $$PWD/../../common/common/md5
+INCLUDEPATH += $$PWD/../../common/common/getinterface
+
+

BIN
src/tool/RemoteCtrl_h264/car.png


+ 256 - 0
src/tool/RemoteCtrl_h264/dialogbigpic.cpp

@@ -0,0 +1,256 @@
+#include "dialogbigpic.h"
+#include "ui_dialogbigpic.h"
+
+#include "mainwindow.h"
+extern iv::vision::rawpic grawpic[CAMERA_NUM];
+extern qint64 gTimeRawPic[CAMERA_NUM] ;
+extern QMutex gMutexPic[CAMERA_NUM];
+extern std::string gstrmem_pic[CAMERA_NUM];
+
+
+DialogBigPic::DialogBigPic(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::DialogBigPic)
+{
+    ui->setupUi(this);
+
+    mpview = new MyView(this);
+    mpview->setObjectName(QStringLiteral("graphicsView"));
+    mpview->setGeometry(QRect(30, 30, 1000, 600));
+    mpview->setCacheMode(mpview->CacheBackground);
+
+    mscene = new QGraphicsScene;
+
+    mpPicView = new IVPicView();
+    mpPicView->start();
+
+    mpviewLeft = new MyView(this);
+    mpviewLeft->setObjectName(QStringLiteral("graphicsView"));
+    mpviewLeft->setGeometry(QRect(30, 30, 450, 300));
+    mpviewLeft->setCacheMode(mpview->CacheBackground);
+    msceneLeft = new QGraphicsScene;
+    mpPicViewLeft = new IVPicView();
+    mpPicViewLeft->start();
+
+    mpviewRight = new MyView(this);
+    mpviewRight->setObjectName(QStringLiteral("graphicsView"));
+    mpviewRight->setGeometry(QRect(30, 30, 450, 300));
+    mpviewRight->setCacheMode(mpview->CacheBackground);
+    msceneRight = new QGraphicsScene;
+    mpPicViewRight = new IVPicView();
+    mpPicViewRight->start();
+
+//    mnLastPicTime = 0;
+    int i;
+    for(i=0;i<3;i++)
+    {
+        mnLastPicTime[i] = 0;
+        mbDraw[i] = false;
+    }
+//    mbDraw = false;
+    connect(mpPicView,SIGNAL(painterupadate()),this,SLOT(onPainterUpdate()));
+    connect(mpPicViewLeft,SIGNAL(painterupadate()),this,SLOT(onPainterUpdate()));
+    connect(mpPicViewRight,SIGNAL(painterupadate()),this,SLOT(onPainterUpdate()));
+
+    mpview->scale(0.8,0.8);
+    mpviewLeft->scale(0.4,0.4);
+    mpviewRight->scale(0.4,0.4);
+
+    qDebug("wid : ",this->winId());
+
+
+    mppicshow[0] = new pluginapp(this->winId(),"big_center","plugin_picshow","/home/yuchuli/qt/modularization/src/plugin/build-plugin_picshow-Debug");
+    mppicshow[0]->SetAttr("rawpicmsgname",gstrmem_pic[0].data(),gstrmem_pic[0].size());
+
+    mppicshow[1] = new pluginapp(this->winId(),"big_left","plugin_picshow","/home/yuchuli/qt/modularization/src/plugin/build-plugin_picshow-Debug");
+    mppicshow[1]->SetAttr("rawpicmsgname",gstrmem_pic[1].data(),gstrmem_pic[1].size());
+
+    mppicshow[2] = new pluginapp(this->winId(),"big_right","plugin_picshow","/home/yuchuli/qt/modularization/src/plugin/build-plugin_picshow-Debug");
+    mppicshow[2]->SetAttr("rawpicmsgname",gstrmem_pic[2].data(),gstrmem_pic[2].size());
+
+    QTimer * timer = new QTimer();
+    connect(timer,SIGNAL(timeout()),this,SLOT(onTimerPic()));
+    timer->start(10);
+
+    setWindowTitle("View Picture");
+}
+
+DialogBigPic::~DialogBigPic()
+{
+    unsigned int i;
+    for(i=0;i<3;i++)delete mppicshow[i];
+    delete ui;
+}
+
+void DialogBigPic::onTimerPic()
+{
+
+    if(mbRefresh == false)return;
+
+    bool bUpdate = false;
+
+//    int ncam = mnCamera;
+//    if((mnLastPicTime != gTimeRawPic[ncam])&&(gTimeRawPic[ncam]!= 0))
+//    {
+//        gMutexPic[ncam].lock();
+//        mpPicView->SetPic(grawpic[ncam]);
+//        gMutexPic[ncam].unlock();
+//        bUpdate = true;
+//        mbDraw = true;
+//    }
+
+    int ncamcenter = 0;
+    int ncamleft = 2;
+    int ncamright = 3;
+    if(mbFront == false)
+    {
+        ncamcenter = 1;
+        ncamright = 2;
+        ncamleft = 3;
+    }
+
+
+    if((mnLastPicTime[0] != gTimeRawPic[ncamcenter])&&(gTimeRawPic[ncamcenter]!= 0))
+    {
+        gMutexPic[ncamcenter].lock();
+        mpPicView->SetPic(grawpic[ncamcenter]);
+        gMutexPic[ncamcenter].unlock();
+        bUpdate = true;
+        mnLastPicTime[0] = gTimeRawPic[ncamcenter];
+ //       mbDraw[0] = true;
+    }
+
+    if((mnLastPicTime[1] != gTimeRawPic[ncamleft])&&(gTimeRawPic[ncamleft]!= 0))
+    {
+        gMutexPic[ncamleft].lock();
+        mpPicViewLeft->SetPic(grawpic[ncamleft]);
+        gMutexPic[ncamleft].unlock();
+        bUpdate = true;
+        mnLastPicTime[1] = gTimeRawPic[ncamleft];
+//        mbDraw[1] = true;
+    }
+
+    if((mnLastPicTime[2] != gTimeRawPic[ncamright])&&(gTimeRawPic[ncamright]!= 0))
+    {
+        gMutexPic[ncamright].lock();
+        mpPicViewRight->SetPic(grawpic[ncamright]);
+        gMutexPic[ncamright].unlock();
+        bUpdate = true;
+        mnLastPicTime[2] = gTimeRawPic[ncamright];
+//        mbDraw[2] = true;
+    }
+
+
+//    if(bUpdate)update();
+
+}
+
+void DialogBigPic::paintEvent(QPaintEvent *)
+{
+
+    if(mbDraw[0])
+    {
+        QImage image = mpPicView->GetImage();
+        mscene->clear();
+        mscene->addPixmap(QPixmap::fromImage(image));
+        mpview->setScene(mscene);
+        mpview->show();
+    }
+
+    if(mbDraw[1])
+    {
+        QImage image = mpPicViewLeft->GetImage();
+        msceneLeft->clear();
+        msceneLeft->addPixmap(QPixmap::fromImage(image));
+        mpviewLeft->setScene(msceneLeft);
+        mpviewLeft->show();
+    }
+
+    if(mbDraw[2])
+    {
+        QImage image = mpPicViewRight->GetImage();
+        msceneRight->clear();
+        msceneRight->addPixmap(QPixmap::fromImage(image));
+        mpviewRight->setScene(msceneRight);
+        mpviewRight->show();
+    }
+
+//    if(mbDraw)
+//    {
+//        QImage image = mpPicView->GetImage();
+//        mscene->clear();
+//        mscene->addPixmap(QPixmap::fromImage(image));
+//        mpview->setScene(mscene);
+//        mpview->show();
+
+//        msceneLeft->clear();
+//        msceneLeft->addPixmap(QPixmap::fromImage(image));
+//        mpviewLeft->setScene(msceneLeft);
+//        mpviewLeft->show();
+
+//        msceneRight->clear();
+//        msceneRight->addPixmap(QPixmap::fromImage(image));
+//        mpviewRight->setScene(msceneRight);
+//        mpviewRight->show();
+//    }
+
+}
+
+void DialogBigPic::resizeEvent(QResizeEvent *event)
+{
+    (void)event;
+     QRect rect = this->geometry();
+     double fwidth = rect.width()/1;
+     double fheight = rect.height()/1;
+ //    mpview->setGeometry(0,0,fwidth,fheight);
+//     mpview->setGeometry(fwidth/4,0,fwidth/2,fheight);
+//     mpviewLeft->setGeometry(0,0,fwidth/4,fheight/2);
+//     mpviewRight->setGeometry(fwidth*3/4,0,fwidth/4,fheight/2);
+
+
+     qDebug("width : %f ",fwidth);
+     mppicshow[0]->SetGeometry(fwidth/4,0,fwidth/2,fheight);
+     mppicshow[1]->SetGeometry(0,0,fwidth/4,fheight/2);
+     mppicshow[2]->SetGeometry(fwidth*3/4,0,fwidth/4,fheight/2);
+//     rect.setX(rect.x());
+}
+
+void DialogBigPic::setRefresh(bool brefresh)
+{
+    mbRefresh = brefresh;
+}
+
+void DialogBigPic::onPainterUpdate()
+{
+    if(sender() == mpPicView)
+    {
+//        qDebug("front draw");
+        mbDraw[0] = true;
+    }
+    if(sender() == mpPicViewLeft)
+    {
+//        qDebug("left draw");
+        mbDraw[1] = true;
+    }
+    if(sender() == mpPicViewRight)
+    {
+//        qDebug("right draw");
+        mbDraw[2] = true;
+    }
+    update();
+}
+
+void DialogBigPic::setCamera(int n)
+{
+    mnCamera = n;
+}
+
+void DialogBigPic::SetFront()
+{
+    mbFront = true;
+}
+
+void DialogBigPic::SetRear()
+{
+    mbFront = false;
+}

+ 70 - 0
src/tool/RemoteCtrl_h264/dialogbigpic.h

@@ -0,0 +1,70 @@
+#ifndef DIALOGBIGPIC_H
+#define DIALOGBIGPIC_H
+
+#include <QDialog>
+
+
+#include "pluginapp.h"
+
+namespace Ui {
+class DialogBigPic;
+}
+
+#include "ivpicview.h"
+#include "myview.h"
+
+class DialogBigPic : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit DialogBigPic(QWidget *parent = nullptr);
+    ~DialogBigPic();
+
+private slots:
+    virtual void paintEvent(QPaintEvent *);
+    void onTimerPic();
+   void onPainterUpdate();
+
+
+public:
+     void resizeEvent(QResizeEvent *event);
+
+     void setRefresh(bool brefresh);
+
+     void setCamera(int n);
+
+     void SetFront();
+     void SetRear();
+
+private:
+    Ui::DialogBigPic *ui;
+
+    MyView * mpview;
+    QGraphicsScene *mscene;
+    IVPicView * mpPicView;
+
+    MyView * mpviewLeft;
+    QGraphicsScene *msceneLeft;
+    IVPicView * mpPicViewLeft;
+
+    MyView * mpviewRight;
+    QGraphicsScene *msceneRight;
+    IVPicView * mpPicViewRight;
+
+//    qint64 mnLastPicTime;
+    qint64 mnLastPicTime[3];
+
+//    bool mbDraw;
+    bool mbDraw[3];
+
+    bool mbRefresh= false;
+
+    int mnCamera = 0;
+
+    bool mbFront = true;  //if false, rear drive
+
+    pluginapp * mppicshow[3];
+};
+
+#endif // DIALOGBIGPIC_H

+ 19 - 0
src/tool/RemoteCtrl_h264/dialogbigpic.ui

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DialogBigPic</class>
+ <widget class="QDialog" name="DialogBigPic">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1920</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 104 - 0
src/tool/RemoteCtrl_h264/dialogpic.cpp

@@ -0,0 +1,104 @@
+#include "dialogpic.h"
+#include "ui_dialogpic.h"
+#include "mainwindow.h"
+
+extern iv::vision::rawpic grawpic[CAMERA_NUM];
+extern qint64 gTimeRawPic[CAMERA_NUM] ;
+extern QMutex gMutexPic[CAMERA_NUM];
+
+
+
+DialogPic::DialogPic(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::DialogPic)
+{
+    ui->setupUi(this);
+
+    int i;
+    for(i=0;i<4;i++)
+    {
+        mpview[i] = new MyView(this);
+        mpview[i]->setObjectName(QStringLiteral("graphicsView"));
+        mpview[i]->setGeometry(QRect(30, 30, 600, 600));
+        mpview[i]->setCacheMode(mpview[i]->CacheBackground);
+
+        mscene[i] = new QGraphicsScene;
+
+        mpPicView[i] = new IVPicView();
+        mpPicView[i]->start();
+        mnLastPicTime[i] = 0;
+        mbDraw[i] = false;
+    }
+
+    QTimer * timer = new QTimer();
+    connect(timer,SIGNAL(timeout()),this,SLOT(onTimerPic()));
+    timer->start(10);
+
+    setWindowTitle("View All Picture");
+}
+
+DialogPic::~DialogPic()
+{
+    qDebug("delete dialog");
+    delete ui;
+}
+
+void DialogPic::resizeEvent(QResizeEvent *event)
+{
+    (void)event;
+     QRect rect = this->geometry();
+     double fwidth = rect.width()/2;
+     double fheight = rect.height()/2;
+     mpview[0]->setGeometry(0,0,fwidth,fheight);
+     mpview[1]->setGeometry(fwidth,0,fwidth,fheight);
+     mpview[2]->setGeometry(0,fheight,fwidth,fheight);
+     mpview[3]->setGeometry(fwidth,fheight,fwidth,fheight);
+//     rect.setX(rect.x());
+}
+
+void DialogPic::onTimerPic()
+{
+    int i;
+
+    if(mbRefresh == false)return;
+
+    bool bUpdate = false;
+    for(i=0;i<4;i++)
+    {
+        if(mnLastPicTime[i] != gTimeRawPic[i])
+        {
+            gMutexPic[i].lock();
+            mpPicView[i]->SetPic(grawpic[i]);
+            gMutexPic[i].unlock();
+            bUpdate = true;
+            mbDraw[i] = true;
+            mnLastPicTime[i] = gTimeRawPic[i];
+//            qDebug("draw time is %ld",mnLastPicTime[i]);
+        }
+    }
+
+    if(bUpdate)update();
+
+}
+
+void DialogPic::paintEvent(QPaintEvent *)
+{
+    int i;
+    for(i=0;i<4;i++)
+    {
+        if(mbDraw[i])
+        {
+            QImage image = mpPicView[i]->GetImage();
+            mscene[i]->clear();
+            mscene[i]->addPixmap(QPixmap::fromImage(image));
+            mpview[i]->setScene(mscene[i]);
+            mpview[i]->show();
+        }
+        mbDraw[i] = false;
+    }
+}
+
+void DialogPic::setRefresh(bool brefresh)
+{
+    mbRefresh = brefresh;
+}

+ 49 - 0
src/tool/RemoteCtrl_h264/dialogpic.h

@@ -0,0 +1,49 @@
+#ifndef DIALOGPIC_H
+#define DIALOGPIC_H
+
+#include <QDialog>
+
+namespace Ui {
+class DialogPic;
+}
+
+#include "ivpicview.h"
+#include "myview.h"
+
+
+class DialogPic : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit DialogPic(QWidget *parent = 0);
+    ~DialogPic();
+
+private slots:
+    void onTimerPic();
+
+    virtual void paintEvent(QPaintEvent *);
+
+
+
+public:
+     void resizeEvent(QResizeEvent *event);
+
+     void setRefresh(bool brefresh);
+private:
+    Ui::DialogPic *ui;
+
+    MyView * mpview[4];
+    QGraphicsScene *mscene[4];
+
+    IVPicView * mpPicView[4];
+
+    qint64 mnLastPicTime[4];
+
+    bool mbDraw[4];
+
+    bool mbRefresh= false;
+
+};
+
+#endif // DIALOGPIC_H

+ 19 - 0
src/tool/RemoteCtrl_h264/dialogpic.ui

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DialogPic</class>
+ <widget class="QDialog" name="DialogPic">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1366</width>
+    <height>680</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 78 - 0
src/tool/RemoteCtrl_h264/dialogsetpassword.cpp

@@ -0,0 +1,78 @@
+#include "dialogsetpassword.h"
+#include "ui_dialogsetpassword.h"
+
+#include <QMessageBox>
+#include <iostream>
+
+#include <remotectrlini.h>
+
+DialogSetPassWord::DialogSetPassWord(DialogSetPassWord_Type xtype,std::string strmd5, QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::DialogSetPassWord)
+{
+    ui->setupUi(this);
+
+    mType = xtype;
+
+    if(xtype == DialogSetPassWord_Type::QUERY)
+    {
+        setWindowTitle("设置查询密码");
+    }
+
+    if(xtype == DialogSetPassWord_Type::CTRL)
+    {
+        setWindowTitle("设置控制密码");
+    }
+
+    mstrmd5 = strmd5;
+}
+
+DialogSetPassWord::~DialogSetPassWord()
+{
+    delete ui;
+}
+
+void DialogSetPassWord::on_pushButton_Set_clicked()
+{
+    std::string stroldpass = ui->lineEdit_OldPass->text().toStdString();
+    std::string strnewpass = ui->lineEdit_NewPass->text().toStdString();
+    if(stroldpass =="")
+    {
+        QMessageBox::warning(this,"Warning"," Old Pass is NULL",QMessageBox::YesAll);
+        return;
+    }
+
+    if(strnewpass == "")
+    {
+        QMessageBox::warning(this,"Warning"," New Pass is NULL",QMessageBox::YesAll);
+        return;
+    }
+
+    Md5Encode encode_obj;
+    std::string stroldmd5 = encode_obj.Encode(stroldpass);
+
+    if(stroldmd5 != mstrmd5)
+    {
+        QMessageBox::warning(this,"Warning"," Old PassWord Error",QMessageBox::YesAll);
+        return;
+    }
+
+    std::string strnewmd5 = encode_obj.Encode(strnewpass);
+
+    std::cout<<"New Pass: "<<strnewmd5<<std::endl;
+
+    if(mType == DialogSetPassWord_Type::QUERY)
+        RemoteCtrlIni::Inst().SetQueryMD5(strnewmd5);
+    else
+       ServiceRCIni.SetCtrlMD5(strnewmd5);
+
+    QMessageBox::information(this,"Info","修改密码成功",QMessageBox::YesAll);
+
+    this->accept();
+
+}
+
+void DialogSetPassWord::on_pushButton_Close_clicked()
+{
+    this->accept();
+}

+ 39 - 0
src/tool/RemoteCtrl_h264/dialogsetpassword.h

@@ -0,0 +1,39 @@
+#ifndef DIALOGSETPASSWORD_H
+#define DIALOGSETPASSWORD_H
+
+#include <QDialog>
+
+#include "md5_encode.h"
+
+namespace Ui {
+class DialogSetPassWord;
+}
+
+enum DialogSetPassWord_Type
+{
+    QUERY,
+    CTRL
+};
+
+class DialogSetPassWord : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit DialogSetPassWord(DialogSetPassWord_Type xtype,std::string strmd5, QWidget *parent = nullptr);
+    ~DialogSetPassWord();
+
+private slots:
+    void on_pushButton_Set_clicked();
+
+    void on_pushButton_Close_clicked();
+
+private:
+    Ui::DialogSetPassWord *ui;
+
+    std::string mstrmd5;
+
+    DialogSetPassWord_Type mType;
+};
+
+#endif // DIALOGSETPASSWORD_H

+ 97 - 0
src/tool/RemoteCtrl_h264/dialogsetpassword.ui

@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DialogSetPassWord</class>
+ <widget class="QDialog" name="DialogSetPassWord">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>504</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QLineEdit" name="lineEdit_NewPass">
+   <property name="geometry">
+    <rect>
+     <x>180</x>
+     <y>103</y>
+     <width>221</width>
+     <height>40</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit_OldPass">
+   <property name="geometry">
+    <rect>
+     <x>180</x>
+     <y>44</y>
+     <width>221</width>
+     <height>41</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_2">
+   <property name="geometry">
+    <rect>
+     <x>60</x>
+     <y>100</y>
+     <width>101</width>
+     <height>41</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>新密码</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>60</x>
+     <y>40</y>
+     <width>101</width>
+     <height>41</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>原密码</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pushButton_Set">
+   <property name="geometry">
+    <rect>
+     <x>60</x>
+     <y>200</y>
+     <width>151</width>
+     <height>51</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>设置</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pushButton_Close">
+   <property name="geometry">
+    <rect>
+     <x>300</x>
+     <y>200</y>
+     <width>151</width>
+     <height>51</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>关闭</string>
+   </property>
+  </widget>
+ </widget>
+ <tabstops>
+  <tabstop>lineEdit_OldPass</tabstop>
+  <tabstop>lineEdit_NewPass</tabstop>
+  <tabstop>pushButton_Set</tabstop>
+  <tabstop>pushButton_Close</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>

+ 54 - 0
src/tool/RemoteCtrl_h264/dialogsetting.cpp

@@ -0,0 +1,54 @@
+#include "dialogsetting.h"
+#include "ui_dialogsetting.h"
+
+#include <QMessageBox>
+
+#include "remotectrlini.h"
+
+DialogSetting::DialogSetting(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::DialogSetting)
+{
+    ui->setupUi(this);
+
+
+    mstrserverip = ServiceRCIni.GetServerIP();
+    mstrserverport = ServiceRCIni.GetServerPort();
+    mstrinterval = ServiceRCIni.GetInterval();
+    mstrVIN = ServiceRCIni.GetVIN();
+
+
+    ui->lineEdit_serverip->setText(mstrserverip.data());
+    ui->lineEdit_serverport->setText(mstrserverport.data());
+    ui->lineEdit_queryinterval->setText(mstrinterval.data());
+    ui->lineEdit_VIN->setText(mstrVIN.data());
+
+
+    setWindowTitle("Set Server");
+
+}
+
+DialogSetting::~DialogSetting()
+{
+    delete ui;
+}
+
+void DialogSetting::on_pushButton_Set_clicked()
+{
+    mstrserverip = ui->lineEdit_serverip->text().toStdString();
+    mstrserverport = ui->lineEdit_serverport->text().toStdString();
+    mstrinterval = ui->lineEdit_queryinterval->text().toStdString();
+    mstrVIN = ui->lineEdit_VIN->text().toStdString();
+
+    ServiceRCIni.SetServerIP(mstrserverip);
+    ServiceRCIni.SetServerPort(mstrserverport);
+    ServiceRCIni.SetInterval(mstrinterval);
+    ServiceRCIni.SetVIN(mstrVIN);
+
+    this->accept();
+}
+
+void DialogSetting::on_pushButton_Close_clicked()
+{
+    this->reject();
+}

+ 33 - 0
src/tool/RemoteCtrl_h264/dialogsetting.h

@@ -0,0 +1,33 @@
+#ifndef DIALOGSETTING_H
+#define DIALOGSETTING_H
+
+#include <QDialog>
+#include <QSettings>
+
+namespace Ui {
+class DialogSetting;
+}
+
+class DialogSetting : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit DialogSetting(QWidget *parent = nullptr);
+    ~DialogSetting();
+
+private slots:
+    void on_pushButton_Set_clicked();
+
+    void on_pushButton_Close_clicked();
+
+private:
+    Ui::DialogSetting *ui;
+
+    std::string mstrserverip;
+    std::string mstrserverport;
+    std::string mstrinterval;
+    std::string mstrVIN;
+};
+
+#endif // DIALOGSETTING_H

+ 137 - 0
src/tool/RemoteCtrl_h264/dialogsetting.ui

@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DialogSetting</class>
+ <widget class="QDialog" name="DialogSetting">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>594</width>
+    <height>361</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QPushButton" name="pushButton_Set">
+   <property name="geometry">
+    <rect>
+     <x>110</x>
+     <y>277</y>
+     <width>111</width>
+     <height>41</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>设置</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pushButton_Close">
+   <property name="geometry">
+    <rect>
+     <x>360</x>
+     <y>281</y>
+     <width>111</width>
+     <height>41</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>关闭</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>50</x>
+     <y>20</y>
+     <width>101</width>
+     <height>41</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>服务器 IP</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit_serverip">
+   <property name="geometry">
+    <rect>
+     <x>170</x>
+     <y>24</y>
+     <width>221</width>
+     <height>41</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_2">
+   <property name="geometry">
+    <rect>
+     <x>50</x>
+     <y>80</y>
+     <width>101</width>
+     <height>41</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>服务器端口</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_3">
+   <property name="geometry">
+    <rect>
+     <x>50</x>
+     <y>140</y>
+     <width>111</width>
+     <height>41</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>查询间隔(ms)</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit_serverport">
+   <property name="geometry">
+    <rect>
+     <x>170</x>
+     <y>83</y>
+     <width>113</width>
+     <height>40</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit_queryinterval">
+   <property name="geometry">
+    <rect>
+     <x>170</x>
+     <y>140</y>
+     <width>113</width>
+     <height>40</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit_VIN">
+   <property name="geometry">
+    <rect>
+     <x>170</x>
+     <y>196</y>
+     <width>221</width>
+     <height>41</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_5">
+   <property name="geometry">
+    <rect>
+     <x>50</x>
+     <y>196</y>
+     <width>101</width>
+     <height>41</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>车辆识别码</string>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 31 - 0
src/tool/RemoteCtrl_h264/driver_cloud_grpc_pc.yaml

@@ -0,0 +1,31 @@
+
+
+querymessage:
+
+  hcp2_gpsimu:
+    msgname: hcp2_gpsimu
+    buffersize: 10000
+    buffercount: 1
+  simpletrace:
+    msgname: simpletrace
+    buffersize: 100000
+    buffercount: 1
+
+ctrlmessage:
+  xodrdst:
+    msgname: xodrdst
+    buffersize: 1000
+    buffercount: 1
+  xodrreq:
+    msgname: xodrreq
+    buffersize: 1000
+    buffercount: 1
+    bimportant: true
+    keeptime: 3000
+  remotectrl:
+    msgname: remotectrl
+    buffersize: 1000
+    buffercount: 1
+
+
+

+ 594 - 0
src/tool/RemoteCtrl_h264/grpcpc.cpp

@@ -0,0 +1,594 @@
+#include "grpcpc.h"
+
+#include "remotectrlini.h"
+
+static grpcpc * ggrpcpc;
+
+void ListenData(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+    ggrpcpc->UpdateData(strdata,nSize,strmemname);
+}
+
+
+grpcpc::grpcpc(std::string stryamlpath)
+{
+
+
+    mstrpicmsgname[0] = "h264front1";
+    mstrpicmsgname[1] = "h264rear1";
+    mstrpicmsgname[2] = "h264left1";
+    mstrpicmsgname[3] = "h264right1";
+
+
+    ggrpcpc = this;
+    dec_yaml(stryamlpath.data());
+
+    if(mvectormsgunit.size() == 0)
+    {
+        iv::msgunit xmu;
+        snprintf(xmu.mstrmsgname,256,"hcp2_gpsimu");
+        xmu.mnBufferSize = 10000;
+        xmu.mnBufferCount = 1;
+        mvectormsgunit.push_back(xmu);
+        snprintf(xmu.mstrmsgname,256,"simpletrace");
+        xmu.mnBufferSize = 100000;
+        xmu.mnBufferCount = 1;
+        mvectormsgunit.push_back(xmu);
+
+        if(mvectorctrlmsgunit.size() == 0)
+        {
+            snprintf(xmu.mstrmsgname,256,"xodrdst");
+            xmu.mnBufferSize = 1000;
+            xmu.mnBufferCount = 1;
+            mvectorctrlmsgunit.push_back(xmu);
+            snprintf(xmu.mstrmsgname,256,"xodrreq");
+            xmu.mnBufferSize = 1000;
+            xmu.mnBufferCount = 1;
+            xmu.mbImportant = true;
+            xmu.mnkeeptime = 3000;
+            mvectorctrlmsgunit.push_back(xmu);
+            snprintf(xmu.mstrmsgname,256,"remotectrl");
+            xmu.mnBufferSize = 1000;
+            xmu.mnBufferCount = 1;
+            mvectorctrlmsgunit.push_back(xmu);
+        }
+    }
+
+    unsigned int i;
+    for(i=0;i<mvectormsgunit.size();i++)
+    {
+        bool bPicMsg = false;
+        unsigned int j;
+        for(j=0;j<NUM_CAM;j++)
+        {
+            if(strncmp(mvectormsgunit[i].mstrmsgname,mstrpicmsgname[j].data(),255 ) == 0)
+            {
+                bPicMsg = true;
+                break;
+            }
+        }
+        if(bPicMsg)
+        {
+            continue;
+        }
+        mvectormsgunit[i].mpa = iv::modulecomm::RegisterSend(mvectormsgunit[i].mstrmsgname,mvectormsgunit[i].mnBufferSize,mvectormsgunit[i].mnBufferCount);
+    }
+
+    for(i=0;i<mvectorctrlmsgunit.size();i++)
+    {
+        mvectorctrlmsgunit[i].mpa = iv::modulecomm::RegisterRecv(mvectorctrlmsgunit[i].mstrmsgname,ListenData);
+    }
+
+    for(i=0;i<NUM_CAM;i++)
+    {
+        mpaPic[i] = iv::modulecomm::RegisterSend(mstrpicmsgname[i].data(),2000000,1);
+        mnPicUpLatency[i] = 1000;
+        mnFrameRate[i] = 0;
+        mnPicDownLatency[i] = 1000;
+    }
+
+
+    for(i=0;i<NUM_CAM;i++)
+    {
+        unsigned int j;
+        for(j=0;j<NUM_THREAD_PERCAM;j++)
+        {
+            mpThread[i*NUM_THREAD_PERCAM + j] = new std::thread(&grpcpc::threadpicdownload,this,i);
+        }
+    }
+}
+
+
+void grpcpc::run()
+{
+    int nsize = mvectormsgunit.size();
+    int nctrlsize = mvectorctrlmsgunit.size();
+    int i;
+
+    qint64 nlasttime = 0;
+
+    int ninterval = atoi(gstruploadinterval.data());
+    if(ninterval<=0)ninterval = 100;
+
+    QTime xTime;
+    xTime.start();
+    int nlastsend = xTime.elapsed();
+
+    std::string target_str = gstrserverip+":";
+    target_str = target_str + gstrserverport ;//std::to_string()
+    auto cargs = grpc::ChannelArguments();
+    cargs.SetMaxReceiveMessageSize(1024 * 1024 * 1024); // 1 GB
+    cargs.SetMaxSendMessageSize(1024 * 1024 * 1024);
+
+    std::shared_ptr<Channel> channel = grpc::CreateCustomChannel(
+             target_str, grpc::InsecureChannelCredentials(),cargs);
+
+    std::unique_ptr<iv::UploadThread::Stub> stub_ = iv::UploadThread::NewStub(channel);
+
+
+    iv::queryReqThread request;
+    iv::queryReplyThread xreply;
+
+    int nid = 0;
+    int nctrlid = 0;
+
+    // Container for the data we expect from the server.
+//    iv::queryReply reply;
+
+    gpr_timespec timespec;
+      timespec.tv_sec = 30;//设置阻塞时间为2秒
+      timespec.tv_nsec = 0;
+      timespec.clock_type = GPR_TIMESPAN;
+
+
+    while(!QThread::isInterruptionRequested())
+    {
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+        if(abs(xTime.elapsed()-nlastsend)<ninterval)
+        {
+            continue;
+        }
+
+        bool bImportant = false;
+        int nkeeptime = 0;
+
+            iv::cloud::cloudmsg xmsg;
+            xmsg.set_xtime(QDateTime::currentMSecsSinceEpoch());
+            nlastsend = xTime.elapsed();
+            gMutexMsg.lock();
+
+  //          std::vector<iv::msgunit> xv = mvectorctrlmsgunit;
+            for(i=0;i<nctrlsize;i++)
+            {
+                if(mvectorctrlmsgunit[i].mbRefresh)
+                {
+                    mvectorctrlmsgunit[i].mbRefresh = false;
+
+                    if(mvectorctrlmsgunit[i].mbImportant)
+                    {
+                        bImportant = true;
+                    }
+                    if(mvectorctrlmsgunit[i].mnkeeptime > nkeeptime)
+                    {
+                        nkeeptime = mvectorctrlmsgunit[i].mnkeeptime;
+                    }
+                    iv::cloud::cloudunit xcloudunit;
+                    xcloudunit.set_msgname(mvectorctrlmsgunit[i].mstrmsgname);
+                    xcloudunit.set_data(mvectorctrlmsgunit[i].mpstrmsgdata.get(),mvectorctrlmsgunit[i].mndatasize);
+                    iv::cloud::cloudunit * pcu = xmsg.add_xclouddata();
+                    pcu->CopyFrom(xcloudunit);
+                }
+
+            }
+            gMutexMsg.unlock();
+
+
+            {
+
+                ClientContext context ;
+                context.set_deadline(timespec);
+ //               qint64 time1 = QDateTime::currentMSecsSinceEpoch();
+
+                request.set_strquerymd5(gstrqueryMD5);
+                request.set_strvin(gstrVIN);
+
+                request.set_nlasttime(nlasttime);
+
+                request.set_id(nctrlid);nctrlid++;
+                request.set_strctrlmd5(gstrctrlMD5);
+                request.set_strvin(gstrVIN);
+                request.set_ntime(QDateTime::currentMSecsSinceEpoch());
+                request.set_bimportant(bImportant);
+                request.set_kepptime(nkeeptime);
+                if(xmsg.xclouddata_size()>0)
+                {
+                    int nbytesize = xmsg.ByteSize();
+                    std::vector<char> pvectordata;
+                    pvectordata.resize(nbytesize);
+                    if(xmsg.SerializeToArray(pvectordata.data(),nbytesize))
+                    {
+
+                        request.set_xdata(pvectordata.data(),pvectordata.size());
+
+                    }
+                }
+
+
+                QDateTime xTime;
+                xTime.fromMSecsSinceEpoch(1607905685318);  //1607914763641
+//                qDebug("time:%s",xTime.toString("yyyy-MM-dd:hh:mm:ss:zzz").toLatin1().data());
+//                qDebug("nlasttime is %ld",nlasttime);//1607905685318
+                nid++;
+                // The actual RPC.
+                Status status = stub_->queryctrl(&context, request, &xreply);
+                if (status.ok()) {
+ //                   std::cout<<nid<<" query successfully, res is "<<xreply.nres()<<std::endl;
+                    if(xreply.nres() == 1)
+                    {
+
+                        if(nlasttime != xmsg.xtime())
+                        {
+                            iv::cloud::cloudmsg xmsg;
+                            if(xmsg.ParseFromArray(xreply.xdata().data(),xreply.xdata().size()))
+                            {
+                                sharequerymsg(&xmsg);
+                            }
+                        }
+
+                        nlasttime = xreply.ntime();
+                    }
+                    else
+                    {
+                        std::this_thread::sleep_for(std::chrono::milliseconds(30));
+                    }
+                } else {
+                  std::cout << status.error_code() << ": " << status.error_message()
+                            << std::endl;
+                  std::cout<<"RPC failed"<<std::endl;
+
+                  if(status.error_code() == 4)
+                  {
+                      std::cout<<" RPC Exceed Time, Create New stub_"<<std::endl;
+                      channel = grpc::CreateCustomChannel(
+                               target_str, grpc::InsecureChannelCredentials(),cargs);
+
+                      stub_ = iv::UploadThread::NewStub(channel);
+                  }
+                  std::this_thread::sleep_for(std::chrono::milliseconds(900));
+
+                }
+
+            }
+
+
+
+    }
+}
+
+
+void grpcpc::dec_yaml(const char *stryamlpath)
+{
+    YAML::Node config;
+    try
+    {
+        config = YAML::LoadFile(stryamlpath);
+    }
+    catch(YAML::BadFile e)
+    {
+        qDebug("load error.");
+        return;
+    }
+
+    std::vector<std::string> vecmodulename;
+
+
+    if(config["server"])
+    {
+        gstrserverip = config["server"].as<std::string>();
+    }
+    if(config["port"])
+    {
+        gstrserverport = config["port"].as<std::string>();
+    }
+    if(config["uploadinterval"])
+    {
+        gstruploadinterval = config["uploadinterval"].as<std::string>();
+    }
+
+
+    if(config["VIN"])
+    {
+        gstrVIN = config["VIN"].as<std::string>();
+    }
+
+    if(config["queryMD5"])
+    {
+        gstrqueryMD5 = config["queryMD5"].as<std::string>();
+    }
+
+    if(config["ctrlMD5"])
+    {
+        gstrctrlMD5 = config["ctrlMD5"].as<std::string>();
+    }
+
+
+    std::string strmsgname;
+
+    if(config["querymessage"])
+    {
+
+        for(YAML::const_iterator it= config["querymessage"].begin(); it != config["querymessage"].end();++it)
+        {
+            std::string strtitle = it->first.as<std::string>();
+            std::cout<<strtitle<<std::endl;
+
+            if(config["querymessage"][strtitle]["msgname"]&&config["querymessage"][strtitle]["buffersize"]&&config["querymessage"][strtitle]["buffercount"])
+            {
+                iv::msgunit xmu;
+                strmsgname = config["querymessage"][strtitle]["msgname"].as<std::string>();
+                strncpy(xmu.mstrmsgname,strmsgname.data(),255);
+                xmu.mnBufferSize = config["querymessage"][strtitle]["buffersize"].as<int>();
+                xmu.mnBufferCount = config["querymessage"][strtitle]["buffercount"].as<int>();
+                mvectormsgunit.push_back(xmu);
+
+
+            }
+        }
+    }
+    else
+    {
+
+    }
+
+    if(config["ctrlmessage"])
+    {
+        std::string strnodename = "ctrlmessage";
+        for(YAML::const_iterator it= config[strnodename].begin(); it != config[strnodename].end();++it)
+        {
+            std::string strtitle = it->first.as<std::string>();
+            std::cout<<strtitle<<std::endl;
+
+            if(config[strnodename][strtitle]["msgname"]&&config[strnodename][strtitle]["buffersize"]&&config[strnodename][strtitle]["buffercount"])
+            {
+                iv::msgunit xmu;
+                strmsgname = config[strnodename][strtitle]["msgname"].as<std::string>();
+                strncpy(xmu.mstrmsgname,strmsgname.data(),255);
+                xmu.mnBufferSize = config[strnodename][strtitle]["buffersize"].as<int>();
+                xmu.mnBufferCount = config[strnodename][strtitle]["buffercount"].as<int>();
+
+                if(config[strnodename][strtitle]["bimportant"])
+                {
+                   std::string strimportant =    config[strnodename][strtitle]["bimportant"].as<std::string>();
+                   if(strimportant == "true")
+                   {
+                       xmu.mbImportant = true;
+                   }
+                }
+                if(config[strnodename][strtitle]["keeptime"])
+                {
+                   std::string strkeep =    config[strnodename][strtitle]["keeptime"].as<std::string>();
+                   xmu.mnkeeptime = atoi(strkeep.data());
+                }
+                mvectorctrlmsgunit.push_back(xmu);
+            }
+        }
+    }
+    else
+    {
+
+    }
+
+    return;
+}
+
+void grpcpc::sharequerymsg(iv::cloud::cloudmsg *pxmsg)
+{
+    int i;
+    int nsize = pxmsg->xclouddata_size();
+    for(i=0;i<nsize;i++)
+    {
+        int j;
+        int nquerysize = mvectormsgunit.size();
+        for(j=0;j<nquerysize;j++)
+        {
+            if(strncmp(pxmsg->xclouddata(i).msgname().data(), mvectormsgunit[j].mstrmsgname,255) == 0)
+            {
+                qDebug("size is %d ",pxmsg->xclouddata(i).data().size());
+                iv::modulecomm::ModuleSendMsg(mvectormsgunit[j].mpa,pxmsg->xclouddata(i).data().data(),pxmsg->xclouddata(i).data().size());
+                break;
+            }
+        }
+    }
+}
+
+void grpcpc::UpdateData(const char *strdata, const unsigned int nSize,const char * strmemname)
+{
+    int nsize = mvectorctrlmsgunit.size();
+    int i;
+    for(i=0;i<nsize;i++)
+    {
+        if(strncmp(strmemname,mvectorctrlmsgunit[i].mstrmsgname,255) == 0)
+        {
+            gMutexMsg.lock();
+            char * strtem = new char[nSize];
+            memcpy(strtem,strdata,nSize);
+            mvectorctrlmsgunit[i].mpstrmsgdata.reset(strtem);
+            mvectorctrlmsgunit[i].mndatasize = nSize;
+            mvectorctrlmsgunit[i].mbRefresh = true;
+            gMutexMsg.unlock();
+            break;
+        }
+    }
+}
+
+std::string grpcpc::GetVIN()
+{
+    return gstrVIN;
+}
+
+
+//int gnPicNum[NUM_CAM];
+//QMutex gMutexPic[NUM_CAM];
+//qint64 gnTimeSecond[NUM_CAM];
+
+
+void grpcpc::threadpicdownload(int nCamPos)
+{
+    std::cout<<"thread cam "<<nCamPos<<"run"<<std::endl;
+    int nsize = mvectormsgunit.size();
+    int i;
+
+    std::string strcclientid = ServiceRCIni.GetClientID();
+
+    int ninterval = atoi(gstruploadinterval.data());
+    if(ninterval<=0)ninterval = 100;
+
+    QTime xTime;
+    xTime.start();
+    int nlastsend = xTime.elapsed();
+
+    std::string target_str = gstrserverip+":";
+    target_str = target_str + gstrserverport ;//std::to_string()
+    auto cargs = grpc::ChannelArguments();
+    cargs.SetMaxReceiveMessageSize(1024 * 1024 * 1024); // 1 GB
+    cargs.SetMaxSendMessageSize(1024 * 1024 * 1024);
+
+    std::shared_ptr<Channel> channel = grpc::CreateCustomChannel(
+             target_str, grpc::InsecureChannelCredentials(),cargs);
+
+    std::unique_ptr<iv::UploadThread::Stub> stub_ = iv::UploadThread::NewStub(channel);
+
+
+    iv::PicDownReqThread request;
+
+    int nid = 0;
+
+    // Container for the data we expect from the server.
+    iv::PicDownReplyThread reply;
+
+    gpr_timespec timespec;
+      timespec.tv_sec = 30;//设置阻塞时间为2秒
+      timespec.tv_nsec = 0;
+      timespec.clock_type = GPR_TIMESPAN;
+
+ //   ClientContext context;
+
+    qint64 nlastpicquerytime = 0;
+
+    while(true)
+    {
+        std::shared_ptr<char> pstr_ptr;
+        if((nCamPos<0)||(nCamPos >= NUM_CAM))
+        {
+            std::cout<<"Cam Pos Error. "<<"Pos: "<<nCamPos<<" TOTAL:"<<NUM_CAM<<std::endl;
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            continue;
+        }
+
+
+        request.set_strclientid(strcclientid);
+        request.set_ncampos(nCamPos);
+        request.set_strquerymd5(gstrqueryMD5);
+        request.set_strvin(gstrVIN);
+        request.set_npicquerytime(nlastpicquerytime);
+
+
+        ClientContext context ;
+        context.set_deadline(timespec);
+        qint64 time1 = QDateTime::currentMSecsSinceEpoch();
+
+
+        nlastsend = xTime.elapsed();
+        // The actual RPC.
+        Status status = stub_->querypic(&context, request, &reply);
+        if (status.ok()) {
+
+            if(reply.nres() == 1)
+            {
+                std::cout<<nCamPos<<":pic time is "<<reply.npictime()<<std::endl;
+                mnPicUpLatency[nCamPos] = reply.npicuplatency();
+                mnFrameRate[nCamPos] = reply.npicframerate();
+                mnPicDownLatency[nCamPos] = QDateTime::currentMSecsSinceEpoch() - time1;
+                mMutexPic[nCamPos].lock();
+                iv::modulecomm::ModuleSendMsg(mpaPic[nCamPos],reply.xdata().data(),reply.xdata().size());
+                mMutexPic[nCamPos].unlock();
+                nlastpicquerytime = reply.npictime();
+//                iv::cloud::cloudmsg xmsg;
+//                if(xmsg.ParseFromArray(reply.xdata().data(),reply.xdata().size()))
+//                {
+//                    sharectrlmsg(&xmsg);
+//                }
+            }
+            else
+            {
+                std::this_thread::sleep_for(std::chrono::milliseconds(10*NUM_THREAD_PERCAM));
+            }
+        } else {
+          std::cout << status.error_code() << ": " << status.error_message()
+                    << std::endl;
+          std::cout<<"camera dowm"<<nCamPos<<" RPC failed"<<std::endl;
+          if(status.error_code() == 4)
+          {
+              std::cout<<nCamPos<<" RPC Exceed Time, Create New stub_"<<std::endl;
+              channel = grpc::CreateCustomChannel(
+                       target_str, grpc::InsecureChannelCredentials(),cargs);
+
+              stub_ = iv::UploadThread::NewStub(channel);
+          }
+          std::this_thread::sleep_for(std::chrono::milliseconds(900));
+
+        }
+
+
+    }
+}
+
+qint64 grpcpc::GetPicLatency(int nCamPos)
+{
+    if((nCamPos < 0)||(nCamPos >= NUM_CAM))return -1;
+    return mnPicUpLatency[nCamPos];
+}
+
+int grpcpc::GetFrameRate(int nCamPos)
+{
+    if((nCamPos < 0)||(nCamPos >= NUM_CAM))return -1;
+    return mnFrameRate[nCamPos];
+}
+
+qint64 grpcpc::GetPicDownLatency(int nCamPos)
+{
+    if((nCamPos < 0)||(nCamPos >= NUM_CAM))return -1;
+    return mnPicDownLatency[nCamPos];
+}
+
+void grpcpc::setserverip(std::string strip)
+{
+    gstrserverip = strip;
+}
+
+void grpcpc::setserverport(std::string strport)
+{
+    gstrserverport = strport;
+}
+
+void grpcpc::setqueryinterval(std::string strinterval)
+{
+    gstruploadinterval = strinterval;
+}
+
+void grpcpc::setVIN(std::string strVIN)
+{
+    gstrVIN = strVIN;
+}
+
+void grpcpc::setqueryMD5(std::string strmd5)
+{
+    gstrqueryMD5 = strmd5;
+}
+
+void grpcpc::setctrlMD5(std::string strmd5)
+{
+    gstrctrlMD5 = strmd5;
+}
+
+

+ 129 - 0
src/tool/RemoteCtrl_h264/grpcpc.h

@@ -0,0 +1,129 @@
+#ifndef GRPCPC_H
+#define GRPCPC_H
+
+#include <QThread>
+
+#include <yaml-cpp/yaml.h>
+
+#include <QDateTime>
+
+#include <iostream>
+
+#include <vector>
+
+#include <memory>
+
+#include <QMutex>
+
+#include <thread>
+
+#include "modulecomm.h"
+
+
+#include "cloud.pb.h"
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+
+#include "uploadthreadmsg.grpc.pb.h"
+
+#ifndef NUM_CAM
+#define NUM_CAM 4
+#endif
+
+#ifndef NUM_THREAD_PERCAM
+#define NUM_THREAD_PERCAM 1
+//int NUM_THREAD_PERCAM = 1;
+#endif
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Status;
+
+namespace iv {
+struct msgunit
+{
+    char mstrmsgname[256];
+    int mnBufferSize = 10000;
+    int mnBufferCount = 1;
+    void * mpa;
+    std::shared_ptr<char> mpstrmsgdata;
+    int mndatasize = 0;
+    bool mbRefresh = false;
+    bool mbImportant = false;
+    int mnkeeptime = 100;
+};
+}
+
+class grpcpc : public QThread
+{
+public:
+    grpcpc(std::string stryamlpath);
+
+private:
+    void run();
+
+private:
+    std::string gstrserverip = "192.168.14.98";//"111.33.136.149";//"127.0.0.1";// "140.143.237.38";
+    std::string gstrserverport = "50051";//"9000";
+    std::string gstruploadinterval = "100";
+    void * gpa;
+    QMutex gMutexMsg;
+    std::vector<iv::msgunit> mvectormsgunit;
+
+    std::vector<iv::msgunit> mvectorctrlmsgunit;
+
+
+    std::string gstrVIN = "AAAAAAAAAAAAAAAAA";
+    std::string gstrqueryMD5 = "5d41402abc4b2a76b9719d911017c592";
+    std::string gstrctrlMD5 = "5d41402abc4b2a76b9719d911017c592";
+
+
+
+
+    int gindex = 0;
+
+
+private:
+    void dec_yaml(const char * stryamlpath);
+    void sharequerymsg(iv::cloud::cloudmsg * pxmsg);
+
+public:
+    void UpdateData(const char * strdata,const unsigned int nSize,const char * strmemname);
+    std::string GetVIN();
+
+private:
+    void threadpicdownload(int nCamPos);
+    void * mpaPic[NUM_CAM];
+    std::string mstrpicmsgname[NUM_CAM];
+
+    std::thread * mpThread[NUM_CAM * NUM_THREAD_PERCAM];
+
+    QMutex mMutexPic[NUM_CAM];
+
+    qint64 mnPicUpLatency[NUM_CAM];
+    int mnFrameRate[NUM_CAM];
+    int mnPicDownLatency[NUM_CAM];
+
+
+public:
+    qint64 GetPicLatency(int nCamPos);
+    int GetFrameRate(int nCamPos);
+    qint64 GetPicDownLatency(int nCamPos);
+
+
+public:
+    void setserverip(std::string strip);
+    void setserverport(std::string strport);
+    void setqueryinterval(std::string strinterval);
+    void setVIN(std::string strVIN);
+    void setqueryMD5(std::string strmd5);
+    void setctrlMD5(std::string strmd5);
+
+
+};
+
+#endif // GRPCPC_H

+ 155 - 0
src/tool/RemoteCtrl_h264/ivpicsave.cpp

@@ -0,0 +1,155 @@
+#include "ivpicsave.h"
+
+#include <QDateTime>
+
+#include <opencv2/opencv.hpp>
+#include <opencv2/core.hpp>
+
+#ifdef NVIDIA_AGX
+#include <opencv2/imgcodecs/legacy/constants_c.h>    //OpenCV4 use this line
+#include <opencv2/imgproc/types_c.h>   //OpenCV4 use this line
+#endif
+
+ivpicsave::ivpicsave(QString strdir,QString strsuffix,std::string strvin)
+{
+    mstrdir = strdir;
+    mstrsuffix = strsuffix;
+    mstrvin = strvin;
+    mnWriteIndex = 0;
+}
+
+void ivpicsave::SetPic(iv::vision::rawpic pic)
+{
+    if((mbGetPicSize == true ) && (mbSave == false))
+    {
+        return;
+    }
+    mMutex.lock();
+    mrawpic.CopyFrom(pic);
+    mnWriteIndex++;
+    mMutex.unlock();
+}
+
+void ivpicsave::run()
+{
+    int nReadIndex = 0;
+    std::vector<iv::vision::rawpic> xvectorpic;
+    bool bgetfps = false;
+    double ffps = 30;
+    while(!QThread::isInterruptionRequested())
+    {
+        if((mbSave == false)&&(bgetfps))
+        {
+            msleep(100);
+            continue;
+        }
+        bool bNew = false;
+        iv::vision::rawpic pic;
+        if(mnWriteIndex != nReadIndex)
+        {
+
+            mMutex.lock();
+            pic.CopyFrom(mrawpic);
+            mMutex.unlock();
+            if(bgetfps == false)
+            {
+                xvectorpic.push_back(pic);
+                if(xvectorpic.size()>=10)
+                {
+                    std::vector<qint64> xtimediff;
+                    int j;
+                    for(j=1;j<xvectorpic.size();j++)
+                    {
+                        qint64 diff = xvectorpic[j].time() - xvectorpic[j-1].time();
+                        xtimediff.push_back(diff);
+                    }
+                    qint64 totaldiff = 0;
+                    for(j=0;j<xtimediff.size();j++)
+                    {
+                        totaldiff = totaldiff + xtimediff[j];
+                    }
+                    qint64 avgdiff = totaldiff/xtimediff.size();
+                    ffps = avgdiff;
+                    if(ffps<1.0)ffps =1.0;
+                    if(ffps>1000.0)ffps = 1000.0;
+                    ffps = 1000.0/ffps;
+                    mMutexSave.lock();
+                    mfps = ffps;
+                    mnpicheight = xvectorpic[0].height();
+                    mnpicwidth = xvectorpic[0].width();
+                    mMutexSave.unlock();
+                    mbGetPicSize = true;
+                    bgetfps = true;
+                    xvectorpic.clear();
+                    xtimediff.clear();
+                }
+            }
+            nReadIndex++;
+            bNew = true;
+        }
+
+        if(mbSave == false)
+        {
+            msleep(1);
+            continue;
+        }
+        if(bNew)
+        {
+            cv::Mat mat(pic.height(),pic.width(),pic.mattype());
+
+            if(mbSave)
+            {
+                if(pic.type() == 1)
+                    memcpy(mat.data,pic.picdata().data(),mat.rows*mat.cols*mat.elemSize());
+                else
+                {
+                    std::vector<unsigned char> buff(pic.picdata().data(),pic.picdata().data()+pic.picdata().size());
+                    mat = cv::imdecode(buff,CV_LOAD_IMAGE_COLOR);
+                }
+                int font = cv::FONT_HERSHEY_DUPLEX;
+                QDateTime xrecvtime = QDateTime::fromMSecsSinceEpoch(pic.time());
+         //       char strtext[256];
+          //      snprintf(strtext,"%s",xrecvtime.toString("yyyy-MM-dd hh:mm:ss:zzz").toLatin1().data());
+                std::string strtext = xrecvtime.toString("yyyy-MM-dd hh:mm:ss:zzz").toStdString();
+                double fratio = pic.width()/640;
+                int fontsize = 0.5*fratio;
+                if(fontsize<1)fontsize = 1;
+                cv::putText(mat,strtext,cv::Point(pic.width() - 230*fratio,30*fratio),font,0.5*fratio,cv::Scalar(0,255,0),fontsize);
+                cv::putText(mat,mstrvin,cv::Point(10,30*fratio),font,0.5*fratio,cv::Scalar(0,255,0),fontsize);
+            }
+
+
+            mMutexSave.lock();
+            if(mbSave)
+            {
+                mWriter<<mat;
+            }
+            mMutexSave.unlock();
+        }
+        msleep(10);
+    }
+}
+
+void ivpicsave::startsave()
+{
+    std::string strfilename;
+    strfilename = mstrdir.toStdString() + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz").toStdString() +"-" + mstrsuffix.toStdString() +".avi";
+    mMutexSave.lock();
+    mWriter.open(strfilename,cv::VideoWriter::fourcc('M','P','4','2'),10.0,cv::Size(mnpicwidth,mnpicheight),1);
+    if(mWriter.isOpened())
+    {
+        mbSave = true;
+    }
+    mMutexSave.unlock();
+}
+
+void ivpicsave::stopsave()
+{
+    if(mbSave)
+    {
+        mMutexSave.lock();
+        mbSave = false;
+        mWriter.release();
+        mMutexSave.unlock();
+    }
+}

+ 44 - 0
src/tool/RemoteCtrl_h264/ivpicsave.h

@@ -0,0 +1,44 @@
+#ifndef IVPICSAVE_H
+#define IVPICSAVE_H
+
+#include "rawpic.pb.h"
+
+#include <QMutex>
+
+#include <QThread>
+
+#include "opencv2/video.hpp"
+#include "opencv2/videoio.hpp"
+
+class ivpicsave : public QThread
+{
+public:
+    ivpicsave(QString strdir,QString strsuffix,std::string strvin);
+
+private:
+    iv::vision::rawpic mrawpic;
+    QMutex mMutex;
+    QMutex mMutexSave;
+    int mnWriteIndex = 0;
+    cv::VideoWriter mWriter;
+    bool mbSave = false;
+    QString mstrdir;
+    QString mstrsuffix;
+    std::string mstrvin;
+    double mfps;
+    int mnpicwidth = 1920;
+    bool mbGetPicSize = false;
+    int mnpicheight = 1080;
+
+    void run();
+
+public:
+    void SetPic(iv::vision::rawpic pic);
+
+    void startsave();
+    void stopsave();
+
+
+};
+
+#endif // IVPICSAVE_H

+ 111 - 0
src/tool/RemoteCtrl_h264/ivpicview.cpp

@@ -0,0 +1,111 @@
+#include "ivpicview.h"
+
+#include <QDateTime>
+
+#include <opencv2/opencv.hpp>
+#include <opencv2/core.hpp>
+
+#ifdef NVIDIA_AGX
+#include <opencv2/imgcodecs/legacy/constants_c.h>    //OpenCV4 use this line
+#include <opencv2/imgproc/types_c.h>   //OpenCV4 use this line
+#endif
+
+#define VIEW_WIDTH 640
+#define VIEW_HEIGHT 360
+
+IVPicView::IVPicView()
+{
+    mimagepaint = new QImage(VIEW_WIDTH, VIEW_HEIGHT, QImage::Format_RGB32);//画布的初始化大小设为300*300,使用32位颜色
+}
+
+void IVPicView::run()
+{
+    while(!QThread::isInterruptionRequested())
+    {
+        if(mnReadIndex != mnWriteIndex)
+        {
+            paint();
+            mnReadIndex = mnWriteIndex;
+            mbImageUpdate = true;
+        }
+        else
+        {
+            msleep(10);
+        }
+    }
+}
+
+
+
+void IVPicView::paint()
+{
+    iv::vision::rawpic pic;
+    mMutex.lock();
+    pic.CopyFrom(mrawpic);
+    mMutex.unlock();
+
+    cv::Mat mat(pic.height(),pic.width(),pic.mattype());
+
+    if(pic.type() == 1)
+        memcpy(mat.data,pic.picdata().data(),mat.rows*mat.cols*mat.elemSize());
+    else
+    {
+//        qDebug("jpg");
+        std::vector<unsigned char> buff(pic.picdata().data(),pic.picdata().data()+pic.picdata().size());
+        mat = cv::imdecode(buff,CV_LOAD_IMAGE_COLOR);
+        int font = cv::FONT_HERSHEY_DUPLEX;
+        QDateTime xrecvtime = QDateTime::fromMSecsSinceEpoch(pic.time());
+ //       char strtext[256];
+  //      snprintf(strtext,"%s",xrecvtime.toString("yyyy-MM-dd hh:mm:ss:zzz").toLatin1().data());
+        std::string strtext = xrecvtime.toString("yyyy-MM-dd hh:mm:ss:zzz").toStdString();
+        double fratio = pic.width()/640;
+        cv::putText(mat,strtext,cv::Point(pic.width() - 230*fratio,30*fratio),font,0.5*fratio,cv::Scalar(0,255,0),0.5*fratio);
+    }
+
+    cv::cvtColor(mat, mat, CV_BGR2RGB);
+    QImage image2 = QImage((uchar*)(mat.data), mat.cols, mat.rows,  QImage::Format_RGB888);
+
+    mMutexPaint.lock();
+
+//    delete mimagepaint;
+//    mimagepaint = new  QImage(mat.cols, mat.rows,  QImage::Format_RGB888);
+    *mimagepaint = image2.copy();
+    //  *mimagepaint = image2;
+ //   mimagepaint = new QImage(image2);
+    mMutexPaint.unlock();
+
+    mat.release();
+
+    emit painterupadate();
+}
+
+QImage IVPicView::GetImage()
+{
+
+    mMutexPaint.lock();
+//    QImage imagertn(*mimagepaint);
+//    QImage imagertn(mimagepaint->width(), mimagepaint->height(), QImage::Format_RGB32);
+    QImage imagertn = mimagepaint->copy();
+    mMutexPaint.unlock();
+    mbImageUpdate = false;
+    return imagertn;
+}
+
+bool IVPicView::IsHaveNew()
+{
+    return mbImageUpdate;
+}
+
+int IVPicView::GetType()
+{
+    return 2;
+}
+
+void IVPicView::SetPic(iv::vision::rawpic pic)
+{
+    mMutex.lock();
+    mrawpic.CopyFrom(pic);
+    mnWriteIndex++;
+    mMutex.unlock();
+}
+

+ 40 - 0
src/tool/RemoteCtrl_h264/ivpicview.h

@@ -0,0 +1,40 @@
+#ifndef IVPICVIEW_H
+#define IVPICVIEW_H
+
+#include "ivview.h"
+
+#include "rawpic.pb.h"
+
+class IVPicView : public IVView
+{
+    Q_OBJECT
+public:
+    IVPicView();
+
+public:
+    QImage GetImage();
+    bool IsHaveNew();
+    int GetType();
+private:
+    void run();
+    int mnWriteIndex = 0;
+    int mnReadIndex = 0;
+
+private:
+    bool mbImageUpdate = false;
+    QMutex mMutex;
+    QMutex mMutexPaint;
+
+private:
+    void paint();
+    QImage * mimagepaint;
+signals:
+    void painterupadate();
+
+private:
+    iv::vision::rawpic mrawpic;
+public:
+    void SetPic(iv::vision::rawpic pic);
+};
+
+#endif // IVPICVIEW_H

+ 25 - 0
src/tool/RemoteCtrl_h264/ivview.cpp

@@ -0,0 +1,25 @@
+#include "ivview.h"
+
+IVView::IVView()
+{
+
+
+}
+
+QImage IVView::GetImage()
+{
+    QImage * pimage = new QImage(100,100,QImage::Format_RGB32);
+    return *pimage;
+
+
+}
+
+bool IVView::IsHaveNew()
+{
+    return false;
+}
+
+int IVView::GetType()
+{
+    return 0;
+}

+ 34 - 0
src/tool/RemoteCtrl_h264/ivview.h

@@ -0,0 +1,34 @@
+#ifndef IVVIEW_H
+#define IVVIEW_H
+
+#include <QImage>
+#include <QGraphicsScene>
+#include <QTimer>
+#include <QPainter>
+
+#include <QThread>
+
+#include <QMutex>
+
+//#include <pcl/conversions.h>
+//#include <pcl/point_cloud.h>
+//#include <pcl/point_types.h>
+
+
+class IVView : public QThread
+{
+public:
+    IVView();  
+
+public:
+    virtual QImage GetImage();
+    virtual bool IsHaveNew();
+    virtual int GetType();
+
+private:
+
+
+
+};
+
+#endif // IVVIEW_H

+ 161 - 0
src/tool/RemoteCtrl_h264/joyreadthread.cpp

@@ -0,0 +1,161 @@
+#include "joyreadthread.h"
+
+#include <assert.h>
+#include <math.h>
+#include <algorithm>
+#include <iostream>
+#include <stdexcept>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sstream>
+#include <unistd.h>
+#include <linux/joystick.h>
+
+#include <QFile>
+
+extern std::string gstrjoy_path;
+
+JoyReadThread::JoyReadThread()
+{
+
+    if ((fd = open(gstrjoy_path.data(), O_RDONLY)) < 0)
+    {
+        mbJoyOK = false;
+      std::ostringstream str;
+//      str << filename << ": " << strerror(errno);
+//      throw std::runtime_error(str.str());
+
+    }
+    else
+    {
+      // ok
+      uint8_t num_axis   = 0;
+      uint8_t num_button = 0;
+      ioctl(fd, JSIOCGAXES,    &num_axis);
+      ioctl(fd, JSIOCGBUTTONS, &num_button);
+      axis_count   = num_axis;
+      button_count = num_button;
+
+      // Get Name
+      char name_c_str[1024];
+      if (ioctl(fd, JSIOCGNAME(sizeof(name_c_str)), name_c_str) < 0)
+      {
+          mbJoyOK = false;
+          std::ostringstream str;
+    //      str << filename << ": " << strerror(errno);
+          str << "joy:" << ": " << strerror(errno);
+  //        throw std::runtime_error(str.str());
+      }
+      else
+      {
+          orig_name = name_c_str;
+//          try {
+//              name = Glib::convert_with_fallback(name_c_str, "UTF-8", "ISO-8859-1");
+//          } catch(Glib::ConvertError& err) {
+//              std::cout << err.what() << std::endl;
+//          }
+      }
+
+//      axis_state.resize(axis_count);
+    }
+}
+
+void JoyReadThread::run()
+{
+    if(mbJoyOK == false)return;
+    while(!QThread::isInterruptionRequested())
+    {
+        struct js_event event;
+
+        ssize_t len = read(fd, &event, sizeof(event));
+
+        if(len < 0)
+        {
+//            qDebug("fail.");
+            mbJoyOK = false;
+            break;
+        }
+
+ //       if(len >0)qDebug("len = %d",len);
+
+        if(len == sizeof(js_event))
+        {
+            switch (event.number) {
+            case 0:
+                mfWheel = event.value;
+                break;
+            case 2:
+                mfAcc = event.value;
+                break;
+            case 3:
+                mfBrake = event.value;
+                break;
+            case 12:
+                if(event.value ==1 ) mnShift = 1;
+                else mnShift = 0;
+                break;
+            case 13:
+                if(event.value ==1 ) mnShift = 2;
+                else mnShift = 0;
+                break;
+            case 14:
+                if(event.value ==1 ) mnShift = 3;
+                else mnShift = 0;
+                break;
+            case 15:
+                if(event.value ==1 ) mnShift = 4;
+                else mnShift = 0;
+                break;
+            case 16:
+                if(event.value ==1 ) mnShift = 5;
+                else mnShift = 0;
+                break;
+            case 17:
+                if(event.value ==1 ) mnShift = 6;
+                else mnShift = 0;
+                break;
+            case 18:
+                if(event.value ==1 ) mnShift = -1;
+                else mnShift = 0;
+                break;
+            default:
+                break;
+            }
+            qDebug("shift = %d",mnShift);
+//            qDebug("type = %d number = %d value = %d ",event.type,event.number,event.value);
+//            qDebug("wheel:%g acc:%g brake:%g",mfWheel,mfAcc,mfBrake);
+        }
+    }
+    close(fd);
+    mbJoyOK = false;
+}
+
+bool JoyReadThread::isOK()
+{
+    return mbJoyOK;
+}
+
+double JoyReadThread::GetAcc()
+{
+    return mfAcc;
+}
+
+double JoyReadThread::GetBrake()
+{
+    return mfBrake;
+}
+
+double JoyReadThread::GetWheel()
+{
+    return mfWheel;
+}
+
+int JoyReadThread::GetShift()
+{
+    return mnShift;
+}

+ 39 - 0
src/tool/RemoteCtrl_h264/joyreadthread.h

@@ -0,0 +1,39 @@
+#ifndef JOYREADTHREAD_H
+#define JOYREADTHREAD_H
+
+#include <QThread>
+
+#include <QFile>
+
+class JoyReadThread : public QThread
+{
+public:
+    JoyReadThread();
+
+public:
+    bool isOK();
+    double GetWheel();
+    double GetAcc();
+    double GetBrake();
+    int GetShift();
+private:
+    void run();
+
+private:
+    int fd;
+    int axis_count;
+    int button_count;
+    std::string orig_name;
+
+    QFile mxFile;
+    QFile * mpFile;
+    bool mbJoyOK = true;
+
+    double mfWheel = 0;
+    double mfAcc = 32767;
+    double mfBrake = 32767;
+
+    int mnShift = 0; //0 N >0 D -1 R
+};
+
+#endif // JOYREADTHREAD_H

+ 76 - 0
src/tool/RemoteCtrl_h264/main.cpp

@@ -0,0 +1,76 @@
+#include "mainwindow.h"
+
+#include <QApplication>
+#include <QList>
+
+#include <vector>
+
+#include "pos_def.h"
+
+#include "xmlparam.h"
+#include "ivversion.h"
+
+std::string gstrmem_gpsimu;
+std::string gstrmem_pic[CAMERA_NUM];
+std::string gstryaml_path;
+std::string gstrjoy_path;
+
+std::vector<iv::pos_def> gvectorpos;
+
+
+void LoadPos(std::string strfilepath)
+{
+    QFile xFile;
+    xFile.setFileName(strfilepath.data());
+    if(xFile.open(QIODevice::ReadOnly))
+    {
+        QByteArray ba = xFile.readAll();
+        QList<QByteArray> baline =  ba.split('\n');
+        int nline = baline.size();
+        int i;
+        for(i=0;i<nline;i++)
+        {
+            QList<QByteArray> badata = baline[i].split('\t');
+            if(badata.size()>=3)
+            {
+                iv::pos_def xposdef;
+                xposdef.mstrstationname = badata[0].toStdString();
+                xposdef.mflon = badata[1].toDouble();
+                xposdef.mflat = badata[2].toDouble();
+                gvectorpos.push_back(xposdef);
+
+            }
+
+        }
+    }
+    xFile.close();
+}
+
+
+#include "ivbacktrace.h"
+
+int main(int argc, char *argv[])
+{
+
+    showversion("RemoteCtl");
+    QApplication a(argc, argv);
+
+    RegisterIVBackTrace();
+
+
+
+    iv::xmlparam::Xmlparam xp("RemoteCtrl.xml");
+    gstrmem_gpsimu = xp.GetParam("gpsimu","hcp2_gpsimu");
+    gstrmem_pic[0] = xp.GetParam("PicFront","h264front");
+    gstrmem_pic[1] = xp.GetParam("PicRear","h264rear");
+    gstrmem_pic[2] = xp.GetParam("PicLeft","h264left");
+    gstrmem_pic[3] = xp.GetParam("PicRight","h264right");
+    gstrjoy_path = xp.GetParam("joypath","/dev/input/js0");
+    gstryaml_path = xp.GetParam("yamlpath","./driver_cloud_grpc_pc.yaml");
+
+    LoadPos("pos.txt");
+
+    MainWindow w;
+    w.show();
+    return a.exec();
+}

+ 955 - 0
src/tool/RemoteCtrl_h264/mainwindow.cpp

@@ -0,0 +1,955 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include "pos_def.h"
+
+#include "remotectrlini.h"
+
+MainWindow * gw;
+//#include "QStringLiteral"
+
+#ifdef NVIDIA_AGX
+#include "opencv2/imgcodecs/legacy/constants_c.h"   //OpenCV4 use this line
+#include <opencv2/imgproc/types_c.h>   //OpenCV4 use this line
+#endif
+
+#include <opencv2/opencv.hpp>
+#include <opencv2/core.hpp>
+
+iv::gps::gpsimu ggpsimu;
+qint64 gTimeGPSIMUUpdate = 0;
+
+iv::vision::rawpic grawpic[CAMERA_NUM];
+qint64 gTimeRawPic[CAMERA_NUM] = {0,0,0,0};
+QMutex gMutexPic[CAMERA_NUM];
+
+extern std::string gstrmem_gpsimu;
+extern std::string gstrmem_pic[CAMERA_NUM];
+extern std::vector<iv::pos_def> gvectorpos;
+extern std::string gstryaml_path;
+
+class xodrobj
+{
+public:
+    double flatsrc;
+    double flonsrc;
+    double fhgdsrc;
+    double flat;
+    double flon;
+    int lane;
+};
+
+namespace iv {
+struct simpletrace
+{
+    double gps_lat = 0;//纬度
+    double gps_lng = 0;//经度
+
+    double gps_x = 0;
+    double gps_y = 0;
+    double gps_z = 0;
+
+
+    double ins_heading_angle = 0;	//航向角
+};
+}
+
+std::vector<iv::simpletrace> gvectorsimplerace;
+QMutex gMutexTrace;
+qint64 gTimeTrace = 0;
+
+
+void * gpaframe;
+
+void Listenpic(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+    if(nSize<50)return;
+
+    int * pnhead = (int * )strdata;
+    std::cout<<" pac count: "<<*pnhead<<" first pac size: "<<*(pnhead + 1)<<std::endl;
+
+    std::cout<<" pic name : "<<strmemname<<std::endl;
+    int npaccount = *pnhead;
+    int j;
+    int ndatapos = 0;
+
+    char * strfdata = (char *)(strdata + 11*sizeof(int));
+    for(j=0;j<npaccount;j++)
+    {
+        int ndatasize = *(pnhead +j +1);
+        char * strframedata = new char[ndatasize];
+        memcpy(strframedata,strfdata + ndatapos,ndatasize);
+        ndatapos = ndatapos + ndatasize;
+        iv::modulecomm::ModuleSendMsg(gpaframe, strframedata,ndatasize);
+        std::this_thread::sleep_for(std::chrono::milliseconds(15));
+
+    }
+    return;
+    iv::vision::rawpic pic;
+    if(false == pic.ParseFromArray(strdata,nSize))
+    {
+        std::cout<<"picview Listenpic fail."<<std::endl;
+        return;
+    }
+    int indexpic = -1;
+    for(int i =0;i<CAMERA_NUM;i++)
+    {
+        if(strncmp(strmemname,gstrmem_pic[i].data(),256) == 0)
+        {
+            indexpic = i;
+            break;
+        }
+    }
+    if(indexpic >= 0)
+    {
+    gMutexPic[indexpic].lock();
+    grawpic[indexpic].CopyFrom(pic);
+    gTimeRawPic[indexpic] = QDateTime::currentMSecsSinceEpoch();
+    gMutexPic[indexpic].unlock();
+    gw->saveavi(indexpic);
+    }
+}
+
+void Listensimpletrace(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+    int npoint = nSize/sizeof(iv::simpletrace);
+    if(npoint < 1)
+    {
+        std::cout<<"simple trace is very smalll"<<std::endl;
+        return;
+    }
+
+    gMutexTrace.lock();
+    gvectorsimplerace.clear();
+    gvectorsimplerace.resize(npoint);
+    memcpy(gvectorsimplerace.data(),strdata,npoint*sizeof(iv::simpletrace));
+    gTimeTrace = QDateTime::currentMSecsSinceEpoch();
+    gMutexTrace.unlock();
+
+
+}
+
+void Listengpsimu(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+//        ggpsimu->UpdateGPSIMU(strdata,nSize);
+
+    iv::gps::gpsimu xgpsimu;
+    if(!xgpsimu.ParseFromArray(strdata,nSize))
+    {
+        std::cout<<"ListenRaw Parse error."<<std::endl;
+    }
+    ggpsimu.CopyFrom(xgpsimu);
+    gTimeGPSIMUUpdate = QDateTime::currentMSecsSinceEpoch();
+
+}
+
+MainWindow::MainWindow(QWidget *parent)
+    : QMainWindow(parent)
+    , ui(new Ui::MainWindow)
+{
+
+    gpaframe = iv::modulecomm::RegisterSend("h264frame",1000000,1);
+    gw = this;
+
+    ui->setupUi(this);
+
+    mstrserverip = ServiceRCIni.GetServerIP();
+    mstrserverport = ServiceRCIni.GetServerPort();
+    mstruploadinterval = ServiceRCIni.GetInterval();
+    mstrVehVIN = ServiceRCIni.GetVIN();
+    mstrqueryMD5 = ServiceRCIni.GetQueryMD5();
+    mstrctrlMD5 = ServiceRCIni.GetCtrlMD5();
+
+    mpJRT = new JoyReadThread();
+    mpJRT->start();
+
+    int i;
+
+    CreateView();
+
+    mpPicView = new IVPicView();
+    mpPicView->start();
+
+
+
+    int nstation = gvectorpos.size();
+    for(i=0;i<nstation;i++)
+    {
+        ui->comboBox_Station->addItem(gvectorpos[i].mstrstationname.data());
+    }
+
+    ui->radioButton_auto->setChecked(true);
+
+    mpa = iv::modulecomm::RegisterSend("remotectrl",10000,1);
+
+    mpTimerManual = new QTimer(this);
+    connect(mpTimerManual,SIGNAL(timeout()),this,SLOT(onTimerManual()));
+
+    mpTimerRemote = new QTimer(this);
+    connect(mpTimerRemote,SIGNAL(timeout()),this,SLOT(onTimerRemote()));
+    mpTimerRemote->start(10);
+
+    mpTimerUpdateView = new QTimer(this);
+    connect(mpTimerUpdateView,SIGNAL(timeout()),this,SLOT(onTimerUpdateView()));
+    mpTimerUpdateView->start(1000);
+
+    QTimer * timer = new QTimer(this);
+    connect(timer,SIGNAL(timeout()),this,SLOT(onTimerUpdatePic()));
+    timer->start(10);
+
+    mpadst = iv::modulecomm::RegisterSend("xodrreq",1000,1);
+
+
+    mgrpcpc = new grpcpc(gstryaml_path);
+    mgrpcpc->setserverip(mstrserverip);
+    mgrpcpc->setserverport(mstrserverport);
+    mgrpcpc->setqueryinterval(mstruploadinterval);
+    mgrpcpc->setVIN(mstrVehVIN);
+    mgrpcpc->setqueryMD5(mstrqueryMD5);
+    mgrpcpc->setctrlMD5(mstrctrlMD5);
+    mgrpcpc->start();
+
+    mstrVIN = mgrpcpc->GetVIN().data();
+    mstrVIN = " VIN:"+ mstrVIN+" ";
+
+    mpPicSave[0] = new ivpicsave("./","front",mstrVIN.toStdString());
+    mpPicSave[1] = new ivpicsave("./","rear",mstrVIN.toStdString());
+    mpPicSave[2] = new ivpicsave("./","left",mstrVIN.toStdString());
+    mpPicSave[3] = new ivpicsave("./","right",mstrVIN.toStdString());
+
+    for(i=0;i<4;i++)
+    {
+        mpPicSave[i]->start();
+    }
+
+    mppicdlg = new DialogPic(this);
+    mppicdlg->setModal(false);
+    connect(mppicdlg,SIGNAL(finished(int)),this,SLOT(onCloseDlg()));
+
+    mpbigpicdlg = new DialogBigPic(this);
+    mpbigpicdlg->setModal(false);
+    connect(mpbigpicdlg,SIGNAL(finished(int)),this,SLOT(onCloseBigDlg()));
+
+    QLabel * pLabel = new QLabel();
+    pLabel->setFixedWidth(600);
+    pLabel->setText("Latency");
+    mpLabelLatency = pLabel;
+    ui->statusbar->addPermanentWidget(pLabel);
+
+    mpasimpletrace = iv::modulecomm::RegisterRecv("simpletrace",Listensimpletrace);
+
+    void * pa = iv::modulecomm::RegisterRecv(gstrmem_gpsimu.data(),Listengpsimu);
+
+    for(i=0;i<CAMERA_NUM;i++)
+        pa = iv::modulecomm::RegisterRecv(gstrmem_pic[i].data(),Listenpic);
+
+
+
+//    mpbaiduapp = new pluginapp(this->winId(),"baidu","baidumapshow","/home/yuchuli/qt/modularization/src/plugin/build-baidumapshow-Debug");
+//    mppicshow = new pluginapp(this->winId(),"main","plugin_picshow","/home/yuchuli/qt/modularization/src/plugin/build-plugin_picshow-Debug");
+
+//    mppicshow->SetAttr("rawpicmsgname",gstrmem_pic[0].data(),gstrmem_pic[0].size());
+
+    setWindowTitle(mstrProgName +mstrVIN+  mstrGPSTime + mstrPicTime);
+
+}
+
+MainWindow::~MainWindow()
+{
+
+//    delete mppicshow;
+//    delete mpbaiduapp;
+    delete ui;
+}
+
+void MainWindow::CreateView()
+{
+    mMapview = new QWebEngineView(ui->centralwidget);
+//    qDebug((QDir::currentPath()).toLatin1().data());
+    mMapview->load(QUrl(QString("file:///%1/%2").arg(QApplication::applicationDirPath()).arg("BaiDuMap.html")));
+
+    mMapview->setGeometry(10,10,800,800);
+
+//    mMapview->page()->runJavaScript("theLocation(117.355,39.066);");  //117.355,39.066
+
+    mpWheel = new Speed(ui->groupBox_rem);
+    mpWheel->settitle(QStringLiteral("方向盘"));
+
+    mpAcc = new Speed(ui->groupBox_rem);
+
+    mpAcc->settitle(QStringLiteral("油门"));
+    mpAcc->updatevalue(0);
+    mpAcc->setminvalue(0);
+    mpAcc->setmaxvalue(100);
+
+    mpBrake = new Speed(ui->groupBox_rem);
+    mpBrake->settitle(QStringLiteral("刹车"));
+    mpBrake->updatevalue(0);
+    mpBrake->setminvalue(0);
+    mpBrake->setmaxvalue(100);
+
+    mmyview = new MyView(ui->centralwidget);
+    mmyview->setObjectName(QStringLiteral("graphicsView"));
+    mmyview->setGeometry(QRect(30, 30, 600, 600));
+
+    mmyview->setCacheMode(mmyview->CacheBackground);
+
+    mscene = new QGraphicsScene;
+
+    ui->radioButton_Null->setChecked(true);
+
+    ui->radioButton_picfront->setChecked(true);
+
+
+}
+
+
+void MainWindow::keyPressEvent(QKeyEvent *event)
+{
+
+    //按键按下,key值放入容器,如果是长按触发的repeat就不判断
+    if(!event->isAutoRepeat())
+        mPressKeys.insert(event->key());
+
+
+}
+
+void MainWindow::keyReleaseEvent(QKeyEvent *event)
+{
+    if(!event->isAutoRepeat())mPressKeys.remove(event->key());
+    qDebug("key count is %d",mPressKeys.count());
+}
+
+void MainWindow::resizeEvent(QResizeEvent *event)
+{
+    QSize sizemain = ui->centralwidget->size();
+    qDebug("size x = %d y=%d",sizemain.width(),sizemain.height());
+
+    mMapview->setGeometry(10,10,sizemain.width()/2,sizemain.height()*3/5);
+
+//    mpbaiduapp->SetGeometry(10,30,sizemain.width()/2,sizemain.height()*3/5);
+
+    mmyview->setGeometry(10+sizemain.width()/2+10,10,sizemain.width()/2-30,sizemain.height()*3/5);
+
+//    mppicshow->SetGeometry(10+sizemain.width()/2+10,10,sizemain.width()/2-30,sizemain.height()*3/5);
+
+    ui->lineEdit_lat->setGeometry(sizemain.width()-100,10,90,30);
+    ui->lineEdit_lon->setGeometry(sizemain.width()-100,50,90,30);
+    ui->pushButton_test->setGeometry(sizemain.width()-100,90,90,30);
+
+//    mpWheel->setGeometry(sizemain.width()/2 + 20,10,200,200);
+
+    int grouppos_x = 10;
+    int grouppos_y = 20 + sizemain.height() *3/5;
+    int grouppos_width = sizemain.width()*6/10;
+    int grouppos_height = sizemain.height()*2/5 - 20;
+
+
+    int speed_width = grouppos_height-40;
+    if((speed_width*3 + 150)>grouppos_width)speed_width = (grouppos_width - 150)/3;
+
+    mpWheel->setGeometry(100,30,speed_width,speed_width);
+    mpBrake->setGeometry(120 + speed_width,30,speed_width,speed_width);
+    mpAcc->setGeometry(140 + 2*speed_width,30,speed_width,speed_width);
+    ui->groupBox_rem->setGeometry(grouppos_x,grouppos_y,grouppos_width,grouppos_height);
+
+    int grouppic_x = 10 + sizemain.width()*6/10 + 10;
+    int grouppic_y = 20 + sizemain.height() *3/5;
+    int grouppic_width = sizemain.width()*4/10 - 30;
+    int grouppic_height = sizemain.height()*1/10;
+
+    ui->groupBox_picsel->setGeometry(grouppic_x,grouppic_y,grouppic_width,grouppic_height);
+
+    int groupmap_x = 10 + sizemain.width()*6/10 + 10;
+    int groupmap_y = 20 + sizemain.height() *7/10;
+    int groupmap_width = sizemain.width()*4/10 - 30;
+    int groupmap_height = sizemain.height()*1/10;
+
+    ui->comboBox_Station->setGeometry(10,30,groupmap_width*3/5,30);
+    ui->pushButton_Go->setGeometry(20 + groupmap_width*3/5,30,groupmap_width*2/5 - 30,30);
+
+    ui->groupBox_map->setGeometry(groupmap_x,groupmap_y,groupmap_width,groupmap_height);
+
+    int groupgps_x = 10 + sizemain.width()*6/10 + 10;
+    int groupgps_y = 30 + sizemain.height() *8/10;
+    int groupgps_width = sizemain.width()*4/10 - 30;
+    int groupgps_height = sizemain.height()*2/10 - 30;
+
+    ui->groupBox_gps->setGeometry(groupgps_x,groupgps_y,groupgps_width,groupgps_height);
+
+    int lablewidth = (groupgps_width-50)*2/10;
+    int lewidth = (groupgps_width-50)*3/10;
+    int leheight = 26;
+
+    int nypos = 40;
+    ui->label_gpsins->setGeometry(10,nypos,lablewidth,leheight);
+    ui->lineEdit_gpsins->setGeometry(20+lablewidth,nypos,lewidth,leheight);
+    ui->label_gpsrtk->setGeometry(30+lablewidth+lewidth,nypos,lablewidth,leheight);
+    ui->lineEdit_gpsrtk->setGeometry(40+2*lablewidth +lewidth,nypos,lewidth,leheight);
+
+    nypos = nypos + leheight*11/10;
+    ui->label_gpslon->setGeometry(10,nypos,lablewidth,leheight);
+    ui->lineEdit_gpslon->setGeometry(20+lablewidth,nypos,lewidth,leheight);
+    ui->label_gpslat->setGeometry(30+lablewidth+lewidth,nypos,lablewidth,leheight);
+    ui->lineEdit_gpslat->setGeometry(40+2*lablewidth +lewidth,nypos,lewidth,leheight);
+
+    nypos = nypos + leheight*11/10;
+    ui->label_gpsheading->setGeometry(10,nypos,lablewidth,leheight);
+    ui->lineEdit_gpsheading->setGeometry(20+lablewidth,nypos,lewidth,leheight);
+    ui->label_gpsheight->setGeometry(30+lablewidth+lewidth,nypos,lablewidth,leheight);
+    ui->lineEdit_gpsheight->setGeometry(40+2*lablewidth +lewidth,nypos,lewidth,leheight);
+
+    nypos = nypos + leheight*11/10;
+    ui->label_gpsspeed->setGeometry(10,nypos,lablewidth,leheight);
+    ui->lineEdit_gpsspeed->setGeometry(20+lablewidth,nypos,lewidth,leheight);
+    ui->label_gpssat->setGeometry(30+lablewidth+lewidth,nypos,lablewidth,leheight);
+    ui->lineEdit_gpssat->setGeometry(40+2*lablewidth +lewidth,nypos,lewidth,leheight);
+
+
+}
+
+
+void MainWindow::on_pushButton_test_clicked()
+{
+    double flat = ui->lineEdit_lat->text().toDouble();
+    double flon = ui->lineEdit_lon->text().toDouble();
+
+    char strscript[256];
+    snprintf(strscript,255,"theLocation(%11.7f,%11.7f);",flon,flat);
+    mMapview->page()->runJavaScript(strscript);
+}
+
+void MainWindow::on_radioButton_manual_clicked()
+{
+    ui->radioButton_manual->setChecked(true);
+    mPressKeys.clear();
+    mfAcc = 0;
+    mfWheel = 0;
+    mfBrake = 0;
+    mpWheel->updatevalue(mfWheel);
+    mpAcc->updatevalue(mfAcc);
+    mpBrake->updatevalue(mfBrake);
+    mManualTime.restart();
+    mnLastTime = mManualTime.elapsed();
+    mpTimerManual->start(10);
+}
+
+void MainWindow::onTimerManual()
+{
+
+
+    double fOldWheel = mfWheel;
+    double fOldAcc = mfAcc;
+    double fOldBrake = mfBrake;
+    int timediff = mManualTime.elapsed() - mnLastTime;
+    mnLastTime = mManualTime.elapsed();
+
+    int nOldShift = mnShift;
+
+    if(mpJRT->isOK())
+    {
+        mfWheel = mpJRT->GetWheel() * (-100.0)/32768.0;
+        mfAcc = ((mpJRT->GetAcc()-32767.0)/65535)*(-100.0);
+        mfBrake = ((mpJRT->GetBrake()-32767.0)/65535)*(-100.0);
+        if(mfWheel != fOldWheel)mpWheel->updatevalue(mfWheel);
+        if(mfAcc != fOldAcc)mpAcc->updatevalue(mfAcc);
+        if(mfBrake != fOldBrake)mpBrake->updatevalue(mfBrake);
+
+        int x = mpJRT->GetShift();
+        if(x > 0)mnShift = 1;
+        if(x == 0)mnShift = 0;
+        if(x < 0)mnShift = -1;
+        if(mnShift != nOldShift)
+        {
+            switch (mnShift) {
+            case 1:
+                ui->radioButton_Drive->setChecked(true);
+                ui->radioButton_picfront->setChecked(true);
+                on_radioButton_picfront_clicked();
+                break;
+            case 0:
+                ui->radioButton_Null->setChecked(true);
+                break;
+            case -1:
+                ui->radioButton_Rear->setChecked(true);
+                ui->radioButton_picrear->setChecked(true);
+                on_radioButton_picrear_clicked();
+                break;
+            default:
+                break;
+            }
+        }
+        return;
+    }
+
+
+    if(mPressKeys.contains(Qt::Key_A)&&(mPressKeys.contains((Qt::Key_D))))
+    {
+        mfWheel = mfWheel;
+    }
+    else
+    {
+        if(mPressKeys.contains(Qt::Key_A))
+        {
+            if(mfWheel<0)mfWheel = 0;
+            else
+            {
+                mfWheel = mfWheel + timediff*mfWheelSpeed/1000;
+                if(mfWheel < -100)mfWheel = -100;
+                if(mfWheel > 100 )mfWheel = 100;
+            }
+        }
+
+        if(mPressKeys.contains(Qt::Key_D))
+        {
+            if(mfWheel>0)mfWheel = 0;
+            else
+            {
+                mfWheel = mfWheel - timediff*mfWheelSpeed/1000;
+                if(mfWheel < -100)mfWheel = -100;
+                if(mfWheel > 100 )mfWheel = 100;
+            }
+        }
+
+
+    }
+
+    if(!mPressKeys.contains(Qt::Key_A)&&(!mPressKeys.contains((Qt::Key_D))))
+    {
+        if(mfWheel != 0)
+        {
+            if(mfWheel > 0)mfWheel = mfWheel - timediff*mfWheelAutoDownSpeed/1000;
+            else mfWheel = mfWheel + timediff*mfWheelAutoDownSpeed/1000;
+            if(fabs(mfWheel)< 10)mfWheel =0;
+        }
+    }
+
+    if(mPressKeys.contains(Qt::Key_W)&&(mPressKeys.contains((Qt::Key_S))))
+    {
+        mfAcc = 0;
+        mfBrake = mfBrake + timediff*mfBrakeSpeed/1000;
+        if(mfBrake<0)mfBrake = 0;
+        if(mfBrake > 100)mfBrake = 100;
+    }
+    else
+    {
+        if(mPressKeys.contains(Qt::Key_W))
+        {
+            mfBrake = 0;
+            mfAcc = mfAcc + timediff*mfAccSpeed/1000;
+            if(mfAcc<0)mfAcc = 0;
+            if(mfAcc > 100)mfAcc = 100;
+
+        }
+
+        if(mPressKeys.contains(Qt::Key_S))
+        {
+            mfAcc = 0;
+            mfBrake = mfBrake + timediff*mfBrakeSpeed/1000;
+            if(mfBrake<0)mfBrake = 0;
+            if(mfBrake > 100)mfBrake = 100;
+        }
+
+
+    }
+
+
+    if(!mPressKeys.contains(Qt::Key_W)&&(!mPressKeys.contains((Qt::Key_S))))
+    {
+        if(mfBrake != 0)
+        {
+            mfBrake = mfBrake - timediff*mfBrakeAutoDownSpeed/1000;
+            if(mfBrake<0)mfBrake = 0;
+            if(mfBrake > 100)mfBrake = 100;
+        }
+
+        if(mfAcc != 0)
+        {
+            mfAcc = mfAcc - timediff*mfAccAutoDownSpeed/1000;
+            if(mfAcc<0)mfAcc = 0;
+            if(mfAcc > 100)mfAcc = 100;
+        }
+    }
+
+    if(mfWheel != fOldWheel)mpWheel->updatevalue(mfWheel);
+    if(mfAcc != fOldAcc)mpAcc->updatevalue(mfAcc);
+    if(mfBrake != fOldBrake)mpBrake->updatevalue(mfBrake);
+}
+
+void MainWindow::on_radioButton_auto_clicked()
+{
+    ui->radioButton_auto->setChecked(true);
+    mPressKeys.clear();
+    mpTimerManual->stop();
+
+}
+
+void MainWindow::onTimerRemote()
+{
+    if(ui->radioButton_auto->isChecked())
+    {
+        mremotectrl.set_ntype(iv::remotectrl_CtrlType_AUTO);
+//        mfAcc = 0;
+//        mfBrake = 0;
+//        mfWheel =0;
+//        mpWheel->updatevalue(mfWheel);
+//        mpAcc->updatevalue(mfAcc);
+//        mpBrake->updatevalue(mfBrake);
+
+
+    }
+    else
+    {
+        mremotectrl.set_ntype(iv::remotectrl_CtrlType_REMOTE);
+
+    }
+    mremotectrl.set_acc(mfAcc);
+    mremotectrl.set_brake(mfBrake);
+    mremotectrl.set_wheel(mfWheel);
+    mremotectrl.set_shift(mnShift);
+
+    int nsersize = mremotectrl.ByteSize();
+    char * strbuf = new char[nsersize];
+    if(mremotectrl.SerializeToArray(strbuf,nsersize))
+    {
+        iv::modulecomm::ModuleSendMsg(mpa,strbuf,nsersize);
+    }
+    delete strbuf;
+}
+
+void MainWindow::onTimerUpdatePic()
+{
+    static qint64 time_pic = 0;
+
+    static qint64 time_trace = 0;
+    static int pos = 0;
+    static std::vector<iv::simpletrace> xvectorsimpletrace;
+
+    if((mnSelPic>=0)&&(mnSelPic<4))
+    {
+        if((gTimeRawPic[mnSelPic] != time_pic) && (gTimeRawPic[mnSelPic] != 0))
+  //      if((gTimeRawPic[mnSelPic] != time_pic))
+        {
+            time_pic = gTimeRawPic[mnSelPic];
+            iv::vision::rawpic xpic;
+            gMutexPic[mnSelPic].lock();
+            xpic.CopyFrom(grawpic[mnSelPic]);
+            gMutexPic[mnSelPic].unlock();
+            mpPicView->SetPic(xpic);
+
+        }
+    }
+
+    if(mpPicView->IsHaveNew())update();
+
+    if(gTimeTrace != time_trace)
+    {
+        time_trace = gTimeTrace;
+
+        gMutexTrace.lock();
+        xvectorsimpletrace = gvectorsimplerace;
+        gMutexTrace.unlock();
+        pos = 0;
+        if(xvectorsimpletrace.size()> 0)
+        {
+            QJsonArray num_json,num2_json;                       //声明QJsonArray
+            QJsonDocument num_document,num2_document;    //将QJsonArray改为QJsonDocument类
+            QByteArray num_byteArray,num2_byteArray;      //
+
+            int i=0;
+            for(i=0;i<xvectorsimpletrace.size();i++)                            //将数组传入压入num_json
+            {
+                num_json.append(xvectorsimpletrace[i].gps_lng);
+                num2_json.append(xvectorsimpletrace[i].gps_lat);
+            }
+
+            num_document.setArray(num_json);
+            num2_document.setArray(num2_json);
+            num_byteArray = num_document.toJson(QJsonDocument::Compact);
+            num2_byteArray = num2_document.toJson(QJsonDocument::Compact);
+            QString numJson(num_byteArray);             //再转为QString
+            QString num2Json(num2_byteArray);             //再转为QString
+
+
+            QString cmd = QString("settrace(\"%1\",\"%2\")").arg(numJson).arg(num2Json);
+            mMapview->page()->runJavaScript(cmd);
+        }
+
+    }
+
+//    if(pos<xvectorsimpletrace.size())
+//    {
+//        if(pos == 0)
+//        {
+//            mMapview->page()->runJavaScript("clear()");
+//        }
+
+//        char strscript[256];
+//        snprintf(strscript,255,"mapLocation(%11.7f,%11.7f);",xvectorsimpletrace[pos].gps_lng,xvectorsimpletrace[pos].gps_lat);
+//        mMapview->page()->runJavaScript(strscript);
+//        pos++;
+
+//    }
+}
+
+void MainWindow::onTimerUpdateView()
+{
+    static qint64 time_gps = 0;
+
+    unsigned int i;
+
+   char strlatency[1000];
+   char strtem[100];
+   snprintf(strlatency,1000,"Latency(Up|FrameRate|Down): ");
+   snprintf(strtem,100,"FT(%d|%d|%d) ",mgrpcpc->GetPicLatency(0),mgrpcpc->GetFrameRate(0),mgrpcpc->GetPicDownLatency(0));strncat(strlatency,strtem,1000);
+   snprintf(strtem,100,"RR(%d|%d|%d) ",mgrpcpc->GetPicLatency(1),mgrpcpc->GetFrameRate(1),mgrpcpc->GetPicDownLatency(1));strncat(strlatency,strtem,1000);
+   snprintf(strtem,100,"LT(%d|%d|%d) ",mgrpcpc->GetPicLatency(2),mgrpcpc->GetFrameRate(2),mgrpcpc->GetPicDownLatency(2));strncat(strlatency,strtem,1000);
+   snprintf(strtem,100,"RT(%d|%d|%d) ",mgrpcpc->GetPicLatency(3),mgrpcpc->GetFrameRate(3),mgrpcpc->GetPicDownLatency(3));strncat(strlatency,strtem,1000);
+
+   mpLabelLatency->setText(strlatency);
+
+
+    if(gTimeGPSIMUUpdate != time_gps)
+    {
+        time_gps = gTimeGPSIMUUpdate;
+        char strscript[256];
+        snprintf(strscript,255,"theLocation(%11.7f,%11.7f,%11.3f);",ggpsimu.lon(),ggpsimu.lat(),ggpsimu.heading());
+        mMapview->page()->runJavaScript(strscript);
+
+        iv::gps::gpsimu xgpsimu;
+        xgpsimu.CopyFrom(ggpsimu);
+
+        ui->lineEdit_gpsins->setText(QString::number(xgpsimu.ins_state()));
+        ui->lineEdit_gpsrtk->setText(QString::number(xgpsimu.rtk_state()));
+        ui->lineEdit_gpslon->setText(QString::number(xgpsimu.lon(),'f',7));
+        ui->lineEdit_gpslat->setText(QString::number(xgpsimu.lat(),'f',7));
+        ui->lineEdit_gpsheading->setText(QString::number(xgpsimu.heading(),'f',2));
+        ui->lineEdit_gpsheight->setText(QString::number(xgpsimu.height(),'f',2));
+        ui->lineEdit_gpsspeed->setText(QString::number(xgpsimu.speed(),'f',2));
+        ui->lineEdit_gpssat->setText(QString::number(xgpsimu.satnum1()));
+
+        mstrGPSTime =  QDateTime::fromMSecsSinceEpoch(xgpsimu.msgtime()).toString("GPS: yyyy-MM-dd hh:mm:ss  ");
+        setWindowTitle(mstrProgName + mstrVIN + mstrGPSTime + mstrPicTime);
+    }
+
+
+
+
+
+}
+
+void MainWindow::paintEvent(QPaintEvent *)
+{
+    if(!mpPicView->IsHaveNew())
+    {
+        return;
+    }
+    else
+    {
+        QImage image = mpPicView->GetImage();
+        mscene->clear();
+        mscene->addPixmap(QPixmap::fromImage(image));
+        mmyview->setScene(mscene);
+        mmyview->show();
+    }
+}
+
+void MainWindow::on_pushButton_Go_clicked()
+{
+
+
+
+    if(ui->comboBox_Station->currentIndex() < 0)return;
+    int index = ui->comboBox_Station->currentIndex();
+
+    if(index<0 ||  index>= gvectorpos.size())
+    {
+        std::cout<<"out range."<<std::endl;
+        return;
+    }
+    iv::pos_def xpos = gvectorpos[index];
+
+    double lon,lat;
+    lon = xpos.mflon;
+    lat = xpos.mflat;
+
+    xodrobj xo;
+    xo.flon = lon;
+    xo.flat = lat;
+    xo.lane = 3;
+
+    iv::modulecomm::ModuleSendMsg(mpadst,(char *)&xo,sizeof(xodrobj));
+}
+
+void MainWindow::on_comboBox_Station_currentIndexChanged(int index)
+{
+    if(index<0 ||  index>= gvectorpos.size())
+    {
+        std::cout<<"out range."<<std::endl;
+        return;
+    }
+    iv::pos_def xpos = gvectorpos[index];
+
+    char strscript[256];
+    snprintf(strscript,255,"objLocation(%11.7f,%11.7f);",xpos.mflon,xpos.mflat);
+    mMapview->page()->runJavaScript(strscript);
+
+}
+
+void MainWindow::on_checkBox_Drive_stateChanged(int arg1)
+{
+
+}
+
+void MainWindow::on_checkBox_Drive_clicked()
+{
+}
+
+void MainWindow::on_checkBox_Null_clicked()
+{
+
+}
+
+void MainWindow::on_checkBox_Rear_clicked()
+{
+
+}
+
+void MainWindow::on_radioButton_Drive_clicked()
+{
+    mnShift = 1;
+    ui->radioButton_picfront->setChecked(true);
+    on_radioButton_picfront_clicked();
+    mpbigpicdlg->SetFront();
+}
+
+void MainWindow::on_radioButton_Null_clicked()
+{
+    mnShift = 0;
+    mpbigpicdlg->SetFront();
+}
+
+void MainWindow::on_radioButton_Rear_clicked()
+{
+    mnShift = -1;
+    ui->radioButton_picrear->setChecked(true);
+    on_radioButton_picrear_clicked();
+    mpbigpicdlg->SetRear();
+}
+
+void MainWindow::on_radioButton_picfront_clicked()
+{
+
+    mnSelPic = 0;
+    mppicshow->SetAttr("rawpicmsgname",gstrmem_pic[mnSelPic].data(),gstrmem_pic[mnSelPic].size());
+    mpbigpicdlg->setCamera(mnSelPic);
+}
+
+void MainWindow::on_radioButton_picrear_clicked()
+{
+    mnSelPic = 1;
+    mppicshow->SetAttr("rawpicmsgname",gstrmem_pic[mnSelPic].data(),gstrmem_pic[mnSelPic].size());
+    mpbigpicdlg->setCamera(mnSelPic);
+}
+
+void MainWindow::on_radioButton_picleft_clicked()
+{
+    mnSelPic = 2;
+    mppicshow->SetAttr("rawpicmsgname",gstrmem_pic[mnSelPic].data(),gstrmem_pic[mnSelPic].size());
+    mpbigpicdlg->setCamera(mnSelPic);
+}
+
+void MainWindow::on_radioButton_picright_clicked()
+{
+    mnSelPic = 3;
+    mppicshow->SetAttr("rawpicmsgname",gstrmem_pic[mnSelPic].data(),gstrmem_pic[mnSelPic].size());
+    mpbigpicdlg->setCamera(mnSelPic);
+}
+
+
+
+void MainWindow::on_pushButton_AllPic_clicked()
+{
+
+    mppicdlg->show();
+    mppicdlg->setRefresh(true);
+}
+
+void MainWindow::onCloseDlg()
+{
+    mppicdlg->setRefresh(false);
+    qDebug("cloase");
+}
+
+void MainWindow::on_checkBox_clicked()
+{
+    int i;
+    if(ui->checkBox->isChecked())
+    {
+        for(i=0;i<4;i++)
+        {
+            mpPicSave[i]->startsave();
+        }
+        mbSavePic = true;
+    }
+    else
+    {
+        for(i=0;i<4;i++)
+        {
+            mpPicSave[i]->stopsave();
+        }
+        mbSavePic = false;
+    }
+}
+
+void MainWindow::saveavi(int index)
+{
+//    if(mbSavePic == false)return;
+    gMutexPic[index].lock();
+    mpPicSave[index]->SetPic(grawpic[index]);
+    gMutexPic[index].unlock();
+}
+
+void MainWindow::on_pushButton_big_clicked()
+{
+//    pluginapp * pa  = new pluginapp(this->winId(),"main","plugin_threepicshow","/home/yuchuli/qt/modularization/src/plugin/build-plugin_threepicshow-Debug");
+
+//    return;
+    mpbigpicdlg->show();
+    mpbigpicdlg->setRefresh(true);
+}
+
+void MainWindow::onCloseBigDlg()
+{
+    mpbigpicdlg->setRefresh(false);
+}
+
+void MainWindow::on_actionSet_Query_Pass_triggered()
+{
+    DialogSetPassWord xdlg(DialogSetPassWord_Type::QUERY,mstrqueryMD5,this);
+    if(xdlg.exec() == xdlg.Accepted)
+    {
+        mgrpcpc->setqueryMD5(ServiceRCIni.GetQueryMD5());
+        mstrqueryMD5 = ServiceRCIni.GetQueryMD5();
+    }
+}
+
+void MainWindow::on_actionSetting_triggered()
+{
+    DialogSetting xdlg(this);
+    if(xdlg.exec() == QDialog::Accepted)
+    {
+        mgrpcpc->setVIN(ServiceRCIni.GetVIN());
+        mstrVehVIN = ServiceRCIni.GetVIN();
+    }
+}
+
+void MainWindow::on_actionSet_Ctrl_Pass_triggered()
+{
+    DialogSetPassWord xdlg(DialogSetPassWord_Type::CTRL,mstrctrlMD5,this);
+    if(xdlg.exec() == xdlg.Accepted)
+    {
+        mgrpcpc->setctrlMD5(ServiceRCIni.GetCtrlMD5());
+        mstrctrlMD5 = ServiceRCIni.GetCtrlMD5();
+    }
+
+}

+ 209 - 0
src/tool/RemoteCtrl_h264/mainwindow.h

@@ -0,0 +1,209 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+
+#define CAMERA_NUM 4
+
+#include <QMainWindow>
+
+#include <QtWidgets>
+#include <QtWebEngineWidgets/QtWebEngineWidgets>
+#include <QSet>
+#include <QMutex>
+#include <QLabel>
+
+#include <iostream>
+
+#include <speed.h>
+
+#include "remotectrl.pb.h"
+#include "gpsimu.pb.h"
+#include "rawpic.pb.h"
+
+#include "ivpicview.h"
+#include "ivpicsave.h"
+#include "myview.h"
+#include "grpcpc.h"
+
+#include "dialogpic.h"
+#include "dialogbigpic.h"
+
+#include "modulecomm.h"
+
+#include "joyreadthread.h"
+
+#include "dialogsetpassword.h"
+#include "dialogsetting.h"
+
+#include "pluginapp.h"
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class MainWindow; }
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    MainWindow(QWidget *parent = nullptr);
+    ~MainWindow();
+
+private slots:
+    void on_pushButton_test_clicked();
+
+    virtual void paintEvent(QPaintEvent *);
+
+    void on_radioButton_manual_clicked();
+
+    void onTimerManual();
+
+    void onTimerRemote();
+
+    void onTimerUpdateView();
+
+    void onTimerUpdatePic();
+
+    void on_radioButton_auto_clicked();
+
+//    virtual void paintEvent(QPaintEvent *);
+
+
+
+    void on_pushButton_Go_clicked();
+
+    void on_comboBox_Station_currentIndexChanged(int index);
+
+    void on_checkBox_Drive_stateChanged(int arg1);
+
+    void on_checkBox_Drive_clicked();
+
+    void on_checkBox_Null_clicked();
+
+    void on_checkBox_Rear_clicked();
+
+    void on_radioButton_Drive_clicked();
+
+    void on_radioButton_Null_clicked();
+
+    void on_radioButton_Rear_clicked();
+
+
+    void on_radioButton_picfront_clicked();
+
+    void on_radioButton_picrear_clicked();
+
+    void on_radioButton_picleft_clicked();
+
+    void on_radioButton_picright_clicked();
+
+    void on_pushButton_AllPic_clicked();
+
+    void onCloseDlg();
+    void onCloseBigDlg();
+
+    void on_checkBox_clicked();
+
+    void on_pushButton_big_clicked();
+
+    void on_actionSet_Query_Pass_triggered();
+
+    void on_actionSetting_triggered();
+
+    void on_actionSet_Ctrl_Pass_triggered();
+
+public:
+     void resizeEvent(QResizeEvent *event);
+
+     void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
+
+     void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
+
+
+
+private:
+    Ui::MainWindow *ui;
+
+
+    QWebEngineView * mMapview;
+
+    Speed * mpWheel, * mpAcc, * mpBrake;
+
+     QSet<int> mPressKeys;
+
+     QTimer * mpTimerManual;
+     QTimer * mpTimerRemote;
+
+     double mfWheel = 0;
+     double mfAcc = 0;
+     double mfBrake = 0;
+
+     int mnLastTime;
+     QTime mManualTime;
+
+     double mfWheelSpeed = 100; //100degree/s
+     double mfAccSpeed = 30; //30/s
+     double mfBrakeSpeed = 100; //100/s
+
+     double mfWheelAutoDownSpeed = 30;
+     double mfAccAutoDownSpeed = 10;
+     double mfBrakeAutoDownSpeed = 30;
+
+     iv::remotectrl mremotectrl;
+
+     void * mpa;
+
+     QTimer * mpTimerUpdateView;
+
+     MyView * mmyview;
+     QGraphicsScene *mscene;
+     IVPicView * mpPicView;
+
+     ivpicsave * mpPicSave[4];
+
+     void * mpadst;
+     void * mpasimpletrace;
+
+     grpcpc * mgrpcpc;
+
+     QString mstrProgName = "ADC IV Remote Control  ";
+     QString mstrGPSTime = " GPS:";
+     QString mstrPicTime = " Pic:";
+
+     QString mstrVIN;
+
+     JoyReadThread * mpJRT;
+
+     int mnShift = 0;
+
+     int mnSelPic = 0;
+
+     DialogPic * mppicdlg;
+     DialogBigPic * mpbigpicdlg;
+
+
+     bool mbSavePic = false;
+
+public:
+     void saveavi(int index);
+
+
+private:
+    void CreateView();
+
+private:
+    QLabel * mpLabelLatency;
+
+private:
+    std::string mstrserverip = "192.168.14.98";//"111.33.136.149";//"127.0.0.1";// "140.143.237.38";
+    std::string mstrserverport = "50051";//"9000";
+    std::string mstruploadinterval = "100";
+    std::string mstrVehVIN = "AAAAAAAAAAAAAAAAA";
+    std::string mstrqueryMD5 = "5d41402abc4b2a76b9719d911017c592";
+    std::string mstrctrlMD5 = "5d41402abc4b2a76b9719d911017c592";
+
+private:
+    pluginapp * mpbaiduapp;
+    pluginapp * mppicshow;
+};
+#endif // MAINWINDOW_H

+ 523 - 0
src/tool/RemoteCtrl_h264/mainwindow.ui

@@ -0,0 +1,523 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1183</width>
+    <height>722</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <property name="windowIcon">
+   <iconset resource="remotectrl.qrc">
+    <normaloff>:/remotectrl.png</normaloff>:/remotectrl.png</iconset>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <widget class="QLineEdit" name="lineEdit_lat">
+    <property name="geometry">
+     <rect>
+      <x>940</x>
+      <y>50</y>
+      <width>113</width>
+      <height>25</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="lineEdit_lon">
+    <property name="geometry">
+     <rect>
+      <x>940</x>
+      <y>110</y>
+      <width>113</width>
+      <height>25</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pushButton_test">
+    <property name="geometry">
+     <rect>
+      <x>950</x>
+      <y>190</y>
+      <width>89</width>
+      <height>25</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Test</string>
+    </property>
+   </widget>
+   <widget class="QGroupBox" name="groupBox_rem">
+    <property name="geometry">
+     <rect>
+      <x>870</x>
+      <y>270</y>
+      <width>291</width>
+      <height>311</height>
+     </rect>
+    </property>
+    <property name="title">
+     <string>Control</string>
+    </property>
+    <widget class="QRadioButton" name="radioButton_manual">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>40</y>
+       <width>61</width>
+       <height>23</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>远程</string>
+     </property>
+    </widget>
+    <widget class="QRadioButton" name="radioButton_auto">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>70</y>
+       <width>61</width>
+       <height>23</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>自动</string>
+     </property>
+    </widget>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>110</y>
+       <width>71</width>
+       <height>101</height>
+      </rect>
+     </property>
+     <property name="title">
+      <string>档位</string>
+     </property>
+     <widget class="QRadioButton" name="radioButton_Drive">
+      <property name="geometry">
+       <rect>
+        <x>10</x>
+        <y>30</y>
+        <width>112</width>
+        <height>23</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>前进</string>
+      </property>
+     </widget>
+     <widget class="QRadioButton" name="radioButton_Null">
+      <property name="geometry">
+       <rect>
+        <x>10</x>
+        <y>50</y>
+        <width>112</width>
+        <height>23</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>空档</string>
+      </property>
+     </widget>
+     <widget class="QRadioButton" name="radioButton_Rear">
+      <property name="geometry">
+       <rect>
+        <x>10</x>
+        <y>70</y>
+        <width>112</width>
+        <height>23</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>后退</string>
+      </property>
+     </widget>
+    </widget>
+   </widget>
+   <widget class="QGroupBox" name="groupBox_map">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>320</y>
+      <width>351</width>
+      <height>121</height>
+     </rect>
+    </property>
+    <property name="title">
+     <string>Map</string>
+    </property>
+    <widget class="QPushButton" name="pushButton_Go">
+     <property name="geometry">
+      <rect>
+       <x>240</x>
+       <y>50</y>
+       <width>91</width>
+       <height>41</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>前往</string>
+     </property>
+    </widget>
+    <widget class="QComboBox" name="comboBox_Station">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>50</y>
+       <width>211</width>
+       <height>41</height>
+      </rect>
+     </property>
+    </widget>
+   </widget>
+   <widget class="QGroupBox" name="groupBox_gps">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>470</y>
+      <width>361</width>
+      <height>151</height>
+     </rect>
+    </property>
+    <property name="title">
+     <string>GPS</string>
+    </property>
+    <widget class="QLineEdit" name="lineEdit_gpsins">
+     <property name="geometry">
+      <rect>
+       <x>80</x>
+       <y>30</y>
+       <width>81</width>
+       <height>25</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_gpsins">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>30</y>
+       <width>67</width>
+       <height>17</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Ins</string>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_gpsrtk">
+     <property name="geometry">
+      <rect>
+       <x>190</x>
+       <y>30</y>
+       <width>67</width>
+       <height>17</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>RTK</string>
+     </property>
+    </widget>
+    <widget class="QLineEdit" name="lineEdit_gpsrtk">
+     <property name="geometry">
+      <rect>
+       <x>250</x>
+       <y>30</y>
+       <width>81</width>
+       <height>25</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLineEdit" name="lineEdit_gpslon">
+     <property name="geometry">
+      <rect>
+       <x>80</x>
+       <y>60</y>
+       <width>81</width>
+       <height>25</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLineEdit" name="lineEdit_gpslat">
+     <property name="geometry">
+      <rect>
+       <x>250</x>
+       <y>60</y>
+       <width>81</width>
+       <height>25</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_gpslon">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>60</y>
+       <width>67</width>
+       <height>17</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Lon</string>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_gpslat">
+     <property name="geometry">
+      <rect>
+       <x>190</x>
+       <y>60</y>
+       <width>67</width>
+       <height>17</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Lat</string>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_gpsheading">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>90</y>
+       <width>67</width>
+       <height>17</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Heading</string>
+     </property>
+    </widget>
+    <widget class="QLineEdit" name="lineEdit_gpsheading">
+     <property name="geometry">
+      <rect>
+       <x>80</x>
+       <y>90</y>
+       <width>81</width>
+       <height>25</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLineEdit" name="lineEdit_gpsheight">
+     <property name="geometry">
+      <rect>
+       <x>250</x>
+       <y>90</y>
+       <width>81</width>
+       <height>25</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_gpsheight">
+     <property name="geometry">
+      <rect>
+       <x>190</x>
+       <y>90</y>
+       <width>67</width>
+       <height>17</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Height</string>
+     </property>
+    </widget>
+    <widget class="QLineEdit" name="lineEdit_gpsspeed">
+     <property name="geometry">
+      <rect>
+       <x>80</x>
+       <y>120</y>
+       <width>81</width>
+       <height>25</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLineEdit" name="lineEdit_gpssat">
+     <property name="geometry">
+      <rect>
+       <x>250</x>
+       <y>120</y>
+       <width>81</width>
+       <height>25</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_gpsspeed">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>120</y>
+       <width>67</width>
+       <height>17</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Speed</string>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_gpssat">
+     <property name="geometry">
+      <rect>
+       <x>190</x>
+       <y>120</y>
+       <width>67</width>
+       <height>17</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Sat</string>
+     </property>
+    </widget>
+   </widget>
+   <widget class="QGroupBox" name="groupBox_picsel">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>210</y>
+      <width>551</width>
+      <height>91</height>
+     </rect>
+    </property>
+    <property name="title">
+     <string>图像</string>
+    </property>
+    <widget class="QRadioButton" name="radioButton_picfront">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>40</y>
+       <width>51</width>
+       <height>23</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>前</string>
+     </property>
+    </widget>
+    <widget class="QRadioButton" name="radioButton_picrear">
+     <property name="geometry">
+      <rect>
+       <x>70</x>
+       <y>40</y>
+       <width>51</width>
+       <height>21</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>后</string>
+     </property>
+    </widget>
+    <widget class="QRadioButton" name="radioButton_picleft">
+     <property name="geometry">
+      <rect>
+       <x>140</x>
+       <y>40</y>
+       <width>41</width>
+       <height>21</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>左</string>
+     </property>
+    </widget>
+    <widget class="QRadioButton" name="radioButton_picright">
+     <property name="geometry">
+      <rect>
+       <x>220</x>
+       <y>40</y>
+       <width>41</width>
+       <height>23</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>右</string>
+     </property>
+    </widget>
+    <widget class="QPushButton" name="pushButton_AllPic">
+     <property name="geometry">
+      <rect>
+       <x>300</x>
+       <y>40</y>
+       <width>71</width>
+       <height>25</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>All</string>
+     </property>
+    </widget>
+    <widget class="QCheckBox" name="checkBox">
+     <property name="geometry">
+      <rect>
+       <x>390</x>
+       <y>40</y>
+       <width>71</width>
+       <height>23</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Save</string>
+     </property>
+    </widget>
+    <widget class="QPushButton" name="pushButton_big">
+     <property name="geometry">
+      <rect>
+       <x>460</x>
+       <y>40</y>
+       <width>51</width>
+       <height>25</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Big</string>
+     </property>
+    </widget>
+   </widget>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>1183</width>
+     <height>28</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menuFile">
+    <property name="title">
+     <string>File</string>
+    </property>
+    <addaction name="actionSetting"/>
+    <addaction name="actionSet_Query_Pass"/>
+    <addaction name="actionSet_Ctrl_Pass"/>
+   </widget>
+   <addaction name="menuFile"/>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+  <action name="actionSetting">
+   <property name="text">
+    <string>Setting</string>
+   </property>
+  </action>
+  <action name="actionSet_Query_Pass">
+   <property name="text">
+    <string>Set Query Pass</string>
+   </property>
+  </action>
+  <action name="actionSet_Ctrl_Pass">
+   <property name="text">
+    <string>Set Ctrl Pass</string>
+   </property>
+  </action>
+ </widget>
+ <resources>
+  <include location="remotectrl.qrc"/>
+ </resources>
+ <connections/>
+</ui>

+ 120 - 0
src/tool/RemoteCtrl_h264/myview.cpp

@@ -0,0 +1,120 @@
+#include "myview.h"
+#include <QScrollBar>
+#include <iostream>
+#define VIEW_CENTER viewport()->rect().center()
+const double PI = 3.1415926535898;
+
+MyView::MyView(QWidget *parent) :
+     QGraphicsView(parent),
+    beishu(1.00000)
+{
+    setDragMode(QGraphicsView::ScrollHandDrag);
+}
+
+void MyView::mousePressEvent(QMouseEvent *event)
+{
+//    qDebug("x is %d",event->pos().x());
+    bottonstatus = true;
+    QGraphicsView::mousePressEvent(event);
+}
+void MyView::mouseMoveEvent(QMouseEvent *event)
+{
+    QGraphicsView::mouseMoveEvent(event);
+//    QScrollBar * ps = verticalScrollBar();
+//    std::cout<<" size is "<<ps->size().height()<<" v = "<<ps->value()<<std::endl;
+//    QScrollBar * ps2= horizontalScrollBar();
+//     std::cout<<" size is "<<ps2->size().width()<<" h = "<<ps2->value()<<std::endl;
+}
+void MyView::mouseReleaseEvent(QMouseEvent *event)
+{
+    bottonstatus = false;
+    QGraphicsView::mouseReleaseEvent(event);
+}
+
+// 放大/缩小
+void MyView::wheelEvent(QWheelEvent *event)
+{
+    // 滚轮的滚动量
+    QPoint scrollAmount = event->angleDelta();
+    // 正值表示滚轮远离使用者(放大),负值表示朝向使用者(缩小)
+    scrollAmount.y() > 0 ? zoomIn() : zoomOut();
+}
+
+
+// 放大
+void MyView::zoomIn()
+{
+
+    int width,hgt;
+    width = sceneRect().width();
+    hgt = sceneRect().height();
+    QScrollBar * psV = verticalScrollBar();
+    QScrollBar * psH = horizontalScrollBar();
+
+    int centery = (psV->value() + psV->size().height()/2)/beishu;
+    int centerx = (psH->value() + psH->size().width()/2)/beishu;
+
+    scale(1.1, 1.1);
+    beishu *= 1.1;
+ //   centerOn(450, 700 - (200 / beishu));
+
+
+
+
+
+    centerOn(centerx,centery);
+
+//    QPoint x = viewport()->rect().center();
+
+
+//    std::cout<<" x is"<<sceneRect().bottom()<<" y is "<<sceneRect().y()<<std::endl;
+//    QScrollBar * ps = verticalScrollBar();
+//    std::cout<<" size is "<<ps->size().height()<<" v = "<<ps->value()<<std::endl;
+
+}
+
+// 缩小
+void MyView::zoomOut()
+{
+
+    int width,hgt;
+    width = sceneRect().width();
+    hgt = sceneRect().height();
+    QScrollBar * psV = verticalScrollBar();
+    QScrollBar * psH = horizontalScrollBar();
+
+    int centery = (psV->value() + psV->size().height()/2)/beishu;
+    int centerx = (psH->value() + psH->size().width()/2)/beishu;
+
+    scale(1 / 1.1, 1 / 1.1);
+    beishu /= 1.1;
+//    centerOn(450, 700 - (200 / beishu));
+
+    centerOn(centerx,centery);
+}
+
+void MyView::mouseDoubleClickEvent(QMouseEvent *event)
+{
+
+    QScrollBar * psV = verticalScrollBar();
+    QScrollBar * psH = horizontalScrollBar();
+
+    int centery = (psV->value() + psV->size().height()/2)/beishu;
+    int centerx = (psH->value() + psH->size().width()/2)/beishu;
+
+
+//    qDebug("x is %d y is %d view center x is %d  centerx is %d",event->pos().x(),
+//           event->pos().y(),
+//           viewport()->rect().center().x(),centerx);
+
+    int viewx,viewy;
+    if(beishu == 0)return;
+    viewx = centerx +(event->pos().x() - viewport()->rect().center().x())/beishu;
+    viewy = centery +(event->pos().y() - viewport()->rect().center().y())/beishu;
+
+    QPoint viewpoint;
+    viewpoint.setX(viewx);
+    viewpoint.setY(viewy);
+
+//    qDebug("view x is %d view y is %d ",viewx,viewy);
+}

+ 35 - 0
src/tool/RemoteCtrl_h264/myview.h

@@ -0,0 +1,35 @@
+#ifndef MYVIEW_H
+#define MYVIEW_H
+
+#include <qtimer.h>
+#include <qpainter.h>
+#include <QGraphicsView>
+#include <QWheelEvent>
+#include <QKeyEvent>
+#include <QPoint>
+#include <QPointF>
+#include <QGraphicsItem>
+#include <QKeyEvent>
+
+class MyView : public QGraphicsView
+{
+    Q_OBJECT
+
+public:
+    explicit MyView(QWidget *parent =0);
+    qreal x, y, beishu;
+protected:
+    void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
+    void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+    void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+    void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+    void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+public Q_SLOTS:
+    void zoomIn();  // 放大
+    void zoomOut();  // 缩小
+private:
+    bool bottonstatus = false;
+    QPoint myview_lastMousePos;
+};
+
+#endif // MYVIEW_H

+ 2 - 0
src/tool/RemoteCtrl_h264/pos.txt

@@ -0,0 +1,2 @@
+站点1	117.02730168	39.12070791
+站点2	117.02730387	39.12051011

+ 16 - 0
src/tool/RemoteCtrl_h264/pos_def.h

@@ -0,0 +1,16 @@
+#ifndef POS_DEF_H
+#define POS_DEF_H
+
+#include <string>
+
+namespace  iv {
+struct pos_def
+{
+    double mflon;
+    double mflat;
+    std::string mstrstationname;
+};
+
+}
+
+#endif // POS_DEF_H

BIN
src/tool/RemoteCtrl_h264/remotectrl.png


+ 5 - 0
src/tool/RemoteCtrl_h264/remotectrl.qrc

@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/">
+        <file>remotectrl.png</file>
+    </qresource>
+</RCC>

+ 143 - 0
src/tool/RemoteCtrl_h264/remotectrlini.cpp

@@ -0,0 +1,143 @@
+#include "remotectrlini.h"
+#include <QSettings>
+#include "get_interface.h"
+
+RemoteCtrlIni::RemoteCtrlIni()
+{
+    mstrinipath = "RemoteCtrl_Thread.ini";
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+
+    mstrserverip = configini->value("setting/serverip").toString().toStdString();
+    if(mstrserverip == "")
+    {
+        mstrserverip = "111.33.136.149";
+    }
+
+    mstrserverport = configini->value("setting/serverport").toString().toStdString();
+    if(mstrserverport == "")
+    {
+        mstrserverport = "50051";
+    }
+
+    mstruploadinterval = configini->value("setting/interval").toString().toStdString();
+    if(mstruploadinterval == "")
+    {
+        mstruploadinterval = "100";
+    }
+
+    mstrVehVIN = configini->value("setting/VIN").toString().toStdString();
+    if(mstrVehVIN == "")
+    {
+        mstrVehVIN = "AAAAAAAAAAAAAAAAA";
+    }
+
+    mstrqueryMD5 = configini->value("setting/queryMD5").toString().toStdString();
+    if(mstrqueryMD5 == "")
+    {
+        mstrqueryMD5 = "5d41402abc4b2a76b9719d911017c592";
+    }
+
+    mstrctrlMD5 = configini->value("setting/ctrlMD5").toString().toStdString();
+    if(mstrctrlMD5 == "")
+    {
+        mstrctrlMD5 = "5d41402abc4b2a76b9719d911017c592";
+    }
+
+    delete configini;
+
+    std::string strclientid;
+    if(getmac(strclientid) == 1)
+    {
+        mstrclientid = strclientid;
+    }
+
+}
+
+RemoteCtrlIni & RemoteCtrlIni::Inst()
+{
+    static RemoteCtrlIni xRemoteIni;
+    return xRemoteIni;
+}
+
+std::string RemoteCtrlIni::GetQueryMD5()
+{
+    return mstrqueryMD5;
+}
+
+void RemoteCtrlIni::SetQueryMD5(std::string strmd5)
+{
+    mstrqueryMD5 = strmd5;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/queryMD5",strmd5.data());
+    delete configini;
+}
+
+std::string RemoteCtrlIni::GetServerIP()
+{
+    return mstrserverip;
+}
+
+void RemoteCtrlIni::SetServerIP(std::string strserverip)
+{
+    mstrserverip = strserverip;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/serverip",strserverip.data());
+    delete configini;
+}
+
+std::string RemoteCtrlIni::GetServerPort()
+{
+    return mstrserverport;
+}
+
+void RemoteCtrlIni::SetServerPort(std::string strserverport)
+{
+    mstrserverport = strserverport;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/serverport",strserverport.data());
+    delete configini;
+}
+
+std::string RemoteCtrlIni::GetInterval()
+{
+    return mstruploadinterval;
+}
+
+void RemoteCtrlIni::SetInterval(std::string strinterval)
+{
+    mstruploadinterval = strinterval;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/interval",strinterval.data());
+    delete configini;
+}
+
+std::string RemoteCtrlIni::GetVIN()
+{
+    return mstrVehVIN;
+}
+
+void RemoteCtrlIni::SetVIN(std::string strVIN)
+{
+    mstrVehVIN = strVIN;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/VIN",strVIN.data());
+    delete configini;
+}
+
+std::string RemoteCtrlIni::GetCtrlMD5()
+{
+    return mstrctrlMD5;
+}
+
+void RemoteCtrlIni::SetCtrlMD5(std::string strmd5)
+{
+    mstrctrlMD5 = strmd5;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/ctrlMD5",strmd5.data());
+    delete configini;
+}
+
+std::string RemoteCtrlIni::GetClientID()
+{
+    return mstrclientid;
+}

+ 53 - 0
src/tool/RemoteCtrl_h264/remotectrlini.h

@@ -0,0 +1,53 @@
+#ifndef REMOTECTRLINI_H
+#define REMOTECTRLINI_H
+
+#include <string>
+
+#include <QSettings>
+
+class RemoteCtrlIni
+{
+public:
+    RemoteCtrlIni();
+
+public:
+    static RemoteCtrlIni & Inst();
+
+public:
+    std::string GetQueryMD5();
+    void SetQueryMD5(std::string strmd5);
+
+    std::string GetServerIP();
+    void SetServerIP(std::string strserverip);
+
+    std::string GetServerPort();
+    void SetServerPort(std::string strserverport);
+
+    std::string GetInterval();
+    void SetInterval(std::string strinterval);
+
+    std::string GetVIN();
+    void SetVIN(std::string strVIN);
+
+    std::string GetCtrlMD5();
+    void SetCtrlMD5(std::string strmd5);
+
+    std::string GetClientID();
+
+private:
+    QString mstrinipath;
+
+private:
+    std::string mstrserverip = "192.168.14.98";//"111.33.136.149";//"127.0.0.1";// "140.143.237.38";
+    std::string mstrserverport = "50051";//"9000";
+    std::string mstruploadinterval = "100";
+    std::string mstrVehVIN = "AAAAAAAAAAAAAAAAA";
+    std::string mstrqueryMD5 = "5d41402abc4b2a76b9719d911017c592";
+    std::string mstrctrlMD5 = "5d41402abc4b2a76b9719d911017c592";
+
+    std::string mstrclientid = "test";
+};
+
+#define ServiceRCIni RemoteCtrlIni::Inst()
+
+#endif // REMOTECTRLINI_H

+ 199 - 0
src/tool/RemoteCtrl_h264/speed.cpp

@@ -0,0 +1,199 @@
+#include "speed.h"
+
+
+#include <QPainter>
+
+#include <math.h>
+
+Speed::Speed(QWidget *parent) : QWidget(parent)
+{
+    m_background = Qt::black;
+    m_foreground = Qt::green;
+
+    m_startAngle = 60;
+    m_endAngle = 60;
+    m_scaleMajor = 10;
+    m_minValue = 100;
+    m_maxValue = -100;
+    m_scaleMajor = 10;//分度
+    m_scaleMinor = 10;
+    m_units = "";
+    m_title = "Wheel";
+    m_precision = 0;
+    m_value = 0;
+}
+
+void Speed::drawCrown(QPainter *painter) //绘制表冠
+{
+    painter->save();
+    int radius = 100;
+    QLinearGradient lg1(0, -radius, 0, radius);
+
+    lg1.setColorAt(0, Qt::white); //设置渐变的颜色和路径比例
+    lg1.setColorAt(1, Qt::gray); //只是粗略的颜色,具体的可以参考RGB颜色查询对照表
+
+    painter->setBrush(lg1); // 创建QBrush对象,把这个渐变对象传递进去:
+    painter->setPen(Qt::NoPen); //边框线无色
+    painter->drawEllipse(-radius, -radius, radius << 1, radius << 1);
+    painter->setBrush(m_background = Qt::black);
+    painter->drawEllipse(-92, -92, 184, 184);
+    painter->restore();
+}
+
+void Speed::drawScaleNum(QPainter *painter) //绘制刻度数字
+{
+    painter->save();
+    painter->setPen(m_foreground);
+    //m_startAngle是起始角度,m_endAngle是结束角度,m_scaleMajor在一个量程中分成的刻度数
+    double startRad = ( 270-m_startAngle) * (3.14 / 180);
+    double deltaRad = (360 - m_startAngle - m_endAngle) * (3.14 / 180) / m_scaleMajor;
+    double sina,cosa;
+    int x, y;
+    QFontMetricsF fm(this->font());
+    double w, h, tmpVal;
+    QString str;
+
+    for (int i = 0; i <= m_scaleMajor; i++)
+    {
+        sina = sin(startRad - i * deltaRad);
+        cosa = cos(startRad - i * deltaRad);
+
+        tmpVal = 1.0 * i *((m_maxValue - m_minValue) / m_scaleMajor) + m_minValue;
+        // tmpVal = 50;
+        str = QString( "%1" ).arg(tmpVal);  //%1作为占位符   arg()函数比起 sprintf()来是类型安全的
+        w = fm.size(Qt::TextSingleLine,str).width();
+        h = fm.size(Qt::TextSingleLine,str).height();
+        x = 82 * cosa - w / 2;
+        y = -82 * sina + h / 4;
+        painter->drawText(x, y, str); //函数的前两个参数是显示的坐标位置,后一个是显示的内容,是字符类型""
+
+    }
+    painter->restore();
+}
+
+void Speed::drawScale(QPainter *painter) //绘制刻度线
+{
+    painter->save();
+    painter->rotate(m_startAngle);
+    int steps = (m_scaleMajor * m_scaleMinor); //相乘后的值是分的份数
+    double angleStep = (360.0 - m_startAngle - m_endAngle) / steps; //每一个份数的角度
+
+    // painter->setPen(m_foreground); //m_foreground是颜色的设置
+    // QPen pen = painter->pen(); //第一种方法
+    QPen pen ;
+    pen.setColor(Qt::green); //推荐使用第二种方式
+    for (int i = 0; i <= steps; i++)
+    {
+        if (i % m_scaleMinor == 0)//整数刻度显示加粗
+        {
+            pen.setWidth(1); //设置线宽
+            painter->setPen(pen); //使用面向对象的思想,把画笔关联上画家。通过画家画出来
+
+            painter->drawLine(0, 62, 0, 72); //两个参数应该是两个坐标值
+        }
+        else
+        {
+            pen.setWidth(0);
+            painter->setPen(pen);
+            painter->drawLine(0, 67, 0, 72);
+        }
+        painter->rotate(angleStep);
+    }
+    painter->restore();
+
+}
+
+void Speed::drawTitle(QPainter *painter)
+{
+    painter->save();
+    painter->setPen(m_foreground);
+    //painter->setBrush(m_foreground);
+    QString str(m_title); //显示仪表的功能
+    QFontMetricsF fm(this->font());
+    double w = fm.size(Qt::TextSingleLine,str).width();
+    painter->drawText(-w / 2, -30, str);
+    painter->restore();
+}
+
+void Speed::drawNumericValue(QPainter *painter)
+{
+    QString str = QString("%1 %2").arg(m_value, 0, 'f', m_precision).arg(m_units);
+    QFontMetricsF fm(font());
+    double w = fm.size(Qt::TextSingleLine,str).width();
+    painter->setPen(m_foreground);
+    painter->drawText(-w / 2, 42, str);
+}
+
+void Speed::drawIndicator(QPainter *painter)
+{
+    painter->save();
+    QPolygon pts;
+    pts.setPoints(3, -2, 0, 2, 0, 0, 60);	/* (-2,0)/(2,0)/(0,60) *///第一个参数是 ,坐标的个数。后边的是坐标
+
+    painter->rotate(m_startAngle);
+    double degRotate = (360.0 - m_startAngle - m_endAngle) / (m_maxValue - m_minValue)*(m_value - m_minValue);
+
+    //画指针
+    painter->rotate(degRotate);  //顺时针旋转坐标系统
+    QRadialGradient haloGradient(0, 0, 60, 0, 0);  //辐射渐变
+    haloGradient.setColorAt(0, QColor(60, 60, 60));
+    haloGradient.setColorAt(1, QColor(160, 160, 160)); //灰
+    painter->setPen(Qt::white); //定义线条文本颜色  设置线条的颜色
+    painter->setBrush(haloGradient);//刷子定义形状如何填满 填充后的颜色
+    painter->drawConvexPolygon(pts); //这是个重载函数,绘制多边形。
+    painter->restore();
+
+    //画中心点
+    QColor niceBlue(150, 150, 200);
+    QConicalGradient coneGradient(0, 0, -90.0);  //角度渐变
+    coneGradient.setColorAt(0.0, Qt::darkGray);
+    coneGradient.setColorAt(0.2, niceBlue);
+    coneGradient.setColorAt(0.5, Qt::white);
+    coneGradient.setColorAt(1.0, Qt::darkGray);
+    painter->setPen(Qt::NoPen);  //没有线,填满没有边界
+    painter->setBrush(coneGradient);
+    painter->drawEllipse(-5, -5, 10, 10);
+}
+
+void Speed ::paintEvent(QPaintEvent *)
+{
+    QPainter painter(this);//一个类中的this表示一个指向该类自己的指针
+    painter.setRenderHint(QPainter::Antialiasing);  /* 使用反锯齿(如果可用) */
+    painter.translate(width() / 2, height() / 2);   /* 坐标变换为窗体中心 */
+    int side = qMin(width(), height());
+    painter.scale(side / 200.0, side / 200.0);      /* 比例缩放 */
+
+   drawCrown(&painter);                                 /* 画表盘边框 */
+   drawScaleNum(&painter);                          /* 画刻度数值值 */
+   drawScale(&painter);                                 /* 画刻度线 */
+   drawTitle(&painter);                                     /* 画单位 */
+   drawNumericValue(&painter);                      /* 画数字显示 */
+   drawIndicator(&painter);                             /* 画表针 */
+
+}
+
+void Speed::setminvalue(int value)
+{
+    m_minValue = value;
+}
+
+void Speed::setmaxvalue(int value)
+{
+    m_maxValue = value;
+}
+
+void Speed::updatevalue(int value)
+{
+    m_value = value;
+    update();
+}
+
+void Speed::setunits(QString strunits)
+{
+    m_units = strunits;
+}
+
+void Speed::settitle(QString strtitle)
+{
+    m_title = strtitle;
+}

+ 51 - 0
src/tool/RemoteCtrl_h264/speed.h

@@ -0,0 +1,51 @@
+#ifndef SPEED_H
+#define SPEED_H
+
+#include <QWidget>
+
+class Speed : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit Speed(QWidget *parent = nullptr);
+
+protected:
+    void paintEvent(QPaintEvent *);
+
+    void drawCrown(QPainter *painter);
+    void drawBackground(QPainter *painter);
+    void drawScale(QPainter *painter);
+    void drawScaleNum(QPainter *painter);
+    void drawTitle(QPainter *painter);
+    void drawIndicator(QPainter *painter);
+    void drawNumericValue(QPainter *painter);
+
+private:
+    QColor m_background;
+    QColor m_foreground;
+
+
+    int m_maxValue;
+    int m_minValue;
+    int m_startAngle;
+    int m_endAngle;
+
+    int m_scaleMajor;
+    int m_scaleMinor;
+    double m_value;
+    int m_precision;
+    QTimer *m_updateTimer;
+    QString m_units;
+    QString m_title;
+    public Q_SLOTS:
+//	void UpdateAngle();
+
+public:
+    void setminvalue(int value);
+    void setmaxvalue(int value);
+    void updatevalue(int value);
+    void setunits(QString strunits);
+    void settitle(QString strtitle);
+};
+
+#endif // SPEED_H

+ 1 - 1
src/tool/picview_civetweb/main.cpp

@@ -180,7 +180,7 @@ int main(int argc, char *argv[])
     CivetServer server(cpp_options); // <-- C++ style start
 
     WsStartHandler h_ws;
-//    server.addHandler("/", h_ws);
+    server.addHandler("/", h_ws);
 
     PicHandler h_pic;
     server.addHandler("/pic", h_pic);