From 0e021985f483e593c6ef872b8bcbe299566c7dd2 Mon Sep 17 00:00:00 2001
From: chenshijun <csj_sky@126.com>
Date: 星期二, 03 十二月 2019 15:32:18 +0800
Subject: [PATCH] 增加获取国标图片接口

---
 csrc/wrapper.cpp                           |   21 +++++++
 csrc/wrapper.hpp                           |    2 
 goffmpeg.go                                |   13 ++++
 cffmpeg.h                                  |    1 
 libcffmpeg.c                               |    8 ++
 csrc/cffmpeg.cpp                           |   12 ++++
 libcffmpeg.h                               |    3 +
 csrc/thirdparty/gb28181/include/PsToEs.hpp |   77 ++++++++++++++++++++-----
 8 files changed, 122 insertions(+), 15 deletions(-)

diff --git a/cffmpeg.h b/cffmpeg.h
index 0a7ebd1..687a4d9 100644
--- a/cffmpeg.h
+++ b/cffmpeg.h
@@ -17,6 +17,7 @@
 
 int c_ffmpeg_get_fps(const cffmpeg h);
 void c_ffmpeg_run_gb28181(const cffmpeg h);
+char * c_ffmpeg_get_gb28181_pic(const char *rtspUrl, int *retDataLen);
 void c_ffmepg_use_cpu(const cffmpeg h);
 /////////passive api
 void c_ffmpeg_set_record_duration(const cffmpeg h, const int min, const int max);
diff --git a/csrc/cffmpeg.cpp b/csrc/cffmpeg.cpp
index 4cf92da..029816d 100644
--- a/csrc/cffmpeg.cpp
+++ b/csrc/cffmpeg.cpp
@@ -43,6 +43,18 @@
     s->GB28181();
 }
 
+char * c_ffmpeg_get_gb28181_pic(const char *rtspUrl, int *retDataLen){
+    char * retData = (char *)malloc(sizeof(char) * 3000000);
+    int flag = GetGb28181Pic(rtspUrl, retData, retDataLen);
+    if(flag == -1){
+        free(retData);
+        *retDataLen = 0;
+        return NULL;
+    }
+
+    return retData;
+}
+
 void c_ffmepg_use_cpu(const cffmpeg h){
     Wrapper *s = (Wrapper*)h;
     s->CPUDec();
diff --git a/csrc/thirdparty/gb28181/include/PsToEs.hpp b/csrc/thirdparty/gb28181/include/PsToEs.hpp
index 4c10a28..3073a45 100644
--- a/csrc/thirdparty/gb28181/include/PsToEs.hpp
+++ b/csrc/thirdparty/gb28181/include/PsToEs.hpp
@@ -4,6 +4,7 @@
 #include <deque>
 #include <pthread.h>
 
+#include <unistd.h>
 #include "librtsp.h"
 #include <sys/time.h>
 
@@ -176,21 +177,64 @@
 	    return bufsize;
 	}
 
+    static int capturePic(void *opaque, char *buf, int *bufsize) {
+
+        GB28181API *_this = (GB28181API *) opaque;
+        int len = 0;
+        *bufsize = 0;
+
+        do {
+            //浠庣紦瀛樹腑鑾峰彇buffinfo
+            if (_this->m_rtpQueue.count_queue() == 0) {
+//                printf(" count_queue == 0 \n");
+                usleep(10000);
+                continue;
+            }
+
+            frameBuffInfo *buffinfo = _this->m_rtpQueue.pop();
+            if (buffinfo == nullptr) {
+                printf(" buffinfo == nullptr \n");
+                return 0;
+            }
+
+            char fileIFrameName[32] = "./tmpCaptureX264IFrame";
+            auto fpIframe = fopen(fileIFrameName, "wb+");
+            fwrite(buffinfo->buff, buffinfo->buffLen, 1, fpIframe);
+            fflush(fpIframe);
+            fclose(fpIframe);
+
+            char cmd[128] = {0};
+            memset(cmd, 0, 128);
+            char fileJpgName[32] = "./tmpCaptureJpg.jpg";
+            sprintf(cmd, "ffmpeg -i %s -y -f image2 -ss 00:00:00 -vframes 1 %s >/dev/null", fileIFrameName,
+                    fileJpgName);
+            system(cmd);
+
+            auto fpJpg = fopen(fileJpgName, "rb");
+            if (fpJpg == NULL) {
+                printf("fopen(fileJpgName, \"rb\")\n");
+                return 0;
+            }
+            fseek(fpJpg, 0, SEEK_END);
+            len = ftell(fpJpg);
+            fseek(fpJpg, 0, SEEK_SET);
+            *bufsize = fread(buf, sizeof(char), len, fpJpg);
+            fclose(fpJpg);
+
+            delete[] buffinfo->buff;
+            delete buffinfo;
+
+            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){
@@ -202,9 +246,12 @@
 	}
 
 	long addCamera(string &rtsp){
-//		long userdata = 1001;//
-		handle = RTSPSTREAM_Open(rtsp.c_str(), streamCallBack, (long)this);
-		printf("RTSPSTREAM_Open, handle:%ld \n", handle);
+        static 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;
 	}
 
diff --git a/csrc/wrapper.cpp b/csrc/wrapper.cpp
index 86662a1..a8e8f6c 100644
--- a/csrc/wrapper.cpp
+++ b/csrc/wrapper.cpp
@@ -501,5 +501,26 @@
         free(c);
     }
 
+    int GetGb28181Pic(const char *rtspUrl, char *retData, int *retDataLen){
+        int ret = 0;
+        std::string fn = rtspUrl;
+
+        auto handle_gb28181 = new GB28181API;
+        if(handle_gb28181->addCamera(fn) == -1){
+            delete(handle_gb28181);
+            logIt("do addCamera Error\n");
+            return -1;
+        }
+
+        int retLen = handle_gb28181->capturePic(handle_gb28181, retData, retDataLen);
+        if(retLen == 0){
+            logIt("do capturePic failed:%d");
+            ret = -1;
+        }
+
+        handle_gb28181->deleteCamera();
+        return ret;
+    }
+
 }
 
diff --git a/csrc/wrapper.hpp b/csrc/wrapper.hpp
index 73da823..4d51708 100644
--- a/csrc/wrapper.hpp
+++ b/csrc/wrapper.hpp
@@ -89,6 +89,8 @@
                           const int dstW, const int dstH, const int dstFormat, const int flag);
     uint8_t *Convert(void *h, uint8_t *src);
     void DestoryConvertor(void *h);
+
+    int GetGb28181Pic(const char *filename, char *retData, int *retDataLen);
 }
 
 #endif
\ No newline at end of file
diff --git a/goffmpeg.go b/goffmpeg.go
index efaf6cc..a2f46bc 100644
--- a/goffmpeg.go
+++ b/goffmpeg.go
@@ -99,3 +99,16 @@
 func (h *GoFFMPEG) FPS() int {
 	return int(C.wrap_fn_fps(unsafe.Pointer(libcffmpeg), h.ffmpeg))
 }
+
+// GetGBJpg Get GB28181 Jpg
+func GetGBJpg(rtspUrl string) []byte {
+    rtsp := C.CString(rtspUrl)
+    defer C.free(unsafe.Pointer(rtsp))
+    var jpgLen C.int
+
+    pic := C.wrap_fn_get_gb28181_pic(unsafe.Pointer(libcffmpeg), rtsp, &jpgLen)
+    defer C.free(unsafe.Pointer(pic))
+
+    retJpg := C.GoBytes(unsafe.Pointer(pic), jpgLen)
+    return retJpg
+}
\ No newline at end of file
diff --git a/libcffmpeg.c b/libcffmpeg.c
index 7c30caf..c6d05f8 100644
--- a/libcffmpeg.c
+++ b/libcffmpeg.c
@@ -79,6 +79,14 @@
     fn_gb28181(h);
 }
 
+char * wrap_fn_get_gb28181_pic(void *lib, const char *rtspUrl, int *retDataLen){
+    if (!fn_get_gb28181_pic){
+        fn_get_gb28181_pic = (lib_cffmpeg_get_gb28181_pic)dlsym(lib, "c_ffmpeg_get_gb28181_pic");
+        if(!fn_get_gb28181_pic) return;
+    }
+    return fn_get_gb28181_pic(rtspUrl, retDataLen);
+}
+
 void wrap_fn_use_cpu(void *lib, const cffmpeg h){
     if (!fn_cpu){
         fn_cpu = (lib_cffmpeg_cpu)dlsym(lib, "c_ffmepg_use_cpu");
diff --git a/libcffmpeg.h b/libcffmpeg.h
index 7bc4998..59e6572 100644
--- a/libcffmpeg.h
+++ b/libcffmpeg.h
@@ -16,6 +16,7 @@
 typedef void (*lib_cffmpeg_run)(const cffmpeg, const char*);
 typedef int (*lib_cffmpeg_fps)(const cffmpeg);
 typedef void (*lib_cffmpeg_gb28181)(const cffmpeg);
+typedef char * (*lib_cffmpeg_get_gb28181_pic)(const char *rtspUrl, int *retDataLen);
 typedef void (*lib_cffmpeg_cpu)(const cffmpeg);
 typedef void (*lib_cffmpeg_rec_duration)(const cffmpeg, const int, const int);
 typedef void (*lib_cffmpeg_recorder)(const cffmpeg, const char*, const char*, const int64_t, int, int, int);
@@ -32,6 +33,7 @@
 static lib_cffmpeg_run                 fn_run = NULL;
 static lib_cffmpeg_fps                 fn_fps = NULL;
 static lib_cffmpeg_gb28181             fn_gb28181 = NULL;
+static lib_cffmpeg_get_gb28181_pic     fn_get_gb28181_pic = NULL;
 static lib_cffmpeg_cpu                 fn_cpu = NULL;
 static lib_cffmpeg_rec_duration        fn_rec_duration = NULL;
 static lib_cffmpeg_recorder            fn_recorder = NULL;
@@ -52,6 +54,7 @@
 void wrap_fn_run(void *lib, const cffmpeg h, const char* input);
 int wrap_fn_fps(void *lib, const cffmpeg h);
 void wrap_fn_run_gb28181(void *lib, const cffmpeg h);
+char * wrap_fn_get_gb28181_pic(void *lib, const char *rtspUrl, int *retDataLen);
 void wrap_fn_use_cpu(void *lib, const cffmpeg h);
 void wrap_fn_rec_duration(void *lib, const cffmpeg h, const int min, const int max);
 void wrap_fn_recorder(void *lib, const cffmpeg h, const char* id, const char* dir, const int64_t fid, int mind, int maxd, int audio);

--
Gitblit v1.8.0