...
 
Commits (8)
    https://gitcode.net/xengine/XEngine_StreamMedia/-/commit/895538aad89b883bc4ebdc167b2251cabb60f812 modify:always update avc configure at the rtmp push 2023-08-17T16:16:36+08:00 qyt 486179@qq.com https://gitcode.net/xengine/XEngine_StreamMedia/-/commit/3cc235d341f2c252ecf66181d0a05b5f5f0e78cc modify:always update avc configure at the rtmp push 2023-08-17T16:57:32+08:00 qyt 486179@qq.com https://gitcode.net/xengine/XEngine_StreamMedia/-/commit/038564eb566c210f8a21d9deda7f5eeeba111bf3 fixed:crashed when app exit 2023-08-21T10:09:49+08:00 qyt 486179@qq.com https://gitcode.net/xengine/XEngine_StreamMedia/-/commit/965edf28249a270236f0b0a5512aae5e38b7acc7 delete:get and set av buffer for push of session module 2023-08-21T10:31:38+08:00 qyt 486179@qq.com https://gitcode.net/xengine/XEngine_StreamMedia/-/commit/08dbea36d16ab6c4a9fad507c95e0056844270fa fixed:flv.js does not play because tagsize is not right 2023-08-21T10:57:48+08:00 qyt 486179@qq.com https://gitcode.net/xengine/XEngine_StreamMedia/-/commit/c420670f430d2eecb562a82d2c2932b4c31d4f8a improved:avhdr packet function 2023-08-22T14:38:32+08:00 qyt 486179@qq.com https://gitcode.net/xengine/XEngine_StreamMedia/-/commit/3c304065d7ac07e724aa95f342c053691ee56360 modify:xstream http supported 2023-08-22T17:03:19+08:00 qyt 486179@qq.com https://gitcode.net/xengine/XEngine_StreamMedia/-/commit/a56d3864ef436804d877592e8adebe24be0e041a added:srt parse process thread 2023-08-22T17:28:29+08:00 qyt 486179@qq.com modify:xstream http chunked has frame size
......@@ -33,6 +33,7 @@ typedef struct tag_XEngine_ServiceConfig
int nXStreamThread; //业务任务处理线程数
int nRTMPThread; //RTMP任务处理线程数
int nJT1078Thread; //JT1078任务线程
int nSRTThread;
}st_XMax;
struct
{
......
......@@ -91,7 +91,7 @@ bool CModuleConfigure_Json::ModuleConfigure_Json_File(LPCXSTR lpszConfigFile, XE
pSt_ServerConfig->nJT1078Port = st_JsonRoot["nJT1078Port"].asInt();
pSt_ServerConfig->nSrtPort = st_JsonRoot["nSrtPort"].asInt();
//最大配置
if (st_JsonRoot["XMax"].empty() || (7 != st_JsonRoot["XMax"].size()))
if (st_JsonRoot["XMax"].empty() || (8 != st_JsonRoot["XMax"].size()))
{
Config_IsErrorOccur = true;
Config_dwErrorCode = ERROR_MODULE_CONFIGURE_JSON_XMAX;
......@@ -105,6 +105,7 @@ bool CModuleConfigure_Json::ModuleConfigure_Json_File(LPCXSTR lpszConfigFile, XE
pSt_ServerConfig->st_XMax.nXStreamThread = st_JsonXMax["nXStreamThread"].asInt();
pSt_ServerConfig->st_XMax.nRTMPThread = st_JsonXMax["nRTMPThread"].asInt();
pSt_ServerConfig->st_XMax.nJT1078Thread = st_JsonXMax["nJT1078Thread"].asInt();
pSt_ServerConfig->st_XMax.nSRTThread = st_JsonXMax["nSRTThread"].asInt();
//时间配置
if (st_JsonRoot["XTime"].empty() || (5 != st_JsonRoot["XTime"].size()))
{
......
......@@ -9,7 +9,7 @@ UNICODE = 0
LOADHDR = -I ./
LOADSO = -L /usr/local/lib/XEngine_Release/XEngine_Core
LIB = -lXEngine_OPenSsl
LIBEX = -lsrt
LIBEX = -lsrt-gnutls
OBJECTS = ModuleHelp_JT1078.o ModuleHelp_SrtCore.o pch.o
ifeq ($(RELEASE),1)
......
......@@ -26,6 +26,7 @@ typedef struct
{
XCHAR tszSMSAddr[MAX_PATH];
XCHAR tszPushAddr[MAX_PATH];
int nFLVTag;
ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType;
}STREAMMEDIA_PULLLISTINFO;
......@@ -169,6 +170,9 @@ extern "C" bool ModuleSession_PullStream_PublishDelete(LPCXSTR lpszClientAddr);
备注:
*********************************************************************/
extern "C" bool ModuleSession_PullStream_GetList(STREAMMEDIA_PULLLISTINFO*** pppSt_PullList, int* pInt_ListCount);
extern "C" bool ModuleSession_PullStream_FLVTagSet(LPCXSTR lpszClientAddr, int nTagSize);
extern "C" bool ModuleSession_PullStream_FLVTagGet(LPCXSTR lpszClientAddr, int* pInt_TagSize);
/*********************************************************************************
* 推流端导出会话模块 *
*********************************************************************************/
......@@ -230,64 +234,6 @@ extern "C" bool ModuleSession_PushStream_Destroy(LPCXSTR lpszClientAddr);
*********************************************************************/
extern "C" bool ModuleSession_PushStream_GetAddrForAddr(LPCXSTR lpszClientAddr, XCHAR * ptszSMSAddr);
/********************************************************************
函数名称:ModuleSession_PushStream_SetHDRBuffer
函数功能:设置流ID的缓存头
参数.一:lpszClientAddr
In/Out:In
类型:常量字符指针
可空:N
意思:输入客户端地址
参数.二:lpszMsgBuffer
In/Out:In
类型:常量字符指针
可空:N
意思:要缓存的数据
参数.三:nMsgLen
In/Out:In
类型:整数型
可空:N
意思:输入缓存大小
参数.四:enStreamType
In/Out:In
类型:枚举型
可空:N
意思:设置的缓冲区类型
返回值
类型:逻辑型
意思:是否成功
备注:
*********************************************************************/
extern "C" bool ModuleSession_PushStream_SetHDRBuffer(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType);
/********************************************************************
函数名称:ModuleSession_PushStream_GetHDRBuffer
函数功能:获取流ID的缓存头
参数.一:lpszClientAddr
In/Out:In
类型:常量字符指针
可空:N
意思:输入客户端地址
参数.二:ptszMsgBuffer
In/Out:In
类型:字符指针
可空:N
意思:输出获取到的数据
参数.三:pInt_MsgLen
In/Out:In
类型:整数型指针
可空:N
意思:输出数据大小
参数.四:enStreamType
In/Out:In
类型:枚举型
可空:N
意思:获取的缓冲区类型
返回值
类型:逻辑型
意思:是否成功
备注:
*********************************************************************/
extern "C" bool ModuleSession_PushStream_GetHDRBuffer(LPCXSTR lpszClientAddr, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType);
/********************************************************************
函数名称:ModuleSession_PushStream_FindStream
函数功能:查找流对应地址
参数.一:lpszSMSAddr
......
......@@ -22,4 +22,5 @@
#define ERROR_STREAMMEDIA_MODULE_SESSION_NOTCHANNEL 0xE0007 //没有通道
#define ERROR_STREAMMEDIA_MODULE_SESSION_NOTLIVE 0xE0008 //没有找到属性
#define ERROR_STREAMMEDIA_MODULE_SESSION_EMPTY 0xE0009 //空的列表
#define ERROR_STREAMMEDIA_MODULE_SESSION_NOTFOUND 0xE000A //没有找到
\ No newline at end of file
#define ERROR_STREAMMEDIA_MODULE_SESSION_NOTFOUND 0xE000A //没有找到
#define ERROR_STREAMMEDIA_MODULE_SESSION_NOTSUPPORT 0xE000B //不支持的类型
\ No newline at end of file
......@@ -300,4 +300,52 @@ bool CModuleSession_PullStream::ModuleSession_PullStream_GetList(STREAMMEDIA_PUL
}
st_Locker.unlock_shared();
return true;
}
bool CModuleSession_PullStream::ModuleSession_PullStream_FLVTagSet(LPCXSTR lpszClientAddr, int nTagSize)
{
Session_IsErrorOccur = false;
if (NULL == lpszClientAddr)
{
Session_IsErrorOccur = true;
Session_dwErrorCode = ERROR_STREAMMEDIA_MODULE_SESSION_PARAMENT;
return false;
}
st_Locker.lock_shared();
//查找最小
auto stl_MapIterator = stl_MapClient.find(lpszClientAddr);
if (stl_MapIterator == stl_MapClient.end())
{
Session_IsErrorOccur = true;
Session_dwErrorCode = ERROR_STREAMMEDIA_MODULE_SESSION_NOTFOUND;
st_Locker.unlock_shared();
return false;
}
stl_MapIterator->second->nFLVTag = nTagSize;
st_Locker.unlock_shared();
return true;
}
bool CModuleSession_PullStream::ModuleSession_PullStream_FLVTagGet(LPCXSTR lpszClientAddr, int* pInt_TagSize)
{
Session_IsErrorOccur = false;
if (NULL == lpszClientAddr)
{
Session_IsErrorOccur = true;
Session_dwErrorCode = ERROR_STREAMMEDIA_MODULE_SESSION_PARAMENT;
return false;
}
st_Locker.lock_shared();
//查找最小
auto stl_MapIterator = stl_MapClient.find(lpszClientAddr);
if (stl_MapIterator == stl_MapClient.end())
{
Session_IsErrorOccur = true;
Session_dwErrorCode = ERROR_STREAMMEDIA_MODULE_SESSION_NOTFOUND;
st_Locker.unlock_shared();
return false;
}
*pInt_TagSize = stl_MapIterator->second->nFLVTag;
st_Locker.unlock_shared();
return true;
}
\ No newline at end of file
......@@ -23,6 +23,9 @@ public:
bool ModuleSession_PullStream_Delete(LPCXSTR lpszClientAddr);
bool ModuleSession_PullStream_PublishDelete(LPCXSTR lpszClientAddr);
bool ModuleSession_PullStream_GetList(STREAMMEDIA_PULLLISTINFO*** pppSt_PullList, int* pInt_ListCount);
public:
bool ModuleSession_PullStream_FLVTagSet(LPCXSTR lpszClientAddr, int nTagSize);
bool ModuleSession_PullStream_FLVTagGet(LPCXSTR lpszClientAddr, int* pInt_TagSize);
private:
shared_mutex st_Locker;
private:
......
......@@ -64,11 +64,9 @@ bool CModuleSession_PushStream::ModuleSession_PushStream_Create(LPCXSTR lpszClie
memset(pSt_Packet, '\0', sizeof(PUSHSTREAM_PACKET));
pSt_Packet->st_ClientLocker = make_unique<mutex>();
pSt_Packet->st_MSGLocker = make_unique<mutex>();
pSt_Packet->pStl_ListClient = make_unique<list<STREAMMEDIA_SESSIONCLIENT>>();
pSt_Packet->pStl_MapPushStream = make_unique<unordered_map<int, AVPACKET_HDRBUFFER>>();
if ((NULL == pSt_Packet->pStl_MapPushStream) || (NULL == pSt_Packet->pStl_ListClient))
if ((NULL == pSt_Packet->pStl_ListClient))
{
Session_IsErrorOccur = true;
Session_dwErrorCode = ERROR_STREAMMEDIA_MODULE_SESSION_MALLOC;
......@@ -177,156 +175,6 @@ bool CModuleSession_PushStream::ModuleSession_PushStream_GetAddrForAddr(LPCXSTR
return true;
}
/********************************************************************
函数名称:ModuleSession_PushStream_SetHDRBuffer
函数功能:设置流ID的缓存头
参数.一:lpszClientAddr
In/Out:In
类型:常量字符指针
可空:N
意思:输入客户端地址
参数.二:lpszMsgBuffer
In/Out:In
类型:常量字符指针
可空:N
意思:要缓存的数据
参数.三:nMsgLen
In/Out:In
类型:整数型
可空:N
意思:输入缓存大小
参数.四:enStreamType
In/Out:In
类型:枚举型
可空:N
意思:设置的缓冲区类型
返回值
类型:逻辑型
意思:是否成功
备注:
*********************************************************************/
bool CModuleSession_PushStream::ModuleSession_PushStream_SetHDRBuffer(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType)
{
Session_IsErrorOccur = false;
if (NULL == lpszClientAddr)
{
Session_IsErrorOccur = true;
Session_dwErrorCode = ERROR_STREAMMEDIA_MODULE_SESSION_PARAMENT;
return false;
}
//设备编号是否存在
st_Locker.lock_shared();
unordered_map<xstring, PUSHSTREAM_PACKET*>::iterator stl_MapIterator = stl_MapPushStream.find(lpszClientAddr);
if (stl_MapIterator == stl_MapPushStream.end())
{
Session_IsErrorOccur = true;
Session_dwErrorCode = ERROR_STREAMMEDIA_MODULE_SESSION_NOTFOUND;
st_Locker.unlock_shared();
return false;
}
AVPACKET_HDRBUFFER st_HDRBuffer;
memset(&st_HDRBuffer, '\0', sizeof(AVPACKET_HDRBUFFER));
if (ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PULL_FLV == enStreamType)
{
//准备头
st_HDRBuffer.nMsgLen = _xstprintf(st_HDRBuffer.tszMsgBuffer, _X("HTTP/1.1 200 OK\r\n"
"Connection: Close\r\n"
"Content-Type: video/x-flv\r\n"
"Server: XEngine/%s\r\n"
"Transfer-Encoding: chunked\r\n\r\n"
"%x\r\n"), BaseLib_OperatorVer_XTypeStr(), nMsgLen);
//拷贝数据
memcpy(st_HDRBuffer.tszMsgBuffer + st_HDRBuffer.nMsgLen, lpszMsgBuffer, nMsgLen);
st_HDRBuffer.nMsgLen += nMsgLen;
//拷贝结尾
memcpy(st_HDRBuffer.tszMsgBuffer + st_HDRBuffer.nMsgLen, _X("\r\n"), 2);
st_HDRBuffer.nMsgLen += 2;
}
else if (ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PULL_RTMP == enStreamType)
{
st_HDRBuffer.nMsgLen = nMsgLen;
memcpy(st_HDRBuffer.tszMsgBuffer, lpszMsgBuffer, nMsgLen);
}
unordered_map<int, AVPACKET_HDRBUFFER>::iterator stl_MapIteratorStream = stl_MapIterator->second->pStl_MapPushStream->find(enStreamType);
if (stl_MapIteratorStream == stl_MapIterator->second->pStl_MapPushStream->end())
{
stl_MapIterator->second->pStl_MapPushStream->insert(make_pair(enStreamType, st_HDRBuffer));
}
else
{
stl_MapIteratorStream->second = st_HDRBuffer;
}
st_Locker.unlock_shared();
return true;
}
/********************************************************************
函数名称:ModuleSession_PushStream_GetHDRBuffer
函数功能:获取流ID的缓存头
参数.一:lpszClientAddr
In/Out:In
类型:常量字符指针
可空:N
意思:输入客户端地址
参数.二:ptszMsgBuffer
In/Out:In
类型:字符指针
可空:N
意思:输出获取到的数据
参数.三:pInt_MsgLen
In/Out:In
类型:整数型指针
可空:N
意思:输出数据大小
参数.四:enStreamType
In/Out:In
类型:枚举型
可空:N
意思:获取的缓冲区类型
返回值
类型:逻辑型
意思:是否成功
备注:
*********************************************************************/
bool CModuleSession_PushStream::ModuleSession_PushStream_GetHDRBuffer(LPCXSTR lpszClientAddr, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType)
{
Session_IsErrorOccur = false;
if (NULL == lpszClientAddr)
{
Session_IsErrorOccur = true;
Session_dwErrorCode = ERROR_STREAMMEDIA_MODULE_SESSION_PARAMENT;
return false;
}
//设备编号是否存在
st_Locker.lock_shared();
unordered_map<xstring, PUSHSTREAM_PACKET*>::iterator stl_MapIterator = stl_MapPushStream.find(lpszClientAddr);
if (stl_MapIterator == stl_MapPushStream.end())
{
Session_IsErrorOccur = true;
Session_dwErrorCode = ERROR_STREAMMEDIA_MODULE_SESSION_NOTFOUND;
st_Locker.unlock_shared();
return false;
}
auto stl_MapIteratorStream = stl_MapIterator->second->pStl_MapPushStream->find(enStreamType);
if (stl_MapIteratorStream == stl_MapIterator->second->pStl_MapPushStream->end())
{
Session_IsErrorOccur = true;
Session_dwErrorCode = ERROR_STREAMMEDIA_MODULE_SESSION_NOTFOUND;
st_Locker.unlock_shared();
return false;
}
*pInt_MsgLen = stl_MapIteratorStream->second.nMsgLen;
if (NULL != ptszMsgBuffer)
{
memcpy(ptszMsgBuffer, stl_MapIteratorStream->second.tszMsgBuffer, stl_MapIteratorStream->second.nMsgLen);
}
st_Locker.unlock_shared();
return true;
}
/********************************************************************
函数名称:ModuleSession_PushStream_SetAVInfo
函数功能:设置推流的音视频信息
参数.一:lpszClientAddr
......
......@@ -10,23 +10,14 @@
// Purpose: 推流全局会话
// History:
*********************************************************************/
typedef struct
{
XCHAR tszMsgBuffer[2048]; //缓存的头
int nMsgLen; //缓冲头大小
}AVPACKET_HDRBUFFER;
typedef struct
{
XENGINE_PROTOCOL_AVINFO st_AVInfo;
XCHAR tszSMSAddr[MAX_PATH];
ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType;
unique_ptr<mutex> st_MSGLocker;
unique_ptr<mutex> st_ClientLocker;
unique_ptr<list<STREAMMEDIA_SESSIONCLIENT>> pStl_ListClient;
unique_ptr<unordered_map<int, AVPACKET_HDRBUFFER>> pStl_MapPushStream;
}PUSHSTREAM_PACKET;
class CModuleSession_PushStream
......@@ -38,8 +29,6 @@ public:
bool ModuleSession_PushStream_Create(LPCXSTR lpszClientAddr, LPCXSTR lpszSMSAddr, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType);
bool ModuleSession_PushStream_Destroy(LPCXSTR lpszClientAddr);
bool ModuleSession_PushStream_GetAddrForAddr(LPCXSTR lpszClientAddr, XCHAR* ptszSMSAddr);
bool ModuleSession_PushStream_SetHDRBuffer(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType);
bool ModuleSession_PushStream_GetHDRBuffer(LPCXSTR lpszClientAddr, XCHAR* ptszMsgBuffer, int* pInt_MsgLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType);
bool ModuleSession_PushStream_SetAVInfo(LPCXSTR lpszClientAddr, XENGINE_PROTOCOL_AVINFO *pSt_AVInfo);
bool ModuleSession_PushStream_GetAVInfo(LPCXSTR lpszClientAddr, XENGINE_PROTOCOL_AVINFO* pSt_AVInfo);
bool ModuleSession_PushStream_FindStream(LPCXSTR lpszSMSAddr, XCHAR* ptszClientAddr);
......
......@@ -10,12 +10,12 @@ EXPORTS
ModuleSession_PullStream_Delete
ModuleSession_PullStream_PublishDelete
ModuleSession_PullStream_GetList
ModuleSession_PullStream_FLVTagSet
ModuleSession_PullStream_FLVTagGet
ModuleSession_PushStream_Create
ModuleSession_PushStream_Destroy
ModuleSession_PushStream_GetAddrForAddr
ModuleSession_PushStream_SetHDRBuffer
ModuleSession_PushStream_GetHDRBuffer
ModuleSession_PushStream_FindStream
ModuleSession_PushStream_ClientInsert
ModuleSession_PushStream_ClientDelete
......
......@@ -59,6 +59,14 @@ extern "C" bool ModuleSession_PullStream_GetList(STREAMMEDIA_PULLLISTINFO * **pp
{
return m_PullStream.ModuleSession_PullStream_GetList(pppSt_PullList, pInt_ListCount);
}
extern "C" bool ModuleSession_PullStream_FLVTagSet(LPCXSTR lpszClientAddr, int nTagSize)
{
return m_PullStream.ModuleSession_PullStream_FLVTagSet(lpszClientAddr, nTagSize);
}
extern "C" bool ModuleSession_PullStream_FLVTagGet(LPCXSTR lpszClientAddr, int* pInt_TagSize)
{
return m_PullStream.ModuleSession_PullStream_FLVTagGet(lpszClientAddr, pInt_TagSize);
}
/*********************************************************************************
* 推流导出会话模块 *
*********************************************************************************/
......@@ -74,14 +82,6 @@ extern "C" bool ModuleSession_PushStream_GetAddrForAddr(LPCXSTR lpszClientAddr,
{
return m_PushStream.ModuleSession_PushStream_GetAddrForAddr(lpszClientAddr, ptszSMSAddr);
}
extern "C" bool ModuleSession_PushStream_SetHDRBuffer(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType)
{
return m_PushStream.ModuleSession_PushStream_SetHDRBuffer(lpszClientAddr, lpszMsgBuffer, nMsgLen, enStreamType);
}
extern "C" bool ModuleSession_PushStream_GetHDRBuffer(LPCXSTR lpszClientAddr, XCHAR * ptszMsgBuffer, int* pInt_MsgLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType)
{
return m_PushStream.ModuleSession_PushStream_GetHDRBuffer(lpszClientAddr, ptszMsgBuffer, pInt_MsgLen, enStreamType);
}
extern "C" bool ModuleSession_PushStream_FindStream(LPCXSTR lpszSMSAddr, XCHAR * ptszClientAddr)
{
return m_PushStream.ModuleSession_PushStream_FindStream(lpszSMSAddr, ptszClientAddr);
......
......@@ -10,7 +10,7 @@ LOADSO = -L /usr/local/lib/XEngine_Release/XEngine_BaseLib -L /usr/local/lib/XEn
-L ../../XEngine_ThirdPart/jsoncpp
LIB = -lXEngine_BaseLib -lXEngine_Algorithm -lXEngine_Core -lXEngine_ManagePool -lHelpComponents_XLog -lHelpComponents_Packets -lNetHelp_APIHelp -lRfcComponents_HttpProtocol -lXEngine_AVHelp -lStreamMedia_FLVProtocol -lStreamMedia_RTMPProtocol \
-lXEngine_ModuleConfigure -lXEngine_ModuleProtocol -lXEngine_ModuleSession -lXEngine_ModuleHelp \
-ljsoncpp -lsrt
-ljsoncpp -lsrt-gnutls
LIBEX =
OBJECTS = PullStream_ClientTask.o \
PushStream_JT1078Task.o PushStream_RTMPTask.o PushStream_XStreamTask.o PushStream_SrtTask.o \
......
......@@ -60,11 +60,85 @@ bool PullStream_ClientTask_Handle(LPCXSTR lpszClientAddr, XCHAR*** ppptszListHdr
ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE enStreamType;
if (0 == _tcsxnicmp(tszVluBuffer, "flv", 3))
{
int nTagSize = 0;
enStreamType = ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PULL_FLV;
//拷贝数据
FLVProtocol_Packet_FrameHdr(tszPushAddr, tszRVBuffer, &nRVLen);
//返回数据,为HTTP CHUNKED
nSDLen = _xstprintf(tszSDBuffer, _X("HTTP/1.1 200 OK\r\n"
"Connection: Close\r\n"
"Content-Type: video/x-flv\r\n"
"Server: XEngine/%s\r\n"
"Transfer-Encoding: chunked\r\n\r\n"
"%x\r\n"), BaseLib_OperatorVer_XTypeStr(), nRVLen);
memcpy(tszSDBuffer + nSDLen, tszRVBuffer, nRVLen);
nSDLen += nRVLen;
memcpy(tszSDBuffer + nSDLen, _X("\r\n"), 2);
nSDLen += 2;
XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_HTTP);
//发送脚本信息
XENGINE_PROTOCOL_AVINFO st_AVInfo;
memset(&st_AVInfo, '\0', sizeof(XENGINE_PROTOCOL_AVINFO));
memset(tszRVBuffer, '\0', sizeof(tszRVBuffer));
memset(tszSDBuffer, '\0', sizeof(tszSDBuffer));
ModuleSession_PushStream_GetAVInfo(tszPushAddr, &st_AVInfo);
FLVProtocol_Packet_FrameScript(tszPushAddr, tszRVBuffer, &nRVLen, &st_AVInfo, &nTagSize);
nSDLen = _xstprintf(tszSDBuffer, _X("%x\r\n"), nRVLen);
memcpy(tszSDBuffer + nSDLen, tszRVBuffer, nRVLen);
nSDLen += nRVLen;
memcpy(tszSDBuffer + nSDLen, _X("\r\n"), 2);
nSDLen += 2;
XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_HTTP);
//发送音视频信息
FLVProtocol_Packet_FrameAVCConfigure(tszPushAddr, tszRVBuffer, &nRVLen, &st_AVInfo, &nTagSize);
nSDLen = _xstprintf(tszSDBuffer, _X("%x\r\n"), nRVLen);
memcpy(tszSDBuffer + nSDLen, tszRVBuffer, nRVLen);
nSDLen += nRVLen;
memcpy(tszSDBuffer + nSDLen, _X("\r\n"), 2);
nSDLen += 2;
XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_HTTP);
FLVProtocol_Packet_FrameAACConfigure(tszPushAddr, tszRVBuffer, &nRVLen, &st_AVInfo, &nTagSize);
nSDLen = _xstprintf(tszSDBuffer, _X("%x\r\n"), nRVLen);
memcpy(tszSDBuffer + nSDLen, tszRVBuffer, nRVLen);
nSDLen += nRVLen;
memcpy(tszSDBuffer + nSDLen, _X("\r\n"), 2);
nSDLen += 2;
XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_HTTP);
ModuleSession_PullStream_Insert(lpszClientAddr, tszSMSAddr, tszPushAddr, enStreamType);
ModuleSession_PushStream_ClientInsert(tszPushAddr, lpszClientAddr, enStreamType);
ModuleSession_PullStream_FLVTagSet(lpszClientAddr, nTagSize);
}
else if (0 == _tcsxnicmp(tszVluBuffer, "xstream", 7))
{
enStreamType = ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PULL_XSTREAM;
XENGINE_PROTOCOL_AVINFO st_AVInfo;
memset(&st_AVInfo, '\0', sizeof(XENGINE_PROTOCOL_AVINFO));
memset(tszSDBuffer, '\0', sizeof(tszSDBuffer));
ModuleSession_PushStream_GetAVInfo(tszPushAddr, &st_AVInfo);
nRVLen = sizeof(XENGINE_PROTOCOL_AVINFO);
//返回数据,为HTTP CHUNKED
nSDLen = _xstprintf(tszSDBuffer, _X("HTTP/1.1 200 OK\r\n"
"Connection: Close\r\n"
"Content-Type: video/x-stream\r\n"
"Server: XEngine/%s\r\n"
"Transfer-Encoding: chunked\r\n\r\n"
"%x\r\n"), BaseLib_OperatorVer_XTypeStr(), nRVLen);
memcpy(tszSDBuffer + nSDLen, &st_AVInfo, nRVLen);
nSDLen += nRVLen;
memcpy(tszSDBuffer + nSDLen, _X("\r\n"), 2);
nSDLen += 2;
XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_HTTP);
ModuleSession_PullStream_Insert(lpszClientAddr, tszSMSAddr, tszPushAddr, enStreamType);
ModuleSession_PushStream_ClientInsert(tszPushAddr, lpszClientAddr, enStreamType);
}
else
{
......@@ -74,12 +148,6 @@ bool PullStream_ClientTask_Handle(LPCXSTR lpszClientAddr, XCHAR*** ppptszListHdr
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("拉流端:%s,请求拉流的数据类型不支持:%s,错误:%lX"), lpszClientAddr, tszVluBuffer, ModuleSession_GetLastError());
return false;
}
//返回数据,为HTTP CHUNKED
ModuleSession_PushStream_GetHDRBuffer(tszPushAddr, tszSDBuffer, &nSDLen, enStreamType);
XEngine_Network_Send(lpszClientAddr, tszSDBuffer, nSDLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_HTTP);
ModuleSession_PullStream_Insert(lpszClientAddr, tszSMSAddr, tszPushAddr, enStreamType);
ModuleSession_PushStream_ClientInsert(tszPushAddr, lpszClientAddr, enStreamType);
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("拉流端:%s,请求拉流数据成功:%s"), lpszClientAddr, tszVluBuffer);
}
else if (0 == _tcsxnicmp(lpszStreamStop, tszVluBuffer, _tcsxlen(lpszStreamStop)))
......@@ -91,7 +159,6 @@ bool PullStream_ClientTask_Handle(LPCXSTR lpszClientAddr, XCHAR*** ppptszListHdr
memset(tszSMSAddr, '\0', sizeof(tszSMSAddr));
memset(tszPushAddr, '\0', sizeof(tszPushAddr));
ModuleSession_PullStream_GetSMSAddr(lpszClientAddr, tszSMSAddr);
if (!ModuleSession_PullStream_GetPushAddr(lpszClientAddr, tszPushAddr))
{
ModuleProtocol_Packet_Comm(tszRVBuffer, &nRVLen, NULL, 404, "not found");
......@@ -100,6 +167,8 @@ bool PullStream_ClientTask_Handle(LPCXSTR lpszClientAddr, XCHAR*** ppptszListHdr
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("拉流端:%s,请求停止拉流失败,获取绑定推流地址失败,错误:%lX"), lpszClientAddr, ModuleSession_GetLastError());
return false;
}
ModuleSession_PullStream_GetSMSAddr(lpszClientAddr, tszSMSAddr);
ModuleSession_PullStream_Delete(lpszClientAddr);
ModuleSession_PushStream_ClientDelete(tszPushAddr, lpszClientAddr);
HttpProtocol_Server_SendMsgEx(xhHttpPacket, tszSDBuffer, &nSDLen, &st_HDRParam);
......
......@@ -373,9 +373,22 @@ bool PushStream_RTMPTask_Handle(XENGINE_RTMPHDR* pSt_RTMPHdr, LPCXSTR lpszClient
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("拉流端:%s,请求拉流的参数不正确:%s,错误:%lX"), lpszClientAddr, tszSMSAddr, ModuleSession_GetLastError());
return false;
}
//返回数据,为HTTP CHUNKED
ModuleSession_PushStream_GetHDRBuffer(tszPushAddr, ptszSDBuffer, &nSDLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PULL_RTMP);
XEngine_Network_Send(lpszClientAddr, ptszSDBuffer, nSDLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PUSH_RTMP);
//配置头
int nHLen = 0;
int nPLen = 0;
XENGINE_PROTOCOL_AVINFO st_AVInfo;
memset(&st_AVInfo, '\0', sizeof(XENGINE_PROTOCOL_AVINFO));
ModuleSession_PushStream_GetAVInfo(tszPushAddr, &st_AVInfo);
RTMPProtocol_Packet_FrameAVScript(ptszSDBuffer + nHLen, &nPLen, &st_AVInfo);
nHLen += nPLen;
RTMPProtocol_Packet_FrameAVCConfigure(ptszSDBuffer + nHLen, &nPLen, &st_AVInfo);
nHLen += nPLen;
RTMPProtocol_Packet_FrameAACConfigure(ptszSDBuffer + nHLen, &nPLen, &st_AVInfo);
nHLen += nPLen;
//返回数据,
XEngine_Network_Send(lpszClientAddr, ptszSDBuffer, nHLen, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PUSH_RTMP);
ModuleSession_PullStream_Insert(lpszClientAddr, tszSMSAddr, tszPushAddr, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PULL_RTMP);
ModuleSession_PushStream_ClientInsert(tszPushAddr, lpszClientAddr, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PULL_RTMP);
......
......@@ -27,7 +27,7 @@ bool PushStream_SrtTask_Connct(LPCXSTR lpszClientAddr, SRTSOCKET hSocket)
//创建会话
ModuleSession_PushStream_Create(lpszClientAddr, tszSMSAddr, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PUSH_SRT);
//need to parse ts stream
ModuleSession_PushStream_SetHDRBuffer(lpszClientAddr, NULL, 0, ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PULL_SRT);
HLSProtocol_TSParse_Insert(lpszClientAddr);
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("SRT客户端:%s,创建流成功,推流地址:%s,类型:推流端"), lpszClientAddr, tszSMSAddr);
}
else
......@@ -49,6 +49,8 @@ bool PushStream_SrtTask_Connct(LPCXSTR lpszClientAddr, SRTSOCKET hSocket)
bool PushStream_SrtTask_Handle(LPCXSTR lpszClientAddr, SRTSOCKET hSocket, LPCXSTR lpszMsgBuffer, int nMsgLen)
{
HLSProtocol_TSParse_Send(lpszClientAddr, lpszMsgBuffer, nMsgLen);
//SRT客户端就直接转发
list<STREAMMEDIA_SESSIONCLIENT> stl_ListClient;
ModuleSession_PushStream_ClientList(lpszClientAddr, &stl_ListClient);
for (auto stl_ListIteratorClient = stl_ListClient.begin(); stl_ListIteratorClient != stl_ListClient.end(); ++stl_ListIteratorClient)
......@@ -60,5 +62,49 @@ bool PushStream_SrtTask_Handle(LPCXSTR lpszClientAddr, SRTSOCKET hSocket, LPCXST
}
}
return true;
}
XHTHREAD CALLBACK PushStream_SRTTask_Thread(XPVOID lParam)
{
//任务池是编号1开始的.
int nThreadPos = *(int*)lParam;
nThreadPos++;
while (bIsRun)
{
//等待编号1的任务池触发一个组完包的事件
if (!HLSProtocol_TSParse_WaitEvent(nThreadPos))
{
continue;
}
int nListCount = 0;
XENGINE_MANAGEPOOL_TASKEVENT** ppSst_ListAddr;
//获得编号1的所有待处理任务的客户端列表(也就是客户端发送过来的数据已经组好了一个包,需要我们处理)
HLSProtocol_TSParse_GetPool(nThreadPos, &ppSst_ListAddr, &nListCount);
for (int i = 0; i < nListCount; i++)
{
//再循环客户端拥有的任务个数
for (int j = 0; j < ppSst_ListAddr[i]->nPktCount; j++)
{
int nMsgLen = 0; //客户端发送的数据大小,不包括头
XBYTE byAVType = 0;
XCHAR* ptszMsgBuffer = NULL; //客户端发送的数据
//得到一个指定客户端的完整数据包
if (HLSProtocol_TSParse_Recv(ppSst_ListAddr[i]->tszClientAddr, ptszMsgBuffer, &nMsgLen, &byAVType))
{
//在另外一个函数里面处理数据
PushStream_SrtTask_ThreadProcess(ppSst_ListAddr[i]->tszClientAddr, ptszMsgBuffer, nMsgLen);
//释放内存
BaseLib_OperatorMemory_FreeCStyle((VOID**)&ptszMsgBuffer);
}
}
}
BaseLib_OperatorMemory_Free((XPPPMEM)&ppSst_ListAddr, nListCount);
}
return 0;
}
bool PushStream_SrtTask_ThreadProcess(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen)
{
return true;
}
\ No newline at end of file
......@@ -12,4 +12,7 @@
*********************************************************************/
bool PushStream_SrtTask_Connct(LPCXSTR lpszClientAddr, SRTSOCKET hSocket);
//任务处理相关函数,处理包的内容
bool PushStream_SrtTask_Handle(LPCXSTR lpszClientAddr, SRTSOCKET hSocket, LPCXSTR lpszMsgBuffer, int nMsgLen);
\ No newline at end of file
bool PushStream_SrtTask_Handle(LPCXSTR lpszClientAddr, SRTSOCKET hSocket, LPCXSTR lpszMsgBuffer, int nMsgLen);
XHTHREAD CALLBACK PushStream_SRTTask_Thread(XPVOID lParam);
bool PushStream_SrtTask_ThreadProcess(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen);
\ No newline at end of file
......@@ -38,6 +38,8 @@ using namespace std;
#include <XEngine_Include/XEngine_StreamMedia/FLVProtocol_Error.h>
#include <XEngine_Include/XEngine_StreamMedia/RTMPProtocol_Define.h>
#include <XEngine_Include/XEngine_StreamMedia/RTMPProtocol_Error.h>
#include <XEngine_Include/XEngine_StreamMedia/HLSProtocol_Define.h>
#include <XEngine_Include/XEngine_StreamMedia/HLSProtocol_Error.h>
#include <XEngine_Include/XEngine_AVCodec/AVCollect_Define.h>
#include <XEngine_Include/XEngine_AVCodec/VideoCodec_Define.h>
#include <XEngine_Include/XEngine_AVCodec/AudioCodec_Define.h>
......@@ -93,6 +95,7 @@ extern XHANDLE xhXStreamPool;
extern XHANDLE xhRTMPSocket;
extern XHANDLE xhRTMPHeart;
extern XHANDLE xhRTMPPool;
extern XHANDLE xhSRTPool;
//配置文件
//JT1078推流
extern XHANDLE xhJT1078Socket;
......@@ -140,6 +143,7 @@ extern FILE* pst_AFile;
#pragma comment(lib,"XEngine_RfcComponents/RfcComponents_HttpProtocol.lib")
#pragma comment(lib,"XEngine_StreamMedia/StreamMedia_FLVProtocol.lib")
#pragma comment(lib,"XEngine_StreamMedia/StreamMedia_RTMPProtocol.lib")
#pragma comment(lib,"XEngine_StreamMedia/StreamMedia_HLSProtocol.lib")
#pragma comment(lib,"XEngine_AVCodec/XEngine_AVHelp.lib")
#pragma comment(lib,"XEngine_NetHelp/NetHelp_APIHelp.lib")
#pragma comment(lib,"Ws2_32.lib")
......
......@@ -220,6 +220,7 @@ void XEngine_Network_Close(LPCXSTR lpszClientAddr, XSOCKET hSocket, bool bHeart,
}
else if (ENUM_XENGINE_STREAMMEDIA_CLIENT_TYPE_PUSH_SRT == enClientType)
{
HLSProtocol_TSParse_delete(lpszClientAddr);
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("SRT客户端:%s,离开服务器,心跳标志:%d"), lpszClientAddr, bHeart);
}
}
......
......@@ -26,6 +26,7 @@ XHANDLE xhXStreamPool = NULL;
XHANDLE xhRTMPSocket = NULL;
XHANDLE xhRTMPHeart = NULL;
XHANDLE xhRTMPPool = NULL;
XHANDLE xhSRTPool = NULL;
//JT1078推流
XHANDLE xhJT1078Socket = NULL;
XHANDLE xhJT1078Heart = NULL;
......@@ -58,6 +59,8 @@ void ServiceApp_Stop(int signo)
HelpComponents_Datas_Destory(xhXStreamPacket);
HelpComponents_PKTCustom_Destory(xhJT1078Pkt);
RTMPProtocol_Parse_Destory();
FLVProtocol_Parse_Destory();
HLSProtocol_TSParse_Destory();
//销毁线程池
ManagePool_Thread_NQDestroy(xhHttpPool);
ManagePool_Thread_NQDestroy(xhXStreamPool);
......@@ -130,6 +133,7 @@ int main(int argc, char** argv)
THREADPOOL_PARAMENT** ppSt_ListCenterParam;
THREADPOOL_PARAMENT** ppSt_ListRTMPParam;
THREADPOOL_PARAMENT** ppSt_ListJT1078Param;
THREADPOOL_PARAMENT** ppSt_ListSRTParam;
memset(&st_XLogConfig, '\0', sizeof(HELPCOMPONENTS_XLOG_CONFIGURE));
memset(&st_ServiceConfig, '\0', sizeof(XENGINE_SERVICECONFIG));
......@@ -401,6 +405,30 @@ int main(int argc, char** argv)
}
ModuleHelp_SrtCore_SetCallback(Network_Callback_SRTLogin, Network_Callback_SRTRecv, Network_Callback_SRTLeave);
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,启动SRT服务成功,绑定的端口:%d"), st_ServiceConfig.nSrtPort);
if (!HLSProtocol_TSParse_Init(st_ServiceConfig.st_XMax.nSRTThread))
{
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,初始化RTMP端流包管理器失败,错误:%lX"), RTMPProtocol_GetLastError());
goto XENGINE_SERVICEAPP_EXIT;
}
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,初始化SRT端流包管理器成功,最大线程:%d"), st_ServiceConfig.st_XMax.nSRTThread);
BaseLib_OperatorMemory_Malloc((XPPPMEM)&ppSt_ListSRTParam, st_ServiceConfig.st_XMax.nSRTThread, sizeof(THREADPOOL_PARAMENT));
for (int i = 0; i < st_ServiceConfig.st_XMax.nSRTThread; i++)
{
int* pInt_Pos = new int;
*pInt_Pos = i;
ppSt_ListSRTParam[i]->lParam = pInt_Pos;
ppSt_ListSRTParam[i]->fpCall_ThreadsTask = PushStream_SRTTask_Thread;
}
xhSRTPool = ManagePool_Thread_NQCreate(&ppSt_ListSRTParam, st_ServiceConfig.st_XMax.nSRTThread);
if (NULL == xhSRTPool)
{
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,启动SRT端处理线程池失败,错误:%d"), errno);
goto XENGINE_SERVICEAPP_EXIT;
}
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,启动SRT端处理线程池成功,线程个数:%d"), st_ServiceConfig.st_XMax.nSRTThread);
}
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("所有服务成功启动,服务运行中,XEngine版本:%s,服务版本:%s,发行次数;%d。。。"), BaseLib_OperatorVer_XNumberStr(), st_ServiceConfig.st_XVer.pStl_ListVer->front().c_str(), st_ServiceConfig.st_XVer.pStl_ListVer->size());
......@@ -426,9 +454,11 @@ XENGINE_SERVICEAPP_EXIT:
SocketOpt_HeartBeat_DestoryEx(xhJT1078Heart);
//销毁包管理器
HttpProtocol_Server_DestroyEx(xhHttpPacket);
RTMPProtocol_Parse_Destory();
HelpComponents_Datas_Destory(xhXStreamPacket);
HelpComponents_PKTCustom_Destory(xhJT1078Pkt);
RTMPProtocol_Parse_Destory();
FLVProtocol_Parse_Destory();
HLSProtocol_TSParse_Destory();
//销毁线程池
ManagePool_Thread_NQDestroy(xhHttpPool);
ManagePool_Thread_NQDestroy(xhXStreamPool);
......