Browse Source

change h264transjpeg_civetweb. near complete.

yuchuli 3 years ago
parent
commit
f65bb047ad

+ 53 - 41
src/driver/driver_h264_dec/ivh264framedecode.cpp

@@ -148,6 +148,7 @@ int ivh264framedecode::GetJpegData(std::shared_ptr<char> & pstr_ptr,int & ndatas
         mjpegdata.mmutexdata.lock();
         mjpegdata.mmutexdata.lock();
         pstr_ptr = mjpegdata.mpstr_ptr;
         pstr_ptr = mjpegdata.mpstr_ptr;
         ndatasize = mjpegdata.ndatasize;
         ndatasize = mjpegdata.ndatasize;
+        mjpegdata.mbupdate = false;
         mjpegdata.mmutexdata.unlock();
         mjpegdata.mmutexdata.unlock();
         return 1;
         return 1;
     }
     }
@@ -157,28 +158,25 @@ int ivh264framedecode::GetJpegData(std::shared_ptr<char> & pstr_ptr,int & ndatas
 
 
 void ivh264framedecode::encodejpeg(AVFrame *frame)
 void ivh264framedecode::encodejpeg(AVFrame *frame)
 {
 {
-    static int nindex = 0;
-    int nsample = 3;
-
-    if(nindex>nsample)
-    {
-        nindex = 0;
-    }
-    nindex++;
-    if(nindex != 1)
-    {
-        return;
-    }
-
 
 
-    av_opt_set(mpCodecCtxJpeg->priv_data, "qscale:v", "95", 0);
-#define DEBUG_ENCODEJPEG
+//    if(mnsamplenow>mnsamplecount)
+//    {
+//        mnsamplenow = 0;
+//    }
+//    mnsamplenow++;
+//    if(mnsamplenow != 1)
+//    {
+//        return;
+//    }
+
+//#define DEBUG_ENCODEJPEG
     int ret;
     int ret;
     AVCodecContext * enc_ctx = mpCodecCtxJpeg;
     AVCodecContext * enc_ctx = mpCodecCtxJpeg;
     AVPacket pkt;
     AVPacket pkt;
     int y_size = enc_ctx->width * enc_ctx->height;
     int y_size = enc_ctx->width * enc_ctx->height;
 
 
 #ifdef DEBUG_ENCODEJPEG
 #ifdef DEBUG_ENCODEJPEG
+//    std::cout<<"encode jpeg."<<std::endl;
     int64_t time1 = std::chrono::system_clock::now().time_since_epoch().count()/1000;
     int64_t time1 = std::chrono::system_clock::now().time_since_epoch().count()/1000;
 #endif
 #endif
 
 
@@ -205,6 +203,7 @@ void ivh264framedecode::encodejpeg(AVFrame *frame)
             return;
             return;
         }
         }
 
 
+        mnjpegcount++;
         std::shared_ptr<char> pstr_data = std::shared_ptr<char>(new char[pkt.size]);
         std::shared_ptr<char> pstr_data = std::shared_ptr<char>(new char[pkt.size]);
         memcpy(pstr_data.get(),pkt.data,pkt.size);
         memcpy(pstr_data.get(),pkt.data,pkt.size);
         mjpegdata.mmutexdata.lock();
         mjpegdata.mmutexdata.lock();
@@ -229,6 +228,17 @@ void ivh264framedecode::encodejpeg(AVFrame *frame)
 
 
 }
 }
 
 
+
+int ivh264framedecode::Getyuvcount()
+{
+    return mnyuvcount;
+}
+
+int ivh264framedecode::Getjpegcount()
+{
+    return mnjpegcount;
+}
+
 void ivh264framedecode::decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt)
 void ivh264framedecode::decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt)
 {
 {
 //    char buf[1024];
 //    char buf[1024];
@@ -257,10 +267,11 @@ void ivh264framedecode::decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket
            free it */
            free it */
 //        snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
 //        snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
 
 
+        mnyuvcount++;
 
 
         if(mbTransJpeg)
         if(mbTransJpeg)
         {
         {
- //           encodejpeg(frame);
+            encodejpeg(frame);
         }
         }
 //        cv::Mat yuvImg;
 //        cv::Mat yuvImg;
 //        cv::Mat rgbImg(cy, cx,CV_8UC3);
 //        cv::Mat rgbImg(cy, cx,CV_8UC3);
@@ -315,30 +326,30 @@ void ivh264framedecode::decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket
 #endif
 #endif
 #endif
 #endif
 
 
-        if(mbTransJpeg)
-        {
-            std::vector<int> param = std::vector<int>(2);
-            param[0] = CV_IMWRITE_JPEG_QUALITY;
-            param[1] = 95; // default(95) 0-100
-            std::vector<unsigned char> buff;
-
-            cv::Mat mat1;
-
-            cv::cvtColor(pbuf->myuvImg,mat1,cv::COLOR_YUV2BGR_I420);
-            cv::imencode(".jpg", mat1, buff, param);
-
-            std::shared_ptr<char> pstr_data = std::shared_ptr<char>(new char[buff.size()]);
-            memcpy(pstr_data.get(),buff.data(),buff.size());
-            mjpegdata.mmutexdata.lock();
-            mjpegdata.mpstr_ptr = pstr_data;
-            mjpegdata.ndatasize =buff.size();
-            mjpegdata.mnupdatetime = std::chrono::system_clock::now().time_since_epoch().count();
-            mjpegdata.mbupdate = true;
-            mjpegdata.mmutexdata.unlock();
-            mcvjpeg.notify_all();
-
-            buff.clear();
-        }
+//        if(mbTransJpeg)
+//        {
+//            std::vector<int> param = std::vector<int>(2);
+//            param[0] = CV_IMWRITE_JPEG_QUALITY;
+//            param[1] = 95; // default(95) 0-100
+//            std::vector<unsigned char> buff;
+
+//            cv::Mat mat1;
+
+//            cv::cvtColor(pbuf->myuvImg,mat1,cv::COLOR_YUV2BGR_I420);
+//            cv::imencode(".jpg", mat1, buff, param);
+
+//            std::shared_ptr<char> pstr_data = std::shared_ptr<char>(new char[buff.size()]);
+//            memcpy(pstr_data.get(),buff.data(),buff.size());
+//            mjpegdata.mmutexdata.lock();
+//            mjpegdata.mpstr_ptr = pstr_data;
+//            mjpegdata.ndatasize =buff.size();
+//            mjpegdata.mnupdatetime = std::chrono::system_clock::now().time_since_epoch().count();
+//            mjpegdata.mbupdate = true;
+//            mjpegdata.mmutexdata.unlock();
+//            mcvjpeg.notify_all();
+
+//            buff.clear();
+//        }
         UnlockWriteBuff(index);
         UnlockWriteBuff(index);
         mcvread.notify_all();
         mcvread.notify_all();
 
 
@@ -457,7 +468,8 @@ void ivh264framedecode::threaddecode()
         mpCodecCtxJpeg->width = mframewidth;
         mpCodecCtxJpeg->width = mframewidth;
         mpCodecCtxJpeg->height = mframeheight;
         mpCodecCtxJpeg->height = mframeheight;
         mpCodecCtxJpeg->time_base.num = 1;
         mpCodecCtxJpeg->time_base.num = 1;
-        mpCodecCtxJpeg->time_base.den = 25;
+        mpCodecCtxJpeg->time_base.den = 30;
+        mpCodecCtxJpeg->bit_rate = 40000000;
 
 
 
 
         av_opt_set_int(mpCodecCtxJpeg->priv_data, "qscale",1, 0);
         av_opt_set_int(mpCodecCtxJpeg->priv_data, "qscale",1, 0);

+ 8 - 0
src/driver/driver_h264_dec/ivh264framedecode.h

@@ -125,10 +125,18 @@ private:
     std::mutex mmutex_cvjpeg;
     std::mutex mmutex_cvjpeg;
     std::condition_variable mcvjpeg;
     std::condition_variable mcvjpeg;
 
 
+    int mnyuvcount = 0;
+    int mnjpegcount = 0;
+
+    int mnsamplenow = 1;
+    int mnsamplecount = 3;
+
 public:
 public:
     //if GetData return 1, else return 0
     //if GetData return 1, else return 0
     int GetJpegData(std::shared_ptr<char> & pstr_ptr,int & ndatasize, int nwaitms = 0);
     int GetJpegData(std::shared_ptr<char> & pstr_ptr,int & ndatasize, int nwaitms = 0);
 
 
+    int Getyuvcount();
+    int Getjpegcount();
 
 
 
 
 
 

+ 1 - 1
src/tool/RemoteCtrl_h264/grpcpc.h

@@ -140,7 +140,7 @@ private:
     std::condition_variable mcvquery;
     std::condition_variable mcvquery;
 
 
 private:
 private:
-    bool mbUseRTSP = true;  //Use RTSP connect to the server.
+    bool mbUseRTSP = false;  //Use RTSP connect to the server.
     std::string mstrrtspserverip = "111.33.136.149";
     std::string mstrrtspserverip = "111.33.136.149";
     std::string mstrrtspserverport = "9554";
     std::string mstrrtspserverport = "9554";
     std::string mstrrtsppass = "hello";
     std::string mstrrtsppass = "hello";

+ 6 - 0
src/tool/RemoteCtrl_h264/rtspclientdown.cpp

@@ -14,6 +14,11 @@ rtspclientdown::~rtspclientdown()
     mpthread->join();
     mpthread->join();
 }
 }
 
 
+int rtspclientdown::Getretrycount()
+{
+    return mretrycount;
+}
+
 void rtspclientdown::threadrtspdown(std::string strrtspserver)
 void rtspclientdown::threadrtspdown(std::string strrtspserver)
 {
 {
 
 
@@ -37,6 +42,7 @@ void rtspclientdown::threadrtspdown(std::string strrtspserver)
             {
             {
                 fprintf(stderr, " = could not open input file\n");
                 fprintf(stderr, " = could not open input file\n");
                 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
                 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+                mretrycount++;
                 continue ;
                 continue ;
             }
             }
 
 

+ 3 - 0
src/tool/RemoteCtrl_h264/rtspclientdown.h

@@ -41,11 +41,14 @@ private:
     std::mutex mmutexcv;
     std::mutex mmutexcv;
     std::condition_variable mcv;
     std::condition_variable mcv;
 
 
+    int mretrycount = 0;
+
 private:
 private:
     void threadrtspdown(std::string strrtspserver);
     void threadrtspdown(std::string strrtspserver);
 
 
 public:
 public:
     int Getrtspframe(iv::h264rawframedata & xframe,int nwaitms);
     int Getrtspframe(iv::h264rawframedata & xframe,int nwaitms);
+    int Getretrycount();
 };
 };
 
 
 #endif // RTSPCLIENTDOWN_H
 #endif // RTSPCLIENTDOWN_H

+ 9 - 4
src/tool/h264transjpeg_civetweb/h264transjpeg_civetweb.pro

@@ -30,7 +30,8 @@ SOURCES += \
         mainwindow.cpp  \
         mainwindow.cpp  \
     ../../driver/driver_h264_dec/ivh264framedecode.cpp \
     ../../driver/driver_h264_dec/ivh264framedecode.cpp \
     transjpegweb.cpp \
     transjpegweb.cpp \
-    ../RemoteCtrl_h264/rtspclientdown.cpp
+    ../RemoteCtrl_h264/rtspclientdown.cpp \
+    transjpegini.cpp
 
 
 HEADERS += \
 HEADERS += \
     ../../../thirdpartylib/civetweb/CivetServer.h \
     ../../../thirdpartylib/civetweb/CivetServer.h \
@@ -38,7 +39,8 @@ HEADERS += \
         mainwindow.h  \
         mainwindow.h  \
     ../../driver/driver_h264_dec/ivh264framedecode.h \
     ../../driver/driver_h264_dec/ivh264framedecode.h \
     transjpegweb.h \
     transjpegweb.h \
-    ../RemoteCtrl_h264/rtspclientdown.h
+    ../RemoteCtrl_h264/rtspclientdown.h \
+    transjpegini.h
 
 
 
 
 FORMS += \
 FORMS += \
@@ -59,6 +61,9 @@ INCLUDEPATH += /usr/include/x86_64-linux-gnu
 LIBS +=  -lavcodec -lavformat -lavutil
 LIBS +=  -lavcodec -lavformat -lavutil
 
 
 
 
-#DEFINES += USEJPEG_NOOPENCV
-LIBS += -lopencv_highgui -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -lopencv_video  -lopencv_videoio -lpthread #-lopencv_shape
+DEFINES += USEJPEG_NOOPENCV
+#LIBS += -lopencv_highgui -lopencv_core -lopencv_imgproc -lopencv_imgcodecs -lopencv_video  -lopencv_videoio -lpthread #-lopencv_shape
+
+RESOURCES += \
+    transjpeg.qrc
 
 

+ 201 - 0
src/tool/h264transjpeg_civetweb/indexpic.html

@@ -0,0 +1,201 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>ADCIV WEB UI. Designed Base CivetWeb.</title>
+<script>
+
+//var i_width=window.document.body.clientWidth//网页可用宽度  
+//var i_height=window.document.body.clientHeight;
+//var pic = document.getElementById("myCanvas");
+//pic.style.height=i_height+"px";
+//pic.style.width=i_width+"px";
+var index=0
+var xc=0
+var ic=0
+var n=0
+//var int=self.setInterval('clock()',100);
+var int2=self.setInterval('changeImage()',29);
+
+	var image=new Image();//放入函数里面:浏览器运行一分钟左右系统内存用到高达90%,故做一个全局的反冲图片
+	var image2=new Image();
+	var image3=new Image();
+	var image4=new Image();
+
+	function changeImage()
+	{ 
+		var canvas=document.getElementById("myCanvas2");  
+		var canvas2=document.getElementById("myCanvas3"); 
+		var canvas3=document.getElementById("myCanvas4"); 
+		var canvas4=document.getElementById("myCanvas5");  
+		var cxt=canvas.getContext("2d");
+		var cxt2=canvas2.getContext("2d");
+		var cxt3=canvas3.getContext("2d");
+		var cxt4=canvas4.getContext("2d");
+
+		var canvaswidth = 640;
+		var canvasheight = 360;
+
+		//ctx.restore();
+		image.src="http://127.0.0.1:6123/frontpic?"+n;
+		image2.src="http://127.0.0.1:6123/rearpic?"+n;
+		image3.src="http://127.0.0.1:6123/leftpic?"+n;
+		image4.src="http://127.0.0.1:6123/rightpic?"+n;
+		n++; 
+		var nerror = 0;
+		
+		image.onload = function () //确保图片已经加载完毕  
+		{  
+			if (image.complete)//如果图片加载完成,绘制
+			{
+				cxt.save(); 
+				cxt.drawImage(image,0,0,image.width,image.height,0,0,canvaswidth,canvasheight);  
+				cxt.restore();
+
+				nerror = 0;
+				upcount++;
+			}
+			else
+			{
+				nerror++;
+				if(nerror>100)
+				{
+//					alert(image.complete);
+					nerror = 0;
+				}
+			}
+			ic = 0;
+			
+		}  
+		image.onerror=function(){  
+			document.getElementById("F2").innerHTML="error N:"+n; 
+			ic = 0;
+		};  
+
+		image2.onload = function () //确保图片已经加载完毕  
+		{  
+			if (image2.complete)//如果图片加载完成,绘制
+			{
+				cxt2.save(); 
+				cxt2.drawImage(image2,0,0,image2.width,image2.height,0,0,canvaswidth,canvasheight);  
+				cxt2.restore();
+				nerror = 0;
+				upcount++;
+			}
+			else
+			{
+				nerror++;
+				if(nerror>100)
+				{
+//					alert(image.complete);
+					nerror = 0;
+				}
+			}
+			ic = 0;
+			
+		}  
+		image2.onerror=function(){  
+			document.getElementById("F2").innerHTML="error N:"+n; 
+			ic = 0;
+		};
+
+
+		image3.onload = function () //确保图片已经加载完毕  
+		{  
+			if (image3.complete)//如果图片加载完成,绘制
+			{
+				cxt3.save(); 
+				cxt3.drawImage(image3,0,0,image3.width,image3.height,0,0,canvaswidth,canvasheight);  
+				cxt3.restore();
+				nerror = 0;
+				upcount++;
+			}
+			else
+			{
+				nerror++;
+				if(nerror>100)
+				{
+//					alert(image.complete);
+					nerror = 0;
+				}
+			}
+			ic = 0;
+			
+		}  
+		image3.onerror=function(){  
+			document.getElementById("F2").innerHTML="error N:"+n; 
+			ic = 0;
+		};
+
+		image4.onload = function () //确保图片已经加载完毕  
+		{  
+			if (image4.complete)//如果图片加载完成,绘制
+			{
+				cxt4.save(); 
+				cxt4.drawImage(image4,0,0,image4.width,image4.height,0,0,canvaswidth,canvasheight);  
+				cxt4.restore();
+				nerror = 0;
+				upcount++;
+			}
+			else
+			{
+				nerror++;
+				if(nerror>100)
+				{
+//					alert(image.complete);
+					nerror = 0;
+				}
+			}
+			ic = 0;
+			
+		}  
+		image4.onerror=function(){  
+			document.getElementById("F2").innerHTML="error N:"+n; 
+			ic = 0;
+		};
+
+  	}
+
+
+
+function clock() 
+{ 
+	if(ic == 0)
+	{
+		ic = 1;
+		changeImage();
+	}
+} 
+function load() {
+	changeImage();
+}
+
+
+
+</script>
+</head>
+<body onload="changeImage()">
+<!-- <div id='websock_text_field'>No websocket connection yet</div>-->
+<!--  <iframe id='image' src="" width="800" height="600"></iframe>  -->
+
+<p>  </p>
+<canvas id="myCanvas2" width="640" height="360" style="border:0px solid #c3c3c3;">  
+Your browser does not support the canvas element.  
+</canvas>
+<canvas id="myCanvas3" width="640" height="360" style="border:0px solid #c3c3c3;">  
+Your browser does not support the canvas element.  
+</canvas>
+
+<p>  </p>
+
+<canvas id="myCanvas4" width="640" height="360" style="border:0px solid #c3c3c3;">  
+Your browser does not support the canvas element.  
+</canvas>
+<canvas id="myCanvas5" width="640" height="360" style="border:0px solid #c3c3c3;">  
+Your browser does not support the canvas element.  
+</canvas>
+
+<p id="demo">This is a paragraph.</p> 
+
+</body>
+</html>

+ 141 - 0
src/tool/h264transjpeg_civetweb/indexws.html

@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+
+<!DOCTYPE html>
+<html lang="zh-hans">
+<head>
+    <meta charset="UTF-8">
+    <title>Websocket</title>
+</head>
+<body>
+<canvas id="myCanvas" width="640" height="360" style="border:0px solid #c3c3c3;">  
+Your browser does not support the canvas element.  
+</canvas>
+<canvas id="myCanvas3" width="640" height="360" style="border:0px solid #c3c3c3;">  
+Your browser does not support the canvas element.  
+</canvas>
+
+<p>  </p>
+
+<canvas id="myCanvas4" width="640" height="360" style="border:0px solid #c3c3c3;">  
+Your browser does not support the canvas element.  
+</canvas>
+<canvas id="myCanvas5" width="640" height="360" style="border:0px solid #c3c3c3;">  
+Your browser does not support the canvas element.  
+</canvas>
+    <script>
+        var ws = new WebSocket( 'ws://127.0.0.1:6123/front' );
+	var ws2 = new WebSocket( 'ws://127.0.0.1:6123/rear' );
+	var ws3 = new WebSocket( 'ws://127.0.0.1:6123/left' );
+	var ws4 = new WebSocket( 'ws://127.0.0.1:6123/right' );
+	var image = new Image();  
+	var image2 = new Image();  
+	var image3 = new Image();  
+	var image4 = new Image();  
+ 
+        ws.onerror = function(e) {
+          console.log(e);
+        };
+ 
+        ws.onopen = function() {
+            console.log( '握手成功' );
+            console.log( ws );
+        };
+ 
+        ws.onmessage = function( e ) {
+ //           console.log( e );
+            var canvas = document.getElementById("myCanvas"); 
+            var context = canvas.getContext("2d"); 
+            
+            image.onload = function () {  
+   //             context.clearRect( 0, 0, canvas.width, canvas.height );  
+			if (image.complete)//如果图片加载完成,绘制
+			{
+		context.save();
+                context.drawImage( image, 0, 0, canvas.width, canvas.height );  
+		context.restore();
+		}
+            }  
+            image.src = URL.createObjectURL(e.data);  
+       };
+
+        ws2.onerror = function(e) {
+          console.log(e);
+        };
+ 
+        ws2.onopen = function() {
+            console.log( '握手成功' );
+            console.log( ws2 );
+        };
+ 
+        ws2.onmessage = function( e ) {
+//            console.log( e );
+            var canvas = document.getElementById("myCanvas3"); 
+            var context = canvas.getContext("2d"); 
+            
+            image2.onload = function () {  
+   //             context.clearRect( 0, 0, canvas.width, canvas.height );  
+			if (image2.complete)//如果图片加载完成,绘制
+			{
+		context.save();
+                context.drawImage( image2, 0, 0, canvas.width, canvas.height );  
+		context.restore();
+		}
+            }  
+            image2.src = URL.createObjectURL(e.data);  
+       };
+
+        ws3.onerror = function(e) {
+          console.log(e);
+        };
+ 
+        ws3.onopen = function() {
+            console.log( '握手成功' );
+            console.log( ws3 );
+        };
+ 
+        ws3.onmessage = function( e ) {
+ //           console.log( e );
+            var canvas = document.getElementById("myCanvas4"); 
+            var context = canvas.getContext("2d"); 
+            
+            image3.onload = function () {  
+   //             context.clearRect( 0, 0, canvas.width, canvas.height );  
+			if (image3.complete)//如果图片加载完成,绘制
+			{
+		context.save();
+                context.drawImage( image3, 0, 0, canvas.width, canvas.height );  
+		context.restore();
+		}
+            }  
+            image3.src = URL.createObjectURL(e.data);  
+       };
+
+        ws4.onerror = function(e) {
+          console.log(e);
+        };
+ 
+        ws4.onopen = function() {
+            console.log( '握手成功' );
+            console.log( ws4 );
+        };
+ 
+        ws4.onmessage = function( e ) {
+ //           console.log( e );
+            var canvas = document.getElementById("myCanvas5"); 
+            var context = canvas.getContext("2d"); 
+            
+            image4.onload = function () {  
+   //             context.clearRect( 0, 0, canvas.width, canvas.height );  
+			if (image4.complete)//如果图片加载完成,绘制
+			{
+		context.save();
+                context.drawImage( image4, 0, 0, canvas.width, canvas.height );  
+		context.restore();
+		}
+            }  
+            image4.src = URL.createObjectURL(e.data);  
+       };
+    </script>
+</body>
+</html>
+

+ 9 - 0
src/tool/h264transjpeg_civetweb/main.cpp

@@ -1,11 +1,20 @@
 #include "mainwindow.h"
 #include "mainwindow.h"
 #include <QApplication>
 #include <QApplication>
 
 
+#include <QFile>
+
 int main(int argc, char *argv[])
 int main(int argc, char *argv[])
 {
 {
     QApplication a(argc, argv);
     QApplication a(argc, argv);
     MainWindow w;
     MainWindow w;
     w.show();
     w.show();
 
 
+    QFile xFile;
+    xFile.setFileName(":/indexpic.html");
+    if(xFile.open(QIODevice::ReadOnly))
+    {
+        QByteArray ba;
+        ba = xFile.readAll();
+    }
     return a.exec();
     return a.exec();
 }
 }

+ 93 - 1
src/tool/h264transjpeg_civetweb/mainwindow.cpp

@@ -1,15 +1,107 @@
 #include "mainwindow.h"
 #include "mainwindow.h"
 #include "ui_mainwindow.h"
 #include "ui_mainwindow.h"
 
 
+#include "transjpegini.h"
+
+#include <QMessageBox>
+#include <QTimer>
+
 MainWindow::MainWindow(QWidget *parent) :
 MainWindow::MainWindow(QWidget *parent) :
     QMainWindow(parent),
     QMainWindow(parent),
     ui(new Ui::MainWindow)
     ui(new Ui::MainWindow)
 {
 {
     ui->setupUi(this);
     ui->setupUi(this);
-    mptjw = new transjpegweb();
+
+    std::string strserverip = ServiceRCIni.GetServerIP();
+    std::string strserverport = ServiceRCIni.GetServerPort();
+    std::string strVIN = ServiceRCIni.GetVIN();
+    std::string strpass = ServiceRCIni.GetPass();
+    std::string strwebmode = ServiceRCIni.GetWebMode();
+
+    ui->lineEdit_ip->setText(strserverip.data());
+    ui->lineEdit_port->setText(strserverport.data());
+    ui->lineEdit_vin->setText(strVIN.data());
+    ui->lineEdit_pass->setText(strpass.data());
+
+    ui->comboBox_language->addItem("English");
+    ui->comboBox_language->addItem(tr("中文"));
+    if(ServiceRCIni.GetLanguage() == "Chinese")
+    {
+        ui->comboBox_language->setCurrentIndex(1);
+    }
+    else
+    {
+        ui->comboBox_language->setCurrentIndex(0);
+    }
+
+    ui->comboBox_webmode->addItem("html");
+    ui->comboBox_webmode->addItem("ws");
+    if(ServiceRCIni.GetWebMode() == "html")
+    {
+        ui->comboBox_webmode->setCurrentIndex(0);
+    }
+    else
+    {
+        ui->comboBox_webmode->setCurrentIndex(1);
+    }
+
+    mptjw = new transjpegweb(strserverip,strserverport,strVIN,strpass,strwebmode);
+
+    QTimer * timer = new QTimer(this);
+    connect(timer,SIGNAL(timeout()),this,SLOT(onTimer()));
+    timer->start(1000);
+
+    setWindowTitle(tr("Trans h264 Frame To JPEG"));
+
 }
 }
 
 
 MainWindow::~MainWindow()
 MainWindow::~MainWindow()
 {
 {
     delete ui;
     delete ui;
 }
 }
+
+void MainWindow::on_pushButton_Set_clicked()
+{
+    std::string strserverip = ui->lineEdit_ip->text().toStdString();
+    std::string strserverport = ui->lineEdit_port->text().toStdString();
+    std::string strVIN = ui->lineEdit_vin->text().toStdString();
+    std::string strpass = ui->lineEdit_pass->text().toStdString();
+
+    ServiceRCIni.SetServerIP(strserverip);
+    ServiceRCIni.SetPass(strpass);
+    ServiceRCIni.SetServerPort(strserverport);
+    ServiceRCIni.SetVIN(strVIN);
+
+    if(ui->comboBox_language->currentIndex() == 0)
+    {
+        ServiceRCIni.SetLanguase("English");
+    }
+    else
+    {
+        ServiceRCIni.SetLanguase("Chinese");
+    }
+
+    if(ui->comboBox_webmode->currentIndex() == 1)
+    {
+        ServiceRCIni.SetWebMode("ws");
+    }
+    else
+    {
+        ServiceRCIni.SetWebMode("html");
+    }
+
+    QMessageBox::information(this,tr("Info"),tr("Set Successfully,Reset take effect. "));
+
+}
+
+void MainWindow::onTimer()
+{
+    ui->plainTextEdit_state->setPlainText(mptjw->GetStatics().data());
+}
+
+void MainWindow::resizeEvent(QResizeEvent *event)
+{
+    (void)event;
+    QSize sizemain = ui->centralWidget->size();
+    ui->plainTextEdit_state->setGeometry(430,20,sizemain.width() - 450,sizemain.height() - 50);
+}

+ 8 - 0
src/tool/h264transjpeg_civetweb/mainwindow.h

@@ -17,6 +17,14 @@ public:
     explicit MainWindow(QWidget *parent = 0);
     explicit MainWindow(QWidget *parent = 0);
     ~MainWindow();
     ~MainWindow();
 
 
+private slots:
+    void on_pushButton_Set_clicked();
+    void onTimer();
+
+public:
+    void resizeEvent(QResizeEvent *event);
+
+
 private:
 private:
     Ui::MainWindow *ui;
     Ui::MainWindow *ui;
 
 

+ 209 - 12
src/tool/h264transjpeg_civetweb/mainwindow.ui

@@ -1,24 +1,221 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
 <ui version="4.0">
  <class>MainWindow</class>
  <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow" >
-  <property name="geometry" >
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
    <rect>
    <rect>
     <x>0</x>
     <x>0</x>
     <y>0</y>
     <y>0</y>
-    <width>400</width>
-    <height>300</height>
+    <width>841</width>
+    <height>562</height>
    </rect>
    </rect>
   </property>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>MainWindow</string>
    <string>MainWindow</string>
   </property>
   </property>
-  <widget class="QMenuBar" name="menuBar" />
-  <widget class="QToolBar" name="mainToolBar" />
-  <widget class="QWidget" name="centralWidget" />
-  <widget class="QStatusBar" name="statusBar" />
+  <property name="windowIcon">
+   <iconset resource="transjpeg.qrc">
+    <normaloff>:/webm.png</normaloff>:/webm.png</iconset>
+  </property>
+  <widget class="QWidget" name="centralWidget">
+   <widget class="QGroupBox" name="groupBox">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>20</y>
+      <width>390</width>
+      <height>471</height>
+     </rect>
+    </property>
+    <property name="title">
+     <string>Setting</string>
+    </property>
+    <widget class="QPushButton" name="pushButton_Set">
+     <property name="geometry">
+      <rect>
+       <x>120</x>
+       <y>410</y>
+       <width>141</width>
+       <height>41</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Set</string>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label">
+     <property name="geometry">
+      <rect>
+       <x>30</x>
+       <y>30</y>
+       <width>141</width>
+       <height>41</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>ServerIP</string>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_2">
+     <property name="geometry">
+      <rect>
+       <x>30</x>
+       <y>90</y>
+       <width>141</width>
+       <height>41</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>ServerPort</string>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_3">
+     <property name="geometry">
+      <rect>
+       <x>30</x>
+       <y>150</y>
+       <width>141</width>
+       <height>41</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>VIN</string>
+     </property>
+    </widget>
+    <widget class="QLineEdit" name="lineEdit_ip">
+     <property name="geometry">
+      <rect>
+       <x>160</x>
+       <y>30</y>
+       <width>200</width>
+       <height>41</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLineEdit" name="lineEdit_port">
+     <property name="geometry">
+      <rect>
+       <x>160</x>
+       <y>90</y>
+       <width>200</width>
+       <height>41</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLineEdit" name="lineEdit_vin">
+     <property name="geometry">
+      <rect>
+       <x>160</x>
+       <y>150</y>
+       <width>200</width>
+       <height>41</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_4">
+     <property name="geometry">
+      <rect>
+       <x>30</x>
+       <y>210</y>
+       <width>141</width>
+       <height>41</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Pass</string>
+     </property>
+    </widget>
+    <widget class="QLineEdit" name="lineEdit_pass">
+     <property name="geometry">
+      <rect>
+       <x>160</x>
+       <y>210</y>
+       <width>200</width>
+       <height>41</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_5">
+     <property name="geometry">
+      <rect>
+       <x>30</x>
+       <y>270</y>
+       <width>141</width>
+       <height>41</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Language</string>
+     </property>
+    </widget>
+    <widget class="QComboBox" name="comboBox_language">
+     <property name="geometry">
+      <rect>
+       <x>160</x>
+       <y>270</y>
+       <width>200</width>
+       <height>41</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="QLabel" name="label_6">
+     <property name="geometry">
+      <rect>
+       <x>30</x>
+       <y>330</y>
+       <width>141</width>
+       <height>41</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>WebMode</string>
+     </property>
+    </widget>
+    <widget class="QComboBox" name="comboBox_webmode">
+     <property name="geometry">
+      <rect>
+       <x>160</x>
+       <y>330</y>
+       <width>200</width>
+       <height>41</height>
+      </rect>
+     </property>
+    </widget>
+   </widget>
+   <widget class="QPlainTextEdit" name="plainTextEdit_state">
+    <property name="geometry">
+     <rect>
+      <x>430</x>
+      <y>20</y>
+      <width>390</width>
+      <height>410</height>
+     </rect>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QMenuBar" name="menuBar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>841</width>
+     <height>28</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QToolBar" name="mainToolBar">
+   <attribute name="toolBarArea">
+    <enum>TopToolBarArea</enum>
+   </attribute>
+   <attribute name="toolBarBreak">
+    <bool>false</bool>
+   </attribute>
+  </widget>
+  <widget class="QStatusBar" name="statusBar"/>
  </widget>
  </widget>
- <layoutDefault spacing="6" margin="11" />
- <pixmapfunction></pixmapfunction>
- <resources/>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources>
+  <include location="transjpeg.qrc"/>
+ </resources>
  <connections/>
  <connections/>
 </ui>
 </ui>

+ 7 - 0
src/tool/h264transjpeg_civetweb/transjpeg.qrc

@@ -0,0 +1,7 @@
+<RCC>
+    <qresource prefix="/">
+        <file>indexpic.html</file>
+        <file>indexws.html</file>
+        <file>webm.png</file>
+    </qresource>
+</RCC>

+ 131 - 0
src/tool/h264transjpeg_civetweb/transjpegini.cpp

@@ -0,0 +1,131 @@
+#include "transjpegini.h"
+
+transjpegini::transjpegini()
+{
+    mstrinipath = "h264transjpeg_civetweb.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 = "9554";
+    }
+
+
+    mstrVehVIN = configini->value("setting/VIN").toString().toStdString();
+    if(mstrVehVIN == "")
+    {
+        mstrVehVIN = "AAAAAAAAAAAAAAAAA";
+    }
+
+    mstrpass = configini->value("setting/pass").toString().toStdString();
+    if(mstrpass == "")
+    {
+        mstrpass = "hello";
+    }
+
+
+    mstrlanguage = configini->value("setting/language").toString().toStdString();
+    if(mstrlanguage == "")
+    {
+        mstrlanguage = "Chinese";
+    }
+
+    mstrwebmode = configini->value("setting/webmode").toString().toStdString();
+    if(mstrwebmode == "")
+    {
+        mstrwebmode = "html";
+    }
+    delete configini;
+}
+
+transjpegini & transjpegini::Inst()
+{
+    static transjpegini xtransjpegIni;
+    return xtransjpegIni;
+}
+
+std::string transjpegini::GetServerIP()
+{
+    return mstrserverip;
+}
+
+void transjpegini::SetServerIP(std::string strserverip)
+{
+    mstrserverip = strserverip;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/serverip",strserverip.data());
+    delete configini;
+}
+
+std::string transjpegini::GetServerPort()
+{
+    return mstrserverport;
+}
+
+void transjpegini::SetServerPort(std::string strserverport)
+{
+    mstrserverport = strserverport;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/serverport",strserverport.data());
+    delete configini;
+}
+
+
+std::string transjpegini::GetVIN()
+{
+    return mstrVehVIN;
+}
+
+void transjpegini::SetVIN(std::string strVIN)
+{
+    mstrVehVIN = strVIN;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/VIN",strVIN.data());
+    delete configini;
+}
+
+std::string transjpegini::GetPass()
+{
+    return mstrpass;
+}
+
+void transjpegini::SetPass(std::string strpass)
+{
+    mstrpass = strpass;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/pass",strpass.data());
+    delete configini;
+}
+
+std::string transjpegini::GetLanguage()
+{
+    return mstrlanguage;
+}
+
+void transjpegini::SetLanguase(std::string strlanguase)
+{
+    mstrlanguage = strlanguase;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/language",strlanguase.data());
+    delete configini;
+}
+
+std::string transjpegini::GetWebMode()
+{
+    return mstrwebmode;
+}
+
+void transjpegini::SetWebMode(std::string strwebmode)
+{
+    mstrwebmode = strwebmode;
+    QSettings * configini = new QSettings(mstrinipath,QSettings::IniFormat);
+    configini->setValue("setting/webmode",strwebmode.data());
+    delete configini;
+}

+ 48 - 0
src/tool/h264transjpeg_civetweb/transjpegini.h

@@ -0,0 +1,48 @@
+#ifndef TRANSJPEGINI_H
+#define TRANSJPEGINI_H
+#include <string>
+
+#include <QSettings>
+
+class transjpegini
+{
+public:
+    transjpegini();
+
+public:
+    static transjpegini & Inst();
+
+private:
+    std::string mstrserverip = "111.33.136.149";
+    std::string mstrserverport = "9554";
+    std::string mstrVehVIN = "AAAAAAAAAAAAAAAAA";
+    std::string mstrpass = "hello";
+
+    std::string mstrlanguage = "Chinese";
+    std::string mstrwebmode = "html";  //html ws
+
+    QString mstrinipath;
+
+public:
+    std::string GetServerIP();
+    void SetServerIP(std::string strserverip);
+
+    std::string GetServerPort();
+    void SetServerPort(std::string strserverport);
+
+    std::string GetVIN();
+    void SetVIN(std::string strVIN);
+
+    std::string GetPass();
+    void SetPass(std::string strpass);
+
+    std::string GetLanguage();
+    void SetLanguase(std::string strlanguase);
+
+    std::string GetWebMode();
+    void SetWebMode(std::string strwebmode);
+};
+
+#define ServiceRCIni transjpegini::Inst()
+
+#endif // TRANSJPEGINI_H

+ 49 - 2
src/tool/h264transjpeg_civetweb/transjpegweb.cpp

@@ -6,8 +6,13 @@
 
 
 
 
 
 
-transjpegweb::transjpegweb()
+transjpegweb::transjpegweb(std::string strip,std::string strport,std::string strvin,std::string strpass,std::string strwebmode)
 {
 {
+    mstrrtspserverip = strip;
+    mstrrtspserverport = strport;
+    mstrvin = strvin;
+    mstrrtsppass = strpass;
+
     mg_init_library(0);
     mg_init_library(0);
 
 
 
 
@@ -31,19 +36,37 @@ transjpegweb::transjpegweb()
     std::string strright = "rtsp://"+mstrrtspserverip+":"+mstrrtspserverport+"/"+mstrvin+"-right-"+mstrrtsppass;
     std::string strright = "rtsp://"+mstrrtspserverip+":"+mstrrtspserverport+"/"+mstrvin+"-right-"+mstrrtsppass;
     mprtspdown[3] = new rtspclientdown(strright);
     mprtspdown[3] = new rtspclientdown(strright);
 
 
+    mstrrtspstring[0] = strfront;
+    mstrrtspstring[1] = strrear;
+    mstrrtspstring[2] = strleft;
+    mstrrtspstring[3] = strright;
+
     int i;
     int i;
     for(i=0;i<NUM_CAM;i++)
     for(i=0;i<NUM_CAM;i++)
     {
     {
         mpws[i] = new WebSocketHandler();
         mpws[i] = new WebSocketHandler();
+        mppichandler[i] = new PicHandler();
         mph264decode[i] = new ivh264framedecode(mnframewidth,mnframeheight,true);
         mph264decode[i] = new ivh264framedecode(mnframewidth,mnframeheight,true);
         mpthreadframe[i] = new std::thread(&transjpegweb::threadframe,this,i);
         mpthreadframe[i] = new std::thread(&transjpegweb::threadframe,this,i);
         mpthreadpic[i] = new std::thread(&transjpegweb::threadpic,this,i);
         mpthreadpic[i] = new std::thread(&transjpegweb::threadpic,this,i);
+        mtjcount[i].nframecount=0;
+        mtjcount[i].njpegcount = 0;
     }
     }
 
 
     mpserver->addWebSocketHandler("/front",mpws[0]);
     mpserver->addWebSocketHandler("/front",mpws[0]);
     mpserver->addWebSocketHandler("/rear",mpws[1]);
     mpserver->addWebSocketHandler("/rear",mpws[1]);
     mpserver->addWebSocketHandler("/left",mpws[2]);
     mpserver->addWebSocketHandler("/left",mpws[2]);
-    mpserver->addWebSocketHandler("right",mpws[3]);
+    mpserver->addWebSocketHandler("/right",mpws[3]);
+
+   mpserver->addHandler("/frontpic",mppichandler[0]);
+   mpserver->addHandler("/rearpic",mppichandler[1]);
+   mpserver->addHandler("/leftpic",mppichandler[2]);
+   mpserver->addHandler("/rightpic",mppichandler[3]);
+
+   mphandleindex = new WsStartHandler();
+   if(strwebmode == "html")  mphandleindex->SetIndexMode(0);
+   else mphandleindex->SetIndexMode(1);
+   mpserver->addHandler("/",mphandleindex);
 }
 }
 
 
 
 
@@ -54,6 +77,7 @@ void transjpegweb::threadframe(int ncam)
         iv::h264rawframedata xframe;
         iv::h264rawframedata xframe;
         if(mprtspdown[ncam]->Getrtspframe(xframe,30) == 1)
         if(mprtspdown[ncam]->Getrtspframe(xframe,30) == 1)
         {
         {
+            mtjcount[ncam].nframecount++;
             iv::rawframedata xraw;
             iv::rawframedata xraw;
             xraw.mpstr_ptr = xframe.mpstr_ptr;
             xraw.mpstr_ptr = xframe.mpstr_ptr;
             xraw.ndatasize = xframe.mdatasize;
             xraw.ndatasize = xframe.mdatasize;
@@ -75,8 +99,12 @@ void transjpegweb::threadpic(int ncam)
         int ndatasize;
         int ndatasize;
         if(mph264decode[ncam]->GetJpegData(pstr_ptr,ndatasize,30) == 1)
         if(mph264decode[ncam]->GetJpegData(pstr_ptr,ndatasize,30) == 1)
         {
         {
+            mtjcount[ncam].njpegcount++;
             if(nnow == 1)
             if(nnow == 1)
+            {
                 mpws[ncam]->BroadData(pstr_ptr.get(),ndatasize);
                 mpws[ncam]->BroadData(pstr_ptr.get(),ndatasize);
+                mppichandler[ncam]->SetData(pstr_ptr,ndatasize);
+            }
             nnow++;
             nnow++;
             if(nnow>nsample)nnow = 1;
             if(nnow>nsample)nnow = 1;
 //            std::cout<<" get jpg . size: "<<ndatasize<<std::endl;
 //            std::cout<<" get jpg . size: "<<ndatasize<<std::endl;
@@ -95,3 +123,22 @@ void transjpegweb::threadpic(int ncam)
         }
         }
     }
     }
 }
 }
+
+std::string transjpegweb::GetStatics()
+{
+    int i;
+    std::string strrtn = "";
+    std::string strline;
+    for(i=0;i<NUM_CAM;i++)
+    {
+        strline= mstrrtspstring[i] + " | " + " Retry:"+QString::number(mprtspdown[i]->Getretrycount()).toStdString()
+                +" | "+"Frame:"+QString::number(mtjcount[i].nframecount).toStdString()
+                +" | "+"YUV:"+QString::number(mph264decode[i]->Getyuvcount()).toStdString()
+                +" | "+"encode jpeg:"+QString::number(mph264decode[i]->Getjpegcount()).toStdString()
+                +" | "+"receive jpeg:"+QString::number(mtjcount[i].njpegcount).toStdString()
+                +" | "+"pic reqest:"+QString::number(mppichandler[i]->GetCount()).toStdString()
+                +" | "+"ws reqest:"+QString::number(mpws[i]->GetCount()).toStdString() + "\r\n";
+        strrtn =strrtn + strline;
+    }
+    return strrtn;
+}

+ 165 - 1
src/tool/h264transjpeg_civetweb/transjpegweb.h

@@ -16,6 +16,8 @@
 #include "rtspclientdown.h"
 #include "rtspclientdown.h"
 #include "ivh264framedecode.h"
 #include "ivh264framedecode.h"
 
 
+#include <QFile>
+
 #define NUM_CAM 4
 #define NUM_CAM 4
 
 
 
 
@@ -25,7 +27,12 @@ class WebSocketHandler : public CivetWebSocketHandler {
 
 
     std::vector<struct mg_connection *> mvectorconn;
     std::vector<struct mg_connection *> mvectorconn;
     std::mutex mMutex;
     std::mutex mMutex;
+    int mnwscount = 0;
 public:
 public:
+    int GetCount()
+    {
+        return mnwscount;
+    }
     void BroadData(const char * strdata,int ndata)
     void BroadData(const char * strdata,int ndata)
     {
     {
         int i;
         int i;
@@ -34,6 +41,7 @@ public:
         {
         {
             std::cout<<" send frame data . size : "<<ndata<<std::endl;
             std::cout<<" send frame data . size : "<<ndata<<std::endl;
             mg_websocket_write(mvectorconn[i], MG_WEBSOCKET_OPCODE_BINARY, strdata, ndata);
             mg_websocket_write(mvectorconn[i], MG_WEBSOCKET_OPCODE_BINARY, strdata, ndata);
+            mnwscount++;
         }
         }
         mMutex.unlock();
         mMutex.unlock();
     }
     }
@@ -82,11 +90,157 @@ private:
 };
 };
 #endif
 #endif
 
 
+class PicHandler : public CivetHandler
+{
+private:
+    int64_t mnpicuptime = 0;
+    std::shared_ptr<char> mpstr_data;
+    int mnpicsize;
+    std::mutex mmutexdata;
+    int mnpiccount = 0;
+
+  public:
+    int GetCount()
+    {
+        return mnpiccount;
+    }
+    void SetData(std::shared_ptr<char> pstr_ptr,int ndatasize)
+    {
+        mmutexdata.lock();
+        mnpicsize = ndatasize;
+        mpstr_data = pstr_ptr;
+        mnpicuptime = std::chrono::system_clock::now().time_since_epoch().count();
+        mmutexdata.unlock();
+    }
+
+    bool
+    handleGet(CivetServer *server, struct mg_connection *conn)
+    {
+
+        std::shared_ptr<char> pstr_ptr;
+        int npicsize;
+        int64_t nnow = std::chrono::system_clock::now().time_since_epoch().count();
+        int64_t ndiff = nnow - mnpicuptime;
+        if(abs(ndiff/1000000)>3000)
+        {
+            return false;
+        }
+        else
+        {
+            mmutexdata.lock();
+            pstr_ptr = mpstr_data;
+            npicsize = mnpicsize;
+            mmutexdata.unlock();
+        }
+        static int ncount;
+
+        mg_printf(conn,
+                  "HTTP/1.1 200 OK\r\n"
+                  "Connection: close\r\n"
+                  "Max-Age: 0\r\n"
+                  "Expires: 0\r\n"
+                  "Cache-Control: no-cache, no-store, must-revalidate, private\r\n"
+                  "Pragma: no-cache\r\n"
+                  "Content-Type: multipart/x-mixed-replace; "
+                  "boundary=--BoundaryString\r\n"
+                  "\r\n");
+
+        mg_printf(conn,"<meta http-equiv=\"refresh\" content=\"1\">");
+        mg_printf(conn,
+        "<script type=\"text/javascript\">\r\n"
+            "function myrefresh() {\r\n"
+                "window.location.reload();\r\n"
+            "}\r\n"
+            "setTimeout('myrefresh()', 1000);\r\n"
+        "</script>\r\n");
+
+
+        mg_printf(conn,
+                  "--BoundaryString\r\n"
+                  "Content-type: image/jpeg\r\n"
+                  "Content-Length: %zu\r\n"
+                  "\r\n",
+                  npicsize);
+
+
+        mg_write(conn, pstr_ptr.get(), npicsize);
+
+
+        mg_printf(conn, "\r\n\r\n");
+
+
+        ncount++;
+ //       printf("send pic. %d\n",ncount);
+
+        mnpiccount++;
+        return true;
+    }
+};
+
+
+class WsStartHandler : public CivetHandler
+{
+private:
+    int mnIndexHtmlMode = 0; //if 0 use indexpic.html, if 1 use websocket.
+  public:
+    void SetIndexMode(int nmode)
+    {
+        if(nmode == 0)mnIndexHtmlMode = 0;
+        else mnIndexHtmlMode = 1;
+    }
+    bool
+    handleGet(CivetServer *server, struct mg_connection *conn)
+    {
+
+    mg_printf(conn,
+              "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: "
+              "close\r\n\r\n");
+
+    mg_printf(conn, "<!DOCTYPE html>\n");
+    mg_printf(conn, "<html>\n<head>\n");
+    mg_printf(conn, "<meta charset=\"UTF-8\">\n");
+    mg_printf(conn, "<title>ADC IV Web UI</title>\n");
+
+    QFile xFile;
+    if(mnIndexHtmlMode == 0)
+    {
+        xFile.setFileName(":/indexpic.html");
+    }
+    else
+    {
+        xFile.setFileName(":/indexws.html");
+    }
+    if(xFile.open(QIODevice::ReadOnly))
+    {
+        QByteArray ba = xFile.readAll();
+        mg_printf(conn,ba.data());
+
+    }
+
+    return 1;
+
+
+
+    }
+};
+
+
+
+namespace iv {
+struct transjpegcount
+{
+    int nrtspretry;
+    int nframecount;
+    int njpegcount;
+    int npicreqcount;
+    int nwsreqcount;
+};
+}
 
 
 class transjpegweb
 class transjpegweb
 {
 {
 public:
 public:
-    transjpegweb();
+    transjpegweb(std::string strip,std::string strport,std::string strvin,std::string strpass,std::string strwebmode);
 
 
 private:
 private:
     CivetServer * mpserver;
     CivetServer * mpserver;
@@ -112,6 +266,16 @@ private:
     bool mbthreadrun = true;
     bool mbthreadrun = true;
 
 
     WebSocketHandler * mpws[NUM_CAM];
     WebSocketHandler * mpws[NUM_CAM];
+    PicHandler * mppichandler[NUM_CAM];
+
+    WsStartHandler * mphandleindex;
+
+    iv::transjpegcount mtjcount[NUM_CAM];
+
+    std::string mstrrtspstring[NUM_CAM];
+
+public:
+    std::string GetStatics();
 
 
 };
 };
 
 

BIN
src/tool/h264transjpeg_civetweb/webm.png