From ab3d17cd44625a762fc10f0f1fd8f2c46b980aff Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期二, 26 四月 2022 11:42:19 +0800
Subject: [PATCH] capture use cpu and add arm version

---
 csrc/thirdparty/gb28181/include/PsToEs.hpp |  157 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 134 insertions(+), 23 deletions(-)

diff --git a/csrc/thirdparty/gb28181/include/PsToEs.hpp b/csrc/thirdparty/gb28181/include/PsToEs.hpp
index 51f613a..4128360 100644
--- a/csrc/thirdparty/gb28181/include/PsToEs.hpp
+++ b/csrc/thirdparty/gb28181/include/PsToEs.hpp
@@ -4,7 +4,9 @@
 #include <deque>
 #include <pthread.h>
 
+#include <unistd.h>
 #include "librtsp.h"
+#include <sys/time.h>
 
 
 using namespace std;
@@ -14,7 +16,7 @@
 public:
     MyQueue():mtx(PTHREAD_MUTEX_INITIALIZER), cond(PTHREAD_COND_INITIALIZER){
         t.tv_sec = 0;
-        t.tv_nsec = 20000000;
+        t.tv_nsec = 0;
     }
 
     ~MyQueue() {
@@ -39,9 +41,16 @@
 
     T pop() {
         pthread_mutex_lock(&mtx);
-        while (q.empty()) {
-            pthread_cond_wait(&cond, &mtx);
+        if (q.empty()) {
+            gettimeofday(&now, NULL);
+            t.tv_sec = now.tv_sec + 3;
+            t.tv_nsec = now.tv_usec * 1000;
+//            pthread_cond_wait(&cond, &mtx);
             pthread_cond_timedwait(&cond, &mtx, &t);
+        }
+        if (q.empty()) {
+            pthread_mutex_unlock(&mtx);
+            return 0;
         }
         T value = q.front();
         q.pop_front();
@@ -67,11 +76,23 @@
 		while (!q.empty()) q.pop_front();
 		pthread_mutex_unlock(&mtx);
     }
+	
+    template<class F>
+	void clearAll(F&& fn){
+		pthread_mutex_lock(&mtx);
+		while (!q.empty()){
+			T value = q.front();
+			fn(value);
+			q.pop_front();
+		} 
+		pthread_mutex_unlock(&mtx);
+	}
 private:
     deque<T> q;
     pthread_mutex_t mtx;
     pthread_cond_t cond;
     timespec t;
+    struct timeval now;
 };
 
 typedef struct _buffInfo {
@@ -87,11 +108,25 @@
 
 	~GB28181API(){
 		printf("GB28181API end!\n");
-		m_rtpQueue.clearAll();
+		// m_rtpQueue.clearAll();
+		m_rtpQueue.clearAll([](frameBuffInfo *info){
+			if (info){
+				delete[] info->buff;
+				delete info;
+			}
+		});
 		deleteCamera();
 	}
 
 	bool pushInfo(unsigned char *data, int datalen) {
+
+		while(m_rtpQueue.count_queue() > 120){
+            auto p = m_rtpQueue.popNotWait();
+            if (p){
+                delete[] p->buff;
+                delete p;
+            }
+        }
 
 		frameBuffInfo *info = new frameBuffInfo();
 		info->buff = new unsigned char[datalen];
@@ -115,7 +150,11 @@
 			//浠庣紦瀛樹腑鑾峰彇buffinfo
 			frameBuffInfo *buffinfo = _this->m_rtpQueue.pop();
 //			printf(" m_rtpQueue.pop after \n");
+            if(buffinfo != nullptr){
 			diff = len - buffinfo->buffLen;
+            }else{
+                return 0;
+            }
 
 			//甯ч暱澶т簬bufsize
 			if (diff < 0) {
@@ -127,6 +166,13 @@
 				info->buff = new unsigned char[buffinfo->buffLen - len]{};
 				memcpy(info->buff, buffinfo->buff + len, buffinfo->buffLen - len);
 
+				while(_this->m_rtpQueue.count_queue() > 120){
+                    auto p = _this->m_rtpQueue.popNotWait();
+                    if (p){
+                        delete[] p->buff;
+                        delete p;
+                    }
+                }
 //				printf("/甯ч暱澶т簬info->buffLen:%d\n", info->buffLen);
 				_this->m_rtpQueue.push_front_one(info);
 //				printf("/甯ч暱澶т簬info->buffLen\n");
@@ -149,21 +195,79 @@
 	    return bufsize;
 	}
 
+    static int capturePic(void *opaque, char *buf, int *bufsize, const int tt) {
+
+        GB28181API *_this = (GB28181API *) opaque;
+        int len = 0;
+        *bufsize = 0;
+
+        int ttt = 0;
+        do {
+        	if (ttt > tt) return 0;
+        	ttt++;
+
+            //浠庣紦瀛樹腑鑾峰彇buffinfo
+            if (_this->m_rtpQueue.count_queue() == 0) {
+//                printf(" count_queue == 0 \n");
+                usleep(200000);
+                continue;
+            }
+
+            frameBuffInfo *buffinfo = _this->m_rtpQueue.pop();
+            if (buffinfo == nullptr) {
+                printf(" buffinfo == nullptr \n");
+                return 0;
+            }
+////////////////////////////////////////////////////////
+            FILE* fpJpg = NULL;
+          	char fileJpgName[32] = "./tmpCaptureJpg.jpg";
+            char fileIFrameName[32] = "./tmpCaptureX264IFrame";
+            char cmd[512] = {0};
+
+            for(int i = 0; i < 10 * 25; i++){
+            	if (!buffinfo){
+            		buffinfo = _this->m_rtpQueue.pop();
+            	}
+            	if (!buffinfo) continue;
+
+            	auto fpIframe = fopen(fileIFrameName, "wb+");
+            	fwrite(buffinfo->buff, buffinfo->buffLen, 1, fpIframe);
+            	fflush(fpIframe);
+            	fclose(fpIframe);
+
+            	memset(cmd, 0, 512);
+            	sprintf(cmd, "ffmpeg -i %s -y -f image2 -ss 00:00:00 -vframes 1 %s >/dev/null", fileIFrameName,
+            	        fileJpgName);
+            	int rr = system(cmd);
+
+                delete[] buffinfo->buff;
+            	delete buffinfo;
+            	buffinfo = nullptr;
+
+            	fpJpg = fopen(fileJpgName, "rb");
+            	if (fpJpg) {
+            	    break;
+            	}
+            }
+///////////////////////////////////////////////////////////
+
+            fseek(fpJpg, 0, SEEK_END);
+            len = ftell(fpJpg);
+            fseek(fpJpg, 0, SEEK_SET);
+            *bufsize = fread(buf, sizeof(char), len, fpJpg);
+            fclose(fpJpg);
+
+            memset(cmd, 0, 128);
+            sprintf(cmd, "rm %s %s >/dev/null", fileIFrameName, fileJpgName);
+            system(cmd);
+        } while (*bufsize == 0);
+
+        return *bufsize;
+    }
+
 	static void streamCallBack(int datatype, int frametype, unsigned char *data, unsigned int datalen, long userdata)
 	{
 		GB28181API *_this = (GB28181API *)userdata;
-		//printf("userdata:%ld,datatype:%d, frametype:%d,  datalen:%d\n", userdata, datatype, frametype, datalen);
-
-		/*static FILE* fp_write = NULL;
-		if (!fp_write)
-
-		{
-
-		    fp_write = fopen("stream_callback.mp4", "wb+");
-
-		}
-
-		fwrite(data, sizeof(char), datalen, fp_write);	*/
 
 		static bool startFlag = false;
 		if(frametype == GB_VIDEO_FRAME_I){
@@ -174,20 +278,27 @@
 		}
 	}
 
-	void addCamera(string &rtsp){
-//		long userdata = 1001;//
-		printf("RTSPSTREAM_Open\n");
-		handle = RTSPSTREAM_Open(rtsp.c_str(), streamCallBack, (long)this);
-//		return handle;
+	long addCamera(string &rtsp){
+        int count = 0;
+        while (handle == -1 && count <= 3) {
+            count ++;
+            handle = RTSPSTREAM_Open(rtsp.c_str(), streamCallBack, (long) this);
+            printf("RTSPSTREAM_Open, handle:%ld \n", handle);
+        }
+		return handle;
 	}
 
 	void deleteCamera(){
 		printf("RTSPSTREAM_Close\n");
-		RTSPSTREAM_Close(handle);
+		if(handle != -1){
+			RTSPSTREAM_Close(handle);
+		}
+
+		handle = -1;
 	}	
 private:
 	MyQueue<frameBuffInfo *> m_rtpQueue;
-	long handle;
+	long handle = -1;
 };
 
 

--
Gitblit v1.8.0