From 513d2e24abff6de1b35b2471a57ce1361686e6de Mon Sep 17 00:00:00 2001
From: chenshijun <csj_sky@126.com>
Date: 星期六, 29 六月 2019 16:21:15 +0800
Subject: [PATCH] 修改解码gb28181的bug

---
 csrc/thirdparty/gb28181/lib/librtspclient.so  |    0 
 .idea/vcs.xml                                 |    6 
 .idea/modules.xml                             |    8 
 .idea/goffmpeg.iml                            |    2 
 csrc/thirdparty/gb28181/include/librtsp.h     |  114 ++++++++++++
 .idea/workspace.xml                           |  142 +++++++++++++++
 csrc/thirdparty/gb28181/include/PsToEs.hpp    |  190 +++++++++++++++++++++
 .idea/codeStyles/Project.xml                  |   29 +++
 .idea/misc.xml                                |    7 
 csrc/thirdparty/gb28181/lib/libStreamParse.so |    0 
 10 files changed, 498 insertions(+), 0 deletions(-)

diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..30aa626
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+<component name="ProjectCodeStyleConfiguration">
+  <code_scheme name="Project" version="173">
+    <Objective-C-extensions>
+      <file>
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
+      </file>
+      <class>
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
+      </class>
+      <extensions>
+        <pair source="cpp" header="h" fileNamingConvention="NONE" />
+        <pair source="c" header="h" fileNamingConvention="NONE" />
+      </extensions>
+    </Objective-C-extensions>
+  </code_scheme>
+</component>
\ No newline at end of file
diff --git a/.idea/goffmpeg.iml b/.idea/goffmpeg.iml
new file mode 100644
index 0000000..f08604b
--- /dev/null
+++ b/.idea/goffmpeg.iml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module classpath="CMake" type="CPP_MODULE" version="4" />
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..8822db8
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
+  <component name="JavaScriptSettings">
+    <option name="languageLevel" value="ES6" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..5377626
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/goffmpeg.iml" filepath="$PROJECT_DIR$/.idea/goffmpeg.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..ec5d76c
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CMakeRunConfigurationManager" shouldGenerate="true" shouldDeleteObsolete="true" buildAllGenerated="true">
+    <generated>
+      <config projectName="cffmpeg" targetName="cffmpeg" />
+    </generated>
+  </component>
+  <component name="CMakeSettings">
+    <configurations>
+      <configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
+    </configurations>
+  </component>
+  <component name="ChangeListManager">
+    <list default="true" id="d36808e2-34af-4b98-9cbb-dcee35b4ca2e" name="Default Changelist" comment="">
+      <change beforePath="$PROJECT_DIR$/csrc/ffmpeg/format/FormatIn.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/csrc/ffmpeg/format/FormatIn.cpp" afterDir="false" />
+    </list>
+    <ignored path="$PROJECT_DIR$/cmake-build-debug/" />
+    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="ExecutionTargetManager" SELECTED_TARGET="CMakeBuildProfile:Debug" />
+  <component name="FUSProjectUsageTrigger">
+    <session id="1605316314">
+      <usages-collector id="statistics.lifecycle.project">
+        <counts>
+          <entry key="project.open.time.0" value="1" />
+          <entry key="project.opened" value="1" />
+        </counts>
+      </usages-collector>
+    </session>
+  </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
+  <component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" />
+  <component name="JsGulpfileManager">
+    <detection-done>true</detection-done>
+    <sorting>DEFINITION_ORDER</sorting>
+  </component>
+  <component name="ProjectFrameBounds" extendedState="7">
+    <option name="x" value="65" />
+    <option name="y" value="24" />
+    <option name="width" value="928" />
+    <option name="height" value="1176" />
+  </component>
+  <component name="ProjectView">
+    <navigator proportions="" version="1">
+      <foldersAlwaysOnTop value="true" />
+    </navigator>
+    <panes>
+      <pane id="Scope" />
+      <pane id="ProjectPane" />
+    </panes>
+  </component>
+  <component name="PropertiesComponent">
+    <property name="WebServerToolWindowFactoryState" value="false" />
+    <property name="last_opened_file_path" value="$PROJECT_DIR$" />
+    <property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
+    <property name="nodejs_npm_path_reset_for_default_project" value="true" />
+    <property name="settings.editor.selected.configurable" value="configurable.group.appearance" />
+  </component>
+  <component name="RunDashboard">
+    <option name="ruleStates">
+      <list>
+        <RuleState>
+          <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
+        </RuleState>
+        <RuleState>
+          <option name="name" value="StatusDashboardGroupingRule" />
+        </RuleState>
+      </list>
+    </option>
+  </component>
+  <component name="RunManager" selected="Application.cffmpeg">
+    <configuration name="Build All" type="CMakeRunConfiguration" factoryName="Application" PASS_PARENT_ENVS_2="true" CONFIG_NAME="Debug" EXPLICIT_BUILD_TARGET_NAME="all">
+      <method v="2">
+        <option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
+      </method>
+    </configuration>
+    <configuration name="cffmpeg" type="CMakeRunConfiguration" factoryName="Application" PASS_PARENT_ENVS_2="true" PROJECT_NAME="cffmpeg" TARGET_NAME="cffmpeg" CONFIG_NAME="Debug">
+      <method v="2">
+        <option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
+      </method>
+    </configuration>
+    <list>
+      <item itemvalue="Application.Build All" />
+      <item itemvalue="Application.cffmpeg" />
+    </list>
+  </component>
+  <component name="SvnConfiguration">
+    <configuration />
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="d36808e2-34af-4b98-9cbb-dcee35b4ca2e" name="Default Changelist" comment="" />
+      <created>1561627005122</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1561627005122</updated>
+      <workItem from="1561627006451" duration="599000" />
+    </task>
+    <servers />
+  </component>
+  <component name="TimeTrackingManager">
+    <option name="totallyTimeSpent" value="599000" />
+  </component>
+  <component name="ToolWindowManager">
+    <frame x="65" y="24" width="928" height="1176" extended-state="7" />
+    <editor active="true" />
+    <layout>
+      <window_info id="Favorites" side_tool="true" />
+      <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.24943566" />
+      <window_info id="Structure" order="1" side_tool="true" weight="0.25" />
+      <window_info anchor="bottom" id="Database Changes" show_stripe_button="false" />
+      <window_info anchor="bottom" id="Version Control" />
+      <window_info anchor="bottom" id="Terminal" />
+      <window_info anchor="bottom" id="Event Log" side_tool="true" />
+      <window_info anchor="bottom" id="CMake" />
+      <window_info anchor="bottom" id="Message" order="0" />
+      <window_info anchor="bottom" id="Find" order="1" />
+      <window_info anchor="bottom" id="Run" order="2" />
+      <window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
+      <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
+      <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
+      <window_info anchor="bottom" id="TODO" order="6" />
+      <window_info anchor="right" id="Database" />
+      <window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
+      <window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
+      <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
+    </layout>
+  </component>
+  <component name="TypeScriptGeneratedFilesManager">
+    <option name="version" value="1" />
+  </component>
+  <component name="VcsContentAnnotationSettings">
+    <option name="myLimit" value="2678400000" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/csrc/thirdparty/gb28181/include/PsToEs.hpp b/csrc/thirdparty/gb28181/include/PsToEs.hpp
new file mode 100644
index 0000000..663fbdb
--- /dev/null
+++ b/csrc/thirdparty/gb28181/include/PsToEs.hpp
@@ -0,0 +1,190 @@
+#include <cstdio>
+#include <string>
+#include <cstring>
+#include <deque>
+#include <pthread.h>
+
+#include "librtsp.h"
+
+
+using namespace std;
+
+template<typename T>
+class MyQueue {
+public:
+    MyQueue():mtx(PTHREAD_MUTEX_INITIALIZER), cond(PTHREAD_COND_INITIALIZER){
+        t.tv_sec = 0;
+        t.tv_nsec = 20000000;
+    }
+
+    ~MyQueue() {
+
+    }
+
+public:
+    void push(T v) {
+        pthread_mutex_lock(&mtx);
+        q.push_back(v);
+        pthread_cond_signal(&cond);
+        pthread_mutex_unlock(&mtx);
+    }
+
+    //鍚戦槦鍒楃殑鍓嶉潰鎻掑叆鍏冪礌
+    void push_front_one(T v) {
+        pthread_mutex_lock(&mtx);
+        q.push_front(v);
+        pthread_cond_signal(&cond);
+        pthread_mutex_unlock(&mtx);
+    }
+
+    T pop() {
+        pthread_mutex_lock(&mtx);
+        while (q.empty()) {
+            pthread_cond_wait(&cond, &mtx);
+            pthread_cond_timedwait(&cond, &mtx, &t);
+        }
+        T value = q.front();
+        q.pop_front();
+        pthread_mutex_unlock(&mtx);
+        return value;
+    }
+
+    T popNotWait() {
+        pthread_mutex_lock(&mtx);
+        T value = q.front();
+        q.pop_front();
+        pthread_mutex_unlock(&mtx);
+        return value;
+
+    }
+
+    int count_queue() {
+        return q.size();
+    }
+
+    T clearAll(){
+		pthread_mutex_lock(&mtx);
+		while (!q.empty()) q.pop_front();
+		pthread_mutex_unlock(&mtx);
+    }
+
+private:
+    deque<T> q;
+    pthread_mutex_t mtx;
+    pthread_cond_t cond;
+    timespec t;
+};
+
+typedef struct _buffInfo {
+	unsigned char *buff;
+	int buffLen;
+} frameBuffInfo;
+
+MyQueue<frameBuffInfo *> m_rtpQueue;
+long Handle;
+
+bool pushInfo(unsigned char *data, int datalen) {
+
+	frameBuffInfo *info = new frameBuffInfo();
+	info->buff = new unsigned char[datalen];
+	info->buffLen = datalen;
+	memcpy(info->buff, data, datalen);
+
+	//printf(" m_rtpQueue.push befores ");
+	m_rtpQueue.push(info);
+	//printf(" m_rtpQueue.push after ");
+
+	return true;
+}
+
+int readData(void *opaque, unsigned char *buf, int bufsize) {
+
+//	GB28181API *_this = (GB28181API *)opaque;
+	int len = bufsize;
+	int diff = 0;
+	do {
+
+	//printf(" m_rtpQueue.pop before ");
+	//浠庣紦瀛樹腑鑾峰彇buffinfo
+	frameBuffInfo *buffinfo = m_rtpQueue.pop();
+//        DBG(" m_rtpQueue.pop after ");
+	diff = len - buffinfo->buffLen;
+
+	//甯ч暱澶т簬bufsize
+	if (diff < 0) {
+		printf("/甯ч暱澶т簬bufsize:%d\n", diff);
+		memcpy(buf + bufsize - len, buffinfo->buff, len);
+
+		frameBuffInfo *info = new frameBuffInfo();
+		info->buffLen = buffinfo->buffLen - len;
+		info->buff = new unsigned char[buffinfo->buffLen - len]{};
+		memcpy(info->buff, buffinfo->buff + len, buffinfo->buffLen - len);
+
+		m_rtpQueue.push_front_one(info);
+	} else if (diff == 0) {
+		printf("/甯ч暱绛変簬bufsize:%d\n", diff);
+		memcpy(buf + bufsize - len, buffinfo->buff, buffinfo->buffLen);
+	} else if (diff > 0) {
+		printf("/甯ч暱灏忎簬bufsize:%d\n", diff);
+		memcpy(buf + bufsize - len, buffinfo->buff, buffinfo->buffLen);
+		len = len - buffinfo->buffLen;   //杩橀渶瑕佸~鍏呯殑澶у皬
+		memset(buf + bufsize - len, 0, len);
+		//涓嶇瓑寰呭~鍏咃紝鐩存帴杩涜瑙g爜
+		diff = 0;
+	}
+	delete[] buffinfo->buff;
+	delete buffinfo;
+	} while (diff > 0);
+
+	return bufsize;
+}
+
+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);
+
+//	//debug===============
+//	static int count = 0;
+//	static FILE *fp_write = NULL;
+//	if(count < 100) {
+//		count++;
+//
+//		if (!fp_write) {
+//			fp_write = fopen("stream_callback.mp4", "wb+");
+//		}
+//
+//		fwrite(data, sizeof(char), datalen, fp_write);
+//	}
+//	if(count >= 100){
+//		if (!fp_write) {
+//			fclose(fp_write);
+//		}
+//	}
+//	//debug===============
+
+	static bool startFlag = false;
+	if(frametype == GB_VIDEO_FRAME_I){
+		startFlag = true;
+	}
+	if((data != NULL) && (startFlag == true)){
+		pushInfo(data, datalen);
+	}
+
+}
+
+long addCamera(string &rtsp){
+	printf("RTSPSTREAM_Open\n");
+	long userdata = 1001;
+	Handle = RTSPSTREAM_Open(rtsp.c_str(), streamCallBack, userdata);
+	return Handle;
+}
+
+void deleteCamera(void){
+	m_rtpQueue.clearAll();
+	RTSPSTREAM_Close(Handle);
+	Handle = 0;
+}
+
+
+
diff --git a/csrc/thirdparty/gb28181/include/librtsp.h b/csrc/thirdparty/gb28181/include/librtsp.h
new file mode 100644
index 0000000..a2d5286
--- /dev/null
+++ b/csrc/thirdparty/gb28181/include/librtsp.h
@@ -0,0 +1,114 @@
+#if !defined(__LIB_RTSP_H__)
+#define __LIB_RTSP_H__
+
+
+#define RTSP_ERR_OK				0		//成功
+//错误码
+#define RTSP_ERR_PARAM			-1001	//参数错误
+#define RTSP_ERR_TIMEOUT		-1002	//超时
+#define RTSP_ERR_OPTIONS		-1003	//options 请求失败
+#define RTSP_ERR_DESCRIBE		-1004	//describe请求失败
+#define RTSP_ERR_SETUP			-1005	//setup请求失败
+#define RTSP_ERR_PLAY			-1006	//play请求失败
+#define RTSP_ERR_PAUSE			-1007	//pause请求失败
+#define RTSP_ERR_TEARDOWN		-1008	//teardown请求失败
+#define RTSP_ERR_NO_MEMORY      -1009   //申请内存失败
+#define RTSP_ERR_CONNECT		-1010   //connect失败
+#define RTSP_ERR_INITPORT		-1011   //初始化端口失败
+
+//码流传输方式
+typedef enum
+{
+	E_STREAM_TRANS_UDP			= 1,	//UDP传输码流
+	E_STREAM_TRANS_TCPACTIVE	= 2,	//GB28181 TCP主动 码流传输方式  TcpClient
+	E_STREAM_TRANS_TCPPASSIVE	= 3,	//GB28181 TCP被动 码流传输方式	TcpServer
+}StreamTransType_E;
+
+//视频请求类型
+typedef enum
+{
+	E_VIDEO_REQUEST_REALPLAY	= 1,	//请求实时视频
+	E_VIDEO_REQUEST_PLAYBACK	= 2,	//请求历史视频
+	E_VIDEO_REQUEST_DOWNLOAD	= 3,	//历史视频下载
+}VideoRequestType_E;
+
+#define HIS_VIDEO_CTRL_PLAY     1		//点播播放控制
+#define HIS_VIDEO_CTRL_FAST     2		//点播快放控制   参数范围:1-32倍
+#define HIS_VIDEO_CTRL_SLOW     3		//点播慢放控制	 参数范围:1-32倍
+#define HIS_VIDEO_CTRL_PAUSE    4		//点播暂停控制
+#define HIS_VIDEO_CTRL_JUMP    	5		//点播跳转控制	参数范围:从开始计算跳转的时间  (时间单位:秒)	
+
+// 码流回调的数据类型 
+#define	GB_VIDEO_STREAM_H264	0
+#define	GB_VIDEO_STREAM_MPEG2	1	// MPEG4		
+#define	GB_VIDEO_STREAM_MPEG4	2	// MPEG4
+#define	GB_VIDEO_STREAM_SVAC	3	// SVAC
+#define	GB_VIDEO_STREAM_3GP		4	// 3GP
+#define	GB_VIDEO_STREAM_H265	5	//H265
+
+// 码流回调帧数据类型 I帧 P帧  目前只判断是否为I帧
+#define GB_VIDEO_FRAME_I		1
+#define GB_VIDEO_FRAME_P		2
+
+////////////////////////////////////////////////////////////////////////////////
+// 函数名:码流回调函数
+// 描述:
+// 参数:datatype:码流格式数据类型(H264 H265等) frametype:帧类型(I帧 P帧)
+//	datalen:长度 data:码流数据  userdata:用户指针
+//
+// 返回值:会话句柄
+//  。
+// 说明:
+//  保留原模块接口。
+////////////////////////////////////////////////////////////////////////////////
+typedef void (*PlayCallBack2)(int datatype, int frametype, unsigned char *data, unsigned int datalen, long userdata);
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// 函数名:RTSPSTREAM_Open
+// 描述:设置回调函数。
+// 参数:rtsp地址、 码流回调函数、用户指针
+//
+//
+// 返回值:会话句柄
+//  。
+// 说明:
+//  保留原模块接口。
+////////////////////////////////////////////////////////////////////////////////
+long RTSPSTREAM_Open(const char *rtspurl, PlayCallBack2 streamcallback, long userdata);
+
+////////////////////////////////////////////////////////////////////////////////
+// 函数名:RTSPSTREAM_Contrl
+// 描述:设置回调函数。
+// 参数:会话句柄, 控制类型, 控制参数
+// 
+//
+// 返回值:
+//  。
+// 说明:
+//  保留原模块接口。
+////////////////////////////////////////////////////////////////////////////////
+long RTSPSTREAM_Contrl(long handle, int ctrltype, double ctrlparam);
+
+////////////////////////////////////////////////////////////////////////////////
+// 函数名:RTSPSTREAM_Close
+// 描述:设置回调函数。
+// 参数:会话句柄
+//
+//
+// 返回值:
+//  。
+// 说明:
+//  保留原模块接口。
+////////////////////////////////////////////////////////////////////////////////
+long RTSPSTREAM_Close(long handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/csrc/thirdparty/gb28181/lib/libStreamParse.so b/csrc/thirdparty/gb28181/lib/libStreamParse.so
new file mode 100644
index 0000000..76b92b9
--- /dev/null
+++ b/csrc/thirdparty/gb28181/lib/libStreamParse.so
Binary files differ
diff --git a/csrc/thirdparty/gb28181/lib/librtspclient.so b/csrc/thirdparty/gb28181/lib/librtspclient.so
new file mode 100644
index 0000000..6757f0f
--- /dev/null
+++ b/csrc/thirdparty/gb28181/lib/librtspclient.so
Binary files differ

--
Gitblit v1.8.0