video analysis2.0拆分,ffmpeg封装go接口库
chenshijun
2019-06-29 513d2e24abff6de1b35b2471a57ce1361686e6de
修改解码gb28181的bug
10个文件已添加
498 ■■■■■ 已修改文件
.idea/codeStyles/Project.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/goffmpeg.iml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/misc.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/modules.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/vcs.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/workspace.xml 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/thirdparty/gb28181/include/PsToEs.hpp 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/thirdparty/gb28181/include/librtsp.h 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/thirdparty/gb28181/lib/libStreamParse.so 补丁 | 查看 | 原始文档 | blame | 历史
csrc/thirdparty/gb28181/lib/librtspclient.so 补丁 | 查看 | 原始文档 | blame | 历史
.idea/codeStyles/Project.xml
New file
@@ -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>
.idea/goffmpeg.iml
New file
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />
.idea/misc.xml
New file
@@ -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>
.idea/modules.xml
New file
@@ -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>
.idea/vcs.xml
New file
@@ -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>
.idea/workspace.xml
New file
@@ -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>
csrc/thirdparty/gb28181/include/PsToEs.hpp
New file
@@ -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);
        //不等待填充,直接进行解码
        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;
}
csrc/thirdparty/gb28181/include/librtsp.h
New file
@@ -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
csrc/thirdparty/gb28181/lib/libStreamParse.so
Binary files differ
csrc/thirdparty/gb28181/lib/librtspclient.so
Binary files differ