Commit 372e629ffafe987b4fd090032566f5086dd43684

Authored by ming
1 parent 2d236ac4

gb28181支持TCP数据流

.vscode/launch.json
... ... @@ -37,6 +37,24 @@
37 37 "ignoreFailures": true
38 38 }
39 39 ]
  40 + },{
  41 + "name": "jrtp",
  42 + "type": "cppdbg",
  43 + "request": "launch",
  44 + "program": "${workspaceFolder}/bin/lib/jrtp_exe",
  45 + "args": ["40030","t"],
  46 + "stopAtEntry": false,
  47 + "cwd": "${workspaceFolder}/bin/lib",
  48 + "environment": [],
  49 + "externalConsole": false,
  50 + "MIMode": "gdb",
  51 + "setupCommands": [
  52 + {
  53 + "description": "Enable pretty-printing for gdb",
  54 + "text": "-enable-pretty-printing",
  55 + "ignoreFailures": true
  56 + }
  57 + ]
40 58 }
41 59 ]
42 60 }
43 61 \ No newline at end of file
... ...
.vscode/settings.json
... ... @@ -61,6 +61,7 @@
61 61 "streambuf": "cpp",
62 62 "cfenv": "cpp",
63 63 "cinttypes": "cpp",
64   - "__nullptr": "cpp"
  64 + "__nullptr": "cpp",
  65 + "list": "cpp"
65 66 }
66 67 }
67 68 \ No newline at end of file
... ...
jrtp/Makefile 0 → 100644
  1 +XX = g++
  2 +
  3 +
  4 +PROJECT_ROOT= /mnt/data/cmhu/FFNvDecoder
  5 +
  6 +DEPEND_DIR = $(PROJECT_ROOT)/bin
  7 +SRC_ROOT = $(PROJECT_ROOT)/jrtp
  8 +THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty
  9 +
  10 +
  11 +TARGET= $(DEPEND_DIR)/lib/jrtp_exe
  12 +
  13 +
  14 +JRTP_ROOT = $(THIRDPARTY_ROOT)/jrtp_export
  15 +
  16 +
  17 +INCLUDE= -I $(SRC_ROOT)\
  18 + -I $(JRTP_ROOT)/jrtplib/include/jrtplib3 \
  19 + -I $(JRTP_ROOT)/jthread/include/jthread
  20 +
  21 +LIBSPATH= -L $(JRTP_ROOT)/jthread/lib -l:libjthread.a \
  22 + -L $(JRTP_ROOT)/jrtplib/lib -l:libjrtp.a
  23 +
  24 +
  25 +CFLAGS= -g -O0 -fPIC $(INCLUDE) -pthread -lrt -lz -std=c++11 -fvisibility=hidden -Wl,-Bsymbolic -ldl
  26 + # -DUNICODE -D_UNICODE
  27 +
  28 +
  29 +SRCS:=$(wildcard $(SRC_ROOT)/*.cpp)
  30 +OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS)))
  31 +
  32 +
  33 +$(TARGET):$(OBJS) $(CU_OBJS)
  34 + rm -f $(TARGET)
  35 + $(XX) -o $@ $^ $(CFLAGS) $(LIBSPATH) $(LIBS) -Wwrite-strings
  36 + rm -f *.o
  37 +
  38 +%.o:$(SRC_ROOT)/%.cpp
  39 + $(XX) $(CFLAGS) -c $<
  40 +
  41 +clean:
  42 + rm -f *.o $(TARGET)
0 43 \ No newline at end of file
... ...
jrtp/example3.cpp 0 → 100644
  1 +/*
  2 + This IPv4 example listens for incoming packets and automatically adds destinations
  3 + for new sources.
  4 +*/
  5 +
  6 +#include "rtpsession.h"
  7 +#include "rtppacket.h"
  8 +#include "rtpudpv4transmitter.h"
  9 +#include "rtptcptransmitter.h"
  10 +#include "rtpipv4address.h"
  11 +#include "rtptcpaddress.h"
  12 +#include "rtpsessionparams.h"
  13 +#include "rtperrors.h"
  14 +#include "rtpsourcedata.h"
  15 +#include <stdlib.h>
  16 +#include <stdio.h>
  17 +#include <iostream>
  18 +#include <string>
  19 +
  20 +using namespace jrtplib;
  21 +using namespace std;
  22 +
  23 +//
  24 +// This function checks if there was a RTP error. If so, it displays an error
  25 +// message and exists.
  26 +//
  27 +
  28 +void checkerror(int rtperr)
  29 +{
  30 + if (rtperr < 0)
  31 + {
  32 + std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;
  33 + exit(-1);
  34 + }
  35 +}
  36 +
  37 +//
  38 +// The new class routine
  39 +//
  40 +
  41 +class MyRTPSession : public RTPSession
  42 +{
  43 +protected:
  44 + void OnNewSource(RTPSourceData *dat)
  45 + {
  46 + if (dat->IsOwnSSRC())
  47 + return;
  48 +
  49 + uint32_t ip;
  50 + uint16_t port;
  51 +
  52 + if (dat->GetRTPDataAddress() != 0)
  53 + {
  54 + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTPDataAddress());
  55 + ip = addr->GetIP();
  56 + port = addr->GetPort();
  57 + }
  58 + else if (dat->GetRTCPDataAddress() != 0)
  59 + {
  60 + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTCPDataAddress());
  61 + ip = addr->GetIP();
  62 + port = addr->GetPort()-1;
  63 + }
  64 + else
  65 + return;
  66 +
  67 + RTPIPv4Address dest(ip,port);
  68 + AddDestination(dest);
  69 +
  70 + struct in_addr inaddr;
  71 + inaddr.s_addr = htonl(ip);
  72 + std::cout << "Adding destination " << std::string(inet_ntoa(inaddr)) << ":" << port << std::endl;
  73 + }
  74 +
  75 + void OnBYEPacket(RTPSourceData *dat)
  76 + {
  77 + if (dat->IsOwnSSRC())
  78 + return;
  79 +
  80 + uint32_t ip;
  81 + uint16_t port;
  82 +
  83 + if (dat->GetRTPDataAddress() != 0)
  84 + {
  85 + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTPDataAddress());
  86 + ip = addr->GetIP();
  87 + port = addr->GetPort();
  88 + }
  89 + else if (dat->GetRTCPDataAddress() != 0)
  90 + {
  91 + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTCPDataAddress());
  92 + ip = addr->GetIP();
  93 + port = addr->GetPort()-1;
  94 + }
  95 + else
  96 + return;
  97 +
  98 + RTPIPv4Address dest(ip,port);
  99 + DeleteDestination(dest);
  100 +
  101 + struct in_addr inaddr;
  102 + inaddr.s_addr = htonl(ip);
  103 + std::cout << "Deleting destination " << std::string(inet_ntoa(inaddr)) << ":" << port << std::endl;
  104 + }
  105 +
  106 + void OnRemoveSource(RTPSourceData *dat)
  107 + {
  108 + if (dat->IsOwnSSRC())
  109 + return;
  110 + if (dat->ReceivedBYE())
  111 + return;
  112 +
  113 + uint32_t ip;
  114 + uint16_t port;
  115 +
  116 + if (dat->GetRTPDataAddress() != 0)
  117 + {
  118 + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTPDataAddress());
  119 + ip = addr->GetIP();
  120 + port = addr->GetPort();
  121 + }
  122 + else if (dat->GetRTCPDataAddress() != 0)
  123 + {
  124 + const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTCPDataAddress());
  125 + ip = addr->GetIP();
  126 + port = addr->GetPort()-1;
  127 + }
  128 + else
  129 + return;
  130 +
  131 + RTPIPv4Address dest(ip,port);
  132 + DeleteDestination(dest);
  133 +
  134 + struct in_addr inaddr;
  135 + inaddr.s_addr = htonl(ip);
  136 + std::cout << "Deleting destination " << std::string(inet_ntoa(inaddr)) << ":" << port << std::endl;
  137 + }
  138 +
  139 + void OnValidatedRTPPacket(RTPSourceData *srcdat, RTPPacket *rtppack, bool isonprobation, bool *ispackethandled)
  140 + {
  141 + printf("SSRC %x Got packet (%d bytes) in OnValidatedRTPPacket from source 0x%04x!\n", GetLocalSSRC(),
  142 + (int)rtppack->GetPayloadLength(), srcdat->GetSSRC());
  143 + DeletePacket(rtppack);
  144 + *ispackethandled = true;
  145 + }
  146 +
  147 + void OnRTCPSDESItem(RTPSourceData *srcdat, RTCPSDESPacket::ItemType t, const void *itemdata, size_t itemlength)
  148 + {
  149 + char msg[1024];
  150 +
  151 + memset(msg, 0, sizeof(msg));
  152 + if (itemlength >= sizeof(msg))
  153 + itemlength = sizeof(msg)-1;
  154 +
  155 + memcpy(msg, itemdata, itemlength);
  156 + printf("SSRC %x Received SDES item (%d): %s from SSRC %x\n", GetLocalSSRC(), (int)t, msg, srcdat->GetSSRC());
  157 + }
  158 +};
  159 +
  160 +class MyTCPTransmitter : public RTPTCPTransmitter
  161 +{
  162 +public:
  163 + MyTCPTransmitter() : RTPTCPTransmitter(0){ }
  164 +
  165 + void OnSendError(SocketType sock)
  166 + {
  167 + cout << ": Error sending over socket " << sock << ", removing destination" << endl;
  168 + DeleteDestination(RTPTCPAddress(sock));
  169 + }
  170 +
  171 + void OnReceiveError(SocketType sock)
  172 + {
  173 + cout << ": Error receiving from socket " << sock << ", removing destination" << endl;
  174 + DeleteDestination(RTPTCPAddress(sock));
  175 + }
  176 +};
  177 +
  178 +int udp_mode(int port){
  179 + MyRTPSession sess;
  180 +
  181 + std::string ipstr;
  182 + int status,i,num;
  183 +
  184 + num = 1000000*30;
  185 +
  186 + // Now, we'll create a RTP session, set the destination
  187 + // and poll for incoming data.
  188 +
  189 + RTPUDPv4TransmissionParams transparams;
  190 + RTPSessionParams sessparams;
  191 +
  192 + // IMPORTANT: The local timestamp unit MUST be set, otherwise
  193 + // RTCP Sender Report info will be calculated wrong
  194 + // In this case, we'll be just use 8000 samples per second.
  195 + sessparams.SetOwnTimestampUnit(1.0/8000.0);
  196 +
  197 + sessparams.SetAcceptOwnPackets(true);
  198 + transparams.SetPortbase(port);
  199 + status = sess.Create(sessparams,&transparams);
  200 + checkerror(status);
  201 +
  202 + std::cout << "begin.." << std::endl;
  203 +
  204 + for (i = 1 ; i <= num ; i++)
  205 + {
  206 + sess.BeginDataAccess();
  207 +
  208 + // check incoming packets
  209 + if (sess.GotoFirstSourceWithData())
  210 + {
  211 + do
  212 + {
  213 + RTPPacket *pack;
  214 +
  215 + while ((pack = sess.GetNextPacket()) != NULL)
  216 + {
  217 + // You can examine the data here
  218 + printf("Got packet !\n");
  219 +
  220 + // we don't longer need the packet, so
  221 + // we'll delete it
  222 + sess.DeletePacket(pack);
  223 + }
  224 + } while (sess.GotoNextSourceWithData());
  225 + }
  226 +
  227 + sess.EndDataAccess();
  228 +
  229 +#ifndef RTP_SUPPORT_THREAD
  230 + status = sess.Poll();
  231 + checkerror(status);
  232 +#endif // RTP_SUPPORT_THREAD
  233 +
  234 + RTPTime::Wait(RTPTime(0,1));
  235 + }
  236 +
  237 + sess.BYEDestroy(RTPTime(10,0),0,0);
  238 +
  239 + return 0;
  240 +}
  241 +
  242 +int tcp_mode(int port){
  243 + int nListener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  244 + if (nListener < 0)
  245 + {
  246 + return -1;
  247 + }
  248 +
  249 + sockaddr_in serverAddr;
  250 + memset(&serverAddr, 0, sizeof(sockaddr_in));
  251 + serverAddr.sin_family = AF_INET;
  252 + serverAddr.sin_port = htons(port);
  253 + serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  254 + int nRet = bind(nListener, (sockaddr*)&serverAddr, sizeof(serverAddr));
  255 + if (nRet == -1)
  256 + {
  257 + return -1;
  258 + }
  259 +
  260 + if (listen(nListener, 1) == -1)
  261 + {
  262 + return -1;
  263 + }
  264 +
  265 + sockaddr_in clientAddr;
  266 + int nLen = sizeof(sockaddr_in);
  267 + int nServer = accept(nListener, (sockaddr*)&clientAddr, (socklen_t * ) &nLen);
  268 + if (nServer == -1)
  269 + {
  270 + return -1;
  271 + }
  272 +
  273 +
  274 + int nPackSize = 45678;
  275 + RTPSessionParams sessparams;
  276 + sessparams.SetProbationType(RTPSources::NoProbation);
  277 + sessparams.SetOwnTimestampUnit(90000.0 / 25.0);
  278 + sessparams.SetMaximumPacketSize(nPackSize + 64);
  279 +
  280 + MyTCPTransmitter trans;
  281 + int status = trans.Init(true);
  282 + status = trans.Create(65535, NULL);
  283 +
  284 + MyRTPSession sess;
  285 + status = sess.Create(sessparams, &trans);
  286 + if (status < 0)
  287 + {
  288 + std::cout << "create session error!!" << std::endl;
  289 + return -1;
  290 + }
  291 +
  292 + sess.AddDestination(RTPTCPAddress(nServer));
  293 +
  294 + std::cout << "begin.." << std::endl;
  295 +
  296 + while (true)
  297 + {
  298 + RTPTime::Wait(RTPTime(1,0));
  299 + }
  300 +
  301 +
  302 + while(true){
  303 + sess.BeginDataAccess();
  304 +
  305 + // check incoming packets
  306 + if (sess.GotoFirstSourceWithData())
  307 + {
  308 + do
  309 + {
  310 + RTPPacket *pack;
  311 +
  312 + while ((pack = sess.GetNextPacket()) != NULL)
  313 + {
  314 + // You can examine the data here
  315 + printf("Got packet !\n");
  316 +
  317 + // we don't longer need the packet, so
  318 + // we'll delete it
  319 + sess.DeletePacket(pack);
  320 + }
  321 + } while (sess.GotoNextSourceWithData());
  322 + }
  323 +
  324 + sess.EndDataAccess();
  325 +
  326 +#ifndef RTP_SUPPORT_THREAD
  327 + status = sess.Poll();
  328 + checkerror(status);
  329 +#endif // RTP_SUPPORT_THREAD
  330 +
  331 + RTPTime::Wait(RTPTime(1,0));
  332 + }
  333 +
  334 + sess.BYEDestroy(RTPTime(10,0),0,0);
  335 +
  336 + return 0;
  337 +}
  338 +//
  339 +// The main routine
  340 +//
  341 +
  342 +int main(int argc, char* argv[]){
  343 +
  344 + int port = atoi(argv[1]);
  345 + std::cout << "port:" << port << std::endl;
  346 +
  347 + while (true)
  348 + {
  349 + int ch = getchar();
  350 + if (ch == 'q')
  351 + {
  352 + break;
  353 + }
  354 +
  355 + switch (ch)
  356 + {
  357 + case 'u':
  358 + udp_mode(port);
  359 + break;
  360 + case 't':
  361 + tcp_mode(port);
  362 + break;
  363 + default:
  364 + break;
  365 + }
  366 +
  367 + /* code */
  368 + }
  369 +
  370 + return 0;
  371 +}
  372 +
... ...
jrtp/tcp_server.cpp 0 → 100644
  1 +/*
  2 + This IPv4 example listens for incoming packets and automatically adds destinations
  3 + for new sources.
  4 +*/
  5 +
  6 +#include "rtpsession.h"
  7 +#include "rtppacket.h"
  8 +#include "rtpudpv4transmitter.h"
  9 +#include "rtptcptransmitter.h"
  10 +#include "rtpipv4address.h"
  11 +#include "rtptcpaddress.h"
  12 +#include "rtpsessionparams.h"
  13 +#include "rtperrors.h"
  14 +#include "rtpsourcedata.h"
  15 +#include <stdlib.h>
  16 +#include <stdio.h>
  17 +#include <iostream>
  18 +#include <string>
  19 +#include <thread>
  20 +#include <chrono>
  21 +#include <unistd.h>
  22 +
  23 +#include <netinet/tcp.h>
  24 +#include <sys/types.h>
  25 +#include <sys/socket.h>
  26 +
  27 +using namespace jrtplib;
  28 +using namespace std;
  29 +
  30 +//
  31 +// This function checks if there was a RTP error. If so, it displays an error
  32 +// message and exists.
  33 +//
  34 +
  35 +void checkerror(int rtperr)
  36 +{
  37 + if (rtperr < 0)
  38 + {
  39 + std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;
  40 + exit(-1);
  41 + }
  42 +}
  43 +
  44 +static long long get_cur_time(){
  45 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMs
  46 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  47 +
  48 + return tpMs.time_since_epoch().count();
  49 +}
  50 +
  51 +//
  52 +// The new class routine
  53 +//
  54 +
  55 +// class MyRTPSession : public RTPSession
  56 +// {
  57 +// protected:
  58 +
  59 +// void OnValidatedRTPPacket(RTPSourceData *srcdat, RTPPacket *rtppack, bool isonprobation, bool *ispackethandled)
  60 +// {
  61 +// // printf("timestamp: %ld SSRC %x Got packet (%d bytes) in OnValidatedRTPPacket from source 0x%04x!\n", get_cur_time(), GetLocalSSRC(),
  62 +// // (int)rtppack->GetPayloadLength(), srcdat->GetSSRC());
  63 +// DeletePacket(rtppack);
  64 +// *ispackethandled = true;
  65 +// }
  66 +
  67 +// void OnRTCPSDESItem(RTPSourceData *srcdat, RTCPSDESPacket::ItemType t, const void *itemdata, size_t itemlength)
  68 +// {
  69 +// char msg[1024];
  70 +
  71 +// memset(msg, 0, sizeof(msg));
  72 +// if (itemlength >= sizeof(msg))
  73 +// itemlength = sizeof(msg)-1;
  74 +
  75 +// memcpy(msg, itemdata, itemlength);
  76 +// // printf("SSRC %x Received SDES item (%d): %s from SSRC %x\n", GetLocalSSRC(), (int)t, msg, srcdat->GetSSRC());
  77 +// }
  78 +
  79 +// virtual void OnRTPPacket(RTPPacket* pack, const RTPTime& receiverTime, const RTPAddress* senderAddress)
  80 +// {
  81 +// AddDestination(*senderAddress);
  82 +// }
  83 +
  84 +// virtual void OnRTCPCompoundPacket(RTCPCompoundPacket *pack, const RTPTime &receivetime,const RTPAddress *senderaddress)
  85 +// {
  86 +// //AddDestination(*senderaddress);
  87 +// //const char* name = "hi~";
  88 +// //SendRTCPAPPPacket(0, (const uint8_t*)name, "keeplive", 8);
  89 +
  90 +// printf("send rtcp app");
  91 +// }
  92 +// };
  93 +
  94 +bool bSocket = false;
  95 +
  96 +class MyTCPTransmitter : public RTPTCPTransmitter
  97 +{
  98 +public:
  99 + MyTCPTransmitter() : RTPTCPTransmitter(0){ }
  100 +
  101 + void OnSendError(SocketType sock)
  102 + {
  103 + cout << "timestamp: " << get_cur_time() << " : Error sending over socket " << sock << ", removing destination" << endl;
  104 + DeleteDestination(RTPTCPAddress(sock));
  105 +
  106 + bSocket = false;
  107 + }
  108 +
  109 + void OnReceiveError(SocketType sock)
  110 + {
  111 + cout << ": Error receiving from socket " << sock << ", removing destination" << endl;
  112 + DeleteDestination(RTPTCPAddress(sock));
  113 + }
  114 +};
  115 +
  116 +RTPSession sess;
  117 +MyTCPTransmitter* trans;
  118 +RTPSessionParams sessparams;
  119 +
  120 +int thread_func(void* param){
  121 +
  122 + cout << "thread started..." << endl;
  123 +
  124 + int* p = (int*) param ;
  125 + sockaddr_in clientAddr;
  126 + int nLen = sizeof(sockaddr_in);
  127 + int nServer = -1;//accept(*p, (sockaddr*)&clientAddr, (socklen_t * ) &nLen);
  128 + // if (nServer == -1){
  129 + // return -1;
  130 + // }
  131 +
  132 + cout << "timestamp: " << get_cur_time() << " while() start" << endl;
  133 +
  134 + while(true){
  135 +
  136 + while (!bSocket)
  137 + {
  138 + nServer = accept(*p, (sockaddr*)&clientAddr, (socklen_t * ) &nLen);
  139 + if (nServer == -1)
  140 + {
  141 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  142 + continue;
  143 + }
  144 +
  145 + cout << "nServer = " << nServer << endl;
  146 + sess.AddDestination(RTPTCPAddress(nServer));
  147 + bSocket = true;
  148 + break;
  149 + }
  150 +
  151 + sess.BeginDataAccess();
  152 +
  153 + // check incoming packets
  154 + if (sess.GotoFirstSourceWithData())
  155 + {
  156 + do
  157 + {
  158 + RTPPacket *pack;
  159 +
  160 + while ((pack = sess.GetNextPacket()) != NULL)
  161 + {
  162 + // You can examine the data here
  163 + // printf("Got packet !\n");
  164 + cout << "Got packet ! timestamp: " << get_cur_time() << endl;
  165 +
  166 + // we don't longer need the packet, so
  167 + // we'll delete it
  168 + sess.DeletePacket(pack);
  169 + }
  170 + } while (sess.GotoNextSourceWithData());
  171 + }
  172 +
  173 + sess.EndDataAccess();
  174 +
  175 + sess.Poll();
  176 +
  177 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  178 + }
  179 +
  180 + close(*p);
  181 +
  182 + // sess.BYEDestroy(RTPTime(10,0),0,0);
  183 +}
  184 +
  185 +int nListener = -1;
  186 +int tcp_mode(int port){
  187 + nListener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  188 + if (nListener < 0)
  189 + {
  190 + return -1;
  191 + }
  192 +
  193 + sockaddr_in serverAddr;
  194 + memset(&serverAddr, 0, sizeof(sockaddr_in));
  195 + serverAddr.sin_family = AF_INET;
  196 + serverAddr.sin_port = htons(port);
  197 + serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  198 + int nRet = bind(nListener, (sockaddr*)&serverAddr, sizeof(serverAddr));
  199 + if (nRet == -1)
  200 + {
  201 + return -1;
  202 + }
  203 +
  204 + if (listen(nListener, 1) == -1)
  205 + {
  206 + return -1;
  207 + }
  208 +
  209 + int nPackSize = 45678;
  210 +
  211 + sessparams.SetProbationType(RTPSources::NoProbation);
  212 + sessparams.SetOwnTimestampUnit(90000.0 / 25.0);
  213 + sessparams.SetMaximumPacketSize(nPackSize + 64);
  214 +
  215 + trans = new MyTCPTransmitter();
  216 + int status = trans->Init(false);
  217 + status = trans->Create(65535, NULL);
  218 +
  219 + status = sess.Create(sessparams, trans);
  220 + if (status < 0)
  221 + {
  222 + std::cout << "create session error!!" << std::endl;
  223 + return -1;
  224 + }
  225 +
  226 + std::cout << "begin.." << std::endl;
  227 +
  228 + thread* t = new std::thread(thread_func, &nListener);
  229 +
  230 + return 0;
  231 +}
  232 +//
  233 +// The main routine
  234 +//
  235 +
  236 +int main(int argc, char* argv[]){
  237 +
  238 + tcp_mode(40032);
  239 +
  240 + while(getchar() =='q');
  241 +
  242 + return 0;
  243 +}
  244 +
... ...
src/AbstractDecoder.h
... ... @@ -32,6 +32,8 @@ typedef void(*POST_DECODE_CALLBACK)(const void * userPtr, AVFrame * gpuFrame);
32 32  
33 33 typedef void(*DECODE_FINISHED_CALLBACK)(const void* userPtr);
34 34  
  35 +typedef bool(*DECODE_REQUEST_STREAM_CALLBACK)();
  36 +
35 37 struct FFDecConfig{
36 38 string uri; // 视频地址
37 39 POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口
... ... @@ -41,6 +43,7 @@ struct FFDecConfig{
41 43 int skip_frame{1}; // 跳帧数
42 44  
43 45 int port; // gb28181接收数据的端口号
  46 + DECODE_REQUEST_STREAM_CALLBACK request_stream_cbk; // gb28181请求流
44 47 };
45 48  
46 49 enum DECODER_TYPE{
... ...
src/FFNvDecoder.cpp
... ... @@ -69,6 +69,9 @@ bool FFNvDecoder::init(FFDecConfig&amp; cfg)
69 69 m_bReal = true;
70 70 }
71 71  
  72 + post_decoded_cbk = cfg.post_decoded_cbk;
  73 + decode_finished_cbk = cfg.decode_finished_cbk;
  74 +
72 75 return init(cfg.uri.c_str(), cfg.gpuid.c_str(),cfg.force_tcp);
73 76 }
74 77  
... ...
src/FFNvDecoderManager.cpp
... ... @@ -15,13 +15,12 @@ AbstractDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig config){
15 15 if (config.cfg.post_decoded_cbk == nullptr || config.cfg.decode_finished_cbk== nullptr){
16 16 return nullptr;
17 17 }
18   -
19 18  
20 19 std::lock_guard<std::mutex> l(m_mutex);
21 20  
22 21 auto it = decoderMap.find(config.name);
23 22 if (it != decoderMap.end()){
24   - LOG_ERROR("已存在name所标记的解码器");
  23 + LOG_ERROR("已存在name为{}的解码器", config.name);
25 24 return nullptr;
26 25 }
27 26  
... ... @@ -41,8 +40,6 @@ AbstractDecoder* FFNvDecoderManager::createDecoder(MgrDecConfig config){
41 40 if (bRet)
42 41 {
43 42 dec->setName(config.name) ;
44   - dec->post_decoded_cbk = config.cfg.post_decoded_cbk;
45   - dec->decode_finished_cbk = config.cfg.decode_finished_cbk;
46 43 decoderMap[config.name] = dec;
47 44  
48 45 LOG_INFO("[{}][{}]- 解码器初始化成功",config.name, config.cfg.uri);
... ...
src/Makefile
... ... @@ -30,7 +30,7 @@ INCLUDE= -I $(DEPEND_DIR)/include \
30 30  
31 31 LIBSPATH= -L $(DEPEND_DIR)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \
32 32 -L $(CUDA_ROOT)/lib64 -lcuda -lcudart -lnvcuvid -lcurand -lcublas -lnvjpeg \
33   - -L $(SPDLOG_ROOT)/lib64 -l:libspdlog.a \
  33 + -L $(SPDLOG_ROOT) -l:libspdlog.a \
34 34 -L $(JRTP_ROOT)/jthread/lib -l:libjthread.a \
35 35 -L $(JRTP_ROOT)/jrtplib/lib -l:libjrtp.a
36 36  
... ...
src/gb28181/FFGB28181Decoder.cpp
... ... @@ -12,6 +12,9 @@ extern &quot;C&quot; {
12 12  
13 13 #include "../logger.hpp"
14 14  
  15 +#include"RTPTcpReceiver.h"
  16 +#include"RTPUdpReceiver.h"
  17 +
15 18 #define ECLOSED 0
16 19 #define ECLOSING 1
17 20 #define ERUNNING 2
... ... @@ -19,14 +22,14 @@ extern &quot;C&quot; {
19 22  
20 23 static void RTP_Stream_CallBack(void* userdata, int videoType, char* data, int len, int isKey, uint64_t pts, uint64_t localPts)
21 24 {
22   - FFGB28181Decoder* session = (FFGB28181Decoder*)userdata;
23   - session->stream_callback(videoType, data, len, isKey, pts, localPts);
  25 + FFGB28181Decoder* decoder = (FFGB28181Decoder*)userdata;
  26 + decoder->stream_callback(videoType, data, len, isKey, pts, localPts);
24 27 }
25 28  
26 29 static void RTP_Stream_End_CallBack(void* userdata)
27 30 {
28   - FFGB28181Decoder* session = (FFGB28181Decoder*)userdata;
29   - session->stream_end_callback();
  31 + FFGB28181Decoder* decoder = (FFGB28181Decoder*)userdata;
  32 + decoder->stream_end_callback();
30 33 }
31 34  
32 35 FFGB28181Decoder::FFGB28181Decoder() {
... ... @@ -59,20 +62,30 @@ void FFGB28181Decoder::close(){
59 62  
60 63 m_status = ECLOSING;
61 64  
62   - LOG_INFO("real decode thread exit success 1--{}", m_dec_name);
  65 + LOG_DEBUG("real decode thread exit success 1--{}", m_dec_name);
  66 +
  67 + if(nullptr != m_rtpPtr){
  68 + if (m_rtpPtr->IsOpened()) {
  69 + m_rtpPtr->Close();
  70 + LOG_DEBUG("real decode thread exit success 2--{}", m_dec_name);
  71 + }
63 72  
64   - if (m_rtp.IsOpened()) {
65   - m_rtp.Close();
66   - LOG_INFO("real decode thread exit success 4--{}", m_dec_name);
  73 + delete m_rtpPtr;
  74 + m_rtpPtr = nullptr;
67 75 }
68 76  
69   - stream_end_callback();
  77 + LOG_INFO("解码器关闭成功 --{}", m_dec_name);
70 78  
71 79 m_status = ECLOSED;
72 80 }
73 81  
74 82 bool FFGB28181Decoder::init(FFDecConfig& cfg){
75   - if (m_rtp.IsOpened()){
  83 + if(cfg.force_tcp){
  84 + m_rtpPtr = new RTPTcpReceiver();
  85 + }else{
  86 + m_rtpPtr = new RTPUdpReceiver();
  87 + }
  88 + if(nullptr == m_rtpPtr){
76 89 return false;
77 90 }
78 91  
... ... @@ -82,12 +95,23 @@ bool FFGB28181Decoder::init(FFDecConfig&amp; cfg){
82 95  
83 96 m_gpuid = atoi(cfg.gpuid.c_str());
84 97  
85   - m_rtp.SetDeviceID(m_dec_name);
  98 + m_rtpPtr->SetDeviceID(m_dec_name);
  99 +
  100 + if(cfg.request_stream_cbk == nullptr){
  101 + LOG_INFO("request_stream_cbk 为 nullptr -- {}", m_dec_name);
  102 + return false;
  103 + }
  104 +
  105 + post_decoded_cbk = cfg.post_decoded_cbk;
  106 + decode_finished_cbk = cfg.decode_finished_cbk;
  107 + m_rtpPtr->SetRequestStreamCallback(cfg.request_stream_cbk);
86 108  
87 109 m_port = cfg.port;
88 110  
89 111 m_cfg = cfg;
90 112  
  113 + LOG_INFO("init - {} : ", m_dec_name, m_port);
  114 +
91 115 return true;
92 116 }
93 117  
... ... @@ -95,10 +119,12 @@ bool FFGB28181Decoder::start() {
95 119  
96 120 m_status = ERUNNING;
97 121  
98   - m_rtp.SetOutputCallback(RTP_Stream_CallBack, this);
99   - m_rtp.SetVodEndCallback(RTP_Stream_End_CallBack, this);
  122 + m_rtpPtr->SetOutputCallback(RTP_Stream_CallBack, this);
  123 + m_rtpPtr->SetVodEndCallback(RTP_Stream_End_CallBack, this);
100 124  
101   - return m_rtp.Open((uint16_t)m_port);
  125 + LOG_INFO("start - {} {}: ", m_dec_name, m_port);
  126 +
  127 + return m_rtpPtr->Open((uint16_t)m_port);
102 128 }
103 129  
104 130 void FFGB28181Decoder::setDecKeyframe(bool bKeyframe){
... ... @@ -135,6 +161,7 @@ void FFGB28181Decoder::stream_callback(int videoType, char* data, int len, int i
135 161 AVDictionary *gpu_options = nullptr;
136 162  
137 163 if (m_pAVCodecCtx == nullptr) {
  164 + LOG_INFO("frame data is zero --{}", m_dec_name);
138 165 if (VIDEO_TYPE_H264 == videoType) {
139 166 if (m_gpuid >= 0){
140 167 m_pAVCodec = avcodec_find_decoder_by_name("h264_cuvid");
... ... @@ -314,5 +341,5 @@ bool FFGB28181Decoder::isSurport(FFDecConfig&amp; cfg){
314 341 }
315 342  
316 343 int FFGB28181Decoder::getCachedQueueLength(){
317   - return m_rtp.GetPsFrameListSize();
  344 + return m_rtpPtr->GetPsFrameListSize();
318 345 }
319 346 \ No newline at end of file
... ...
src/gb28181/FFGB28181Decoder.h
... ... @@ -53,7 +53,7 @@ private:
53 53  
54 54 int m_gpuid {-1};
55 55  
56   - RTPReceiver m_rtp;
  56 + RTPReceiver* m_rtpPtr;
57 57 int m_port;
58 58 uint64_t m_frameCount {};
59 59  
... ...
src/gb28181/RTPReceiver.cpp
1   -
2 1 #include "RTPReceiver.h"
3   -#include <iostream>
4   -#include <time.h>
5   -
6   -#include <thread>
7   -#include <chrono>
8   -
  2 +#include "rtppacket.h"
9 3 #include "../logger.hpp"
10   -
11   -using namespace std;
  4 +#include <thread>
12 5  
13 6 #define BUFFERSIZE_1024 1024
14   -#define BUFFERSIZE_GAP 1024//5120 //1024*5
  7 +const int kVideoFrameSize = BUFFERSIZE_1024*BUFFERSIZE_1024*5*2;
15 8  
16   -namespace
  9 +// PS解包器回调
  10 +static int ReceivePESFunction(unsigned char streamid, void * data, int size, uint64_t pts, uint64_t localPts, bool key, void* param)
17 11 {
18   - const int kH264EndFlag = 0x00000001;
19   - const int kH264EndFlag_ = 0x000001;
20   - const int kMpeg4IEndFlag = 0x000001B0;
21   - const int kMpeg4PEndFlag = 0x000001B6;
22   - const int kSvacEndFlag = 0x000001B6;
23   - const int kVideoFrameSize = BUFFERSIZE_1024*BUFFERSIZE_1024*5*2;
24   - const int kRtpRecvBufferSize = BUFFERSIZE_1024*BUFFERSIZE_1024*2;
25   - const int kSockBufferSize = BUFFERSIZE_1024*BUFFERSIZE_1024*2;
26   - const uint16_t kInvalidPort = 0;
27   -
28   - // PS解包器回调
29   - int ReceivePESFunction(unsigned char streamid, void * data, int size, uint64_t pts, uint64_t localPts, bool key, void* param)
  12 + if (NULL != data && size > 0)
  13 + {
  14 + ((RTPReceiver*)param)->OnPsDemux(streamid, (BYTE*)data, size, key, (uint64_t)pts, (uint64_t)localPts);
  15 + }
  16 + return 0;
  17 +}
  18 +
  19 +static int ps_demuxer_thread_(void* param)
  20 +{
  21 + if (!param)
30 22 {
31   - if (NULL != data && size > 0)
32   - {
33   - ((RTPReceiver*)param)->OnPsDemux(streamid, (BYTE*)data, size, key, (uint64_t)pts, (uint64_t)localPts);
34   - }
35   - return 0;
  23 + return -1;
36 24 }
37 25  
38   -}; // namespace
39   -
40   -static long long get_cur_time() {
41   - // 获取操作系统当前时间点(精确到微秒)
42   - chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
43   - = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
44   - // (微秒精度的)时间点 => (微秒精度的)时间戳
45   - return tpMicro.time_since_epoch().count();
  26 + RTPReceiver* self = (RTPReceiver*)param;
  27 + return self->OnPsProcess();
46 28 }
47 29  
48   -RTPReceiver::RTPReceiver()
49   -: m_localPort(kInvalidPort)
50   -, m_bRtpExit(false)
51   -, m_bPsExit(false)
52   -, m_h264DataFunc(NULL)
53   -, m_usrParam(NULL)
54   -, m_bOpened(false)
55   -, m_hVodEndFunc(NULL)
56   -, m_LastPTS(-1)
  30 +RTPReceiver::RTPReceiver()
  31 +:m_LastPTS(-1)
57 32 , m_LastIsKeyFrame(0)
58 33 , m_SliceBuf(1024*1024)
59   -, m_idleCount(-1)
60   -,m_noDataCount(-1)
  34 +, m_h264DataFunc(NULL)
  35 +, m_hVodEndFunc(NULL)
  36 +, m_usrParam(NULL)
  37 +, m_bPsExit(false)
  38 +, m_psThreadPtr(nullptr)
61 39 {
62   - m_LastStreamType=0;
  40 + m_LastStreamType = 0;
  41 + recvTmpBuf = new BYTE[kVideoFrameSize];
63 42 }
64 43  
65   -RTPReceiver::~RTPReceiver()
66   -{
67   - if (IsOpened())
68   - Close();
69   -
70   - LOG_INFO("RTPReceiver::~RTPReceiver() destruct OK--{}", m_deviceID);
  44 +RTPReceiver::~RTPReceiver(){
  45 + if(recvTmpBuf != nullptr){
  46 + delete[] recvTmpBuf;
  47 + }
71 48 }
72 49  
73 50 void RTPReceiver::SetOutputCallback(CallBack_Stream cb, void* param)
... ... @@ -82,376 +59,36 @@ void RTPReceiver::SetVodEndCallback(CallBack_VodFileEnd cb, void* param)
82 59 m_usrParam = param;
83 60 }
84 61  
85   -int RTPReceiver::rtp_revc_thread_(void* param)
86   -{
87   - if (!param)
88   - {
89   - return -1;
90   - }
91   -
92   - RTPReceiver* self = (RTPReceiver*)param;
93   - return self->OnRtpRecv();
  62 +void RTPReceiver::SetRequestStreamCallback(CallBack_Request_Stream cb){
  63 + m_callback_request_stream = cb;
94 64 }
95 65  
96   -int RTPReceiver::ps_demuxer_thread_(void* param)
97   -{
98   - if (!param)
99   - {
100   - return -1;
101   - }
102   -
103   - RTPReceiver* self = (RTPReceiver*)param;
104   - return self->OnPsProcess();
105   -}
106   -
107   -int RTPReceiver::ps_decode_thread_(void* param)
108   -{
109   - if (!param)
110   - {
111   - return -1;
112   - }
113   -
114   - RTPReceiver* self = (RTPReceiver*)param;
115   - return self->OnDecodeProcess();
116   -}
117   -
118   -bool RTPReceiver::Open(uint16_t localPort)
119   -{
120   - LOG_INFO("--2---RTPReceiver::Open--{}", m_deviceID);
121   - m_localPort = localPort;
122   -
123   - RTPSessionParams sessparams;
124   - sessparams.SetUsePollThread(true);
125   - sessparams.SetMinimumRTCPTransmissionInterval(10);
126   - sessparams.SetOwnTimestampUnit(1.0/90000.0);
127   - sessparams.SetAcceptOwnPackets(true);
128   -
129   - RTPUDPv4TransmissionParams transparams;
130   - transparams.SetPortbase(m_localPort);
131   - transparams.SetRTPReceiveBuffer(kRtpRecvBufferSize);
132   - cout << "port: " << m_localPort << endl;
133   - LOG_INFO("--3---RTPReceiver::Open--{}", m_deviceID);
134   -
135   - int err = m_rtpSession.Create(sessparams, &transparams);
136   - LOG_INFO("--4---RTPReceiver::Open--{}", m_deviceID);
137   - if (err != 0)
138   - {
139   - LOG_INFO("RTPReceiver::Open m_rtpSession.Create error: {}--{}", err, m_deviceID);
140   - return false;
141   - }
142   - LOG_INFO("--5---RTPReceiver::Open--{}", m_deviceID);
  66 +int RTPReceiver::InitPS(){
  67 +
143 68 m_psParser.SetReceiveFunction(ReceivePESFunction, this);
144 69  
145   - m_bOpened = true;
146   - LOG_INFO("RTPReceiver::Open ok--{}", m_deviceID);
147   -
148   - LOG_INFO("--1---RTPReceiver::Open--{}", m_deviceID);
149   - m_rtpThread = std::thread(rtp_revc_thread_, this);
150   - m_psThread = std::thread(ps_demuxer_thread_, this);
  70 + m_psThreadPtr = new std::thread(ps_demuxer_thread_, this);
  71 + if(nullptr == m_psThreadPtr){
  72 + return -1;
  73 + }
151 74  
152   - return true;
153   -}
  75 + LOG_INFO("[{}] InitPS finished", m_deviceID);
154 76  
155   -bool RTPReceiver::IsOpened() const
156   -{
157   - return m_bOpened;
  77 + return 0;
158 78 }
159 79  
160   -void RTPReceiver::Close()
161   -{
162   - m_bRtpExit = true;
  80 +void RTPReceiver::ClosePsThread(){
  81 + LOG_INFO("[{}] 3.", m_deviceID);
163 82 m_bPsExit = true;
164   -
165   - // rtp接收线程退出
166   - if (m_rtpThread.joinable())
167   - {
168   - m_rtpThread.join();
169   - }
170   - m_rtpSession.Destroy();
171   - LOG_INFO("--2---RTPReceiver::Close rtp recv thread quit --{}", m_deviceID);
172   -
173 83 // PS解包线程退出
174   - if (m_psThread.joinable())
  84 + if (m_psThreadPtr->joinable())
175 85 {
176   - m_psThread.join();
  86 + m_psThreadPtr->join();
  87 + delete m_psThreadPtr;
  88 + m_psThreadPtr = nullptr;
177 89 }
178   - LOG_INFO("--3---RTPReceiver::Close ps demux thread quit--{}", m_deviceID);
179   -
180   - m_bOpened = false;
181   -}
182   -
183   -int RTPReceiver::GetPsFrameListSize()
184   -{
185   - std::lock_guard<std::mutex> l(m_psFrameMutex);
186   - return m_psVideoFrames.size();
187   -}
188   -
189   -void RTPReceiver::ClearPsVideoFrameList()
190   -{
191   - std::lock_guard<std::mutex> l(m_psFrameMutex);
192   - while (!m_psVideoFrames.empty()) {
193   - Frame* f = m_psVideoFrames.front();
194   - delete f;
195   - m_psVideoFrames.pop();
196   - }
197   - LOG_INFO("---->cleared ps video frame list!<----{}", m_deviceID);
198   -}
199   -
200   -// 收RTP包线程
201   -int RTPReceiver::OnRtpRecv()
202   -{
203   - uint32_t lastPts = 0;
204   - uint64_t last_recv_ts{0};
205   - int offset = 0;
206   - int mark = 0;
207   - BYTE* recvTmpBuf = new BYTE[kVideoFrameSize];
208   - while (!m_bRtpExit)
209   - {
210   - //try
211   - //{
212   - m_rtpSession.Poll();
213   - m_rtpSession.BeginDataAccess();
214   - if (m_rtpSession.GotoFirstSourceWithData())
215   - {
216   - last_recv_ts = get_cur_time();
217   - m_idleCount = 0;
218   - m_noDataCount = 0;
219   - do
220   - {
221   - RTPPacket* packet;
222   - while ((packet = m_rtpSession.GetNextPacket()) != NULL/* && !mark*/)
223   - {
224   - do {
225   - if (0 == packet->GetPayloadType())
226   - {
227   - // 音频数据, 暂不处理
228   - break; // goto skip_this_packet;
229   - }
230   -
231   - // 判断是否收到完整的帧(有些厂商打的marker标记不准, 所以只能看时间戳来判断)
232   - uint32_t curPts = packet->GetTimestamp();
233   - if (lastPts != 0 && curPts != lastPts) {
234   - mark = 1;
235   - }
236   - lastPts = curPts;
237   -
238   - int payloadLen = packet->GetPayloadLength();
239   - if (offset + payloadLen > kVideoFrameSize)
240   - {
241   - offset = 0, mark = 0;
242   - break; // goto skip_this_packet;
243   - }
244   -
245   - if (mark)
246   - {
247   - BYTE* frameBuf = (BYTE*)malloc(sizeof(BYTE) * offset);
248   - if (!frameBuf) {
249   - offset = 0, mark = 0;
250   - break; // goto skip_this_packet;
251   - }
252   - memcpy(frameBuf, recvTmpBuf, offset);
253   - if (!m_bPsExit)
254   - {
255   - std::lock_guard<std::mutex> l(m_psFrameMutex);
256   - if (m_psVideoFrames.size() < 100)
257   - {
258   - m_psVideoFrames.push(new Frame(frameBuf, offset, false));
259   - }
260   - else {
261   - free(frameBuf);
262   - }
263   - }
264   - else
265   - {
266   - //若此时解码线程已经退出,不再往m_psVideoFrames推送帧,且退出当前线程
267   - free(frameBuf);
268   - LOG_INFO("OnPsProcess quit, device_id:{}", m_deviceID);
269   - //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "recv video stream interruption!");
270   - }
271   - offset = 0;
272   - mark = 0;
273   - }
274   -
275   - memcpy(recvTmpBuf + offset, packet->GetPayloadData(), payloadLen);
276   - offset += payloadLen;
277   - } while (0);
278   - //skip_this_packet:
279   - m_rtpSession.DeletePacket(packet);
280   - }
281   - } while (m_rtpSession.GotoNextSourceWithData());
282   - }
283   - //else {
284   - // if (m_idleCount != -1)
285   - // {
286   - // ++m_idleCount;//流中断计数
287   - // }
288   - // if (m_noDataCount != 0)
289   - // {
290   - // --m_noDataCount;//没流计数
291   - // }
292   - // //if (m_idleCount > 3000) {
293   - // // m_hVodEndFunc(m_usrParam);
294   - // // m_idleCount = 0;
295   - // //历史流结束的时候,也会出现超时,这个是正常的
296   - // if(m_usrParam && ((VideoSession *)GetUsrParam())->video_type() == VideoType::ERECORD)
297   - // {
298   - // if (m_idleCount > 10000)
299   - // {
300   - // //这里要判断下历史流是否结束,如果未结束,就设置为流中断
301   - // //由于record_stream_status这个函数返回值不准确,所以增加一个进度条大于80%
302   - // if(record_stream_status(((VideoSession *)GetUsrParam())->streamHandle()))
303   - // {
304   - // LOG_INFO("************Record stream is finished**{}**m_progress = {}********", m_deviceID, ((VideoSession *)GetUsrParam())->progress());
305   - // m_idleCount = -1;
306   - // m_hVodEndFunc(m_usrParam);
307   - // record_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
308   - // ((VideoSession *)GetUsrParam())->streamHandle().clear();
309   - // }
310   - // else
311   - // {
312   - // //如果此时进度大于80% 算完成吧
313   - // if(((VideoSession *)GetUsrParam())->progress() > 0.80)
314   - // {
315   - // LOG_INFO("************Record stream is overtime**{}**m_progress = {}********", m_deviceID, ((VideoSession *)GetUsrParam())->progress());
316   -
317   - // m_idleCount = 0;
318   - // m_hVodEndFunc(m_usrParam);
319   - // record_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
320   - // ((VideoSession *)GetUsrParam())->streamHandle().clear();
321   - // }
322   - // else
323   - // {
324   - // m_idleCount = -1;
325   - // //LOG_ERROR("************post ERROR_REALSTREAM_INTERRUPT to structure****{}********", m_deviceID);
326   - // //发送流中断
327   - // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Record time video streaming interruption!");
328   - // }
329   - // }
330   - //
331   - //
332   - // }
333   - //
334   - // if (m_noDataCount < -200000)//任务开始时没收到流
335   - // {
336   - // //LOG_ERROR("************m_hVodEndFunc(m_usrParam)!!!m_hVodEndFunc(m_usrParam)********{}******", m_deviceID);
337   - // m_noDataCount = -1;
338   -
339   - // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Record time video streaming interruption2!");
340   - // //m_hVodEndFunc(m_usrParam);
341   - // }
342   - // }
343   - // else//实时任务断流
344   - // //if (m_usrParam && ((VideoSession *)GetUsrParam())->video_type() == VideoType::EREAL)
345   - // {
346   - //
347   - // //每超过3000次,发送一次send_vedio_eof 时长大约1.5s
348   - // //若是30000,时长大约 18s
349   - // if(m_idleCount > 30000)
350   - // {
351   - // uint64_t cts = get_cur_time();
352   - // float duration_not_recv = (cts - last_recv_ts) / 1000.0;
353   - //
354   - // //LOG_ERROR("************I haven't got stream from hik gateway exceed {}s,send eof********{}******", duration_not_recv, m_deviceID);
355   - // m_idleCount = -1;
356   -
357   - // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Real time video streaming interruption!");
358   - // }
359   - //
360   - // if (m_noDataCount < -200000)//任务开始时没收到流
361   - // {
362   - // //LOG_ERROR("************m_noDataCount < -200000********{}******", m_deviceID);
363   - // m_noDataCount = -1;
364   -
365   - // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Real time video streaming interruption2!");
366   - // }
367   - //
368   - // }
369   - //}
370   - //}
371   - // catch (GeneralException2& e)
372   - //{
373   - // //LOG_ERROR("---> video streaming interruption!<---{}, error: {}", m_deviceID, e.err_msg());
374   -
375   - // byte_buffer bb(64);
376   - // bb << VasCmd::VAS_CMD_REALSTREAM_INTERRUPT << e.err_msg();
377   -
378   - // if (m_usrParam)
379   - // {
380   - // if (((VideoSession *)GetUsrParam())->msgChan()->is_valid()) {
381   - // try {
382   - // ((VideoSession *)GetUsrParam())->msgChan()->send_msg(bb.data_ptr(), bb.data_size());
383   - // }
384   - // catch (GeneralException2& e) {
385   - // //LOG_ERROR("[{}] send vas cmd VAS_CMD_REALSTREAM_INTERRUPT error: {}, {}", m_deviceID, e.err_code(), e.err_str());
386   - // }
387   - // }
388   -
389   - // //通知网关关闭句柄
390   - // if(!((VideoSession *)GetUsrParam())->streamHandle().empty())
391   - // {
392   -
393   - // LOG_INFO("---->Notify hisense gateway release handle = {} !<----{}", ((VideoSession *)GetUsrParam())->streamHandle().c_str(), m_deviceID);
394   - // if (((VideoSession *)GetUsrParam())->video_type() == VideoType::EREAL)
395   - // real_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
396   - //
397   - // if (((VideoSession *)GetUsrParam())->video_type() == VideoType::ERECORD)
398   - // record_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
399   - //
400   - // //清理保活的句柄
401   - // ((VideoSession *)GetUsrParam())->streamHandle().clear();
402   - // }
403   - // }
404   - //
405   - // bb.bset(0);
406   - //
407   - //}
408   - m_rtpSession.EndDataAccess();
409   - RTPTime::Wait(RTPTime(0, 500));
410   - }
411   -
412   - delete [] recvTmpBuf;
413   -
414   - return 0;
415   -}
416   -
417   -// 解PS包线程
418   -int RTPReceiver::OnPsProcess()
419   -{
420   - while (!m_bPsExit) {
421   - m_psFrameMutex.lock();
422   - if (m_psVideoFrames.size() <= 0){
423   - m_psFrameMutex.unlock();
424   - std::this_thread::sleep_for(std::chrono::milliseconds(10));
425   - continue;
426   - }
427   - Frame* frame = m_psVideoFrames.front();
428   - m_psVideoFrames.pop();
429   - m_psFrameMutex.unlock();
430   - if (frame != nullptr)
431   - {
432   - int nRet = m_psParser.AddData(frame->buf_, frame->len_);
433   - if (nRet == -1)
434   - {
435   - LOG_INFO("m_psParser return -1--{}", m_deviceID);
436   - }
437   - else if (nRet == -2)
438   - {
439   - LOG_INFO("m_psParser return -2--{}", m_deviceID);
440   - }
441   - else if (nRet == -3)
442   - {
443   - LOG_INFO("m_psParser return -3--{}", m_deviceID);
444   - }
445   -
446   - delete frame;
447   - frame = nullptr;
448   - }
449   -
450   - }
451   -
452   - ClearPsVideoFrameList();
453   -
454   - return 0;
  90 +
  91 + LOG_INFO("[{}] ps demux thread quit", m_deviceID);
455 92 }
456 93  
457 94 // 处理去除了PS头的数据
... ... @@ -531,7 +168,129 @@ void RTPReceiver::OnPsDemux(unsigned char streamId, BYTE *data, int len, bool ke
531 168 m_SliceBuf.add((char*)data, len);
532 169 }
533 170  
534   -int RTPReceiver::OnDecodeProcess()
  171 +// 解PS包线程
  172 +int RTPReceiver::OnPsProcess()
535 173 {
  174 + LOG_INFO("[{}] started.", m_deviceID);
  175 + while (!m_bPsExit) {
  176 + m_psFrameMutex.lock();
  177 + LOG_DEBUG("[{}] PS frame size : {}", m_deviceID, m_psVideoFrames.size());
  178 + if (m_psVideoFrames.size() <= 0){
  179 + m_psFrameMutex.unlock();
  180 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  181 + continue;
  182 + }
  183 + Frame* frame = m_psVideoFrames.front();
  184 + m_psVideoFrames.pop();
  185 + m_psFrameMutex.unlock();
  186 + if (frame != nullptr)
  187 + {
  188 + int nRet = m_psParser.AddData(frame->buf_, frame->len_);
  189 + if (nRet == -1)
  190 + {
  191 + LOG_INFO("m_psParser return -1--{}", m_deviceID);
  192 + }
  193 + else if (nRet == -2)
  194 + {
  195 + LOG_INFO("m_psParser return -2--{}", m_deviceID);
  196 + }
  197 + else if (nRet == -3)
  198 + {
  199 + LOG_INFO("m_psParser return -3--{}", m_deviceID);
  200 + }
  201 +
  202 + delete frame;
  203 + frame = nullptr;
  204 + }
  205 + }
  206 +
  207 + ClearPsVideoFrameList();
  208 +
  209 + m_hVodEndFunc(m_usrParam);
  210 +
  211 + LOG_INFO("[{}] exited.", m_deviceID);
  212 +
536 213 return 0;
537 214 }
  215 +
  216 +void RTPReceiver::SetDeviceID(string deviceID){
  217 + m_deviceID = deviceID;
  218 +}
  219 +
  220 +int RTPReceiver::GetPsFrameListSize()
  221 +{
  222 + std::lock_guard<std::mutex> l(m_psFrameMutex);
  223 + return m_psVideoFrames.size();
  224 +}
  225 +
  226 +void RTPReceiver::ClearPsVideoFrameList()
  227 +{
  228 + std::lock_guard<std::mutex> l(m_psFrameMutex);
  229 + while (!m_psVideoFrames.empty()) {
  230 + Frame* f = m_psVideoFrames.front();
  231 + delete f;
  232 + m_psVideoFrames.pop();
  233 + }
  234 + LOG_INFO("[{}] cleared ps video frame list!", m_deviceID);
  235 +}
  236 +
  237 +int RTPReceiver::ParsePacket(RTPPacket* packet){
  238 + do {
  239 +
  240 + if (0 == packet->GetPayloadType())
  241 + {
  242 + // 音频数据, 暂不处理
  243 + break;
  244 + }
  245 +
  246 + // 判断是否收到完整的帧(有些厂商打的marker标记不准, 所以只能看时间戳来判断)
  247 + uint32_t curPts = packet->GetTimestamp();
  248 + if (lastPts != 0 && curPts != lastPts) {
  249 + mark = 1;
  250 + }
  251 + lastPts = curPts;
  252 +
  253 + int payloadLen = packet->GetPayloadLength();
  254 + if (offset + payloadLen > kVideoFrameSize)
  255 + {
  256 + offset = 0, mark = 0;
  257 + break;
  258 + }
  259 +
  260 + LOG_DEBUG("[{}] ParsePacket GetPayloadLength", m_deviceID);
  261 +
  262 + if (mark)
  263 + {
  264 + BYTE* frameBuf = (BYTE*)malloc(sizeof(BYTE) * offset);
  265 + if (!frameBuf) {
  266 + offset = 0, mark = 0;
  267 + break;
  268 + }
  269 + memcpy(frameBuf, recvTmpBuf, offset);
  270 + if (!m_bPsExit){
  271 + std::lock_guard<std::mutex> l(m_psFrameMutex);
  272 + if (m_psVideoFrames.size() < 100)
  273 + {
  274 + LOG_DEBUG("[{}]ParsePacket push", m_deviceID);
  275 + m_psVideoFrames.push(new Frame(frameBuf, offset, false));
  276 + }
  277 + else {
  278 + free(frameBuf);
  279 + }
  280 + }
  281 + else{
  282 + //若此时解码线程已经退出,不再往m_psVideoFrames推送帧,且退出当前线程
  283 + free(frameBuf);
  284 + LOG_INFO("ParsePacket quit, device_id:{}", m_deviceID);
  285 + return 1;
  286 + }
  287 + offset = 0;
  288 + mark = 0;
  289 + }
  290 +
  291 + memcpy(recvTmpBuf + offset, packet->GetPayloadData(), payloadLen);
  292 + offset += payloadLen;
  293 + } while (0);
  294 +
  295 + return 0;
  296 +}
538 297 \ No newline at end of file
... ...
src/gb28181/RTPReceiver.h
1   -#ifndef _RTP_RECEIVER_H_
2   -#define _RTP_RECEIVER_H_
3   -
4   -
5   -#include "demuxer.h"
6   -#include "buffer.h"
7   -
8   -
9   -#include "rtpudpv4transmitter.h"
10   -#include "rtpipv4address.h"
11   -#include "rtpsessionparams.h"
12   -#include "rtpsession.h"
13   -#include "rtppacket.h"
14   -#include <queue>
15   -#include <iostream>
16   -#include <atomic>
17   -#include <thread>
18   -#include <string>
19   -#include <mutex>
20   -
21   -
22   -#define OUTTIME_RTCP 30*1000
23   -#define PAYLOAD 99
24   -#define PAYLOAD_PS 96
25   -#define PAYLOAD_H264 98
26   -#define PAYLOAD_MP4 97
27   -
28   -#define UDP_SIZE 1400
29   -#define MIN_PORT 10000
30   -#define MAX_PORT 60000
31   -#define RTP_MAX_PACKET_LEN 1450
32   -
33   -using namespace jrtplib;
34   -using namespace std;
35   -
36   -typedef unsigned char BYTE;
37   -
38   -/** 视频数据回调
39   -*
40   -* @param videoType [in] 视频类型 音频-0xC0、h264-0x1B、MPEG4-0x01、SVAC-0x80
41   -* @param data [in] 视频数据
42   -* @param len [in] 视频数据长度
43   -* @param isKey [in] 是否为关键帧
44   -* @param pts [in] 时间戳
45   -*/
46   -typedef void(*CallBack_Stream)(void* userdata, int videoType, char* data, int len, int isKey, uint64_t pts, uint64_t localPts);
47   -
48   -/** 录像回放完成回调消息通知
49   -*/
50   -typedef void(*CallBack_VodFileEnd)(void* userdata);
51   -
52   -int AllocRtpPort(void);
53   -
54   -class MyRTPSession : public RTPSession
55   -{
56   -public:
57   - MyRTPSession() {}
58   - virtual ~MyRTPSession() {}
59   -
60   -private:
61   - virtual void OnRTPPacket(RTPPacket* pack, const RTPTime& receiverTime, const RTPAddress* senderAddress)
62   - {
63   - AddDestination(*senderAddress);
64   - }
65   -
66   - virtual void OnRTCPCompoundPacket(RTCPCompoundPacket *pack, const RTPTime &receivetime,const RTPAddress *senderaddress)
67   - {
68   - //AddDestination(*senderaddress);
69   - //const char* name = "hi~";
70   - //SendRTCPAPPPacket(0, (const uint8_t*)name, "keeplive", 8);
71   -
72   - //printf("send rtcp app");
73   - }
74   -};
75   -
76   -// 标识帧, 注意buffer需要自己开辟和释放
77   -struct Frame {
78   - Frame() { buf_ = NULL; len_ = 0; }
79   - ~Frame() {
80   - if (buf_ != nullptr)
81   - {
82   - free(buf_);
83   - buf_ = nullptr;
84   - }
85   - }
86   - Frame(BYTE* buf, int len, bool key) : buf_(buf), len_(len), key_(key) {}
87   - BYTE* buf_;
88   - int len_;
89   - bool key_{};
90   -};
91   -
92   -class FrameToDecode
93   -{
94   -public:
95   - FrameToDecode()
96   - : m_SliceBuf(0)
97   - , m_localPts(0)
98   - , m_LastPTS(-1)
99   - , m_LastIsKeyFrame(0) {}
100   - FrameToDecode(unsigned char m_streamId)
101   - : m_SliceBuf(0)
102   - , m_localPts(0)
103   - , m_LastPTS(-1)
104   - , m_LastIsKeyFrame(0)
105   - , m_streamId (m_streamId) {}
106   -
107   - void operator=(FrameToDecode &temp)
108   - {
109   - m_SliceBuf = temp.m_SliceBuf;
110   - m_streamId = temp.m_streamId;
111   - m_localPts = temp.m_localPts;
112   - m_LastPTS = temp.m_LastPTS;
113   - m_LastIsKeyFrame = temp.m_LastIsKeyFrame;
114   - }
115   -
116   - CBuffer m_SliceBuf;
117   - unsigned char m_streamId{};
118   - uint64_t m_localPts;
119   - uint64_t m_LastPTS;
120   - bool m_LastIsKeyFrame;
121   -};
122   -
123   -
124   -class RTPReceiver
125   -{
126   - RTPReceiver(const RTPReceiver& other);
127   - RTPReceiver& operator= (const RTPReceiver& other);
128   -
129   -public:
130   - RTPReceiver();
131   - ~RTPReceiver();
132   -
133   - bool Open(uint16_t localPort);
134   - bool IsOpened() const;
135   - void Close();
136   -
137   - int GetPsFrameListSize();
138   - void ClearPsVideoFrameList();
139   -
140   - void OnPsDemux(unsigned char streamId, BYTE *data, int len, bool key, uint64_t pts, uint64_t localPts);
141   -
142   - void SetOutputCallback(CallBack_Stream cb, void* param);
143   - void SetVodEndCallback(CallBack_VodFileEnd cb, void* param);
144   - CallBack_VodFileEnd GetVodEndFunc(){ return m_hVodEndFunc; }
145   -
146   - void *GetUsrParam(){ return m_usrParam; }
147   - void SetDeviceID(string deviceID){this->m_deviceID = deviceID; }
148   -
149   -private:
150   - static int rtp_revc_thread_(void* param);
151   - static int ps_demuxer_thread_(void* param);
152   - static int ps_decode_thread_(void* param);
153   -
154   - int OnRtpRecv();
155   - int OnPsProcess();
156   - int OnDecodeProcess();
157   -
158   -private:
159   - std::thread m_rtpThread; // RTP接收线程
160   - std::thread m_psThread; // PS解包线程
161   -
162   - uint16_t m_localPort; // RTP接收端口
163   - MyRTPSession m_rtpSession; // RTP会话
164   - std::atomic_bool m_bRtpExit; // 标识RTP收包线程闭
165   - std::atomic_bool m_bPsExit; // 标识PS解包线程关闭
166   - std::queue<Frame*> m_psVideoFrames;
167   - mutex m_psFrameMutex;
168   -
169   - CMpeg2Demux m_psParser;
170   -
171   - void* m_usrParam;
172   - std::atomic_bool m_bOpened;
173   -
174   - CallBack_Stream m_h264DataFunc; // 视频流回调
175   - CallBack_VodFileEnd m_hVodEndFunc; // 录像流结束回调
176   -
177   - CBuffer m_SliceBuf;
178   - uint64_t m_LastPTS;
179   - bool m_LastIsKeyFrame;
180   - unsigned char m_LastStreamType;
181   - int64_t m_idleCount;
182   - int64_t m_noDataCount;//线程计数,用于打开流成功但是实际没流过来
183   -
184   - string m_deviceID;
185   - int64_t m_notToDecodCount{0};//线程计数,用来代表多长时间没有调用解码回调,针对大华相机
186   -};
187   -
188   -#endif // _RTP_RECEIVER_H_
  1 +#ifndef _RTP_RECEIVER_H_
  2 +#define _RTP_RECEIVER_H_
  3 +
  4 +#include "buffer.h"
  5 +#include "demuxer.h"
  6 +#include "rtppacket.h"
  7 +#include <stdint.h>
  8 +#include <mutex>
  9 +#include <queue>
  10 +#include <atomic>
  11 +#include <thread>
  12 +
  13 +typedef unsigned char BYTE;
  14 +
  15 +using namespace jrtplib;
  16 +using namespace std;
  17 +
  18 +/** 视频数据回调
  19 +*
  20 +* @param videoType [in] 视频类型 音频-0xC0、h264-0x1B、MPEG4-0x01、SVAC-0x80
  21 +* @param data [in] 视频数据
  22 +* @param len [in] 视频数据长度
  23 +* @param isKey [in] 是否为关键帧
  24 +* @param pts [in] 时间戳
  25 +*/
  26 +typedef void(*CallBack_Stream)(void* userdata, int videoType, char* data, int len, int isKey, uint64_t pts, uint64_t localPts);
  27 +
  28 +/** 录像回放完成回调消息通知
  29 +*/
  30 +typedef void(*CallBack_VodFileEnd)(void* userdata);
  31 +
  32 +/**
  33 + * 请求流
  34 +*/
  35 +typedef bool(*CallBack_Request_Stream)();
  36 +
  37 +// 标识帧, 注意buffer需要自己开辟和释放
  38 +struct Frame {
  39 + Frame() { buf_ = NULL; len_ = 0; }
  40 + ~Frame() {
  41 + if (buf_ != nullptr)
  42 + {
  43 + free(buf_);
  44 + buf_ = nullptr;
  45 + }
  46 + }
  47 + Frame(BYTE* buf, int len, bool key) : buf_(buf), len_(len), key_(key) {}
  48 + BYTE* buf_;
  49 + int len_;
  50 + bool key_{};
  51 +};
  52 +
  53 +class FrameToDecode
  54 +{
  55 +public:
  56 + FrameToDecode()
  57 + : m_SliceBuf(0)
  58 + , m_localPts(0)
  59 + , m_LastPTS(-1)
  60 + , m_LastIsKeyFrame(0) {}
  61 + FrameToDecode(unsigned char m_streamId)
  62 + : m_SliceBuf(0)
  63 + , m_localPts(0)
  64 + , m_LastPTS(-1)
  65 + , m_LastIsKeyFrame(0)
  66 + , m_streamId (m_streamId) {}
  67 +
  68 + void operator=(FrameToDecode &temp)
  69 + {
  70 + m_SliceBuf = temp.m_SliceBuf;
  71 + m_streamId = temp.m_streamId;
  72 + m_localPts = temp.m_localPts;
  73 + m_LastPTS = temp.m_LastPTS;
  74 + m_LastIsKeyFrame = temp.m_LastIsKeyFrame;
  75 + }
  76 +
  77 + CBuffer m_SliceBuf;
  78 + unsigned char m_streamId{};
  79 + uint64_t m_localPts;
  80 + uint64_t m_LastPTS;
  81 + bool m_LastIsKeyFrame;
  82 +};
  83 +
  84 +class RTPReceiver{
  85 +
  86 +public:
  87 + RTPReceiver();
  88 + ~RTPReceiver();
  89 +
  90 + virtual bool Open(uint16_t localPort) = 0;
  91 + virtual bool IsOpened() = 0;
  92 + virtual void Close() = 0;
  93 +
  94 + void SetVodEndCallback(CallBack_VodFileEnd cb, void* param);
  95 +
  96 + void SetOutputCallback(CallBack_Stream cb, void* param);
  97 +
  98 + void SetRequestStreamCallback(CallBack_Request_Stream cb);
  99 +
  100 + void SetDeviceID(string deviceID);
  101 +
  102 + int GetPsFrameListSize();
  103 +
  104 +public:
  105 + void OnPsDemux(unsigned char streamId, BYTE *data, int len, bool key, uint64_t pts, uint64_t localPts);
  106 + int OnPsProcess();
  107 + void ClearPsVideoFrameList();
  108 + int ParsePacket(RTPPacket* packet);
  109 +
  110 +public:
  111 + int InitPS();
  112 + void ClosePsThread();
  113 + void *GetUsrParam(){ return m_usrParam; }
  114 +
  115 +public:
  116 + CBuffer m_SliceBuf;
  117 + uint64_t m_LastPTS;
  118 + bool m_LastIsKeyFrame;
  119 + unsigned char m_LastStreamType;
  120 +
  121 + int64_t m_notToDecodCount{0};//线程计数,用来代表多长时间没有调用解码回调,针对大华相机
  122 +
  123 + void* m_usrParam;
  124 + CallBack_Stream m_h264DataFunc; // 视频流回调
  125 +
  126 + std::queue<Frame*> m_psVideoFrames;
  127 + mutex m_psFrameMutex;
  128 +
  129 + string m_deviceID;
  130 +
  131 + CMpeg2Demux m_psParser;
  132 + std::atomic_bool m_bPsExit; // 标识PS解包线程关闭
  133 +
  134 + uint32_t lastPts{0};
  135 + uint64_t last_recv_ts{0};
  136 + int offset{0};
  137 + int mark{0};
  138 + BYTE* recvTmpBuf{nullptr};
  139 +
  140 + std::thread* m_psThreadPtr; // PS解包线程
  141 +
  142 + CallBack_VodFileEnd m_hVodEndFunc; // 录像流结束回调
  143 + CallBack_Request_Stream m_callback_request_stream; //请求流回调
  144 +};
  145 +
  146 +#endif // _RTP_RECEIVER_H_
189 147 \ No newline at end of file
... ...
src/gb28181/RTPTcpReceiver.cpp 0 → 100644
  1 +#include"RTPTcpReceiver.h"
  2 +#include "../logger.hpp"
  3 +
  4 +
  5 +static long long get_cur_time() {
  6 +
  7 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  8 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  9 +
  10 + return tpMicro.time_since_epoch().count();
  11 +}
  12 +
  13 +// class TcpRTPSession : public RTPSession
  14 +// {
  15 +// public:
  16 +// void setReceiver(RTPTcpReceiver* r){
  17 +// tcpReceiver = r;
  18 +// }
  19 +
  20 +// protected:
  21 +// void OnValidatedRTPPacket(RTPSourceData *srcdat, RTPPacket *rtppack, bool isonprobation, bool *ispackethandled)
  22 +// {
  23 +// // printf("SSRC %x Got packet (%d bytes) in OnValidatedRTPPacket from source 0x%04x!\n", GetLocalSSRC(),
  24 +// // (int)rtppack->GetPayloadLength(), srcdat->GetSSRC());
  25 +
  26 +// LOG_DEBUG("SSRC {} Got packet ({} bytes) in OnValidatedRTPPacket from source {}}!\n", GetLocalSSRC(),
  27 +// (int)rtppack->GetPayloadLength(), srcdat->GetSSRC());
  28 +
  29 +// if(nullptr != tcpReceiver){
  30 +// tcpReceiver->ParsePacket(rtppack);
  31 +// }
  32 +// DeletePacket(rtppack);
  33 +// *ispackethandled = true;
  34 +// }
  35 +
  36 +// void OnRTCPSDESItem(RTPSourceData *srcdat, RTCPSDESPacket::ItemType t, const void *itemdata, size_t itemlength)
  37 +// {
  38 +// char msg[1024];
  39 +
  40 +// memset(msg, 0, sizeof(msg));
  41 +// if (itemlength >= sizeof(msg))
  42 +// itemlength = sizeof(msg)-1;
  43 +
  44 +// memcpy(msg, itemdata, itemlength);
  45 +// // printf("SSRC %x Received SDES item (%d): %s from SSRC %x\n", GetLocalSSRC(), (int)t, msg, srcdat->GetSSRC());
  46 +// LOG_DEBUG("SSRC {} Received SDES item ({}): {} from SSRC {}\n", GetLocalSSRC(), (int)t, msg, srcdat->GetSSRC());
  47 +// }
  48 +
  49 +// private:
  50 +// RTPTcpReceiver* tcpReceiver{nullptr};
  51 +// };
  52 +
  53 +class MyTCPTransmitter : public RTPTCPTransmitter
  54 +{
  55 +public:
  56 + void setReceiver(RTPTcpReceiver* r){
  57 + tcpReceiver = r;
  58 + }
  59 +
  60 +public:
  61 + MyTCPTransmitter() : RTPTCPTransmitter(0){ }
  62 +
  63 + void OnSendError(SocketType sock)
  64 + {
  65 + LOG_ERROR("Error sending over socket {}, removing destination", sock);
  66 + DeleteDestination(RTPTCPAddress(sock));
  67 + if(nullptr != tcpReceiver && !tcpReceiver->isClosing()){
  68 + tcpReceiver->RequestStream();
  69 + }
  70 + }
  71 +
  72 + void OnReceiveError(SocketType sock)
  73 + {
  74 + LOG_ERROR("Error receiving over socket {}, removing destination", sock);
  75 + DeleteDestination(RTPTCPAddress(sock));
  76 + }
  77 +
  78 +private:
  79 + RTPTcpReceiver* tcpReceiver{nullptr};
  80 +};
  81 +
  82 +static int rtp_revc_thread_(void* param)
  83 +{
  84 + if (!param)
  85 + {
  86 + return -1;
  87 + }
  88 +
  89 + RTPTcpReceiver* self = (RTPTcpReceiver*)param;
  90 + return self->OnRtpRecv();
  91 +}
  92 +
  93 +
  94 +RTPTcpReceiver::RTPTcpReceiver()
  95 +: m_bRtpExit(false)
  96 +, m_bOpened(false)
  97 +, m_idleCount(-1)
  98 +, m_noDataCount(-1)
  99 +, m_nListener(-1)
  100 +, m_bAccepted(false)
  101 +, m_bClosing(false)
  102 +{
  103 + m_rtpSessionPtr = new RTPSession();
  104 + m_pSessparams = new RTPSessionParams();
  105 + m_pTrans = new MyTCPTransmitter();
  106 +}
  107 +
  108 +RTPTcpReceiver::~RTPTcpReceiver(){
  109 + if (IsOpened())
  110 + Close();
  111 +
  112 + if(m_rtpSessionPtr != nullptr){
  113 + delete m_rtpSessionPtr;
  114 + m_rtpSessionPtr = nullptr;
  115 + }
  116 +
  117 + if(m_pSessparams != nullptr){
  118 + delete m_pSessparams;
  119 + m_pSessparams = nullptr;
  120 + }
  121 +
  122 + if(m_pTrans != nullptr){
  123 + delete m_pTrans;
  124 + m_pTrans = nullptr;
  125 + }
  126 +}
  127 +
  128 +bool RTPTcpReceiver::Open(uint16_t localPort){
  129 + if(0 != initSession(localPort)){
  130 + return false;
  131 + }
  132 +
  133 + m_bOpened = true;
  134 +
  135 + LOG_INFO("[{}] started.", m_deviceID);
  136 +
  137 + return true;
  138 +}
  139 +
  140 +bool RTPTcpReceiver::IsOpened(){
  141 + LOG_INFO("[{}] isopng:{} ", m_deviceID, m_bOpened);
  142 + return m_bOpened;
  143 +}
  144 +
  145 +void RTPTcpReceiver::Close(){
  146 +
  147 + m_bClosing = true;
  148 +
  149 + m_bAccepted = true;
  150 + m_bRtpExit = true;
  151 +
  152 + LOG_DEBUG("[{}] 1.", m_deviceID);
  153 +
  154 + // rtp接收线程退出
  155 + if (m_rtpThread.joinable())
  156 + {
  157 + m_rtpThread.join();
  158 + }
  159 +
  160 + LOG_DEBUG("[{}] 2.", m_deviceID);
  161 +
  162 + ClosePsThread();
  163 +
  164 + m_bOpened = false;
  165 +
  166 + LOG_INFO("[{}] closed.", m_deviceID);
  167 +}
  168 +
  169 +bool RTPTcpReceiver::isClosing(){
  170 + return m_bClosing;
  171 +}
  172 +
  173 +int RTPTcpReceiver::initSession(int localPort){
  174 + m_nListener = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
  175 + if (m_nListener < 0)
  176 + {
  177 + return -1;
  178 + }
  179 +
  180 + sockaddr_in serverAddr;
  181 + memset(&serverAddr, 0, sizeof(sockaddr_in));
  182 + serverAddr.sin_family = AF_INET;
  183 + serverAddr.sin_port = htons(localPort);
  184 + serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  185 + int nRet = bind(m_nListener, (sockaddr*)&serverAddr, sizeof(serverAddr));
  186 + if (nRet == -1)
  187 + {
  188 + LOG_ERROR("[{}] 绑定端口失败: {}", m_deviceID, localPort);
  189 + return -1;
  190 + }
  191 +
  192 + if (listen(m_nListener, 1) == -1)
  193 + {
  194 + LOG_ERROR("[{}] listen 失败", m_deviceID);
  195 + return -1;
  196 + }
  197 +
  198 + int nPackSize = 45678;
  199 + m_pSessparams->SetProbationType(RTPSources::NoProbation);
  200 + m_pSessparams->SetOwnTimestampUnit(90000.0 / 25.0);
  201 + m_pSessparams->SetMaximumPacketSize(nPackSize + 64);
  202 +
  203 + int status = m_pTrans->Init(false);
  204 + status = m_pTrans->Create(65535, NULL);
  205 + m_pTrans->setReceiver(this);
  206 +
  207 + status = m_rtpSessionPtr->Create(*m_pSessparams, m_pTrans);
  208 + if (status < 0)
  209 + {
  210 + LOG_ERROR("[{}] create session error!!", m_deviceID);
  211 + return -1;
  212 + }
  213 +
  214 + m_rtpThread = std::thread(rtp_revc_thread_, this);
  215 +
  216 + InitPS();
  217 +
  218 + bool bRet = RequestStream();
  219 + if (!bRet)
  220 + {
  221 + LOG_INFO("[{}] 请求流失败!", m_deviceID);
  222 + return -1;
  223 + }
  224 +
  225 + LOG_INFO("[{}] 初始化成功, congratulations !!!", m_deviceID);
  226 +
  227 + return 0;
  228 +}
  229 +
  230 +int RTPTcpReceiver::OnRtpRecv()
  231 +{
  232 + if(nullptr == m_rtpSessionPtr){
  233 + return -1;
  234 + }
  235 +
  236 + LOG_INFO("[{}] OnRtpRecv started, m_nListener : {}", m_deviceID, m_nListener);
  237 +
  238 + sockaddr_in clientAddr;
  239 + int nLen = sizeof(sockaddr_in);
  240 + SocketType nServer = -1;
  241 +
  242 + LOG_INFO("[{}] Poll started.", m_deviceID);
  243 + int status = -1;
  244 + while(!m_bRtpExit){
  245 + while(!m_bAccepted){
  246 + LOG_DEBUG("[{}] accepting...", m_deviceID);
  247 + nServer = accept(m_nListener, (sockaddr*)&clientAddr, (socklen_t * ) &nLen);
  248 + if (-1 == nServer){
  249 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  250 + continue;
  251 + }
  252 + m_rtpSessionPtr->AddDestination(RTPTCPAddress(nServer));
  253 + m_bAccepted = true;
  254 +
  255 + LOG_INFO("[{}] nServer={}", m_deviceID, nServer);
  256 + break;
  257 + }
  258 +
  259 + m_rtpSessionPtr->BeginDataAccess();
  260 + if (m_rtpSessionPtr->GotoFirstSourceWithData())
  261 + {
  262 + do
  263 + {
  264 + RTPPacket *pack;
  265 +
  266 + while ((pack = m_rtpSessionPtr->GetNextPacket()) != NULL)
  267 + {
  268 + LOG_DEBUG("[{}] time: {} ", m_deviceID, get_cur_time());
  269 + ParsePacket(pack);
  270 +
  271 + m_rtpSessionPtr->DeletePacket(pack);
  272 + }
  273 + } while (m_rtpSessionPtr->GotoNextSourceWithData());
  274 + }
  275 +
  276 + m_rtpSessionPtr->EndDataAccess();
  277 +
  278 + m_rtpSessionPtr->Poll();
  279 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  280 + }
  281 +
  282 + m_rtpSessionPtr->Destroy();
  283 +
  284 + if(nServer > 0){
  285 + close(nServer);
  286 + }
  287 + if(m_nListener > 0){
  288 + close(m_nListener);
  289 + }
  290 +
  291 + LOG_INFO("[{}] OnRtpRecv exited.", m_deviceID);
  292 +
  293 + return 0;
  294 +}
  295 +
  296 +bool RTPTcpReceiver::RequestStream(){
  297 + bool bConnect = m_callback_request_stream();
  298 + if(!bConnect){
  299 + Close();
  300 + return false;
  301 + }
  302 + m_bAccepted = false;
  303 +
  304 + return true;
  305 +}
0 306 \ No newline at end of file
... ...
src/gb28181/RTPTcpReceiver.h 0 → 100644
  1 +#ifndef _RTP_TCP_RECEIVER_H_
  2 +#define _RTP_TCP_RECEIVER_H_
  3 +
  4 +
  5 +#include "demuxer.h"
  6 +#include "buffer.h"
  7 +
  8 +#include "rtpsession.h"
  9 +#include "rtptcptransmitter.h"
  10 +#include "rtpipv4address.h"
  11 +#include "rtptcpaddress.h"
  12 +#include "rtpsessionparams.h"
  13 +#include "rtperrors.h"
  14 +#include "rtpsourcedata.h"
  15 +#include "rtpsocketutil.h"
  16 +#include <stdlib.h>
  17 +#include <stdio.h>
  18 +#include <iostream>
  19 +#include <string>
  20 +
  21 +#include <queue>
  22 +#include <atomic>
  23 +#include <thread>
  24 +#include <mutex>
  25 +
  26 +#include "RTPReceiver.h"
  27 +
  28 +
  29 +#define OUTTIME_RTCP 30*1000
  30 +#define PAYLOAD 99
  31 +#define PAYLOAD_PS 96
  32 +#define PAYLOAD_H264 98
  33 +#define PAYLOAD_MP4 97
  34 +
  35 +#define UDP_SIZE 1400
  36 +#define MIN_PORT 10000
  37 +#define MAX_PORT 60000
  38 +#define RTP_MAX_PACKET_LEN 1450
  39 +
  40 +using namespace jrtplib;
  41 +using namespace std;
  42 +
  43 +
  44 +
  45 +class TcpRTPSession;
  46 +class MyTCPTransmitter;
  47 +
  48 +class RTPTcpReceiver:public RTPReceiver
  49 +{
  50 +public:
  51 + RTPTcpReceiver();
  52 + ~RTPTcpReceiver();
  53 +
  54 + bool Open(uint16_t localPort);
  55 + bool IsOpened();
  56 + void Close();
  57 +
  58 +public:
  59 + int OnRtpRecv();
  60 + bool RequestStream();
  61 + bool isClosing();
  62 +
  63 +private:
  64 + int initSession(int localPort);
  65 +
  66 +private:
  67 +
  68 + std::atomic_bool m_bRtpExit; // 标识RTP收包线程闭
  69 +
  70 + std::atomic_bool m_bOpened;
  71 + std::atomic_bool m_bAccepted;
  72 + std::atomic_bool m_bClosing;
  73 +
  74 + int64_t m_idleCount;
  75 + int64_t m_noDataCount;//线程计数,用于打开流成功但是实际没流过来
  76 +
  77 + std::thread m_rtpThread; // RTP接收线程
  78 + SocketType m_nListener;
  79 +
  80 + RTPSession* m_rtpSessionPtr; // RTP会话
  81 + RTPSessionParams* m_pSessparams;
  82 + MyTCPTransmitter* m_pTrans;
  83 +};
  84 +
  85 +#endif // _RTP_TCP_RECEIVER_H_
... ...
src/gb28181/RTPUdpReceiver.cpp 0 → 100644
  1 +
  2 +#include "RTPUdpReceiver.h"
  3 +#include <iostream>
  4 +#include <time.h>
  5 +
  6 +#include <thread>
  7 +#include <chrono>
  8 +
  9 +#include "../logger.hpp"
  10 +
  11 +using namespace std;
  12 +
  13 +#define BUFFERSIZE_1024 4096
  14 +#define BUFFERSIZE_GAP 4096//5120 //1024*5
  15 +
  16 +namespace
  17 +{
  18 + const int kVideoFrameSize = BUFFERSIZE_1024*BUFFERSIZE_1024*5*2;
  19 + const int kRtpRecvBufferSize = BUFFERSIZE_1024*BUFFERSIZE_1024*2;
  20 + const uint16_t kInvalidPort = 0;
  21 +}; // namespace
  22 +
  23 +class UdpRTPSession : public RTPSession
  24 +{
  25 +public:
  26 + UdpRTPSession() {}
  27 + virtual ~UdpRTPSession() {}
  28 +
  29 +private:
  30 + virtual void OnRTPPacket(RTPPacket* pack, const RTPTime& receiverTime, const RTPAddress* senderAddress)
  31 + {
  32 + AddDestination(*senderAddress);
  33 + }
  34 +
  35 + virtual void OnRTCPCompoundPacket(RTCPCompoundPacket *pack, const RTPTime &receivetime,const RTPAddress *senderaddress)
  36 + {
  37 + //AddDestination(*senderaddress);
  38 + //const char* name = "hi~";
  39 + //SendRTCPAPPPacket(0, (const uint8_t*)name, "keeplive", 8);
  40 +
  41 + //printf("send rtcp app");
  42 + }
  43 +};
  44 +
  45 +
  46 +static long long get_cur_time() {
  47 +
  48 + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro
  49 + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  50 +
  51 + return tpMicro.time_since_epoch().count();
  52 +}
  53 +
  54 +static int rtp_revc_thread_(void* param)
  55 +{
  56 + if (!param)
  57 + {
  58 + return -1;
  59 + }
  60 +
  61 + RTPUdpReceiver* self = (RTPUdpReceiver*)param;
  62 + return self->OnRtpRecv();
  63 +}
  64 +
  65 +RTPUdpReceiver::RTPUdpReceiver()
  66 +: m_bRtpExit(false)
  67 +, m_bOpened(false)
  68 +, m_idleCount(-1)
  69 +,m_noDataCount(-1)
  70 +{
  71 + m_sessparamsPtr = new RTPSessionParams();
  72 + m_transparamsPtr = new RTPUDPv4TransmissionParams();
  73 + m_rtpSessionPtr = new UdpRTPSession();
  74 +}
  75 +
  76 +RTPUdpReceiver::~RTPUdpReceiver()
  77 +{
  78 + if (IsOpened())
  79 + Close();
  80 +
  81 + if(nullptr != m_sessparamsPtr){
  82 + delete m_sessparamsPtr;
  83 + m_sessparamsPtr = nullptr;
  84 + }
  85 +
  86 + if(nullptr != m_transparamsPtr){
  87 + delete m_transparamsPtr;
  88 + m_transparamsPtr = nullptr;
  89 + }
  90 +
  91 + if(nullptr != m_rtpSessionPtr){
  92 + delete m_rtpSessionPtr;
  93 + m_rtpSessionPtr = nullptr;
  94 + }
  95 +}
  96 +
  97 +bool RTPUdpReceiver::Open(uint16_t localPort)
  98 +{
  99 + m_sessparamsPtr->SetUsePollThread(true);
  100 + m_sessparamsPtr->SetMinimumRTCPTransmissionInterval(10);
  101 + m_sessparamsPtr->SetOwnTimestampUnit(1.0/90000.0);
  102 + m_sessparamsPtr->SetAcceptOwnPackets(true);
  103 +
  104 + m_transparamsPtr->SetPortbase(localPort);
  105 + m_transparamsPtr->SetRTPReceiveBuffer(kRtpRecvBufferSize);
  106 +
  107 + LOG_INFO("[{}] port: {}", m_deviceID, localPort);
  108 +
  109 + int err = m_rtpSessionPtr->Create(*m_sessparamsPtr, m_transparamsPtr);
  110 + if (err != 0)
  111 + {
  112 + LOG_ERROR("[{}] Create error: {}", m_deviceID, err);
  113 + return false;
  114 + }
  115 +
  116 + m_rtpThreadPtr = new std::thread(rtp_revc_thread_, this);
  117 + if (nullptr == m_rtpThreadPtr)
  118 + {
  119 + LOG_ERROR("[{}] Create m_rtpThreadPtr error", m_deviceID);
  120 + return false;
  121 + }
  122 +
  123 +
  124 + if (InitPS() != 0)
  125 + {
  126 + return false;
  127 + }
  128 +
  129 + m_bOpened = true;
  130 + LOG_INFO("[{}] Open ok", m_deviceID);
  131 +
  132 + return true;
  133 +}
  134 +
  135 +bool RTPUdpReceiver::IsOpened()
  136 +{
  137 + return m_bOpened;
  138 +}
  139 +
  140 +void RTPUdpReceiver::Close()
  141 +{
  142 + m_bRtpExit = true;
  143 +
  144 + // rtp接收线程退出
  145 + if (nullptr != m_rtpThreadPtr && m_rtpThreadPtr->joinable())
  146 + {
  147 + m_rtpThreadPtr->join();
  148 + delete m_rtpThreadPtr;
  149 + m_rtpThreadPtr = nullptr;
  150 + }
  151 + m_rtpSessionPtr->Destroy();
  152 +
  153 + ClosePsThread();
  154 +
  155 + m_bOpened = false;
  156 +
  157 + LOG_INFO("[{}] closed.", m_deviceID);
  158 +}
  159 +
  160 +// 收RTP包线程
  161 +int RTPUdpReceiver::OnRtpRecv()
  162 +{
  163 + if(nullptr == m_rtpSessionPtr){
  164 + return -1;
  165 + }
  166 +
  167 + LOG_INFO("[{}] OnRtpRecv started.", m_deviceID);
  168 + while (!m_bRtpExit)
  169 + {
  170 + //try
  171 + //{
  172 + m_rtpSessionPtr->Poll();
  173 + m_rtpSessionPtr->BeginDataAccess();
  174 +
  175 + if (m_rtpSessionPtr->GotoFirstSourceWithData())
  176 + {
  177 + LOG_INFO("OnRtpRecv GotoFirstSourceWithData --{}", m_deviceID);
  178 + last_recv_ts = get_cur_time();
  179 + m_idleCount = 0;
  180 + m_noDataCount = 0;
  181 + do
  182 + {
  183 + RTPPacket* packet;
  184 + while ((packet = m_rtpSessionPtr->GetNextPacket()) != NULL)
  185 + {
  186 + LOG_INFO("OnRtpRecv GetNextPacket --{}", m_deviceID);
  187 + int ret = ParsePacket(packet);
  188 + m_rtpSessionPtr->DeletePacket(packet);
  189 +
  190 + if(ret != 0){
  191 + m_bRtpExit = true;
  192 + }
  193 + }
  194 + } while (m_rtpSessionPtr->GotoNextSourceWithData());
  195 + }
  196 + //else {
  197 + // if (m_idleCount != -1)
  198 + // {
  199 + // ++m_idleCount;//流中断计数
  200 + // }
  201 + // if (m_noDataCount != 0)
  202 + // {
  203 + // --m_noDataCount;//没流计数
  204 + // }
  205 + // //if (m_idleCount > 3000) {
  206 + // // m_hVodEndFunc(m_usrParam);
  207 + // // m_idleCount = 0;
  208 + // //历史流结束的时候,也会出现超时,这个是正常的
  209 + // if(m_usrParam && ((VideoSession *)GetUsrParam())->video_type() == VideoType::ERECORD)
  210 + // {
  211 + // if (m_idleCount > 10000)
  212 + // {
  213 + // //这里要判断下历史流是否结束,如果未结束,就设置为流中断
  214 + // //由于record_stream_status这个函数返回值不准确,所以增加一个进度条大于80%
  215 + // if(record_stream_status(((VideoSession *)GetUsrParam())->streamHandle()))
  216 + // {
  217 + // LOG_INFO("************Record stream is finished**{}**m_progress = {}********", m_deviceID, ((VideoSession *)GetUsrParam())->progress());
  218 + // m_idleCount = -1;
  219 + // m_hVodEndFunc(m_usrParam);
  220 + // record_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
  221 + // ((VideoSession *)GetUsrParam())->streamHandle().clear();
  222 + // }
  223 + // else
  224 + // {
  225 + // //如果此时进度大于80% 算完成吧
  226 + // if(((VideoSession *)GetUsrParam())->progress() > 0.80)
  227 + // {
  228 + // LOG_INFO("************Record stream is overtime**{}**m_progress = {}********", m_deviceID, ((VideoSession *)GetUsrParam())->progress());
  229 +
  230 + // m_idleCount = 0;
  231 + // m_hVodEndFunc(m_usrParam);
  232 + // record_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
  233 + // ((VideoSession *)GetUsrParam())->streamHandle().clear();
  234 + // }
  235 + // else
  236 + // {
  237 + // m_idleCount = -1;
  238 + // //LOG_ERROR("************post ERROR_REALSTREAM_INTERRUPT to structure****{}********", m_deviceID);
  239 + // //发送流中断
  240 + // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Record time video streaming interruption!");
  241 + // }
  242 + // }
  243 + //
  244 + //
  245 + // }
  246 + //
  247 + // if (m_noDataCount < -200000)//任务开始时没收到流
  248 + // {
  249 + // //LOG_ERROR("************m_hVodEndFunc(m_usrParam)!!!m_hVodEndFunc(m_usrParam)********{}******", m_deviceID);
  250 + // m_noDataCount = -1;
  251 +
  252 + // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Record time video streaming interruption2!");
  253 + // //m_hVodEndFunc(m_usrParam);
  254 + // }
  255 + // }
  256 + // else//实时任务断流
  257 + // //if (m_usrParam && ((VideoSession *)GetUsrParam())->video_type() == VideoType::EREAL)
  258 + // {
  259 + //
  260 + // //每超过3000次,发送一次send_vedio_eof 时长大约1.5s
  261 + // //若是30000,时长大约 18s
  262 + // if(m_idleCount > 30000)
  263 + // {
  264 + // uint64_t cts = get_cur_time();
  265 + // float duration_not_recv = (cts - last_recv_ts) / 1000.0;
  266 + //
  267 + // //LOG_ERROR("************I haven't got stream from hik gateway exceed {}s,send eof********{}******", duration_not_recv, m_deviceID);
  268 + // m_idleCount = -1;
  269 +
  270 + // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Real time video streaming interruption!");
  271 + // }
  272 + //
  273 + // if (m_noDataCount < -200000)//任务开始时没收到流
  274 + // {
  275 + // //LOG_ERROR("************m_noDataCount < -200000********{}******", m_deviceID);
  276 + // m_noDataCount = -1;
  277 +
  278 + // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Real time video streaming interruption2!");
  279 + // }
  280 + //
  281 + // }
  282 + //}
  283 + //}
  284 + // catch (GeneralException2& e)
  285 + //{
  286 + // //LOG_ERROR("---> video streaming interruption!<---{}, error: {}", m_deviceID, e.err_msg());
  287 +
  288 + // byte_buffer bb(64);
  289 + // bb << VasCmd::VAS_CMD_REALSTREAM_INTERRUPT << e.err_msg();
  290 +
  291 + // if (m_usrParam)
  292 + // {
  293 + // if (((VideoSession *)GetUsrParam())->msgChan()->is_valid()) {
  294 + // try {
  295 + // ((VideoSession *)GetUsrParam())->msgChan()->send_msg(bb.data_ptr(), bb.data_size());
  296 + // }
  297 + // catch (GeneralException2& e) {
  298 + // //LOG_ERROR("[{}] send vas cmd VAS_CMD_REALSTREAM_INTERRUPT error: {}, {}", m_deviceID, e.err_code(), e.err_str());
  299 + // }
  300 + // }
  301 +
  302 + // //通知网关关闭句柄
  303 + // if(!((VideoSession *)GetUsrParam())->streamHandle().empty())
  304 + // {
  305 +
  306 + // LOG_INFO("---->Notify hisense gateway release handle = {} !<----{}", ((VideoSession *)GetUsrParam())->streamHandle().c_str(), m_deviceID);
  307 + // if (((VideoSession *)GetUsrParam())->video_type() == VideoType::EREAL)
  308 + // real_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
  309 + //
  310 + // if (((VideoSession *)GetUsrParam())->video_type() == VideoType::ERECORD)
  311 + // record_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
  312 + //
  313 + // //清理保活的句柄
  314 + // ((VideoSession *)GetUsrParam())->streamHandle().clear();
  315 + // }
  316 + // }
  317 + //
  318 + // bb.bset(0);
  319 + //
  320 + //}
  321 + m_rtpSessionPtr->EndDataAccess();
  322 +
  323 + std::this_thread::sleep_for(std::chrono::milliseconds(10));
  324 + }
  325 +
  326 + LOG_INFO("[{}] OnRtpRecv exited.", m_deviceID);
  327 +
  328 + return 0;
  329 +}
  330 +
  331 +
... ...
src/gb28181/RTPUdpReceiver.h 0 → 100644
  1 +#ifndef _RTP_UDP_RECEIVER_H_
  2 +#define _RTP_UDP_RECEIVER_H_
  3 +
  4 +#include "rtpudpv4transmitter.h"
  5 +#include "rtpipv4address.h"
  6 +#include "rtpsessionparams.h"
  7 +#include "rtpsession.h"
  8 +#include <queue>
  9 +#include <iostream>
  10 +#include <thread>
  11 +#include <string>
  12 +#include <mutex>
  13 +
  14 +#include "RTPReceiver.h"
  15 +
  16 +
  17 +#define OUTTIME_RTCP 30*1000
  18 +#define PAYLOAD 99
  19 +#define PAYLOAD_PS 96
  20 +#define PAYLOAD_H264 98
  21 +#define PAYLOAD_MP4 97
  22 +
  23 +#define UDP_SIZE 1400
  24 +#define MIN_PORT 10000
  25 +#define MAX_PORT 60000
  26 +#define RTP_MAX_PACKET_LEN 1450
  27 +
  28 +using namespace jrtplib;
  29 +using namespace std;
  30 +
  31 +
  32 +class UdpRTPSession;
  33 +
  34 +class RTPUdpReceiver: public RTPReceiver
  35 +{
  36 +public:
  37 + RTPUdpReceiver();
  38 + ~RTPUdpReceiver();
  39 +
  40 + virtual bool Open(uint16_t localPort);
  41 + virtual bool IsOpened() ;
  42 + virtual void Close() ;
  43 +
  44 +public:
  45 + int OnRtpRecv();
  46 +
  47 +private:
  48 + std::thread* m_rtpThreadPtr; // RTP接收线程
  49 +
  50 + UdpRTPSession* m_rtpSessionPtr; // RTP会话
  51 + std::atomic_bool m_bRtpExit; // 标识RTP收包线程闭
  52 +
  53 + std::atomic_bool m_bOpened;
  54 +
  55 + int64_t m_idleCount;
  56 + int64_t m_noDataCount;//线程计数,用于打开流成功但是实际没流过来
  57 +
  58 + RTPSessionParams* m_sessparamsPtr;
  59 + RTPUDPv4TransmissionParams* m_transparamsPtr;
  60 +};
  61 +
  62 +#endif // _RTP_UDP_RECEIVER_H_
... ...
src/gb28181/demuxer.h
... ... @@ -8,6 +8,9 @@
8 8 { CMpeg2Demux class. }
9 9 { }
10 10 {*******************************************************/
  11 +#ifndef _DEMUXER_H_
  12 +#define _DEMUXER_H_
  13 +
11 14 #include <stdint.h>
12 15 #include "buffer.h"
13 16  
... ... @@ -46,8 +49,8 @@
46 49 //typedef long long INT64;
47 50 //typedef unsigned long long UINT64;
48 51  
49   -typedef int ReceiveFunction(unsigned char streamType, void* data, int size, uint64_t pts, uint64_t localPts, bool bKey, void* userData);//es»Øµ÷
50   -typedef int ReceiveFunction2(unsigned int streamtype, void * Data, int Size, uint64_t pts, bool iskeyfram, void* userdata);//ps»Øµ÷
  52 +typedef int ReceiveFunction(unsigned char streamType, void* data, int size, uint64_t pts, uint64_t localPts, bool bKey, void* userData);//es�ص�
  53 +typedef int ReceiveFunction2(unsigned int streamtype, void * Data, int Size, uint64_t pts, bool iskeyfram, void* userdata);//ps�ص�
51 54  
52 55 static /*_inline*/ unsigned int asm_swap32(unsigned int x);
53 56 static /*_inline*/ unsigned short asm_swap16(unsigned short x);
... ... @@ -77,4 +80,6 @@ public:
77 80 int AddData(void * Data, int Size/*, DWORD pts*/);
78 81 void SetReceiveFunction(ReceiveFunction * func, void* userdata);
79 82 void SetReceiveFunction2(ReceiveFunction2 * func2, void* userdata2);
80   -};
81 83 \ No newline at end of file
  84 +};
  85 +
  86 +#endif // _DEMUXER_H_
82 87 \ No newline at end of file
... ...
src/main.cpp
... ... @@ -28,8 +28,6 @@
28 28 #define MIN_RTP_PORT 10000
29 29 #define MAX_RTP_PORT 60000
30 30  
31   -string data_home = "/mnt/f/fiss/data/";
32   -
33 31 // ȡ MIN_RTP_PORT(10000)~MAX_RTP_PORT(60000)֮�������˿�(ż���������������˿ڿ���)
34 32 int allocRtpPort() {
35 33  
... ... @@ -90,7 +88,7 @@ int sum2 = 0;
90 88  
91 89 cudaStream_t stream[2];
92 90  
93   -string data_home = "/mnt/data/cmhu/FFNvDecoder/data/";
  91 +string data_home = "/data/tongtu/";
94 92  
95 93  
96 94 #define checkCudaErrors(S) do {CUresult status; \
... ... @@ -173,7 +171,7 @@ void postDecoded(const void * userPtr, AVFrame * gpuFrame){
173 171 // cout << "decode successed ✿✿ヽ(°▽°)ノ✿ " << endl;
174 172  
175 173 int sum = sum1;
176   - if (decoder->getName() == "dec1")
  174 + if (decoder->getName() == "dec0")
177 175 {
178 176 sum1 ++ ;
179 177 sum = sum1;
... ... @@ -301,17 +299,17 @@ void decode_finished_cbk(const void* userPtr){
301 299 cout << "当前时间戳: " << get_cur_time() << endl;
302 300 }
303 301  
  302 +bool decode_request_stream_cbk(){
  303 + cout << "需在此请求流" << endl;
  304 + return true;
  305 +}
  306 +
304 307 // string test_uri = "rtmp://192.168.10.56:1935/objecteye/1";
305 308 // string test_uri = "/home/cmhu/data/output_800x480.mp4";
306 309 // string test_uri = "/home/cmhu/data/output_1920x1080.mp4";
307 310 // string test_uri = "rtsp://176.10.0.2:8554/stream";
308 311 // string test_uri = "/mnt/f/fiss/test_data/h265.mp4";
309 312 string test_uri = "rtsp://176.10.0.4:8554/stream";
310   -char* gpuid = "0";
311   -string test_uri = "ws://127.0.0.1:10000/sms/34020000002020000001/flv/hls/34020000001110005555_34020000001310005554.flv";
312   -// string test_uri = "rtsp://176.10.0.4:8554/stream";
313   -
314   -char* gpu_id = "0";
315 313  
316 314 void createDecode(int index, const char* gpu_id){
317 315 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
... ... @@ -323,7 +321,7 @@ void createDecode(int index, const char* gpu_id){
323 321 config.cfg.force_tcp = true;
324 322 config.dec_type = DECODER_TYPE_FFMPEG;
325 323  
326   - config.cfg.gpuid = gpuid;
  324 + config.cfg.gpuid = gpu_id;
327 325 // if (index % 2 == 0)
328 326 // {
329 327 // config.cfg.gpuid = "0";
... ... @@ -343,19 +341,20 @@ void createDecode(int index, const char* gpu_id){
343 341 pDecManager->startDecodeByName(config.name);
344 342 }
345 343  
346   -void createGB28181Decode(int index, char* gpuid){
  344 +void createGB28181Decode(int index, char* gpu_id, int port){
347 345 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
348 346 MgrDecConfig config;
349 347 config.name = "dec" + to_string(index);
350 348 config.cfg.uri = config.name;
351 349 config.cfg.post_decoded_cbk = postDecoded;
352 350 config.cfg.decode_finished_cbk = decode_finished_cbk;
  351 + config.cfg.request_stream_cbk = decode_request_stream_cbk;
353 352 config.cfg.force_tcp = true;
354 353  
355 354 config.dec_type = DECODER_TYPE_GB28181;
356   - config.cfg.port = 30012;//allocRtpPort();
  355 + config.cfg.port = port;//allocRtpPort();
357 356  
358   - config.cfg.gpuid = gpuid;
  357 + config.cfg.gpuid = gpu_id;
359 358  
360 359 AbstractDecoder* decoder = pDecManager->createDecoder(config);
361 360 if (!decoder)
... ... @@ -376,23 +375,14 @@ void logFF(void *, int level, const char *fmt, va_list ap)
376 375 int main(int argc, char* argv[]){
377 376  
378 377 test_uri = argv[1];
379   - gpuid = argv[2];
380   - cout << test_uri << " gpu_id:" << gpu_id << endl;
  378 + char* gpuid = argv[2];
  379 + int port = atoi(argv[3]);
  380 + cout << test_uri << " gpu_id:" << gpuid << " port:" << port << endl;
381 381  
382 382 // av_log_set_callback(&logFF);
383 383  
384 384 CheckCUDAProperty(atoi(gpuid));
385 385  
386   - FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
387   -
388   - // int count = 99;
389   - // for (size_t i = 0; i < count ; i++)
390   - // {
391   - // createDecode(i);
392   - // }
393   -
394   -
395   -
396 386 pthread_t m_decode_thread;
397 387 pthread_create(&m_decode_thread,0,
398 388 [](void* arg)
... ... @@ -400,7 +390,7 @@ int main(int argc, char* argv[]){
400 390 // cudaSetDevice(atoi(gpuid));
401 391 while (true)
402 392 {
403   - std::this_thread::sleep_for(std::chrono::milliseconds(5000));
  393 + std::this_thread::sleep_for(std::chrono::minutes(1));
404 394 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
405 395 int count = pDecManager->count();
406 396 cout << "当前时间:" << get_cur_time() << " 当前运行路数: " << pDecManager->count() << endl;
... ... @@ -410,8 +400,6 @@ int main(int argc, char* argv[]){
410 400 }
411 401 ,nullptr);
412 402  
413   -
414   -
415 403  
416 404 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
417 405 int i = 0;
... ... @@ -423,18 +411,17 @@ int main(int argc, char* argv[]){
423 411 {
424 412 break;
425 413 }
426   -
427 414  
428 415 switch (ch)
429 416 {
430 417 case 'f':
431 418 case 'F':
432   - createDecode(i, gpu_id);
  419 + createDecode(i, gpuid);
433 420 i++;
434 421 break;
435 422 case 'g':
436 423 case 'G':
437   - createGB28181Decode(i, gpu_id);
  424 + createGB28181Decode(i, gpuid, port);
438 425 i++;
439 426 break;
440 427 case 'r':
... ...