c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
1
2
3
4
5
6
7
8
9
|
#include "RTPUdpReceiver.h"
#include <iostream>
#include <time.h>
#include <thread>
#include <chrono>
#include "../common_header.h"
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
10
|
#include "../sip/SipServer.h"
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
using namespace std;
#define BUFFERSIZE_1024 4096
#define BUFFERSIZE_GAP 4096//5120 //1024*5
namespace
{
const int kVideoFrameSize = BUFFERSIZE_1024*BUFFERSIZE_1024*5*2;
const int kRtpRecvBufferSize = BUFFERSIZE_1024*BUFFERSIZE_1024*2;
const uint16_t kInvalidPort = 0;
}; // namespace
class UdpRTPSession : public RTPSession
{
public:
UdpRTPSession() {}
virtual ~UdpRTPSession() {}
private:
virtual void OnRTPPacket(RTPPacket* pack, const RTPTime& receiverTime, const RTPAddress* senderAddress)
{
AddDestination(*senderAddress);
}
virtual void OnRTCPCompoundPacket(RTCPCompoundPacket *pack, const RTPTime &receivetime,const RTPAddress *senderaddress)
{
//AddDestination(*senderaddress);
//const char* name = "hi~";
//SendRTCPAPPPacket(0, (const uint8_t*)name, "keeplive", 8);
//printf("send rtcp app");
}
};
static int rtp_revc_thread_(void* param)
{
if (!param)
{
return -1;
}
RTPUdpReceiver* self = (RTPUdpReceiver*)param;
return self->OnRtpRecv();
}
RTPUdpReceiver::RTPUdpReceiver()
: m_bRtpExit(false)
, m_bOpened(false)
, m_idleCount(-1)
,m_noDataCount(-1)
{
m_sessparamsPtr = new RTPSessionParams();
m_transparamsPtr = new RTPUDPv4TransmissionParams();
m_rtpSessionPtr = new UdpRTPSession();
}
RTPUdpReceiver::~RTPUdpReceiver()
{
if (IsOpened())
Close();
if(nullptr != m_sessparamsPtr){
delete m_sessparamsPtr;
m_sessparamsPtr = nullptr;
}
if(nullptr != m_transparamsPtr){
delete m_transparamsPtr;
m_transparamsPtr = nullptr;
}
if(nullptr != m_rtpSessionPtr){
delete m_rtpSessionPtr;
m_rtpSessionPtr = nullptr;
}
}
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
90
|
bool RTPUdpReceiver::Open(string channel_id)
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
91
|
{
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
92
93
94
95
96
97
98
99
|
m_SipChannelId = channel_id;
int rtpPort = allocRtpPort();
if (rtpPort < 0) {
return false;
}
m_rtp_port = rtpPort;
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
100
101
102
103
104
|
m_sessparamsPtr->SetUsePollThread(true);
m_sessparamsPtr->SetMinimumRTCPTransmissionInterval(10);
m_sessparamsPtr->SetOwnTimestampUnit(1.0/90000.0);
m_sessparamsPtr->SetAcceptOwnPackets(true);
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
105
|
m_transparamsPtr->SetPortbase(m_rtp_port);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
106
107
|
m_transparamsPtr->SetRTPReceiveBuffer(kRtpRecvBufferSize);
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
108
|
LOG_INFO("[{}] port: {}", m_SipChannelId, m_rtp_port);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
109
110
|
int err = m_rtpSessionPtr->Create(*m_sessparamsPtr, m_transparamsPtr);
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
111
112
|
if (err != 0) {
LOG_ERROR("[{}] Create error: {}", m_SipChannelId, err);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
113
114
115
116
|
return false;
}
m_rtpThreadPtr = new std::thread(rtp_revc_thread_, this);
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
117
118
|
if (nullptr == m_rtpThreadPtr) {
LOG_ERROR("[{}] Create m_rtpThreadPtr error", m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
119
120
|
return false;
}
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
121
|
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
122
|
if (InitPS() != 0) {
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
123
124
125
126
|
return false;
}
m_bOpened = true;
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
127
|
LOG_INFO("[{}] Open ok", m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
128
129
130
131
|
return true;
}
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
132
133
134
135
136
137
138
139
140
141
|
bool RTPUdpReceiver::RequestStream() {
SipServer* pServer = SipServer::getInstance();
int ret = -1;
if (pServer){
ret = pServer->RequestInvite_UDP(m_SipChannelId.c_str(), m_rtp_port);
}
return (ret > 0) ;
}
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
bool RTPUdpReceiver::IsOpened()
{
return m_bOpened;
}
void RTPUdpReceiver::Close()
{
m_bRtpExit = true;
// rtp接收线程退出
if (nullptr != m_rtpThreadPtr && m_rtpThreadPtr->joinable())
{
m_rtpThreadPtr->join();
delete m_rtpThreadPtr;
m_rtpThreadPtr = nullptr;
}
m_rtpSessionPtr->Destroy();
ClosePsThread();
m_bOpened = false;
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
164
|
LOG_INFO("[{}] closed.", m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
165
166
167
168
169
170
171
172
173
|
}
// 收RTP包线程
int RTPUdpReceiver::OnRtpRecv()
{
if(nullptr == m_rtpSessionPtr){
return -1;
}
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
174
|
LOG_INFO("[{}] OnRtpRecv started.", m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
175
176
177
178
179
180
181
182
183
|
while (!m_bRtpExit)
{
//try
//{
m_rtpSessionPtr->Poll();
m_rtpSessionPtr->BeginDataAccess();
if (m_rtpSessionPtr->GotoFirstSourceWithData())
{
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
184
|
// LOG_INFO("OnRtpRecv GotoFirstSourceWithData --{}", m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
185
186
187
188
189
190
191
192
|
last_recv_ts = UtilTools::get_cur_time_ms();
m_idleCount = 0;
m_noDataCount = 0;
do
{
RTPPacket* packet;
while ((packet = m_rtpSessionPtr->GetNextPacket()) != NULL)
{
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
193
|
// LOG_INFO("OnRtpRecv GetNextPacket --{}", m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
int ret = ParsePacket(packet);
m_rtpSessionPtr->DeletePacket(packet);
if(ret != 0){
m_bRtpExit = true;
}
}
} while (m_rtpSessionPtr->GotoNextSourceWithData());
}
//else {
// if (m_idleCount != -1)
// {
// ++m_idleCount;//流中断计数
// }
// if (m_noDataCount != 0)
// {
// --m_noDataCount;//没流计数
// }
// //if (m_idleCount > 3000) {
// // m_hVodEndFunc(m_usrParam);
// // m_idleCount = 0;
// //历史流结束的时候,也会出现超时,这个是正常的
// if(m_usrParam && ((VideoSession *)GetUsrParam())->video_type() == VideoType::ERECORD)
// {
// if (m_idleCount > 10000)
// {
// //这里要判断下历史流是否结束,如果未结束,就设置为流中断
// //由于record_stream_status这个函数返回值不准确,所以增加一个进度条大于80%
// if(record_stream_status(((VideoSession *)GetUsrParam())->streamHandle()))
// {
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
224
|
// LOG_INFO("************Record stream is finished**{}**m_progress = {}********", m_SipChannelId, ((VideoSession *)GetUsrParam())->progress());
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
225
226
227
228
229
230
231
232
233
234
|
// m_idleCount = -1;
// m_hVodEndFunc(m_usrParam);
// record_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
// ((VideoSession *)GetUsrParam())->streamHandle().clear();
// }
// else
// {
// //如果此时进度大于80% 算完成吧
// if(((VideoSession *)GetUsrParam())->progress() > 0.80)
// {
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
235
|
// LOG_INFO("************Record stream is overtime**{}**m_progress = {}********", m_SipChannelId, ((VideoSession *)GetUsrParam())->progress());
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
236
237
238
239
240
241
242
243
244
|
// m_idleCount = 0;
// m_hVodEndFunc(m_usrParam);
// record_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
// ((VideoSession *)GetUsrParam())->streamHandle().clear();
// }
// else
// {
// m_idleCount = -1;
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
245
|
// //LOG_ERROR("************post ERROR_REALSTREAM_INTERRUPT to structure****{}********", m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
246
247
248
249
250
251
252
253
254
255
|
// //发送流中断
// //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Record time video streaming interruption!");
// }
// }
//
//
// }
//
// if (m_noDataCount < -200000)//任务开始时没收到流
// {
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
256
|
// //LOG_ERROR("************m_hVodEndFunc(m_usrParam)!!!m_hVodEndFunc(m_usrParam)********{}******", m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
// m_noDataCount = -1;
// //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Record time video streaming interruption2!");
// //m_hVodEndFunc(m_usrParam);
// }
// }
// else//实时任务断流
// //if (m_usrParam && ((VideoSession *)GetUsrParam())->video_type() == VideoType::EREAL)
// {
//
// //每超过3000次,发送一次send_vedio_eof 时长大约1.5s
// //若是30000,时长大约 18s
// if(m_idleCount > 30000)
// {
// uint64_t cts = UtilTools::get_cur_time_ms();
// float duration_not_recv = (cts - last_recv_ts) / 1000.0;
//
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
274
|
// //LOG_ERROR("************I haven't got stream from hik gateway exceed {}s,send eof********{}******", duration_not_recv, m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
275
276
277
278
279
280
281
|
// m_idleCount = -1;
// //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Real time video streaming interruption!");
// }
//
// if (m_noDataCount < -200000)//任务开始时没收到流
// {
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
282
|
// //LOG_ERROR("************m_noDataCount < -200000********{}******", m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
283
284
285
286
287
288
289
290
291
292
|
// m_noDataCount = -1;
// //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Real time video streaming interruption2!");
// }
//
// }
//}
//}
// catch (GeneralException2& e)
//{
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
293
|
// //LOG_ERROR("---> video streaming interruption!<---{}, error: {}", m_SipChannelId, e.err_msg());
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
294
295
296
297
298
299
300
301
302
303
304
|
// byte_buffer bb(64);
// bb << VasCmd::VAS_CMD_REALSTREAM_INTERRUPT << e.err_msg();
// if (m_usrParam)
// {
// if (((VideoSession *)GetUsrParam())->msgChan()->is_valid()) {
// try {
// ((VideoSession *)GetUsrParam())->msgChan()->send_msg(bb.data_ptr(), bb.data_size());
// }
// catch (GeneralException2& e) {
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
305
|
// //LOG_ERROR("[{}] send vas cmd VAS_CMD_REALSTREAM_INTERRUPT error: {}, {}", m_SipChannelId, e.err_code(), e.err_str());
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
306
307
308
309
310
311
312
|
// }
// }
// //通知网关关闭句柄
// if(!((VideoSession *)GetUsrParam())->streamHandle().empty())
// {
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
313
|
// LOG_INFO("---->Notify hisense gateway release handle = {} !<----{}", ((VideoSession *)GetUsrParam())->streamHandle().c_str(), m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
|
// if (((VideoSession *)GetUsrParam())->video_type() == VideoType::EREAL)
// real_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
//
// if (((VideoSession *)GetUsrParam())->video_type() == VideoType::ERECORD)
// record_stream_stop(((VideoSession *)GetUsrParam())->streamHandle());
//
// //清理保活的句柄
// ((VideoSession *)GetUsrParam())->streamHandle().clear();
// }
// }
//
// bb.bset(0);
//
//}
m_rtpSessionPtr->EndDataAccess();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
|
74d1e6a8
Hu Chunming
完成gb28181大体的代码,未完...
|
333
|
LOG_INFO("[{}] OnRtpRecv exited.", m_SipChannelId);
|
c8285c8d
Hu Chunming
GB28181 UDP 有重大进展...
|
334
335
336
|
return 0;
}
|