Commit 5f4935b71a48800ef927d34c822852e4980eeae9
1 parent
662d1447
删除不用的文件
Showing
17 changed files
with
8 additions
and
3138 deletions
build/jrtplib/Makefile deleted
1 | -XX = g++ | ||
2 | - | ||
3 | - | ||
4 | -PROJECT_ROOT= /home/cmhu/vpt_ascend_arm | ||
5 | - | ||
6 | -DEPEND_DIR = $(PROJECT_ROOT)/bin | ||
7 | - | ||
8 | -TARGET= $(PROJECT_ROOT)/bin/test_rtp | ||
9 | - | ||
10 | -DEFS = -DLinux | ||
11 | - | ||
12 | - | ||
13 | -THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty | ||
14 | -SPDLOG_ROOT = $(THIRDPARTY_ROOT)/spdlog-1.9.2/release | ||
15 | - | ||
16 | -GB28181_ROOT = /home/cmhu/vpt_ascend_arm/3rdparty/gb28181_3rd | ||
17 | -JRTP_ROOT = $(GB28181_ROOT)/jrtp_export | ||
18 | - | ||
19 | - | ||
20 | -SRC_ROOT = /home/cmhu/vpt_ascend_arm/build/jrtplib | ||
21 | - | ||
22 | - | ||
23 | -INCLUDE=-I $(SPDLOG_ROOT)/include \ | ||
24 | - -I $(JRTP_ROOT)/jrtplib/include/jrtplib3 \ | ||
25 | - | ||
26 | - | ||
27 | -LIBS= -L $(SPDLOG_ROOT)/lib -l:libspdlog.a \ | ||
28 | - -L $(JRTP_ROOT)/jrtplib/lib -l:libjrtp.a \ | ||
29 | - | ||
30 | - | ||
31 | -CXXFLAGS= -g -O0 -fPIC $(INCLUDE) $(LIBS) $(DEFS) -lpthread -lrt -lz -fexceptions -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -fvisibility=hidden -Wall -Wno-deprecated -Wdeprecated-declarations -Wl,-Bsymbolic -ldl | ||
32 | - | ||
33 | - | ||
34 | - | ||
35 | -SRCS:=$(wildcard $(SRC_ROOT)/*.cpp) \ | ||
36 | - | ||
37 | -OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS))) | ||
38 | - | ||
39 | - | ||
40 | -$(TARGET):$(OBJS) | ||
41 | - rm -f $(TARGET) | ||
42 | - $(XX) -o $@ $^ $(CXXFLAGS) | ||
43 | -# rm -f *.o | ||
44 | - | ||
45 | -%.o:$(SRC_ROOT)/%.cpp | ||
46 | - $(XX) $(CXXFLAGS) -c $< | ||
47 | - | ||
48 | -clean: | ||
49 | - rm -f *.o $(TARGET) |
build/jrtplib/example2.cpp deleted
1 | -#include <stdio.h> | ||
2 | -#include <iostream> | ||
3 | -#include "rtpsessionparams.h" | ||
4 | -#include "rtpudpv4transmitter.h" | ||
5 | -#include "rtpsession.h" | ||
6 | -#include "rtppacket.h" | ||
7 | - | ||
8 | -#include <thread> | ||
9 | -#include <chrono> | ||
10 | - | ||
11 | -using namespace jrtplib; | ||
12 | - | ||
13 | - | ||
14 | - | ||
15 | -int main(void) | ||
16 | -{ | ||
17 | - int localPort = 30026; | ||
18 | - | ||
19 | - // RTPSession rtpSession; | ||
20 | - RTPSession* rtpSessionPtr = new RTPSession(); | ||
21 | - RTPSessionParams SessParams; | ||
22 | - RTPUDPv4TransmissionParams TransParams; | ||
23 | - SessParams.SetOwnTimestampUnit(1.0/8000.0); // 时间戳:1秒钟8000个样本 | ||
24 | - TransParams.SetPortbase(localPort); // 设置本地接收的端口号 | ||
25 | - int iErrNum = rtpSessionPtr->Create(SessParams, &TransParams); | ||
26 | - if (iErrNum < 0){ | ||
27 | - printf( "Create RTP Session error! Reason: %d!\r\n", iErrNum ); | ||
28 | - exit(-1); | ||
29 | - } | ||
30 | - printf( "Create RTP Session OK! Reason: %d!\r\n", iErrNum); | ||
31 | - | ||
32 | - | ||
33 | - bool m_bRtpExit = false; | ||
34 | - while (!m_bRtpExit) | ||
35 | - { | ||
36 | - | ||
37 | - rtpSessionPtr->Poll(); | ||
38 | - rtpSessionPtr->BeginDataAccess(); | ||
39 | - | ||
40 | - if (rtpSessionPtr->GotoFirstSourceWithData()) | ||
41 | - { | ||
42 | - do | ||
43 | - { | ||
44 | - RTPPacket* packet; | ||
45 | - while ((packet = rtpSessionPtr->GetNextPacket()) != NULL) | ||
46 | - { | ||
47 | - printf("got data \n"); | ||
48 | - | ||
49 | - rtpSessionPtr->DeletePacket(packet); | ||
50 | - } | ||
51 | - } while (rtpSessionPtr->GotoNextSourceWithData()); | ||
52 | - } | ||
53 | - | ||
54 | - rtpSessionPtr->EndDataAccess(); | ||
55 | - | ||
56 | - std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
57 | - } | ||
58 | - | ||
59 | - | ||
60 | - | ||
61 | - | ||
62 | - | ||
63 | - // // 开始接收数据 | ||
64 | - // rtpSessionPtr->BeginDataAccess(); | ||
65 | - // if (rtpSessionPtr->GotoFirstSource()) | ||
66 | - // { | ||
67 | - // do | ||
68 | - // { | ||
69 | - // RTPPacket *packet; | ||
70 | - // while ((packet = rtpSessionPtr->GetNextPacket()) != 0) | ||
71 | - // { | ||
72 | - | ||
73 | - // // 获取接收数据长度 | ||
74 | - // unsigned int recvSize = packet->GetPayloadLength(); | ||
75 | - // // 获取接收数据 | ||
76 | - // unsigned char * recvData = (unsigned char *)packet->GetPayloadData(); | ||
77 | - // std::cout << "Got packet with extended sequence number " | ||
78 | - // << packet->GetExtendedSequenceNumber() | ||
79 | - // << " from SSRC " << packet->GetSSRC() << "; recvSize " << recvSize << "[" << recvData << "]" | ||
80 | - // << std::endl; | ||
81 | - // // 删除数据包 | ||
82 | - // rtpSessionPtr->DeletePacket(packet); | ||
83 | - // } | ||
84 | - // } while (rtpSessionPtr->GotoNextSource()); | ||
85 | - // } | ||
86 | - // rtpSessionPtr->EndDataAccess(); | ||
87 | - | ||
88 | - // rtpSessionPtr->Destroy(); | ||
89 | - // rtpSessionPtr->AbortWait(); | ||
90 | - | ||
91 | - return 0; | ||
92 | -} |
src/decoder/gb28181/DvppGB28181Decoder.cpp0 deleted
1 | -//#include "LOG_manager.h" | ||
2 | -#include <iostream> | ||
3 | -#include "DvppGB28181Decoder.h" | ||
4 | - | ||
5 | -extern "C" { | ||
6 | - #include "libavutil/avstring.h" | ||
7 | - #include "libavformat/avformat.h" | ||
8 | - #include "libswscale/swscale.h" | ||
9 | -} | ||
10 | - | ||
11 | -#include"RTPTcpReceiver.h" | ||
12 | -#include"RTPUdpReceiver.h" | ||
13 | - | ||
14 | -#include "common_header.h" | ||
15 | - | ||
16 | -// #include "../nvdec/FFCuContextManager.h" | ||
17 | -// #include "../nvdec/GpuRgbMemory.hpp" | ||
18 | -// #include "../nvdec/cuda_kernels.h" | ||
19 | - | ||
20 | -#define ECLOSED 0 | ||
21 | -#define ECLOSING 1 | ||
22 | -#define ERUNNING 2 | ||
23 | -#define EPAUSE 3 | ||
24 | -#define EINITED 4 | ||
25 | - | ||
26 | -static void RTP_Stream_CallBack(void* userdata, int videoType, char* data, int len, int isKey, uint64_t pts, uint64_t localPts) | ||
27 | -{ | ||
28 | - DvppGB28181Decoder* decoder = (DvppGB28181Decoder*)userdata; | ||
29 | - decoder->stream_callback(videoType, data, len, isKey, pts, localPts); | ||
30 | -} | ||
31 | - | ||
32 | -static void RTP_Stream_End_CallBack(void* userdata) | ||
33 | -{ | ||
34 | - DvppGB28181Decoder* decoder = (DvppGB28181Decoder*)userdata; | ||
35 | - decoder->stream_end_callback(); | ||
36 | -} | ||
37 | - | ||
38 | -DvppGB28181Decoder::DvppGB28181Decoder() { | ||
39 | - m_frameSkip = 1; | ||
40 | - m_dec_keyframe = false; | ||
41 | - m_post_decode_thread = 0; | ||
42 | -} | ||
43 | - | ||
44 | -DvppGB28181Decoder::~DvppGB28181Decoder() | ||
45 | -{ | ||
46 | - close(); | ||
47 | - | ||
48 | - // if (m_pAVCodecCtx) { | ||
49 | - // avcodec_close(m_pAVCodecCtx); | ||
50 | - // avcodec_free_context(&m_pAVCodecCtx); | ||
51 | - // } | ||
52 | - | ||
53 | - m_dec_keyframe = false; | ||
54 | - | ||
55 | - LOG_INFO("destroy OK--{}", m_dec_name); | ||
56 | -} | ||
57 | - | ||
58 | -void DvppGB28181Decoder::close(){ | ||
59 | - | ||
60 | - if (m_status == ECLOSED) return; | ||
61 | - | ||
62 | - m_status = ECLOSING; | ||
63 | - | ||
64 | - LOG_DEBUG("real decode thread exit success 1--{}", m_dec_name); | ||
65 | - | ||
66 | - if(nullptr != m_rtpPtr){ | ||
67 | - if (m_rtpPtr->IsOpened()) { | ||
68 | - m_rtpPtr->Close(); | ||
69 | - LOG_DEBUG("real decode thread exit success 2--{}", m_dec_name); | ||
70 | - } | ||
71 | - | ||
72 | - delete m_rtpPtr; | ||
73 | - m_rtpPtr = nullptr; | ||
74 | - } | ||
75 | - | ||
76 | - // if (gpu_options) av_dict_free(&gpu_options); | ||
77 | - | ||
78 | - if (m_post_decode_thread != 0) { | ||
79 | - pthread_join(m_post_decode_thread,0); | ||
80 | - m_post_decode_thread = 0; | ||
81 | - } | ||
82 | - | ||
83 | - streamDecoder.Close(); | ||
84 | - | ||
85 | - m_status = ECLOSED; | ||
86 | - | ||
87 | - LOG_INFO("解码器关闭成功 --{}", m_dec_name); | ||
88 | -} | ||
89 | - | ||
90 | -bool DvppGB28181Decoder::init(FFDecConfig& cfg){ | ||
91 | - if(cfg.force_tcp){ | ||
92 | - m_rtpPtr = new RTPTcpReceiver(); | ||
93 | - }else{ | ||
94 | - m_rtpPtr = new RTPUdpReceiver(); | ||
95 | - } | ||
96 | - if(nullptr == m_rtpPtr){ | ||
97 | - return false; | ||
98 | - } | ||
99 | - | ||
100 | - m_dec_name = cfg.dec_name; | ||
101 | - m_frameSkip = cfg.skip_frame; | ||
102 | - if (m_frameSkip < 1) m_frameSkip = 1; | ||
103 | - | ||
104 | - m_gpuid = atoi(cfg.gpuid.c_str()); | ||
105 | - | ||
106 | - m_rtpPtr->SetOutputCallback(RTP_Stream_CallBack, this); | ||
107 | - m_rtpPtr->SetVodEndCallback(RTP_Stream_End_CallBack, this); | ||
108 | - | ||
109 | - post_decoded_cbk = cfg.post_decoded_cbk; | ||
110 | - decode_finished_cbk = cfg.decode_finished_cbk; | ||
111 | - | ||
112 | - if (!streamDecoder.Init(cfg)) { | ||
113 | - return false; | ||
114 | - } | ||
115 | - | ||
116 | - m_cfg = cfg; | ||
117 | - | ||
118 | - LOG_INFO("init - {} ", m_dec_name); | ||
119 | - | ||
120 | - m_status = EINITED; | ||
121 | - | ||
122 | - return true; | ||
123 | -} | ||
124 | - | ||
125 | -bool DvppGB28181Decoder::start() { | ||
126 | - | ||
127 | - m_status = ERUNNING; | ||
128 | - | ||
129 | - bool bRet = m_rtpPtr->Open(m_cfg.uri); | ||
130 | - if(bRet){ | ||
131 | - pthread_create(&m_post_decode_thread,0, | ||
132 | - [](void* arg) | ||
133 | - { | ||
134 | - DvppGB28181Decoder* a=(DvppGB28181Decoder*)arg; | ||
135 | - a->display_thread(); | ||
136 | - return (void*)0; | ||
137 | - } | ||
138 | - ,this); | ||
139 | - | ||
140 | - return true; | ||
141 | - } | ||
142 | - | ||
143 | - close(); | ||
144 | - | ||
145 | - LOG_ERROR("[{}] - rtp receiver open failed !", m_dec_name); | ||
146 | - | ||
147 | - return bRet; | ||
148 | -} | ||
149 | - | ||
150 | -void DvppGB28181Decoder::setDecKeyframe(bool bKeyframe){ | ||
151 | - m_dec_keyframe = bKeyframe; | ||
152 | -} | ||
153 | - | ||
154 | -void DvppGB28181Decoder::stream_callback(int videoType, char* data, int len, int isKey, uint64_t pts, uint64_t localPts) { | ||
155 | - if (m_status == EPAUSE) return; | ||
156 | - | ||
157 | - // 若设置为关键帧解码,非关键帧数据直接返回 | ||
158 | - if(m_dec_keyframe && !isKey) return; | ||
159 | - | ||
160 | - if (len <= 0) { | ||
161 | - if (data == nullptr && pts == -1) { | ||
162 | - LOG_INFO("frame callback EOF!"); | ||
163 | - post_decoded_cbk(m_postDecArg, nullptr); | ||
164 | - return ; | ||
165 | - } | ||
166 | - LOG_INFO("frame data is zero --{}", m_dec_name); | ||
167 | - return; | ||
168 | - } | ||
169 | - | ||
170 | - streamDecoder.SendData(videoType, data, len, isKey, pts); | ||
171 | - | ||
172 | - // AVPacket* pkt = av_packet_alloc(); | ||
173 | - // av_init_packet(pkt); | ||
174 | - | ||
175 | - // pkt->size = len; | ||
176 | - // pkt->data = (uint8_t*)data; | ||
177 | - | ||
178 | - // // ffmpeg 解码 | ||
179 | - // ff_decode(videoType, pkt); | ||
180 | - | ||
181 | - // av_packet_free(&pkt); | ||
182 | - // pkt = nullptr; | ||
183 | - | ||
184 | -} | ||
185 | - | ||
186 | -int DvppGB28181Decoder::ff_decode(int videoType, AVPacket* pkt) { | ||
187 | - | ||
188 | - // if (m_pAVCodecCtx == nullptr) { | ||
189 | - // LOG_INFO("frame data is zero --{}", m_dec_name); | ||
190 | - // if (VIDEO_TYPE_H264 == videoType) { | ||
191 | - // if (m_gpuid >= 0){ | ||
192 | - // m_pAVCodec = avcodec_find_decoder_by_name("h264_cuvid"); | ||
193 | - // } | ||
194 | - // else{ | ||
195 | - // m_pAVCodec = avcodec_find_decoder(AV_CODEC_ID_H264); | ||
196 | - // } | ||
197 | - // LOG_INFO("m_avCodecName is H264"); | ||
198 | - // } | ||
199 | - // else if (VIDEO_TYPE_H265 == videoType) | ||
200 | - // { | ||
201 | - // if (m_gpuid >= 0){ | ||
202 | - // m_pAVCodec = avcodec_find_decoder_by_name("hevc_cuvid"); | ||
203 | - // } | ||
204 | - // else{ | ||
205 | - // m_pAVCodec = avcodec_find_decoder(AV_CODEC_ID_H265); | ||
206 | - // } | ||
207 | - // LOG_INFO("m_avCodecName is H265"); | ||
208 | - // } | ||
209 | - // else{ | ||
210 | - // LOG_INFO("m_avCodecName is unknown, videoType is {}", videoType); | ||
211 | - // } | ||
212 | - | ||
213 | - // if (!m_pAVCodec) | ||
214 | - // { | ||
215 | - // LOG_ERROR("frameCallback frame decode error, ERROR_DECODER_NOT_FOUND"); | ||
216 | - // return; | ||
217 | - // } | ||
218 | - | ||
219 | - // m_pAVCodecCtx = avcodec_alloc_context3(m_pAVCodec); | ||
220 | - | ||
221 | - // if (m_gpuid >= 0) { | ||
222 | - // char gpui[8] = { 0 }; | ||
223 | - // sprintf(gpui, "%d", m_gpuid); | ||
224 | - // av_dict_set(&gpu_options, "gpu", gpui, 0); | ||
225 | - | ||
226 | - // m_pAVCodecCtx->get_format = get_hw_format; | ||
227 | - | ||
228 | - // FFCuContextManager* pCtxMgr = FFCuContextManager::getInstance(); | ||
229 | - // m_pAVCodecCtx->hw_device_ctx = av_buffer_ref(pCtxMgr->getCuCtx(gpui)); | ||
230 | - // if (nullptr == m_pAVCodecCtx->hw_device_ctx){ | ||
231 | - // // TODO 这里应该抛出错误 | ||
232 | - // return ; | ||
233 | - // } | ||
234 | - // } | ||
235 | - | ||
236 | - // if (avcodec_open2(m_pAVCodecCtx, m_pAVCodec, &gpu_options) < 0) | ||
237 | - // return; | ||
238 | - // } | ||
239 | - | ||
240 | - // //开始解码 | ||
241 | - // int ret = avcodec_send_packet(m_pAVCodecCtx, pkt); | ||
242 | - // if (ret < 0) { | ||
243 | - // //send_exception(RunMessageType::E2002, e_msg); | ||
244 | - // LOG_ERROR("Real stream视频解码失败,请检查视频设备{}: avcodec_send_packet failed. ret={}", m_dec_name, ret); | ||
245 | - // return; | ||
246 | - // } | ||
247 | - | ||
248 | - // if (frameW < 1) { | ||
249 | - // frameW = m_pAVCodecCtx->width; | ||
250 | - // frameH = m_pAVCodecCtx->height; | ||
251 | - // if (frameW <= 0 || frameH <= 0) { | ||
252 | - // LOG_ERROR("[{}] - frame W or H is error! ({},{})", m_dec_name, frameW, frameH); | ||
253 | - // return; | ||
254 | - // } | ||
255 | - // } | ||
256 | - | ||
257 | - // m_fps = av_q2d(m_pAVCodecCtx->framerate); | ||
258 | - | ||
259 | - // AVFrame* gpuFrame = av_frame_alloc(); | ||
260 | - // ret = avcodec_receive_frame(m_pAVCodecCtx, gpuFrame); | ||
261 | - // if ((ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) || ret < 0){ | ||
262 | - // LOG_ERROR("[{}] - Failed to receive frame: {}", m_dec_name, ret); | ||
263 | - // av_frame_free(&gpuFrame); | ||
264 | - // gpuFrame = nullptr; | ||
265 | - // return; | ||
266 | - // } | ||
267 | - | ||
268 | - // if (gpuFrame->width != frameW || gpuFrame->height != frameH){ | ||
269 | - // LOG_INFO("[{}] - AVFrame is inconsistent: width is {}, height is {}; original frameW is {}, frameH is {}--{}", m_dec_name, gpuFrame->width, gpuFrame->height, frameW, frameH); | ||
270 | - // av_frame_free(&gpuFrame); | ||
271 | - // gpuFrame = nullptr; | ||
272 | - // return; | ||
273 | - // } | ||
274 | - | ||
275 | - // av_frame_free(&gpuFrame); | ||
276 | - // gpuFrame = nullptr; | ||
277 | -} | ||
278 | - | ||
279 | -void DvppGB28181Decoder::display_thread(){ | ||
280 | - | ||
281 | - int index = 0; | ||
282 | - while (isRunning()) | ||
283 | - { | ||
284 | - auto mem = streamDecoder.GetFrame(); | ||
285 | - if(mem) { | ||
286 | - if ((m_frameSkip == 1 || index % m_frameSkip == 0) && post_decoded_cbk){ | ||
287 | - post_decoded_cbk(m_postDecArg, mem); | ||
288 | - } else { | ||
289 | - delete mem; | ||
290 | - mem = nullptr; | ||
291 | - } | ||
292 | - | ||
293 | - index++; | ||
294 | - if(index >= 100000){ | ||
295 | - index = 0; | ||
296 | - } | ||
297 | - } | ||
298 | - | ||
299 | - std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
300 | - } | ||
301 | - | ||
302 | - LOG_INFO("[{}] - display thread exited.", m_dec_name); | ||
303 | -} | ||
304 | - | ||
305 | -void DvppGB28181Decoder::stream_end_callback() | ||
306 | -{ | ||
307 | - LOG_INFO("[{}] - send_video_eof", m_dec_name); | ||
308 | - | ||
309 | - m_status = ECLOSING; | ||
310 | - | ||
311 | - decode_finished_cbk(m_finishedDecArg); | ||
312 | - | ||
313 | - return; | ||
314 | -} | ||
315 | - | ||
316 | -void DvppGB28181Decoder::setPostDecArg(const void* postDecArg){ | ||
317 | - m_postDecArg = postDecArg; | ||
318 | -} | ||
319 | - | ||
320 | -void DvppGB28181Decoder::setFinishedDecArg(const void* finishedDecArg){ | ||
321 | - m_finishedDecArg = finishedDecArg; | ||
322 | -} | ||
323 | - | ||
324 | -void DvppGB28181Decoder::pause() { | ||
325 | - m_status = EPAUSE; | ||
326 | - LOG_INFO("[{}] - pause", m_dec_name); | ||
327 | -} | ||
328 | - | ||
329 | -void DvppGB28181Decoder::resume() { | ||
330 | - m_status = ERUNNING; | ||
331 | - LOG_INFO("[{}] - resume", m_dec_name); | ||
332 | -} | ||
333 | - | ||
334 | -bool DvppGB28181Decoder::isRunning(){ | ||
335 | - if (m_status == ECLOSED || m_status == ECLOSING){ | ||
336 | - return false; | ||
337 | - } | ||
338 | - return true; | ||
339 | -} | ||
340 | - | ||
341 | -bool DvppGB28181Decoder::isFinished(){ | ||
342 | - if (m_status == ECLOSED || m_status == ECLOSING){ | ||
343 | - return true; | ||
344 | - } | ||
345 | - return false; | ||
346 | -} | ||
347 | - | ||
348 | -bool DvppGB28181Decoder::isPausing(){ | ||
349 | - if (m_status == EPAUSE){ | ||
350 | - return true; | ||
351 | - } | ||
352 | - return false; | ||
353 | -} | ||
354 | - | ||
355 | -bool DvppGB28181Decoder::getResolution( int &width, int &height ){ | ||
356 | - width = frameW; | ||
357 | - height = frameH; | ||
358 | - return true; | ||
359 | -} | ||
360 | - | ||
361 | -bool DvppGB28181Decoder::getOutResolution( int &width, int &height ) { | ||
362 | - width = frameW; | ||
363 | - height = frameH; | ||
364 | - return true; | ||
365 | -} | ||
366 | - | ||
367 | -float DvppGB28181Decoder::fps() { | ||
368 | - return m_fps; | ||
369 | -} | ||
370 | - | ||
371 | -bool DvppGB28181Decoder::isSurport(FFDecConfig& cfg){ | ||
372 | - // 由于是否支持需要在拿到数据后才能断定,无法事先判断,所以这个地方默认返回true | ||
373 | - return true; | ||
374 | -} | ||
375 | - | ||
376 | -DeviceMemory* DvppGB28181Decoder::snapshot() { | ||
377 | - | ||
378 | - DeviceMemory* snapshot_mem = nullptr; | ||
379 | - int loop_times = 0; | ||
380 | - while (isRunning()) { | ||
381 | - snapshot_mem = streamDecoder.GetFrame(); | ||
382 | - if (snapshot_mem) { | ||
383 | - break; | ||
384 | - } | ||
385 | - | ||
386 | - loop_times++; | ||
387 | - if(loop_times > 100) { | ||
388 | - // 1s都没截取到图,退出 | ||
389 | - break; | ||
390 | - } | ||
391 | - std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
392 | - } | ||
393 | - | ||
394 | - return snapshot_mem; | ||
395 | -} | ||
396 | - | ||
397 | -void DvppGB28181Decoder::doRecode(RecoderInfo& recoderInfo) { | ||
398 | - return streamDecoder.doRecode(recoderInfo); | ||
399 | -} | ||
400 | - | ||
401 | -void DvppGB28181Decoder::set_mq_callback(std::function<bool(const char *msg)> mq_publish) { | ||
402 | - streamDecoder.set_mq_callback(mq_publish); | ||
403 | -} | ||
404 | \ No newline at end of file | 0 | \ No newline at end of file |
src/decoder/gb28181/DvppGB28181Decoder.h deleted
1 | -#ifndef _GB28181_DECODER_H_ | ||
2 | -#define _GB28181_DECODER_H_ | ||
3 | - | ||
4 | -#include <atomic> | ||
5 | -#include <mutex> | ||
6 | - | ||
7 | -#include "RTPReceiver.h" | ||
8 | -#include "../dvpp/DvppStreamDecoder.h" | ||
9 | - | ||
10 | -#include "common_header.h" | ||
11 | -#include "../interface/AbstractDecoder.h" | ||
12 | - | ||
13 | - | ||
14 | -struct AVFormatContext; | ||
15 | -struct AVCodecContext; | ||
16 | -struct AVCodec; | ||
17 | -struct AVFrame; | ||
18 | -struct AVDictionary; | ||
19 | -struct AVPacket; | ||
20 | - | ||
21 | -using namespace std; | ||
22 | - | ||
23 | -class DvppGB28181Decoder: public AbstractDecoder | ||
24 | -{ | ||
25 | -public: | ||
26 | - DvppGB28181Decoder(); | ||
27 | - ~DvppGB28181Decoder(); | ||
28 | - | ||
29 | - bool init(FFDecConfig& cfg); | ||
30 | - void close(); | ||
31 | - bool start(); | ||
32 | - void pause(); | ||
33 | - void resume(); | ||
34 | - | ||
35 | - void setDecKeyframe(bool bKeyframe); | ||
36 | - | ||
37 | - bool isRunning(); | ||
38 | - bool isFinished(); | ||
39 | - bool isPausing(); | ||
40 | - bool getResolution( int &width, int &height ); | ||
41 | - bool getOutResolution( int &width, int &height ); | ||
42 | - | ||
43 | - bool isSurport(FFDecConfig& cfg); | ||
44 | - | ||
45 | - float fps(); | ||
46 | - | ||
47 | - DECODER_TYPE getDecoderType(){ return DECODER_TYPE_DVPP_GB28181; } | ||
48 | - | ||
49 | - DeviceMemory* snapshot(); | ||
50 | - | ||
51 | - void setName(string nm){ | ||
52 | - m_dec_name = nm; | ||
53 | - } | ||
54 | - | ||
55 | - string getName(){ | ||
56 | - return m_dec_name; | ||
57 | - } | ||
58 | - | ||
59 | - void setPostDecArg(const void* postDecArg); | ||
60 | - void setFinishedDecArg(const void* finishedDecArg); | ||
61 | - | ||
62 | - void doRecode(RecoderInfo& recoderInfo); | ||
63 | - | ||
64 | - void set_mq_callback(std::function<bool(const char *msg)> mq_publish); | ||
65 | - | ||
66 | -public: | ||
67 | - void stream_callback(int videoType, char* data, int len, int isKey, uint64_t pts, uint64_t localPts); | ||
68 | - void stream_end_callback(); | ||
69 | - void display_thread(); | ||
70 | - | ||
71 | -private: | ||
72 | - int ff_decode(int videoType, AVPacket* pkt); | ||
73 | - | ||
74 | -private: | ||
75 | - string m_dec_name; // 必须为28181编码 | ||
76 | - FFDecConfig m_cfg; | ||
77 | - | ||
78 | - RTPReceiver* m_rtpPtr {nullptr}; | ||
79 | - | ||
80 | - uint64_t m_startPts {}; | ||
81 | - uint64_t m_lastPts {}; //上一次pts的值 | ||
82 | - uint64_t m_curPts {}; //当前的pts值 | ||
83 | - uint64_t m_diffPts {}; | ||
84 | - | ||
85 | - uint32_t frameW {}, frameH {}; | ||
86 | - float m_fps {}; | ||
87 | - int m_frameSkip {}; | ||
88 | - | ||
89 | - int log_count {}; | ||
90 | - | ||
91 | - std::atomic_int m_status {}; | ||
92 | - | ||
93 | - pthread_t m_post_decode_thread; | ||
94 | - const void * m_postDecArg; | ||
95 | - POST_DECODE_CALLBACK post_decoded_cbk; // 解码数据回调接口 | ||
96 | - | ||
97 | - const void * m_finishedDecArg; | ||
98 | - DECODE_FINISHED_CALLBACK decode_finished_cbk; | ||
99 | - | ||
100 | - queue<AVFrame*> mFrameQueue; | ||
101 | - mutex m_queue_mutex; | ||
102 | - mutex m_snapshot_mutex; | ||
103 | - | ||
104 | - bool m_dec_keyframe; | ||
105 | - | ||
106 | - DvppStreamDecoder streamDecoder; | ||
107 | - | ||
108 | - int m_gpuid {0}; | ||
109 | -}; | ||
110 | - | ||
111 | -#endif // _GB28181_DECODER_H_ |
src/decoder/gb28181/DvppGB28181Decoder2.cpp
@@ -46,22 +46,20 @@ void DvppGB28181Decoder2::close(){ | @@ -46,22 +46,20 @@ void DvppGB28181Decoder2::close(){ | ||
46 | LOG_DEBUG("real decode thread exit success 1--{}", m_dec_name); | 46 | LOG_DEBUG("real decode thread exit success 1--{}", m_dec_name); |
47 | 47 | ||
48 | if(nullptr != m_rtpPtr){ | 48 | if(nullptr != m_rtpPtr){ |
49 | - if (m_rtpPtr->IsOpened()) { | ||
50 | - m_rtpPtr->Close(); | ||
51 | - LOG_DEBUG("real decode thread exit success 2--{}", m_dec_name); | ||
52 | - } | 49 | + m_rtpPtr->Close(); |
50 | + LOG_DEBUG("real decode thread exit success 2--{}", m_dec_name); | ||
53 | 51 | ||
54 | delete m_rtpPtr; | 52 | delete m_rtpPtr; |
55 | m_rtpPtr = nullptr; | 53 | m_rtpPtr = nullptr; |
56 | } | 54 | } |
57 | 55 | ||
56 | + rtpDecoder.Close(); | ||
57 | + | ||
58 | if (m_post_decode_thread != 0) { | 58 | if (m_post_decode_thread != 0) { |
59 | pthread_join(m_post_decode_thread,0); | 59 | pthread_join(m_post_decode_thread,0); |
60 | m_post_decode_thread = 0; | 60 | m_post_decode_thread = 0; |
61 | } | 61 | } |
62 | 62 | ||
63 | - rtpDecoder.Close(); | ||
64 | - | ||
65 | m_status = ECLOSED; | 63 | m_status = ECLOSED; |
66 | 64 | ||
67 | LOG_INFO("解码器关闭成功 --{}", m_dec_name); | 65 | LOG_INFO("解码器关闭成功 --{}", m_dec_name); |
@@ -90,6 +88,8 @@ bool DvppGB28181Decoder2::init(FFDecConfig& cfg){ | @@ -90,6 +88,8 @@ bool DvppGB28181Decoder2::init(FFDecConfig& cfg){ | ||
90 | return false; | 88 | return false; |
91 | } | 89 | } |
92 | 90 | ||
91 | + rtpDecoder.SetFinishedCallback(RTP_Stream_End_CallBack, this); | ||
92 | + | ||
93 | m_cfg = cfg; | 93 | m_cfg = cfg; |
94 | 94 | ||
95 | LOG_INFO("init - {} ", m_dec_name); | 95 | LOG_INFO("init - {} ", m_dec_name); |
@@ -160,6 +160,8 @@ void DvppGB28181Decoder2::display_thread(){ | @@ -160,6 +160,8 @@ void DvppGB28181Decoder2::display_thread(){ | ||
160 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); | 160 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
161 | } | 161 | } |
162 | 162 | ||
163 | + decode_finished_cbk(m_finishedDecArg); | ||
164 | + | ||
163 | LOG_INFO("[{}] - display thread exited.", m_dec_name); | 165 | LOG_INFO("[{}] - display thread exited.", m_dec_name); |
164 | } | 166 | } |
165 | 167 | ||
@@ -169,8 +171,6 @@ void DvppGB28181Decoder2::stream_end_callback() | @@ -169,8 +171,6 @@ void DvppGB28181Decoder2::stream_end_callback() | ||
169 | 171 | ||
170 | m_status = ECLOSING; | 172 | m_status = ECLOSING; |
171 | 173 | ||
172 | - decode_finished_cbk(m_finishedDecArg); | ||
173 | - | ||
174 | return; | 174 | return; |
175 | } | 175 | } |
176 | 176 |
src/decoder/gb28181/FFDecoder.cpp0 deleted
1 | -#include "FFDecoder.h" | ||
2 | - | ||
3 | -#include "./rtp/demuxer.h" | ||
4 | - | ||
5 | -#include "common_header.h" | ||
6 | -#include "../nvdec/FFCuContextManager.h" | ||
7 | - | ||
8 | -static AVPixelFormat get_hw_format(AVCodecContext *avctx, const AVPixelFormat *pix_fmts){ | ||
9 | - return AV_PIX_FMT_CUDA; | ||
10 | -} | ||
11 | - | ||
12 | -FFDecoder::FFDecoder(/* args */) | ||
13 | -{ | ||
14 | -} | ||
15 | - | ||
16 | -FFDecoder::~FFDecoder() | ||
17 | -{ | ||
18 | -} | ||
19 | - | ||
20 | -FrameData* FFDecoder::Decode(int videoType, char* data, int len, int isKey, uint64_t pts) { | ||
21 | - | ||
22 | - AVPacket* pkt = av_packet_alloc(); | ||
23 | - av_init_packet(pkt); | ||
24 | - | ||
25 | - pkt->size = len; | ||
26 | - pkt->data = (uint8_t*)data; | ||
27 | - | ||
28 | - // ffmpeg 解码 | ||
29 | - FrameData* frame_data = ff_decode(videoType, pkt); | ||
30 | - | ||
31 | - av_packet_free(&pkt); | ||
32 | - pkt = nullptr; | ||
33 | - | ||
34 | - frame_data.bKeyframe = (isKey != 0); | ||
35 | - frame_data.pts = pts; | ||
36 | - | ||
37 | - return frame_data; | ||
38 | -} | ||
39 | - | ||
40 | -FrameData* FFDecoder::ff_decode(int videoType, AVPacket* pkt) { | ||
41 | - if (m_pAVCodecCtx == nullptr) { | ||
42 | - LOG_INFO("frame data is zero --{}", m_dec_name); | ||
43 | - if (VIDEO_TYPE_H264 == videoType) { | ||
44 | - if (m_devid >= 0){ | ||
45 | - m_pAVCodec = avcodec_find_decoder_by_name("h264_cuvid"); | ||
46 | - } | ||
47 | - else{ | ||
48 | - m_pAVCodec = avcodec_find_decoder(AV_CODEC_ID_H264); | ||
49 | - } | ||
50 | - LOG_INFO("m_avCodecName is H264"); | ||
51 | - } | ||
52 | - else if (VIDEO_TYPE_H265 == videoType) | ||
53 | - { | ||
54 | - if (m_devid >= 0){ | ||
55 | - m_pAVCodec = avcodec_find_decoder_by_name("hevc_cuvid"); | ||
56 | - } | ||
57 | - else{ | ||
58 | - m_pAVCodec = avcodec_find_decoder(AV_CODEC_ID_H265); | ||
59 | - } | ||
60 | - LOG_INFO("m_avCodecName is H265"); | ||
61 | - } | ||
62 | - else{ | ||
63 | - LOG_INFO("m_avCodecName is unknown, videoType is {}", videoType); | ||
64 | - } | ||
65 | - | ||
66 | - if (!m_pAVCodec) | ||
67 | - { | ||
68 | - LOG_ERROR("frameCallback frame decode error, ERROR_DECODER_NOT_FOUND"); | ||
69 | - return nullptr;return; | ||
70 | - } | ||
71 | - | ||
72 | - m_pAVCodecCtx = avcodec_alloc_context3(m_pAVCodec); | ||
73 | - | ||
74 | - if (m_devid >= 0) { | ||
75 | - char gpui[8] = { 0 }; | ||
76 | - sprintf(gpui, "%d", m_devid); | ||
77 | - av_dict_set(&gpu_options, "gpu", gpui, 0); | ||
78 | - | ||
79 | - m_pAVCodecCtx->get_format = get_hw_format; | ||
80 | - | ||
81 | - FFCuContextManager* pCtxMgr = FFCuContextManager::getInstance(); | ||
82 | - m_pAVCodecCtx->hw_device_ctx = av_buffer_ref(pCtxMgr->getCuCtx(gpui)); | ||
83 | - if (nullptr == m_pAVCodecCtx->hw_device_ctx){ | ||
84 | - // TODO 这里应该抛出错误 | ||
85 | - return nullptr; | ||
86 | - } | ||
87 | - } | ||
88 | - | ||
89 | - if (avcodec_open2(m_pAVCodecCtx, m_pAVCodec, &gpu_options) < 0) | ||
90 | - return nullptr; | ||
91 | - } | ||
92 | - | ||
93 | - //开始解码 | ||
94 | - int ret = avcodec_send_packet(m_pAVCodecCtx, pkt); | ||
95 | - if (ret < 0) { | ||
96 | - //send_exception(RunMessageType::E2002, e_msg); | ||
97 | - LOG_ERROR("Real stream视频解码失败,请检查视频设备{}: avcodec_send_packet failed. ret={}", m_dec_name, ret); | ||
98 | - return; | ||
99 | - } | ||
100 | - | ||
101 | - if (frameW < 1) { | ||
102 | - frameW = m_pAVCodecCtx->width; | ||
103 | - frameH = m_pAVCodecCtx->height; | ||
104 | - if (frameW <= 0 || frameH <= 0) { | ||
105 | - LOG_ERROR("[{}] frame W or H is error! ({},{})", m_dec_name, frameW, frameH); | ||
106 | - return nullptr; | ||
107 | - } | ||
108 | - } | ||
109 | - // m_fps = m_pAVCodecCtx->pkt_timebase.den == 0 ? 25.0 : av_q2d(m_pAVCodecCtx->pkt_timebase); | ||
110 | - m_fps = av_q2d(m_pAVCodecCtx->framerate); | ||
111 | - // LOG_DEBUG("frameW {}--frameH {}", frameW, frameH); | ||
112 | - | ||
113 | - FrameData* pData = new FrameData(); | ||
114 | - ret = avcodec_receive_frame(m_pAVCodecCtx, pData->frame); | ||
115 | - if ((ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) || ret < 0){ | ||
116 | - LOG_ERROR("{} - Failed to receive frame: {}", m_dec_name, ret); | ||
117 | - delete pData; | ||
118 | - pData = nullptr; | ||
119 | - return nullptr; | ||
120 | - } | ||
121 | - | ||
122 | - AVFrame* gpuFrame = pData->frame; | ||
123 | - if (gpuFrame->width != frameW || gpuFrame->height != frameH){ | ||
124 | - LOG_INFO("AVFrame is inconsistent: width is {}, height is {}; original frameW is {}, frameH is {}--{}", gpuFrame->width, gpuFrame->height, frameW, frameH , m_dec_name); | ||
125 | - delete pData; | ||
126 | - pData = nullptr; | ||
127 | - return nullptr; | ||
128 | - } | ||
129 | - | ||
130 | - return pData; | ||
131 | -} | ||
132 | \ No newline at end of file | 0 | \ No newline at end of file |
src/decoder/gb28181/FFDecoder.h0 deleted
1 | -#ifndef __FF_DECODER_H__ | ||
2 | -#define __FF_DECODER_H__ | ||
3 | - | ||
4 | -#include "../interface/interface_headers.h" | ||
5 | - | ||
6 | -extern "C" { | ||
7 | - #include "libavutil/avstring.h" | ||
8 | - #include "libavformat/avformat.h" | ||
9 | - #include "libswscale/swscale.h" | ||
10 | -} | ||
11 | - | ||
12 | -struct FrameData { | ||
13 | - AVFrame* frame {nullptr}; | ||
14 | - unsigned long pts {0}; | ||
15 | - bool bKeyframe {false}; | ||
16 | - | ||
17 | - FrameData() { | ||
18 | - frame = av_frame_alloc(); | ||
19 | - } | ||
20 | - | ||
21 | - ~FrameData() { | ||
22 | - if (frame) { | ||
23 | - av_frame_free(&frame); | ||
24 | - frame = nullptr; | ||
25 | - } | ||
26 | - } | ||
27 | -}; | ||
28 | - | ||
29 | -class FFDecoder | ||
30 | -{ | ||
31 | -public: | ||
32 | - FFDecoder(/* args */); | ||
33 | - ~FFDecoder(); | ||
34 | - | ||
35 | - FrameData* Decode(int videoType, char* data, int len, int isKey, uint64_t pts); | ||
36 | - | ||
37 | -private: | ||
38 | - FrameData* ff_decode(int videoType, AVPacket* pkt); | ||
39 | - | ||
40 | -private: | ||
41 | - string m_dec_name; | ||
42 | - | ||
43 | - AVDictionary *gpu_options {nullptr}; | ||
44 | - AVCodecContext* m_pAVCodecCtx {nullptr}; | ||
45 | - const AVCodec* m_pAVCodec {nullptr}; | ||
46 | - | ||
47 | - int m_devid {-1}; | ||
48 | - | ||
49 | - int frameW {-1}; | ||
50 | - int frameH {-1}; | ||
51 | - float m_fps {0.0}; | ||
52 | -}; | ||
53 | - | ||
54 | - | ||
55 | - | ||
56 | - | ||
57 | -#endif // __FF_DECODER_H__ | ||
58 | \ No newline at end of file | 0 | \ No newline at end of file |
src/decoder/gb28181/rtp/Pack_Header_Def.h deleted
1 | -/* | ||
2 | -writer:Kevin.liu | ||
3 | -Date:2010-08-06 | ||
4 | -*/ | ||
5 | -#ifndef __HEADER_PACK_HEADER_DEF_H__ | ||
6 | -#define __HEADER_PACK_HEADER_DEF_H__ | ||
7 | - | ||
8 | -#include <stdint.h> | ||
9 | - | ||
10 | -typedef struct PS_HEADER_tag | ||
11 | -{ | ||
12 | - unsigned char pack_start_code[4]; //'0x000001BA' | ||
13 | - | ||
14 | - unsigned char system_clock_reference_base21:2; | ||
15 | - unsigned char marker_bit:1; | ||
16 | - unsigned char system_clock_reference_base1:3; | ||
17 | - unsigned char fix_bit:2; //'01' | ||
18 | - | ||
19 | - unsigned char system_clock_reference_base22; | ||
20 | - | ||
21 | - unsigned char system_clock_reference_base31:2; | ||
22 | - unsigned char marker_bit1:1; | ||
23 | - unsigned char system_clock_reference_base23:5; | ||
24 | - | ||
25 | - unsigned char system_clock_reference_base32; | ||
26 | - | ||
27 | - unsigned char system_clock_reference_extension1:2; | ||
28 | - unsigned char marker_bit2:1; | ||
29 | - unsigned char system_clock_reference_base33:5; //system_clock_reference_base 33bit | ||
30 | - | ||
31 | - unsigned char marker_bit3:1; | ||
32 | - unsigned char system_clock_reference_extension2:7; //system_clock_reference_extension 9bit | ||
33 | - | ||
34 | - unsigned char program_mux_rate1; | ||
35 | - | ||
36 | - unsigned char program_mux_rate2; | ||
37 | - | ||
38 | - unsigned char marker_bit5:1; | ||
39 | - unsigned char marker_bit4:1; | ||
40 | - unsigned char program_mux_rate3:6; | ||
41 | - | ||
42 | - unsigned char pack_stuffing_length:3; | ||
43 | - unsigned char reserved:5; | ||
44 | - | ||
45 | - PS_HEADER_tag() | ||
46 | - { | ||
47 | - pack_start_code[0] = 0x00; | ||
48 | - pack_start_code[1] = 0x00; | ||
49 | - pack_start_code[2] = 0x01; | ||
50 | - pack_start_code[3] = 0xBA; | ||
51 | - fix_bit = 0x01; | ||
52 | - marker_bit = 0x01; | ||
53 | - marker_bit1 = 0x01; | ||
54 | - marker_bit2 = 0x01; | ||
55 | - marker_bit3 = 0x01; | ||
56 | - marker_bit4 = 0x01; | ||
57 | - marker_bit5 = 0x01; | ||
58 | - reserved = 0x1F; | ||
59 | - pack_stuffing_length = 0x00; | ||
60 | - system_clock_reference_extension1 = 0; | ||
61 | - system_clock_reference_extension2 = 0; | ||
62 | - } | ||
63 | - | ||
64 | - void getSystem_clock_reference_base(uint64_t &_ui64SCR) | ||
65 | - { | ||
66 | - _ui64SCR = (system_clock_reference_base1 << 30) | (system_clock_reference_base21 << 28) | ||
67 | - | (system_clock_reference_base22 << 20) | (system_clock_reference_base23 << 15) | ||
68 | - | (system_clock_reference_base31 << 13) | (system_clock_reference_base32 << 5) | ||
69 | - | (system_clock_reference_base33); | ||
70 | - | ||
71 | - } | ||
72 | - | ||
73 | - void setSystem_clock_reference_base(uint64_t _ui64SCR) | ||
74 | - { | ||
75 | - system_clock_reference_base1 = (_ui64SCR >> 30) & 0x07; | ||
76 | - system_clock_reference_base21 = (_ui64SCR >> 28) & 0x03; | ||
77 | - system_clock_reference_base22 = (_ui64SCR >> 20) & 0xFF; | ||
78 | - system_clock_reference_base23 = (_ui64SCR >> 15) & 0x1F; | ||
79 | - system_clock_reference_base31 = (_ui64SCR >> 13) & 0x03; | ||
80 | - system_clock_reference_base32 = (_ui64SCR >> 5) & 0xFF; | ||
81 | - system_clock_reference_base33 = _ui64SCR & 0x1F; | ||
82 | - } | ||
83 | - | ||
84 | - void getProgram_mux_rate(unsigned int &_uiMux_rate) | ||
85 | - { | ||
86 | - _uiMux_rate = (program_mux_rate1 << 14) | (program_mux_rate2 << 6) | program_mux_rate3; | ||
87 | - } | ||
88 | - | ||
89 | - void setProgram_mux_rate(unsigned int _uiMux_rate) | ||
90 | - { | ||
91 | - program_mux_rate1 = (_uiMux_rate >> 14) & 0xFF; | ||
92 | - program_mux_rate2 = (_uiMux_rate >> 6) & 0xFF; | ||
93 | - program_mux_rate3 = _uiMux_rate & 0x3F; | ||
94 | - } | ||
95 | - | ||
96 | -}*pPS_HEADER_tag; | ||
97 | - | ||
98 | -typedef struct PES_HEADER_tag | ||
99 | -{ | ||
100 | - unsigned char packet_start_code_prefix[3]; | ||
101 | - unsigned char stream_id; | ||
102 | - unsigned char PES_packet_length[2]; | ||
103 | - | ||
104 | - unsigned char original_or_copy:1; | ||
105 | - unsigned char copyright:1; | ||
106 | - unsigned char data_alignment_indicator:1; | ||
107 | - unsigned char PES_priority:1; | ||
108 | - unsigned char PES_scrambling_control:2; | ||
109 | - unsigned char fix_bit:2; | ||
110 | - | ||
111 | - unsigned char PES_extension_flag:1; | ||
112 | - unsigned char PES_CRC_flag:1; | ||
113 | - unsigned char additional_copy_info_flag:1; | ||
114 | - unsigned char DSM_trick_mode_flag:1; | ||
115 | - unsigned char ES_rate_flag:1; | ||
116 | - unsigned char ESCR_flag:1; | ||
117 | - unsigned char PTS_DTS_flags:2; | ||
118 | - | ||
119 | - unsigned char PES_header_data_length; | ||
120 | - | ||
121 | - PES_HEADER_tag() | ||
122 | - { | ||
123 | - packet_start_code_prefix[0] = 0x00; | ||
124 | - packet_start_code_prefix[1] = 0x00; | ||
125 | - packet_start_code_prefix[2] = 0x01; | ||
126 | - | ||
127 | - PES_packet_length[0] = 0x00; | ||
128 | - PES_packet_length[1] = 0x00; | ||
129 | - | ||
130 | - stream_id = 0xE0; | ||
131 | - fix_bit = 0x02; | ||
132 | - } | ||
133 | - | ||
134 | -}*pPES_HEADER_tag; | ||
135 | - | ||
136 | -typedef struct PTS_tag | ||
137 | -{ | ||
138 | - unsigned char marker_bit:1; | ||
139 | - unsigned char PTS1:3; | ||
140 | - unsigned char fix_bit:4; | ||
141 | - | ||
142 | - unsigned char PTS21; | ||
143 | - | ||
144 | - unsigned char marker_bit1:1; | ||
145 | - unsigned char PTS22:7; | ||
146 | - | ||
147 | - unsigned char PTS31; | ||
148 | - | ||
149 | - unsigned char marker_bit2:1; | ||
150 | - unsigned char PTS32:7; | ||
151 | - | ||
152 | - PTS_tag() | ||
153 | - { | ||
154 | - fix_bit = 0x02; | ||
155 | - marker_bit = 0x01; | ||
156 | - marker_bit1 = 0x01; | ||
157 | - marker_bit2 = 0x01; | ||
158 | - } | ||
159 | - | ||
160 | - void getPTS(uint64_t &_ui64PTS) | ||
161 | - { | ||
162 | - _ui64PTS = (PTS1 << 30) | (PTS21 << 22) | ||
163 | - | (PTS22 << 15) | (PTS31 << 7) | (PTS32); | ||
164 | - | ||
165 | - } | ||
166 | - | ||
167 | - void setPTS(uint64_t _ui64PTS) | ||
168 | - { | ||
169 | - PTS1 = (_ui64PTS >> 30) & 0x07; | ||
170 | - PTS21 = (_ui64PTS >> 22) & 0xFF; | ||
171 | - PTS22 = (_ui64PTS >> 15) & 0x7F; | ||
172 | - PTS31 = (_ui64PTS >> 7) & 0xFF; | ||
173 | - PTS32 = _ui64PTS & 0x7F; | ||
174 | - } | ||
175 | -}*pPTS_tag; | ||
176 | - | ||
177 | -typedef struct PSM_tag | ||
178 | -{ | ||
179 | - unsigned char packet_start_code_prefix[3]; | ||
180 | - unsigned char map_stream_id; | ||
181 | - unsigned char program_stream_map_length[2]; | ||
182 | - | ||
183 | - unsigned char program_stream_map_version:5; | ||
184 | - unsigned char reserved1:2; | ||
185 | - unsigned char current_next_indicator:1; | ||
186 | - | ||
187 | - unsigned char marker_bit:1; | ||
188 | - unsigned char reserved2:7; | ||
189 | - | ||
190 | - unsigned char program_stream_info_length[2]; | ||
191 | - unsigned char elementary_stream_map_length[2]; | ||
192 | - unsigned char stream_type; | ||
193 | - unsigned char elementary_stream_id; | ||
194 | - unsigned char elementary_stream_info_length[2]; | ||
195 | - unsigned char CRC_32[4]; | ||
196 | - | ||
197 | - PSM_tag() | ||
198 | - { | ||
199 | - packet_start_code_prefix[0] = 0x00; | ||
200 | - packet_start_code_prefix[1] = 0x00; | ||
201 | - packet_start_code_prefix[2] = 0x01; | ||
202 | - | ||
203 | - map_stream_id = 0xBC; | ||
204 | - program_stream_map_length[0] = 0x00; | ||
205 | - program_stream_map_length[1] = 0x0E; | ||
206 | - | ||
207 | - program_stream_map_version = 0x00; | ||
208 | - current_next_indicator = 0x01; | ||
209 | - reserved1 = 0x03; | ||
210 | - program_stream_map_version = 0x00; | ||
211 | - | ||
212 | - reserved2 = 0x7F; | ||
213 | - marker_bit = 0x01; | ||
214 | - | ||
215 | - program_stream_info_length[0] = 0x00; | ||
216 | - program_stream_info_length[1] = 0x00; | ||
217 | - | ||
218 | - elementary_stream_map_length[0] = 0x00; | ||
219 | - elementary_stream_map_length[1] = 0x04; | ||
220 | - | ||
221 | - stream_type = 0x1B; | ||
222 | - elementary_stream_id = 0xE0; | ||
223 | - | ||
224 | - elementary_stream_info_length[0] = 0x00; | ||
225 | - elementary_stream_info_length[1] = 0x00; | ||
226 | - | ||
227 | - CRC_32[3] = 0x45; | ||
228 | - CRC_32[2] = 0xBD; | ||
229 | - CRC_32[1] = 0xDC; | ||
230 | - CRC_32[0] = 0xF4; | ||
231 | - } | ||
232 | -}*pPSM_tag; | ||
233 | - | ||
234 | -#endif | ||
235 | \ No newline at end of file | 0 | \ No newline at end of file |
src/decoder/gb28181/rtp/RTPReceiver.cpp deleted
1 | -#include "RTPReceiver.h" | ||
2 | -#include "rtppacket.h" | ||
3 | -#include <thread> | ||
4 | - | ||
5 | -#include "../common_header.h" | ||
6 | -#include "../websocket/WebsocketClient.h" | ||
7 | - | ||
8 | -#ifdef __linux__ | ||
9 | -#include "arpa/inet.h" | ||
10 | -#endif | ||
11 | - | ||
12 | -#define BUFFERSIZE_1024 1024 | ||
13 | - | ||
14 | -const int kVideoFrameSize = BUFFERSIZE_1024*BUFFERSIZE_1024*5*2; | ||
15 | - | ||
16 | -// PS解包器回调 | ||
17 | -static int ReceivePESFunction(unsigned char streamid, void * data, int size, uint64_t pts, uint64_t localPts, bool key, void* param) | ||
18 | -{ | ||
19 | - if (NULL != data && size > 0) | ||
20 | - { | ||
21 | - ((RTPReceiver*)param)->OnPsDemux(streamid, (BYTE*)data, size, key, (uint64_t)pts, (uint64_t)localPts); | ||
22 | - } | ||
23 | - return 0; | ||
24 | -} | ||
25 | - | ||
26 | -static int ps_demuxer_thread_(void* param) | ||
27 | -{ | ||
28 | - if (!param) | ||
29 | - { | ||
30 | - return -1; | ||
31 | - } | ||
32 | - | ||
33 | - RTPReceiver* self = (RTPReceiver*)param; | ||
34 | - return self->OnPsProcess(); | ||
35 | -} | ||
36 | - | ||
37 | -RTPReceiver::RTPReceiver() | ||
38 | -:m_LastPTS(-1) | ||
39 | -, m_LastIsKeyFrame(0) | ||
40 | -, m_SliceBuf(1024*1024) | ||
41 | -, m_h264DataFunc(NULL) | ||
42 | -, m_hVodEndFunc(NULL) | ||
43 | -, m_usrParam(NULL) | ||
44 | -, m_bPsExit(false) | ||
45 | -, m_psThreadPtr(nullptr) | ||
46 | -{ | ||
47 | - m_LastStreamType = 0; | ||
48 | - recvTmpBuf = new BYTE[kVideoFrameSize]; | ||
49 | -} | ||
50 | - | ||
51 | -RTPReceiver::~RTPReceiver(){ | ||
52 | - if(recvTmpBuf != nullptr){ | ||
53 | - delete[] recvTmpBuf; | ||
54 | - } | ||
55 | - | ||
56 | - WebsocketClient* pClient = WebsocketClient::getInstance(); | ||
57 | - if (pClient){ | ||
58 | - pClient->DeleteReceiverPair(m_SipChannelId, m_rtp_port); | ||
59 | - } | ||
60 | -} | ||
61 | - | ||
62 | -void RTPReceiver::SetOutputCallback(CallBack_Stream cb, void* param) | ||
63 | -{ | ||
64 | - m_h264DataFunc = cb; | ||
65 | - m_usrParam = param; | ||
66 | -} | ||
67 | - | ||
68 | -void RTPReceiver::SetVodEndCallback(CallBack_VodFileEnd cb, void* param) | ||
69 | -{ | ||
70 | - m_hVodEndFunc = cb; | ||
71 | - m_usrParam = param; | ||
72 | -} | ||
73 | - | ||
74 | -void RTPReceiver::SetRequestStreamCallback(CallBack_Request_Stream cb){ | ||
75 | - m_callback_request_stream = cb; | ||
76 | -} | ||
77 | - | ||
78 | -int RTPReceiver::InitPS(){ | ||
79 | - | ||
80 | - m_psParser.SetReceiveFunction(ReceivePESFunction, this); | ||
81 | - | ||
82 | - m_psThreadPtr = new std::thread(ps_demuxer_thread_, this); | ||
83 | - if(nullptr == m_psThreadPtr){ | ||
84 | - return -1; | ||
85 | - } | ||
86 | - | ||
87 | - LOG_INFO("[{}] InitPS successed", m_SipChannelId); | ||
88 | - | ||
89 | - return 0; | ||
90 | -} | ||
91 | - | ||
92 | -void RTPReceiver::ClosePsThread(){ | ||
93 | - LOG_INFO("[{}] 3.", m_SipChannelId); | ||
94 | - m_bPsExit = true; | ||
95 | - // PS解包线程退出 | ||
96 | - if (m_psThreadPtr && m_psThreadPtr->joinable()) | ||
97 | - { | ||
98 | - m_psThreadPtr->join(); | ||
99 | - delete m_psThreadPtr; | ||
100 | - m_psThreadPtr = nullptr; | ||
101 | - } | ||
102 | - | ||
103 | - LOG_INFO("[{}] ps demux thread quit", m_SipChannelId); | ||
104 | -} | ||
105 | - | ||
106 | -// 处理去除了PS头的数据 | ||
107 | -// 下级厂商发过来的流有可能是MPEG-4/H264/SVAC中的任意一种 | ||
108 | -// 国标标准规定, 编码方(下级)可以选择实现H264、MPEG4或者SVAC, 但解码方(上级) | ||
109 | -// 必须同时实现对H264、MPEG4和SVAC的支持 | ||
110 | -void RTPReceiver::OnPsDemux(unsigned char streamId, BYTE *data, int len, bool key, uint64_t pts, uint64_t localPts) | ||
111 | -{ | ||
112 | - if (!m_h264DataFunc) | ||
113 | - { | ||
114 | - return; | ||
115 | - } | ||
116 | - | ||
117 | - if (-1 == m_LastPTS) | ||
118 | - { | ||
119 | - if (!key) | ||
120 | - { | ||
121 | - return; | ||
122 | - } | ||
123 | - m_LastPTS = pts; | ||
124 | - m_LastIsKeyFrame = key; | ||
125 | - m_LastStreamType = streamId; | ||
126 | - } | ||
127 | - | ||
128 | - // 音频数据不处理 | ||
129 | - if (0xC0 == streamId) | ||
130 | - { | ||
131 | - return; | ||
132 | - } | ||
133 | - | ||
134 | - ////add by mds 20190424 | ||
135 | - //if (m_notToDecodCount > 50000)//针对大华相机,可能会很久不调用解码 | ||
136 | - //{ | ||
137 | - // byte_buffer bb(64); | ||
138 | - // bb << ERROR_REALSTREAM_INTERRUPT << "This session have a long time no decoding"; | ||
139 | - // LOG_INFO("[{}] Long time no decoding!!!m_notToDecodCount=[{}]", m_SipChannelId, m_notToDecodCount); | ||
140 | - // | ||
141 | - // if (m_usrParam) | ||
142 | - // { | ||
143 | - // if (((VideoSession *)GetUsrParam())->msgChan()->is_valid()) | ||
144 | - // ((VideoSession *)GetUsrParam())->msgChan()->send_msg(bb.data_ptr(), bb.data_size()); | ||
145 | - | ||
146 | - // //通知网关关闭句柄 | ||
147 | - // if(!((VideoSession *)GetUsrParam())->streamHandle().empty()) | ||
148 | - // { | ||
149 | - // LOG_INFO("[{}] ---->Notify hisense gateway release handle = {} !<----", m_SipChannelId, ((VideoSession *)GetUsrParam())->streamHandle()); | ||
150 | - | ||
151 | - // if (((VideoSession *)GetUsrParam())->video_type() == EREAL) | ||
152 | - // real_stream_stop(((VideoSession *)GetUsrParam())->streamHandle()); | ||
153 | - // | ||
154 | - // if (((VideoSession *)GetUsrParam())->video_type() == ERECORD) | ||
155 | - // record_stream_stop(((VideoSession *)GetUsrParam())->streamHandle()); | ||
156 | - // | ||
157 | - // ((VideoSession *)GetUsrParam())->streamHandle().clear(); | ||
158 | - // } | ||
159 | - // | ||
160 | - // m_hVodEndFunc(m_usrParam); | ||
161 | - // } | ||
162 | - // | ||
163 | - // bb.bset(0); | ||
164 | - // return; | ||
165 | - //} | ||
166 | - | ||
167 | - if (m_LastPTS != pts) | ||
168 | - { | ||
169 | - int stream_type = 0; | ||
170 | - if (VIDEO_TYPE_H264 == streamId) { | ||
171 | - stream_type = 0; | ||
172 | - } else if(VIDEO_TYPE_H265 == streamId) { | ||
173 | - stream_type = 1; | ||
174 | - } else { | ||
175 | - LOG_ERROR("[{}] - video type not support!", m_SipChannelId); | ||
176 | - } | ||
177 | - | ||
178 | - | ||
179 | - m_notToDecodCount = 0; | ||
180 | - m_h264DataFunc(m_usrParam, stream_type, (char *)m_SliceBuf.head(), m_SliceBuf.len(), m_LastIsKeyFrame, m_LastPTS, localPts); | ||
181 | - | ||
182 | - m_SliceBuf.reset(); | ||
183 | - | ||
184 | - m_LastPTS = pts; | ||
185 | - m_LastIsKeyFrame = key; | ||
186 | - m_LastStreamType = streamId; | ||
187 | - } | ||
188 | - | ||
189 | - m_notToDecodCount++; | ||
190 | - m_SliceBuf.add((char*)data, len); | ||
191 | -} | ||
192 | - | ||
193 | -// 解PS包线程 | ||
194 | -int RTPReceiver::OnPsProcess() | ||
195 | -{ | ||
196 | - LOG_INFO("[{}] started.", m_SipChannelId); | ||
197 | - while (!m_bPsExit) { | ||
198 | - m_psFrameMutex.lock(); | ||
199 | - // LOG_DEBUG("[{}] PS frame size : {}", m_SipChannelId, m_psVideoFrames.size()); | ||
200 | - if (m_psVideoFrames.size() <= 0){ | ||
201 | - m_psFrameMutex.unlock(); | ||
202 | - std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
203 | - continue; | ||
204 | - } | ||
205 | - Frame* frame = m_psVideoFrames.front(); | ||
206 | - m_psVideoFrames.pop(); | ||
207 | - m_psFrameMutex.unlock(); | ||
208 | - if (frame != nullptr) | ||
209 | - { | ||
210 | - int nRet = m_psParser.AddData(frame->buf_, frame->len_); | ||
211 | - if (nRet == -1) | ||
212 | - { | ||
213 | - LOG_INFO("m_psParser return -1--{}", m_SipChannelId); | ||
214 | - } | ||
215 | - else if (nRet == -2) | ||
216 | - { | ||
217 | - LOG_INFO("m_psParser return -2--{}", m_SipChannelId); | ||
218 | - } | ||
219 | - else if (nRet == -3) | ||
220 | - { | ||
221 | - LOG_INFO("m_psParser return -3--{}", m_SipChannelId); | ||
222 | - } | ||
223 | - | ||
224 | - delete frame; | ||
225 | - frame = nullptr; | ||
226 | - } | ||
227 | - } | ||
228 | - | ||
229 | - ClearPsVideoFrameList(); | ||
230 | - | ||
231 | - m_hVodEndFunc(m_usrParam); | ||
232 | - | ||
233 | - LOG_INFO("[{}] exited.", m_SipChannelId); | ||
234 | - | ||
235 | - return 0; | ||
236 | -} | ||
237 | - | ||
238 | -int RTPReceiver::GetPsFrameListSize() | ||
239 | -{ | ||
240 | - std::lock_guard<std::mutex> l(m_psFrameMutex); | ||
241 | - return m_psVideoFrames.size(); | ||
242 | -} | ||
243 | - | ||
244 | -void RTPReceiver::ClearPsVideoFrameList() | ||
245 | -{ | ||
246 | - std::lock_guard<std::mutex> l(m_psFrameMutex); | ||
247 | - while (!m_psVideoFrames.empty()) { | ||
248 | - Frame* f = m_psVideoFrames.front(); | ||
249 | - delete f; | ||
250 | - m_psVideoFrames.pop(); | ||
251 | - } | ||
252 | - LOG_INFO("[{}] cleared ps video frame list!", m_SipChannelId); | ||
253 | -} | ||
254 | - | ||
255 | -int RTPReceiver::ParsePacket(RTPPacket* packet){ | ||
256 | - do { | ||
257 | - | ||
258 | - if (0 == packet->GetPayloadType()) | ||
259 | - { | ||
260 | - // 音频数据, 暂不处理 | ||
261 | - break; | ||
262 | - } | ||
263 | - | ||
264 | - // 判断是否收到完整的帧(有些厂商打的marker标记不准, 所以只能看时间戳来判断) | ||
265 | - uint32_t curPts = packet->GetTimestamp(); | ||
266 | - if (lastPts != 0 && curPts != lastPts) { | ||
267 | - mark = 1; | ||
268 | - } | ||
269 | - lastPts = curPts; | ||
270 | - | ||
271 | - int payloadLen = packet->GetPayloadLength(); | ||
272 | - if (offset + payloadLen > kVideoFrameSize) | ||
273 | - { | ||
274 | - offset = 0, mark = 0; | ||
275 | - break; | ||
276 | - } | ||
277 | - | ||
278 | - // LOG_DEBUG("[{}] ParsePacket GetPayloadLength", m_SipChannelId); | ||
279 | - | ||
280 | - if (mark) | ||
281 | - { | ||
282 | - BYTE* frameBuf = (BYTE*)malloc(sizeof(BYTE) * offset); | ||
283 | - if (!frameBuf) { | ||
284 | - offset = 0, mark = 0; | ||
285 | - break; | ||
286 | - } | ||
287 | - memcpy(frameBuf, recvTmpBuf, offset); | ||
288 | - if (!m_bPsExit){ | ||
289 | - std::lock_guard<std::mutex> l(m_psFrameMutex); | ||
290 | - if (m_psVideoFrames.size() < 100) | ||
291 | - { | ||
292 | - // LOG_DEBUG("[{}]ParsePacket push", m_SipChannelId); | ||
293 | - m_psVideoFrames.push(new Frame(frameBuf, offset, false)); | ||
294 | - } | ||
295 | - else { | ||
296 | - free(frameBuf); | ||
297 | - } | ||
298 | - } | ||
299 | - else{ | ||
300 | - //若此时解码线程已经退出,不再往m_psVideoFrames推送帧,且退出当前线程 | ||
301 | - free(frameBuf); | ||
302 | - LOG_INFO("ParsePacket quit, device_id:{}", m_SipChannelId); | ||
303 | - return 1; | ||
304 | - } | ||
305 | - offset = 0; | ||
306 | - mark = 0; | ||
307 | - } | ||
308 | - | ||
309 | - memcpy(recvTmpBuf + offset, packet->GetPayloadData(), payloadLen); | ||
310 | - offset += payloadLen; | ||
311 | - } while (0); | ||
312 | - | ||
313 | - return 0; | ||
314 | -} | ||
315 | - | ||
316 | -int RTPReceiver::allocRtpPort() { | ||
317 | - | ||
318 | - WebsocketClient* pServer = WebsocketClient::getInstance(); | ||
319 | - int MIN_RTP_PORT = pServer->GetMinRtpPort() ; | ||
320 | - int MAX_RTP_PORT = pServer->GetMaxRtpPort(); | ||
321 | - | ||
322 | - int s_rtpPort = MIN_RTP_PORT; | ||
323 | - | ||
324 | - srand((unsigned int)time(NULL)); | ||
325 | - s_rtpPort = MIN_RTP_PORT + (rand() % MIN_RTP_PORT); | ||
326 | - | ||
327 | - if (s_rtpPort % 2) | ||
328 | - ++s_rtpPort; | ||
329 | - | ||
330 | - int count = 0; | ||
331 | - | ||
332 | - while (true) | ||
333 | - { | ||
334 | - if (s_rtpPort >= MAX_RTP_PORT) { | ||
335 | - s_rtpPort = MIN_RTP_PORT; | ||
336 | - count ++; | ||
337 | - if (count > 1) { | ||
338 | - LOG_ERROR("[{}] - 范围内没有可用的port", m_SipChannelId); | ||
339 | - } | ||
340 | - } | ||
341 | - | ||
342 | - int i = 0; | ||
343 | - for (; i < 2; i++) { | ||
344 | - sockaddr_in sRecvAddr; | ||
345 | - int s = socket(AF_INET, SOCK_DGRAM, 0); | ||
346 | - | ||
347 | - sRecvAddr.sin_family = AF_INET; | ||
348 | - sRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); | ||
349 | - sRecvAddr.sin_port = htons(s_rtpPort + i); | ||
350 | - | ||
351 | - int nResult = bind(s, (sockaddr *)&sRecvAddr, sizeof(sRecvAddr)); | ||
352 | - if (nResult != 0) { | ||
353 | - break; | ||
354 | - } | ||
355 | - | ||
356 | - nResult = close(s); | ||
357 | - if (nResult != 0) { | ||
358 | - LOG_ERROR("[{}] - closesocket failed : {}", m_SipChannelId, nResult); | ||
359 | - break; | ||
360 | - } | ||
361 | - } | ||
362 | - | ||
363 | - if (i == 2) | ||
364 | - break; | ||
365 | - | ||
366 | - s_rtpPort += 2; | ||
367 | - } | ||
368 | - | ||
369 | - return s_rtpPort; | ||
370 | -} | ||
371 | - | ||
372 | -void RTPReceiver::RequestStreamFailed() { | ||
373 | - m_bRtpExit = true; | ||
374 | -} | ||
375 | \ No newline at end of file | 0 | \ No newline at end of file |
src/decoder/gb28181/rtp/RTPReceiver.h deleted
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)(const char* deviceId, int rtp_port); | ||
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 | - virtual ~RTPReceiver(); | ||
89 | - | ||
90 | - virtual bool Open(string channel_id) = 0; | ||
91 | - virtual bool IsOpened() = 0; | ||
92 | - virtual void Close() = 0; | ||
93 | - virtual bool RequestStream() = 0; | ||
94 | - | ||
95 | - void SetVodEndCallback(CallBack_VodFileEnd cb, void* param); | ||
96 | - | ||
97 | - void SetOutputCallback(CallBack_Stream cb, void* param); | ||
98 | - | ||
99 | - void SetRequestStreamCallback(CallBack_Request_Stream cb); | ||
100 | - | ||
101 | - int GetPsFrameListSize(); | ||
102 | - | ||
103 | - int allocRtpPort(); | ||
104 | - | ||
105 | - void RequestStreamFailed(); | ||
106 | - | ||
107 | -public: | ||
108 | - void OnPsDemux(unsigned char streamId, BYTE *data, int len, bool key, uint64_t pts, uint64_t localPts); | ||
109 | - int OnPsProcess(); | ||
110 | - void ClearPsVideoFrameList(); | ||
111 | - int ParsePacket(RTPPacket* packet); | ||
112 | - | ||
113 | -public: | ||
114 | - int InitPS(); | ||
115 | - void ClosePsThread(); | ||
116 | - void *GetUsrParam(){ return m_usrParam; } | ||
117 | - | ||
118 | -public: | ||
119 | - CBuffer m_SliceBuf; | ||
120 | - uint64_t m_LastPTS; | ||
121 | - bool m_LastIsKeyFrame; | ||
122 | - unsigned char m_LastStreamType; | ||
123 | - | ||
124 | - int64_t m_notToDecodCount{0};//线程计数,用来代表多长时间没有调用解码回调,针对大华相机 | ||
125 | - | ||
126 | - void* m_usrParam; | ||
127 | - CallBack_Stream m_h264DataFunc; // 视频流回调 | ||
128 | - | ||
129 | - std::queue<Frame*> m_psVideoFrames; | ||
130 | - mutex m_psFrameMutex; | ||
131 | - | ||
132 | - string m_SipChannelId; | ||
133 | - int m_rtp_port{-1}; | ||
134 | - | ||
135 | - CMpeg2Demux m_psParser; | ||
136 | - std::atomic_bool m_bPsExit; // 标识PS解包线程关闭 | ||
137 | - std::atomic_bool m_bRtpExit; // RTP收包线程结束开关 | ||
138 | - | ||
139 | - uint32_t lastPts{0}; | ||
140 | - uint64_t last_recv_ts{0}; | ||
141 | - int offset{0}; | ||
142 | - int mark{0}; | ||
143 | - BYTE* recvTmpBuf{nullptr}; | ||
144 | - | ||
145 | - std::thread* m_psThreadPtr{nullptr}; // PS解包线程 | ||
146 | - | ||
147 | - CallBack_VodFileEnd m_hVodEndFunc; // 录像流结束回调 | ||
148 | - CallBack_Request_Stream m_callback_request_stream; //请求流回调 | ||
149 | -}; | ||
150 | - | ||
151 | -#endif // _RTP_RECEIVER_H_ | ||
152 | \ No newline at end of file | 0 | \ No newline at end of file |
src/decoder/gb28181/rtp/RTPTcpReceiver.cpp deleted
1 | -#include"RTPTcpReceiver.h" | ||
2 | - | ||
3 | -#include "../common_header.h" | ||
4 | -#include "../websocket/WebsocketClient.h" | ||
5 | - | ||
6 | - | ||
7 | -// class TcpRTPSession : public RTPSession | ||
8 | -// { | ||
9 | -// public: | ||
10 | -// void setReceiver(RTPTcpReceiver* r){ | ||
11 | -// tcpReceiver = r; | ||
12 | -// } | ||
13 | - | ||
14 | -// protected: | ||
15 | -// void OnValidatedRTPPacket(RTPSourceData *srcdat, RTPPacket *rtppack, bool isonprobation, bool *ispackethandled) | ||
16 | -// { | ||
17 | -// // printf("SSRC %x Got packet (%d bytes) in OnValidatedRTPPacket from source 0x%04x!\n", GetLocalSSRC(), | ||
18 | -// // (int)rtppack->GetPayloadLength(), srcdat->GetSSRC()); | ||
19 | - | ||
20 | -// LOG_DEBUG("SSRC {} Got packet ({} bytes) in OnValidatedRTPPacket from source {}}!\n", GetLocalSSRC(), | ||
21 | -// (int)rtppack->GetPayloadLength(), srcdat->GetSSRC()); | ||
22 | - | ||
23 | -// if(nullptr != tcpReceiver){ | ||
24 | -// tcpReceiver->ParsePacket(rtppack); | ||
25 | -// } | ||
26 | -// DeletePacket(rtppack); | ||
27 | -// *ispackethandled = true; | ||
28 | -// } | ||
29 | - | ||
30 | -// void OnRTCPSDESItem(RTPSourceData *srcdat, RTCPSDESPacket::ItemType t, const void *itemdata, size_t itemlength) | ||
31 | -// { | ||
32 | -// char msg[1024]; | ||
33 | - | ||
34 | -// memset(msg, 0, sizeof(msg)); | ||
35 | -// if (itemlength >= sizeof(msg)) | ||
36 | -// itemlength = sizeof(msg)-1; | ||
37 | - | ||
38 | -// memcpy(msg, itemdata, itemlength); | ||
39 | -// // printf("SSRC %x Received SDES item (%d): %s from SSRC %x\n", GetLocalSSRC(), (int)t, msg, srcdat->GetSSRC()); | ||
40 | -// LOG_DEBUG("SSRC {} Received SDES item ({}): {} from SSRC {}\n", GetLocalSSRC(), (int)t, msg, srcdat->GetSSRC()); | ||
41 | -// } | ||
42 | - | ||
43 | -// private: | ||
44 | -// RTPTcpReceiver* tcpReceiver{nullptr}; | ||
45 | -// }; | ||
46 | - | ||
47 | -class MyTCPTransmitter : public RTPTCPTransmitter | ||
48 | -{ | ||
49 | -public: | ||
50 | - void setReceiver(RTPTcpReceiver* r){ | ||
51 | - tcpReceiver = r; | ||
52 | - } | ||
53 | - | ||
54 | -public: | ||
55 | - MyTCPTransmitter() : RTPTCPTransmitter(0){ } | ||
56 | - | ||
57 | - void OnSendError(SocketType sock) | ||
58 | - { | ||
59 | - LOG_ERROR("Error sending over socket {}, removing destination", sock); | ||
60 | - DeleteDestination(RTPTCPAddress(sock)); | ||
61 | - if(nullptr != tcpReceiver && !tcpReceiver->isClosing()){ | ||
62 | - tcpReceiver->ReConnect(); | ||
63 | - } | ||
64 | - } | ||
65 | - | ||
66 | - void OnReceiveError(SocketType sock) | ||
67 | - { | ||
68 | - LOG_ERROR("Error receiving over socket {}, removing destination", sock); | ||
69 | - DeleteDestination(RTPTCPAddress(sock)); | ||
70 | - } | ||
71 | - | ||
72 | -private: | ||
73 | - RTPTcpReceiver* tcpReceiver{nullptr}; | ||
74 | -}; | ||
75 | - | ||
76 | -static int rtp_revc_thread_(void* param) | ||
77 | -{ | ||
78 | - if (!param) | ||
79 | - { | ||
80 | - return -1; | ||
81 | - } | ||
82 | - | ||
83 | - RTPTcpReceiver* self = (RTPTcpReceiver*)param; | ||
84 | - return self->OnRtpRecv(); | ||
85 | -} | ||
86 | - | ||
87 | -static int listen_finish_thread_(void* param) | ||
88 | -{ | ||
89 | - if (!param) | ||
90 | - { | ||
91 | - return -1; | ||
92 | - } | ||
93 | - | ||
94 | - RTPTcpReceiver* self = (RTPTcpReceiver*)param; | ||
95 | - return self->ListenFinish(); | ||
96 | -} | ||
97 | - | ||
98 | -RTPTcpReceiver::RTPTcpReceiver() | ||
99 | -: m_bOpened(false) | ||
100 | -, m_idleCount(-1) | ||
101 | -, m_noDataCount(-1) | ||
102 | -, m_nListener(-1) | ||
103 | -, m_bAccepted(false) | ||
104 | -, m_bClosing(false) | ||
105 | -{ | ||
106 | - m_bRtpExit = false; | ||
107 | - m_rtpSessionPtr = new RTPSession(); | ||
108 | - m_pSessparams = new RTPSessionParams(); | ||
109 | - m_pTrans = new MyTCPTransmitter(); | ||
110 | -} | ||
111 | - | ||
112 | -RTPTcpReceiver::~RTPTcpReceiver(){ | ||
113 | - | ||
114 | - Close(); | ||
115 | - | ||
116 | - if(m_rtpSessionPtr != nullptr){ | ||
117 | - delete m_rtpSessionPtr; | ||
118 | - m_rtpSessionPtr = nullptr; | ||
119 | - } | ||
120 | - | ||
121 | - if(m_pSessparams != nullptr){ | ||
122 | - delete m_pSessparams; | ||
123 | - m_pSessparams = nullptr; | ||
124 | - } | ||
125 | - | ||
126 | - if(m_pTrans != nullptr){ | ||
127 | - delete m_pTrans; | ||
128 | - m_pTrans = nullptr; | ||
129 | - } | ||
130 | -} | ||
131 | - | ||
132 | -bool RTPTcpReceiver::Open(string channel_id){ | ||
133 | - m_SipChannelId = channel_id; | ||
134 | - | ||
135 | - m_rtp_port = allocRtpPort(); | ||
136 | - if (m_rtp_port < 0) { | ||
137 | - return false; | ||
138 | - } | ||
139 | - | ||
140 | - if(0 != initSession(m_rtp_port)){ | ||
141 | - return false; | ||
142 | - } | ||
143 | - | ||
144 | - m_bOpened = true; | ||
145 | - | ||
146 | - LOG_INFO("[{}] started.", m_SipChannelId); | ||
147 | - | ||
148 | - return true; | ||
149 | -} | ||
150 | - | ||
151 | -bool RTPTcpReceiver::IsOpened(){ | ||
152 | - LOG_INFO("[{}] isopen:{} ", m_SipChannelId, m_bOpened); | ||
153 | - return m_bOpened; | ||
154 | -} | ||
155 | - | ||
156 | -void RTPTcpReceiver::Close(){ | ||
157 | - m_bRtpExit = true; | ||
158 | - | ||
159 | - WebsocketClient* pServer = WebsocketClient::getInstance(); | ||
160 | - if (pServer){ | ||
161 | - pServer->ByeInvite(m_SipChannelId, m_rtp_port); | ||
162 | - } | ||
163 | - | ||
164 | - if(m_listenFinishThread.joinable()){ | ||
165 | - m_listenFinishThread.join(); | ||
166 | - } | ||
167 | -} | ||
168 | - | ||
169 | -void RTPTcpReceiver::close_task(){ | ||
170 | - m_bRtpExit = true; | ||
171 | - | ||
172 | - m_bClosing = true; | ||
173 | - | ||
174 | - m_bAccepted = true; | ||
175 | - | ||
176 | - LOG_DEBUG("[{}] 1.", m_SipChannelId); | ||
177 | - | ||
178 | - // rtp接收线程退出 | ||
179 | - if (m_rtpThread.joinable()) { | ||
180 | - m_rtpThread.join(); | ||
181 | - } | ||
182 | - | ||
183 | - LOG_DEBUG("[{}] 2.", m_SipChannelId); | ||
184 | - | ||
185 | - ClosePsThread(); | ||
186 | - | ||
187 | - m_bOpened = false; | ||
188 | - | ||
189 | - LOG_INFO("[{}] closed.", m_SipChannelId); | ||
190 | -} | ||
191 | - | ||
192 | -bool RTPTcpReceiver::isClosing(){ | ||
193 | - return m_bClosing; | ||
194 | -} | ||
195 | - | ||
196 | -int RTPTcpReceiver::initSession(int localPort){ | ||
197 | - m_nListener = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); | ||
198 | - if (m_nListener < 0) | ||
199 | - { | ||
200 | - return -1; | ||
201 | - } | ||
202 | - | ||
203 | - sockaddr_in serverAddr; | ||
204 | - memset(&serverAddr, 0, sizeof(sockaddr_in)); | ||
205 | - serverAddr.sin_family = AF_INET; | ||
206 | - serverAddr.sin_port = htons(localPort); | ||
207 | - serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); | ||
208 | - int nRet = bind(m_nListener, (sockaddr*)&serverAddr, sizeof(serverAddr)); | ||
209 | - if (nRet == -1) | ||
210 | - { | ||
211 | - LOG_ERROR("[{}] 绑定端口失败: {}", m_SipChannelId, localPort); | ||
212 | - return -1; | ||
213 | - } | ||
214 | - | ||
215 | - if (listen(m_nListener, 1) == -1) | ||
216 | - { | ||
217 | - LOG_ERROR("[{}] listen 失败", m_SipChannelId); | ||
218 | - return -1; | ||
219 | - } | ||
220 | - | ||
221 | - int nPackSize = 45678; | ||
222 | - m_pSessparams->SetProbationType(RTPSources::NoProbation); | ||
223 | - m_pSessparams->SetOwnTimestampUnit(90000.0 / 25.0); | ||
224 | - m_pSessparams->SetMaximumPacketSize(nPackSize + 64); | ||
225 | - | ||
226 | - int status = m_pTrans->Init(false); | ||
227 | - status = m_pTrans->Create(65535, NULL); | ||
228 | - m_pTrans->setReceiver(this); | ||
229 | - | ||
230 | - status = m_rtpSessionPtr->Create(*m_pSessparams, m_pTrans); | ||
231 | - if (status < 0) | ||
232 | - { | ||
233 | - // 若status = -59 ,需运行 export LOGNAME=root ,见 https://blog.csdn.net/m0_37876242/article/details/128588162 | ||
234 | - LOG_ERROR("[{}] create session error: {}", m_SipChannelId, status); | ||
235 | - return -1; | ||
236 | - } | ||
237 | - | ||
238 | - m_rtpThread = std::thread(rtp_revc_thread_, this); | ||
239 | - m_listenFinishThread = std::thread(listen_finish_thread_, this); | ||
240 | - | ||
241 | - if (InitPS() != 0) { | ||
242 | - return false; | ||
243 | - } | ||
244 | - | ||
245 | - bool bRet = RequestStream(); | ||
246 | - if (!bRet) | ||
247 | - { | ||
248 | - LOG_INFO("[{}] 请求流失败!", m_SipChannelId); | ||
249 | - return -1; | ||
250 | - } | ||
251 | - | ||
252 | - LOG_INFO("[{}] 初始化成功, congratulations !!!", m_SipChannelId); | ||
253 | - | ||
254 | - return 0; | ||
255 | -} | ||
256 | - | ||
257 | -// 图灵版本的请求 | ||
258 | -int RTPTcpReceiver::OnRtpRecv() | ||
259 | -{ | ||
260 | - if(nullptr == m_rtpSessionPtr){ | ||
261 | - return -1; | ||
262 | - } | ||
263 | - | ||
264 | - LOG_INFO("[{}] OnRtpRecv started, m_nListener : {}", m_SipChannelId, m_nListener); | ||
265 | - | ||
266 | - sockaddr_in clientAddr; | ||
267 | - int nLen = sizeof(sockaddr_in); | ||
268 | - SocketType nServer = -1; | ||
269 | - | ||
270 | - LOG_INFO("[{}] Poll started.", m_SipChannelId); | ||
271 | - int reconn_times = 0; | ||
272 | - int reaccept_times = 0; | ||
273 | - bool bReconn = false; | ||
274 | - while(!m_bRtpExit){ | ||
275 | - while(!m_bAccepted){ | ||
276 | - if(m_bRtpExit){ | ||
277 | - goto end_flag; | ||
278 | - } | ||
279 | - | ||
280 | - while (!bReconn){ | ||
281 | - if(m_bRtpExit){ | ||
282 | - goto end_flag; | ||
283 | - } | ||
284 | - | ||
285 | - reconn_times++; | ||
286 | - if(reconn_times > 10){ | ||
287 | - // 10次请求都失败,结束任务 | ||
288 | - m_bRtpExit = true; | ||
289 | - goto end_flag; | ||
290 | - } | ||
291 | - LOG_DEBUG("[{}] RequestStream...", m_SipChannelId); | ||
292 | - bReconn = RequestStream(); | ||
293 | - if (bReconn){ | ||
294 | - LOG_DEBUG("[{}] RequestStream, True", m_SipChannelId); | ||
295 | - continue; | ||
296 | - } | ||
297 | - LOG_DEBUG("[{}] RequestStream, False", m_SipChannelId); | ||
298 | - | ||
299 | - std::this_thread::sleep_for(std::chrono::seconds(5)); | ||
300 | - } | ||
301 | - | ||
302 | - LOG_DEBUG("[{}] accepting...", m_SipChannelId); | ||
303 | - nServer = accept(m_nListener, (sockaddr*)&clientAddr, (socklen_t * ) &nLen); | ||
304 | - if (-1 == nServer){ | ||
305 | - reaccept_times++; | ||
306 | - LOG_DEBUG("[{}] reaccept_times = {}", m_SipChannelId, reaccept_times); | ||
307 | - if(reaccept_times > 600){ | ||
308 | - LOG_DEBUG("[{}] reaccept_times > 600", m_SipChannelId); | ||
309 | - bReconn = false; | ||
310 | - reaccept_times = 0; | ||
311 | - } | ||
312 | - std::this_thread::sleep_for(std::chrono::milliseconds(100)); | ||
313 | - continue; | ||
314 | - } | ||
315 | - LOG_DEBUG("[{}] accept success", m_SipChannelId); | ||
316 | - m_rtpSessionPtr->AddDestination(RTPTCPAddress(nServer)); | ||
317 | - m_bAccepted = true; | ||
318 | - bReconn = false; | ||
319 | - reconn_times = 0; | ||
320 | - reaccept_times = 0; | ||
321 | - | ||
322 | - LOG_INFO("[{}] nServer={}", m_SipChannelId, nServer); | ||
323 | - break; | ||
324 | - } | ||
325 | - | ||
326 | - m_rtpSessionPtr->BeginDataAccess(); | ||
327 | - if (m_rtpSessionPtr->GotoFirstSourceWithData()) | ||
328 | - { | ||
329 | - do | ||
330 | - { | ||
331 | - RTPPacket *pack; | ||
332 | - | ||
333 | - while ((pack = m_rtpSessionPtr->GetNextPacket()) != NULL) | ||
334 | - { | ||
335 | - // LOG_DEBUG("[{}] time: {} ", m_SipChannelId, UtilTools::get_cur_time_ms()); | ||
336 | - ParsePacket(pack); | ||
337 | - | ||
338 | - m_rtpSessionPtr->DeletePacket(pack); | ||
339 | - } | ||
340 | - } while (m_rtpSessionPtr->GotoNextSourceWithData()); | ||
341 | - } | ||
342 | - | ||
343 | - m_rtpSessionPtr->EndDataAccess(); | ||
344 | - | ||
345 | - m_rtpSessionPtr->Poll(); | ||
346 | - std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
347 | - } | ||
348 | - | ||
349 | -end_flag: | ||
350 | - | ||
351 | - m_rtpSessionPtr->Destroy(); | ||
352 | - | ||
353 | - if(nServer > 0){ | ||
354 | - close(nServer); | ||
355 | - } | ||
356 | - if(m_nListener > 0){ | ||
357 | - close(m_nListener); | ||
358 | - } | ||
359 | - | ||
360 | - LOG_INFO("[{}] OnRtpRecv exited.", m_SipChannelId); | ||
361 | - | ||
362 | - return 0; | ||
363 | -} | ||
364 | - | ||
365 | - | ||
366 | -int RTPTcpReceiver::OnRtpRecv2() | ||
367 | -{ | ||
368 | - if(nullptr == m_rtpSessionPtr){ | ||
369 | - return -1; | ||
370 | - } | ||
371 | - | ||
372 | - LOG_INFO("[{}] OnRtpRecv started, m_nListener : {}", m_SipChannelId, m_nListener); | ||
373 | - | ||
374 | - sockaddr_in clientAddr; | ||
375 | - int nLen = sizeof(sockaddr_in); | ||
376 | - SocketType nServer = -1; | ||
377 | - | ||
378 | - LOG_INFO("[{}] Poll started.", m_SipChannelId); | ||
379 | - int reconn_times = 0; | ||
380 | - int reaccept_times = 0; | ||
381 | - bool bReconn = false; | ||
382 | - while(!m_bRtpExit){ | ||
383 | - while(!m_bAccepted){ | ||
384 | - if(m_bRtpExit){ | ||
385 | - goto end_flag; | ||
386 | - } | ||
387 | - | ||
388 | - while (!bReconn){ | ||
389 | - if(m_bRtpExit){ | ||
390 | - goto end_flag; | ||
391 | - } | ||
392 | - | ||
393 | - reconn_times++; | ||
394 | - if(reconn_times > 10){ | ||
395 | - // 10次请求都失败,结束任务 | ||
396 | - m_bRtpExit = true; | ||
397 | - goto end_flag; | ||
398 | - } | ||
399 | - LOG_DEBUG("[{}] RequestStream...", m_SipChannelId); | ||
400 | - bReconn = RequestStream(); | ||
401 | - if (bReconn){ | ||
402 | - LOG_DEBUG("[{}] RequestStream, True", m_SipChannelId); | ||
403 | - continue; | ||
404 | - } | ||
405 | - LOG_DEBUG("[{}] RequestStream, False", m_SipChannelId); | ||
406 | - | ||
407 | - std::this_thread::sleep_for(std::chrono::seconds(5)); | ||
408 | - } | ||
409 | - | ||
410 | - LOG_DEBUG("[{}] accepting...", m_SipChannelId); | ||
411 | - nServer = accept(m_nListener, (sockaddr*)&clientAddr, (socklen_t * ) &nLen); | ||
412 | - if (-1 == nServer){ | ||
413 | - reaccept_times++; | ||
414 | - LOG_DEBUG("[{}] reaccept_times = {}", m_SipChannelId, reaccept_times); | ||
415 | - if(reaccept_times > 600){ | ||
416 | - LOG_DEBUG("[{}] reaccept_times > 600", m_SipChannelId); | ||
417 | - bReconn = false; | ||
418 | - reaccept_times = 0; | ||
419 | - } | ||
420 | - std::this_thread::sleep_for(std::chrono::milliseconds(100)); | ||
421 | - continue; | ||
422 | - } | ||
423 | - LOG_DEBUG("[{}] accept success", m_SipChannelId); | ||
424 | - m_rtpSessionPtr->AddDestination(RTPTCPAddress(nServer)); | ||
425 | - m_bAccepted = true; | ||
426 | - bReconn = false; | ||
427 | - reconn_times = 0; | ||
428 | - reaccept_times = 0; | ||
429 | - | ||
430 | - LOG_INFO("[{}] nServer={}", m_SipChannelId, nServer); | ||
431 | - break; | ||
432 | - } | ||
433 | - | ||
434 | - m_rtpSessionPtr->BeginDataAccess(); | ||
435 | - if (m_rtpSessionPtr->GotoFirstSourceWithData()) | ||
436 | - { | ||
437 | - do | ||
438 | - { | ||
439 | - RTPPacket *pack; | ||
440 | - | ||
441 | - while ((pack = m_rtpSessionPtr->GetNextPacket()) != NULL) | ||
442 | - { | ||
443 | - // LOG_DEBUG("[{}] time: {} ", m_SipChannelId, UtilTools::get_cur_time_ms()); | ||
444 | - ParsePacket(pack); | ||
445 | - | ||
446 | - m_rtpSessionPtr->DeletePacket(pack); | ||
447 | - } | ||
448 | - } while (m_rtpSessionPtr->GotoNextSourceWithData()); | ||
449 | - } | ||
450 | - | ||
451 | - m_rtpSessionPtr->EndDataAccess(); | ||
452 | - | ||
453 | - m_rtpSessionPtr->Poll(); | ||
454 | - std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
455 | - } | ||
456 | - | ||
457 | -end_flag: | ||
458 | - | ||
459 | - m_rtpSessionPtr->Destroy(); | ||
460 | - | ||
461 | - if(nServer > 0){ | ||
462 | - close(nServer); | ||
463 | - } | ||
464 | - if(m_nListener > 0){ | ||
465 | - close(m_nListener); | ||
466 | - } | ||
467 | - | ||
468 | - LOG_INFO("[{}] OnRtpRecv exited.", m_SipChannelId); | ||
469 | - | ||
470 | - return 0; | ||
471 | -} | ||
472 | - | ||
473 | -int RTPTcpReceiver::ListenFinish(){ | ||
474 | - while(!m_bRtpExit){ | ||
475 | - std::this_thread::sleep_for(std::chrono::seconds(3)); | ||
476 | - } | ||
477 | - | ||
478 | - close_task(); | ||
479 | -} | ||
480 | - | ||
481 | -bool RTPTcpReceiver::ReConnect(){ | ||
482 | - m_bAccepted = false; | ||
483 | -} | ||
484 | - | ||
485 | -bool RTPTcpReceiver::RequestStream(){ | ||
486 | - WebsocketClient* pServer = WebsocketClient::getInstance(); | ||
487 | - if (pServer){ | ||
488 | - if (pServer->InviteTcp(m_SipChannelId, m_rtp_port, this) < 0) { | ||
489 | - return false; | ||
490 | - } | ||
491 | - } | ||
492 | - | ||
493 | - return true ; | ||
494 | -} | ||
495 | \ No newline at end of file | 0 | \ No newline at end of file |
src/decoder/gb28181/rtp/RTPTcpReceiver.h deleted
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 | -using namespace jrtplib; | ||
30 | -using namespace std; | ||
31 | - | ||
32 | - | ||
33 | - | ||
34 | -class TcpRTPSession; | ||
35 | -class MyTCPTransmitter; | ||
36 | - | ||
37 | -class RTPTcpReceiver:public RTPReceiver | ||
38 | -{ | ||
39 | -public: | ||
40 | - RTPTcpReceiver(); | ||
41 | - ~RTPTcpReceiver(); | ||
42 | - | ||
43 | - virtual bool Open(string channel_id); | ||
44 | - virtual bool IsOpened() ; | ||
45 | - virtual void Close() ; | ||
46 | - virtual bool RequestStream(); | ||
47 | - | ||
48 | -public: | ||
49 | - int OnRtpRecv(); | ||
50 | - int OnRtpRecv2(); | ||
51 | - bool ReConnect(); | ||
52 | - int ListenFinish(); | ||
53 | - bool isClosing(); | ||
54 | - | ||
55 | -private: | ||
56 | - int initSession(int localPort); | ||
57 | - void close_task(); | ||
58 | - | ||
59 | -private: | ||
60 | - std::atomic_bool m_bOpened; | ||
61 | - std::atomic_bool m_bAccepted; | ||
62 | - std::atomic_bool m_bClosing; | ||
63 | - | ||
64 | - int64_t m_idleCount; | ||
65 | - int64_t m_noDataCount;//线程计数,用于打开流成功但是实际没流过来 | ||
66 | - | ||
67 | - std::thread m_rtpThread; // RTP接收线程 | ||
68 | - SocketType m_nListener; | ||
69 | - | ||
70 | - RTPSession* m_rtpSessionPtr; // RTP会话 | ||
71 | - RTPSessionParams* m_pSessparams; | ||
72 | - MyTCPTransmitter* m_pTrans; | ||
73 | - | ||
74 | - std::thread m_listenFinishThread; // RTP接收线程 | ||
75 | - | ||
76 | - std::atomic_bool m_bNoData{false}; | ||
77 | -}; | ||
78 | - | ||
79 | -#endif // _RTP_TCP_RECEIVER_H_ |
src/decoder/gb28181/rtp/RTPUdpReceiver.cpp deleted
1 | - | ||
2 | -#include "RTPUdpReceiver.h" | ||
3 | -#include <iostream> | ||
4 | -#include <time.h> | ||
5 | - | ||
6 | -#include <thread> | ||
7 | -#include <chrono> | ||
8 | - | ||
9 | -#include "../common_header.h" | ||
10 | -#include "../websocket/WebsocketClient.h" | ||
11 | - | ||
12 | - | ||
13 | -using namespace std; | ||
14 | - | ||
15 | -#define BUFFERSIZE_1024 4096 | ||
16 | -#define BUFFERSIZE_GAP 4096//5120 //1024*5 | ||
17 | - | ||
18 | -namespace | ||
19 | -{ | ||
20 | - const int kVideoFrameSize = BUFFERSIZE_1024*BUFFERSIZE_1024*5*2; | ||
21 | - const int kRtpRecvBufferSize = BUFFERSIZE_1024*BUFFERSIZE_1024*2; | ||
22 | - const uint16_t kInvalidPort = 0; | ||
23 | -}; // namespace | ||
24 | - | ||
25 | -class UdpRTPSession : public RTPSession | ||
26 | -{ | ||
27 | -public: | ||
28 | - UdpRTPSession() {} | ||
29 | - virtual ~UdpRTPSession() {} | ||
30 | - | ||
31 | -private: | ||
32 | - virtual void OnRTPPacket(RTPPacket* pack, const RTPTime& receiverTime, const RTPAddress* senderAddress) | ||
33 | - { | ||
34 | - AddDestination(*senderAddress); | ||
35 | - } | ||
36 | - | ||
37 | - virtual void OnRTCPCompoundPacket(RTCPCompoundPacket *pack, const RTPTime &receivetime,const RTPAddress *senderaddress) | ||
38 | - { | ||
39 | - //AddDestination(*senderaddress); | ||
40 | - //const char* name = "hi~"; | ||
41 | - //SendRTCPAPPPacket(0, (const uint8_t*)name, "keeplive", 8); | ||
42 | - | ||
43 | - //printf("send rtcp app"); | ||
44 | - } | ||
45 | -}; | ||
46 | - | ||
47 | -static int rtp_revc_thread_(void* param) | ||
48 | -{ | ||
49 | - if (!param) | ||
50 | - { | ||
51 | - return -1; | ||
52 | - } | ||
53 | - | ||
54 | - RTPUdpReceiver* self = (RTPUdpReceiver*)param; | ||
55 | - return self->OnRtpRecv(); | ||
56 | -} | ||
57 | - | ||
58 | -static int connecting_thread_(void* param) | ||
59 | -{ | ||
60 | - if (!param) { | ||
61 | - return -1; | ||
62 | - } | ||
63 | - | ||
64 | - RTPUdpReceiver* self = (RTPUdpReceiver*)param; | ||
65 | - return self->CheckConnecting(); | ||
66 | -} | ||
67 | - | ||
68 | -RTPUdpReceiver::RTPUdpReceiver() | ||
69 | -:m_bOpened(false) | ||
70 | -, m_idleCount(-1) | ||
71 | -,m_noDataCount(-1) | ||
72 | -{ | ||
73 | - m_bRtpExit = false; | ||
74 | - m_sessparamsPtr = new RTPSessionParams(); | ||
75 | - m_transparamsPtr = new RTPUDPv4TransmissionParams(); | ||
76 | - m_rtpSessionPtr = new UdpRTPSession(); | ||
77 | -} | ||
78 | - | ||
79 | -RTPUdpReceiver::~RTPUdpReceiver() | ||
80 | -{ | ||
81 | - m_bRtpExit = true; | ||
82 | - | ||
83 | - if(nullptr != m_sessparamsPtr){ | ||
84 | - delete m_sessparamsPtr; | ||
85 | - m_sessparamsPtr = nullptr; | ||
86 | - } | ||
87 | - | ||
88 | - if(nullptr != m_transparamsPtr){ | ||
89 | - delete m_transparamsPtr; | ||
90 | - m_transparamsPtr = nullptr; | ||
91 | - } | ||
92 | - | ||
93 | - if (nullptr != m_connThreadPtr && m_connThreadPtr->joinable()) { | ||
94 | - m_connThreadPtr->join(); | ||
95 | - delete m_connThreadPtr; | ||
96 | - m_connThreadPtr = nullptr; | ||
97 | - } | ||
98 | - | ||
99 | - if(nullptr != m_rtpSessionPtr){ | ||
100 | - delete m_rtpSessionPtr; | ||
101 | - m_rtpSessionPtr = nullptr; | ||
102 | - } | ||
103 | -} | ||
104 | - | ||
105 | -bool RTPUdpReceiver::Open(string channel_id) | ||
106 | -{ | ||
107 | - m_SipChannelId = channel_id; | ||
108 | - | ||
109 | - m_rtp_port = allocRtpPort(); | ||
110 | - if (m_rtp_port < 0) { | ||
111 | - return false; | ||
112 | - } | ||
113 | - | ||
114 | - m_sessparamsPtr->SetUsePollThread(true); | ||
115 | - m_sessparamsPtr->SetMinimumRTCPTransmissionInterval(10); | ||
116 | - m_sessparamsPtr->SetOwnTimestampUnit(1.0/90000.0); | ||
117 | - m_sessparamsPtr->SetAcceptOwnPackets(true); | ||
118 | - | ||
119 | - m_transparamsPtr->SetPortbase(m_rtp_port); | ||
120 | - m_transparamsPtr->SetRTPReceiveBuffer(kRtpRecvBufferSize); | ||
121 | - | ||
122 | - LOG_INFO("[{}] port: {}", m_SipChannelId, m_rtp_port); | ||
123 | - | ||
124 | - int err = m_rtpSessionPtr->Create(*m_sessparamsPtr, m_transparamsPtr); | ||
125 | - if (err != 0) { | ||
126 | - LOG_ERROR("[{}] Create error: {}", m_SipChannelId, err); | ||
127 | - return false; | ||
128 | - } | ||
129 | - | ||
130 | - m_rtpThreadPtr = new std::thread(rtp_revc_thread_, this); | ||
131 | - if (nullptr == m_rtpThreadPtr) { | ||
132 | - LOG_ERROR("[{}] Create m_rtpThreadPtr error", m_SipChannelId); | ||
133 | - return false; | ||
134 | - } | ||
135 | - | ||
136 | - if (InitPS() != 0) { | ||
137 | - return false; | ||
138 | - } | ||
139 | - | ||
140 | - // InitPS()成功就得起该线程,因为ClosePsThread是在这里完成的 | ||
141 | - m_connThreadPtr = new std::thread(connecting_thread_, this); | ||
142 | - if (nullptr == m_connThreadPtr) { | ||
143 | - LOG_ERROR("[{}] Create m_connThreadPtr error", m_SipChannelId); | ||
144 | - return false; | ||
145 | - } | ||
146 | - | ||
147 | - bool bReq = RequestStream(); | ||
148 | - if (!bReq) { | ||
149 | - LOG_INFO("[{}] RequestStream failed !", m_SipChannelId); | ||
150 | - Close(); | ||
151 | - return false; | ||
152 | - } | ||
153 | - | ||
154 | - m_bOpened = true; | ||
155 | - m_bNoData = false; | ||
156 | - LOG_INFO("[{}] Open ok", m_SipChannelId); | ||
157 | - | ||
158 | - return true; | ||
159 | -} | ||
160 | - | ||
161 | -bool RTPUdpReceiver::IsOpened() | ||
162 | -{ | ||
163 | - return m_bOpened; | ||
164 | -} | ||
165 | - | ||
166 | -void RTPUdpReceiver::Close() | ||
167 | -{ | ||
168 | - m_bRtpExit = true; | ||
169 | -} | ||
170 | - | ||
171 | -// 收RTP包线程 | ||
172 | -int RTPUdpReceiver::OnRtpRecv() | ||
173 | -{ | ||
174 | - if(nullptr == m_rtpSessionPtr){ | ||
175 | - return -1; | ||
176 | - } | ||
177 | - | ||
178 | - m_bRecvExit = false; | ||
179 | - | ||
180 | - LOG_INFO("[{}] OnRtpRecv started.", m_SipChannelId); | ||
181 | - while (!m_bRecvExit) | ||
182 | - { | ||
183 | - m_rtpSessionPtr->Poll(); | ||
184 | - m_rtpSessionPtr->BeginDataAccess(); | ||
185 | - | ||
186 | - if (m_rtpSessionPtr->GotoFirstSourceWithData()) | ||
187 | - { | ||
188 | - // LOG_INFO("OnRtpRecv GotoFirstSourceWithData --{}", m_SipChannelId); | ||
189 | - last_recv_ts = UtilTools::get_cur_time_ms(); | ||
190 | - m_idleCount = 0; | ||
191 | - m_noDataCount = 0; | ||
192 | - do | ||
193 | - { | ||
194 | - RTPPacket* packet; | ||
195 | - while ((packet = m_rtpSessionPtr->GetNextPacket()) != NULL) | ||
196 | - { | ||
197 | - m_bNoData = false; | ||
198 | - // LOG_INFO("OnRtpRecv GetNextPacket --{}", m_SipChannelId); | ||
199 | - int ret = ParsePacket(packet); | ||
200 | - m_rtpSessionPtr->DeletePacket(packet); | ||
201 | - | ||
202 | - if(ret != 0){ | ||
203 | - m_bRecvExit = true; | ||
204 | - } | ||
205 | - } | ||
206 | - } while (m_rtpSessionPtr->GotoNextSourceWithData()); | ||
207 | - } | ||
208 | - | ||
209 | - m_rtpSessionPtr->EndDataAccess(); | ||
210 | - | ||
211 | - std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
212 | - } | ||
213 | - | ||
214 | - LOG_INFO("[{}] OnRtpRecv exited.", m_SipChannelId); | ||
215 | - | ||
216 | - return 0; | ||
217 | -} | ||
218 | - | ||
219 | -bool RTPUdpReceiver::RequestStream() { | ||
220 | - WebsocketClient* pClient = WebsocketClient::getInstance(); | ||
221 | - if (pClient){ | ||
222 | - if (pClient->InviteUdp(m_SipChannelId, m_rtp_port, this) < 0) { | ||
223 | - return false; | ||
224 | - } | ||
225 | - } | ||
226 | - | ||
227 | - return true; | ||
228 | -} | ||
229 | - | ||
230 | -int RTPUdpReceiver::CheckConnecting() { | ||
231 | - LOG_INFO("[{}] CheckConnecting started.", m_SipChannelId); | ||
232 | - | ||
233 | - int count = 0; | ||
234 | - while (!m_bRtpExit) | ||
235 | - { | ||
236 | - if (m_bNoData) { | ||
237 | - // bool bReq = RequestStream(); | ||
238 | - // if (!bReq) { | ||
239 | - // LOG_INFO("[{}] RequestStream failed !", m_SipChannelId); | ||
240 | - // } | ||
241 | - | ||
242 | - wait_times(50); // 等待5s | ||
243 | - | ||
244 | - count++; | ||
245 | - | ||
246 | - if (count > 60) { | ||
247 | - // 3min 依然没数据过来,则关闭 | ||
248 | - m_bRtpExit = true; | ||
249 | - break; | ||
250 | - } | ||
251 | - } else { | ||
252 | - m_bNoData = true; | ||
253 | - | ||
254 | - wait_times(100); // 等待10s, 10s之内正常有数据的情况 m_bNoData 已经被置为false | ||
255 | - } | ||
256 | - } | ||
257 | - | ||
258 | - m_bRecvExit = true; | ||
259 | - | ||
260 | - // 结束整个任务 | ||
261 | - WebsocketClient* pClient = WebsocketClient::getInstance(); | ||
262 | - if (pClient){ | ||
263 | - pClient->ByeInvite(m_SipChannelId, m_rtp_port); | ||
264 | - } | ||
265 | - | ||
266 | - LOG_DEBUG("[{}] ByeInvite", m_SipChannelId); | ||
267 | - | ||
268 | - // rtp接收线程退出 | ||
269 | - if (nullptr != m_rtpThreadPtr && m_rtpThreadPtr->joinable()) | ||
270 | - { | ||
271 | - m_rtpThreadPtr->join(); | ||
272 | - delete m_rtpThreadPtr; | ||
273 | - m_rtpThreadPtr = nullptr; | ||
274 | - } | ||
275 | - | ||
276 | - m_rtpSessionPtr->Destroy(); | ||
277 | - | ||
278 | - ClosePsThread(); | ||
279 | - | ||
280 | - m_bOpened = false; | ||
281 | - | ||
282 | - LOG_INFO("[{}] CheckConnecting exited.", m_SipChannelId); | ||
283 | - | ||
284 | - return 0; | ||
285 | -} | ||
286 | - | ||
287 | -// 对退出命令敏感的延时 | ||
288 | -bool RTPUdpReceiver::wait_times(int times) { | ||
289 | - int count_sleep = times; | ||
290 | - while (!m_bRtpExit) { | ||
291 | - count_sleep-- ; | ||
292 | - if (count_sleep <= 0) { | ||
293 | - count_sleep = times; | ||
294 | - break; | ||
295 | - } | ||
296 | - std::this_thread::sleep_for(std::chrono::milliseconds(100)); | ||
297 | - } | ||
298 | -} | ||
299 | \ No newline at end of file | 0 | \ No newline at end of file |
src/decoder/gb28181/rtp/RTPUdpReceiver.h deleted
1 | -#ifndef _RTP_UDP_RECEIVER_H_ | ||
2 | -#define _RTP_UDP_RECEIVER_H_ | ||
3 | - | ||
4 | -#include "rtpsessionparams.h" | ||
5 | -#include "rtpudpv4transmitter.h" | ||
6 | -#include "rtpsession.h" | ||
7 | -#include "rtppacket.h" | ||
8 | -#include <queue> | ||
9 | -#include <iostream> | ||
10 | -#include <thread> | ||
11 | -#include <string> | ||
12 | -#include <mutex> | ||
13 | - | ||
14 | -#include "RTPReceiver.h" | ||
15 | - | ||
16 | - | ||
17 | -using namespace jrtplib; | ||
18 | -using namespace std; | ||
19 | - | ||
20 | - | ||
21 | -class UdpRTPSession; | ||
22 | - | ||
23 | -class RTPUdpReceiver: public RTPReceiver | ||
24 | -{ | ||
25 | -public: | ||
26 | - RTPUdpReceiver(); | ||
27 | - ~RTPUdpReceiver(); | ||
28 | - | ||
29 | - virtual bool Open(string channel_id); | ||
30 | - virtual bool IsOpened() ; | ||
31 | - virtual void Close() ; | ||
32 | - virtual bool RequestStream(); | ||
33 | - | ||
34 | -public: | ||
35 | - int OnRtpRecv(); | ||
36 | - int CheckConnecting(); | ||
37 | - | ||
38 | -private: | ||
39 | - bool wait_times(int times); | ||
40 | - | ||
41 | -private: | ||
42 | - std::thread* m_rtpThreadPtr{nullptr}; // RTP接收线程 | ||
43 | - std::thread* m_connThreadPtr{nullptr}; // 判断流是否还在的线程 | ||
44 | - | ||
45 | - RTPSession* m_rtpSessionPtr{nullptr}; // RTP会话 | ||
46 | - RTPSession m_rtpSession; | ||
47 | - | ||
48 | - std::atomic_bool m_bOpened; | ||
49 | - | ||
50 | - int64_t m_idleCount; | ||
51 | - int64_t m_noDataCount;//线程计数,用于打开流成功但是实际没流过来 | ||
52 | - | ||
53 | - RTPSessionParams* m_sessparamsPtr{nullptr}; | ||
54 | - RTPUDPv4TransmissionParams* m_transparamsPtr{nullptr}; | ||
55 | - | ||
56 | - string m_sip_channel_id; | ||
57 | - | ||
58 | - std::atomic_bool m_bNoData{false}; | ||
59 | - bool m_bRecvExit{false}; | ||
60 | -}; | ||
61 | - | ||
62 | -#endif // _RTP_UDP_RECEIVER_H_ |
src/decoder/gb28181/rtp/buffer.h deleted
1 | -/*******************************************************} | ||
2 | -{ } | ||
3 | -{ File: buffer.h } | ||
4 | -{ Created by Tsviatko Jongov } | ||
5 | -{ http://tsviatko.jongov.com } | ||
6 | -{ Date : 25.01.2007 } | ||
7 | -{ } | ||
8 | -{ CBuffer class. } | ||
9 | -{ } | ||
10 | -{*******************************************************/ | ||
11 | -#pragma once | ||
12 | -#include <string.h> | ||
13 | -#include <malloc.h> | ||
14 | - | ||
15 | -typedef int BOOL; | ||
16 | - | ||
17 | -class CBuffer | ||
18 | -{ | ||
19 | -private: | ||
20 | - char * fBuf = NULL; // buffer for bytes | ||
21 | - int fSize; // size of buffer | ||
22 | - int fLast; // points after Last valid byte | ||
23 | -public: | ||
24 | - CBuffer(int Size) | ||
25 | - { | ||
26 | - fLast = 0; | ||
27 | - fSize = 0; | ||
28 | - fFirst = 0; | ||
29 | - | ||
30 | - if (Size > 0) | ||
31 | - { | ||
32 | - fBuf = (char *)malloc(Size); | ||
33 | - fSize = Size; | ||
34 | - } | ||
35 | - } | ||
36 | - | ||
37 | - ~CBuffer() | ||
38 | - { | ||
39 | - if (fBuf != NULL) | ||
40 | - { | ||
41 | - free(fBuf); | ||
42 | - fBuf = NULL; | ||
43 | - } | ||
44 | - } | ||
45 | - | ||
46 | - | ||
47 | - void add(char * Data, int Size) | ||
48 | - { | ||
49 | - | ||
50 | - if (fLast + Size > fSize) | ||
51 | - { | ||
52 | - char * tmp = (char *)malloc(fSize + Size); | ||
53 | - memcpy(tmp, fBuf, fLast); | ||
54 | - fSize += Size; | ||
55 | - free(fBuf); | ||
56 | - fBuf = tmp; | ||
57 | - } | ||
58 | - | ||
59 | - memcpy(fBuf + fLast, Data, Size); | ||
60 | - fLast += Size; | ||
61 | - } | ||
62 | - | ||
63 | - void compact() | ||
64 | - { | ||
65 | - if (fFirst > 0) | ||
66 | - { | ||
67 | - int aLen = fLast - fFirst; | ||
68 | - memmove(fBuf, fBuf + fFirst, aLen); | ||
69 | - fFirst = 0; | ||
70 | - fLast = aLen; | ||
71 | - } | ||
72 | - } | ||
73 | - | ||
74 | - void reset() | ||
75 | - { | ||
76 | - fFirst = 0; | ||
77 | - fLast = 0; | ||
78 | - } | ||
79 | - | ||
80 | - int len() | ||
81 | - { | ||
82 | - return (fLast - fFirst); | ||
83 | - } | ||
84 | - | ||
85 | - void * head() | ||
86 | - { | ||
87 | - return fBuf + fFirst; | ||
88 | - } | ||
89 | - | ||
90 | - int fFirst; | ||
91 | -}; | ||
92 | \ No newline at end of file | 0 | \ No newline at end of file |
src/decoder/gb28181/rtp/demuxer.cpp deleted
1 | -/*******************************************************} | ||
2 | -{ } | ||
3 | -{ File: demuxer.cpp } | ||
4 | -{ Created by Tsviatko Jongov } | ||
5 | -{ http://tsviatko.jongov.com } | ||
6 | -{ Date : 25.01.2007 } | ||
7 | -{ } | ||
8 | -{ CMpeg2Demux class. } | ||
9 | -{ } | ||
10 | -{*******************************************************/ | ||
11 | -#include "assert.h" | ||
12 | -#include <stdio.h> | ||
13 | -#include "demuxer.h" | ||
14 | -#include "Pack_Header_Def.h" | ||
15 | -#include "time.h" | ||
16 | - | ||
17 | -#include <chrono> | ||
18 | - | ||
19 | -#ifdef _WIN32 | ||
20 | -#include "Winsock2.h" | ||
21 | -#pragma comment(lib, "ws2_32.lib") | ||
22 | -#endif | ||
23 | -#ifdef __linux__ | ||
24 | -#include "arpa/inet.h" | ||
25 | -#endif | ||
26 | - | ||
27 | -#include "../common_header.h" | ||
28 | - | ||
29 | -using namespace std; | ||
30 | - | ||
31 | - | ||
32 | -static /*_inline*/ unsigned int asm_swap32(unsigned int x) | ||
33 | -{ | ||
34 | - return ntohl(x); | ||
35 | -} | ||
36 | - | ||
37 | -static /*_inline*/ unsigned short asm_swap16(unsigned short x) | ||
38 | -{ | ||
39 | - return ntohs(x); | ||
40 | -} | ||
41 | - | ||
42 | -CMpeg2Demux::CMpeg2Demux() | ||
43 | -: m_streamType(STREAM_TYPE_UNKNOWN) | ||
44 | -,m_userdata(NULL) | ||
45 | -,m_userdata2(NULL) | ||
46 | -,m_lastiskeyfram(false) | ||
47 | -{ | ||
48 | - try | ||
49 | - { | ||
50 | - fBuffer = new CBuffer(1024 * 1024); | ||
51 | - if (fBuffer == NULL) | ||
52 | - { | ||
53 | - } | ||
54 | - m_lastpts = 0; | ||
55 | - fReceiveFunction = 0; | ||
56 | - fReceiveFunction2 = 0; | ||
57 | - | ||
58 | - m_psvideo= new CBuffer(1024*50); | ||
59 | - m_esvideo= new CBuffer(1024*50); | ||
60 | - m_psaudio= new CBuffer(1024*50); | ||
61 | - m_esaudio= new CBuffer(1024*50); | ||
62 | - } | ||
63 | - catch (...) | ||
64 | - { | ||
65 | - } | ||
66 | -}; | ||
67 | - | ||
68 | -CMpeg2Demux::~CMpeg2Demux() | ||
69 | -{ | ||
70 | - try | ||
71 | - { | ||
72 | - if (fBuffer != NULL) | ||
73 | - { | ||
74 | - delete fBuffer; | ||
75 | - fBuffer = NULL; | ||
76 | - } | ||
77 | - | ||
78 | - if (NULL != m_psvideo) | ||
79 | - { | ||
80 | - delete m_psvideo; | ||
81 | - m_psvideo = NULL; | ||
82 | - } | ||
83 | - if (NULL != m_esvideo) | ||
84 | - { | ||
85 | - delete m_esvideo; | ||
86 | - m_esvideo = NULL; | ||
87 | - } | ||
88 | - if (NULL != m_psaudio) | ||
89 | - { | ||
90 | - delete m_psaudio; | ||
91 | - m_psaudio = NULL; | ||
92 | - } | ||
93 | - if (NULL != m_esaudio) | ||
94 | - { | ||
95 | - delete m_esaudio; | ||
96 | - m_esaudio = NULL; | ||
97 | - } | ||
98 | - } | ||
99 | - catch (...) | ||
100 | - { | ||
101 | - } | ||
102 | -}; | ||
103 | - | ||
104 | -int CMpeg2Demux::AddData(void * Data, int Size/*, DWORD pts*/) | ||
105 | -{ | ||
106 | - try | ||
107 | - { | ||
108 | - if ((Data == NULL) || (Size <= 0)) | ||
109 | - { | ||
110 | - return (-1); | ||
111 | - } | ||
112 | - | ||
113 | - /*m_timeStamp = pts;*/ | ||
114 | - fBuffer->add((char *)Data, Size); | ||
115 | - if (!Demultiplex()) | ||
116 | - { | ||
117 | - return (-1); | ||
118 | - } | ||
119 | - | ||
120 | - return (0); | ||
121 | - } | ||
122 | - catch (...) | ||
123 | - { | ||
124 | - return (-1); | ||
125 | - } | ||
126 | -} | ||
127 | - | ||
128 | -void CMpeg2Demux::SetReceiveFunction(ReceiveFunction * func, void* userdata) | ||
129 | -{ | ||
130 | - try | ||
131 | - { | ||
132 | - fReceiveFunction = func; | ||
133 | - m_userdata = userdata; | ||
134 | - } | ||
135 | - catch (...) | ||
136 | - { | ||
137 | - } | ||
138 | -} | ||
139 | - | ||
140 | -void CMpeg2Demux::SetReceiveFunction2(ReceiveFunction2 * func2, void* userdata2) | ||
141 | -{ | ||
142 | - fReceiveFunction2 = func2; | ||
143 | - m_userdata2 = userdata2; | ||
144 | -} | ||
145 | - | ||
146 | -uint64_t GetLocalTimeOfMicroSecond() | ||
147 | -{ | ||
148 | - chrono::time_point<chrono::system_clock, chrono::microseconds> tpMicro | ||
149 | - = chrono::time_point_cast<chrono::microseconds>(chrono::system_clock::now()); | ||
150 | - | ||
151 | - return tpMicro.time_since_epoch().count(); | ||
152 | -} | ||
153 | - | ||
154 | -int CMpeg2Demux::Demultiplex() | ||
155 | -{ | ||
156 | - try | ||
157 | - { | ||
158 | - unsigned char * PDW {}; | ||
159 | - unsigned int Code {}; | ||
160 | - int Processed = 0; | ||
161 | - int StreamID {}; | ||
162 | - int PES_packet_length {}; | ||
163 | - int PES_header_data_length {}; | ||
164 | - int Val {}; | ||
165 | - | ||
166 | - if (fBuffer->len() <= 0) | ||
167 | - { | ||
168 | - return (0); | ||
169 | - } | ||
170 | - | ||
171 | - PDW = (unsigned char *)fBuffer->head(); | ||
172 | - while (fBuffer->len() - Processed > 140) | ||
173 | - { | ||
174 | - if ((*(unsigned int *)PDW & 0x00FFFFFF) != 0x00010000) | ||
175 | - { | ||
176 | - PDW++; | ||
177 | - Processed++; | ||
178 | - continue; | ||
179 | - } | ||
180 | - | ||
181 | - Code = asm_swap32(*(unsigned int *)PDW); | ||
182 | - StreamID = (Code & 0xFF); | ||
183 | - if (PACK_START_CODE != Code) | ||
184 | - { | ||
185 | - unsigned short pespacklen = asm_swap16(*(unsigned short *)(PDW + 4)) + 6; | ||
186 | - if (fBuffer->len() - Processed < pespacklen + 6) | ||
187 | - { | ||
188 | - break; | ||
189 | - } | ||
190 | - } | ||
191 | - | ||
192 | - if (PACK_START_CODE == Code)//ǰһ��pspack�����һ��pspack��ʼ | ||
193 | - { | ||
194 | - if (fReceiveFunction != NULL && m_esvideo->len())//��Ƶes | ||
195 | - { | ||
196 | - PS_HEADER_tag* pshead = (PS_HEADER_tag*)m_psvideo->head(); | ||
197 | - uint64_t pts = 0; | ||
198 | - pshead->getSystem_clock_reference_base(pts); | ||
199 | - pts = pts/90; | ||
200 | - int64_t localPts = GetLocalTimeOfMicroSecond(); | ||
201 | - fReceiveFunction(m_streamType, m_esvideo->head(), m_esvideo->len(), pts, localPts, m_lastiskeyfram, m_userdata); | ||
202 | - } | ||
203 | - m_esvideo->fFirst = m_esvideo->len(); | ||
204 | - m_esvideo->compact(); | ||
205 | - | ||
206 | - if (fReceiveFunction != NULL && m_esaudio->len())//��Ƶes | ||
207 | - { | ||
208 | - int64_t localPts = GetLocalTimeOfMicroSecond(); | ||
209 | - fReceiveFunction(0xC0, m_esaudio->head(), m_esaudio->len(), m_lastpts, localPts, 0, m_userdata); | ||
210 | - } | ||
211 | - m_esaudio->fFirst = m_esaudio->len(); | ||
212 | - m_esaudio->compact(); | ||
213 | - | ||
214 | - if (fReceiveFunction2 != NULL && m_psvideo->len())//��Ƶps | ||
215 | - { | ||
216 | - fReceiveFunction2(STREAM_TYPE_VIDEO,m_psvideo->head(),m_psvideo->len(),m_lastpts,m_lastiskeyfram,m_userdata2); | ||
217 | - } | ||
218 | - m_psvideo->fFirst = m_psvideo->len(); | ||
219 | - m_psvideo->compact(); | ||
220 | - | ||
221 | - if (fReceiveFunction2 != NULL && m_psaudio->len())//��Ƶ | ||
222 | - { | ||
223 | - fReceiveFunction2(STREAM_TYPE_AUDIO,m_psaudio->head(),m_psaudio->len(),m_lastpts,0,m_userdata2); | ||
224 | - } | ||
225 | - m_psaudio->fFirst = m_psaudio->len(); | ||
226 | - m_psaudio->compact(); | ||
227 | - | ||
228 | - PS_HEADER_tag* ppshead = (PS_HEADER_tag*)PDW; | ||
229 | - unsigned long psheadlen = sizeof(PS_HEADER_tag) + ppshead->pack_stuffing_length; | ||
230 | - if (fBuffer->len() - Processed < (int)psheadlen) | ||
231 | - { | ||
232 | - break; | ||
233 | - } | ||
234 | - | ||
235 | - // | ||
236 | - m_lastiskeyfram = false; | ||
237 | - if ((*(unsigned int *)(PDW+psheadlen)&0x00FFFFFF) != 0x00010000) | ||
238 | - { | ||
239 | - } | ||
240 | - else | ||
241 | - { | ||
242 | - m_psvideo->add((char*)PDW,psheadlen);//psͷд����Ƶ������ | ||
243 | - PDW += psheadlen; | ||
244 | - Processed += psheadlen; | ||
245 | - continue; | ||
246 | - } | ||
247 | - } | ||
248 | - else if (SYSTEM_START_CODE == Code)//system_header | ||
249 | - { | ||
250 | - unsigned short pespacklen = asm_swap16(*(unsigned short *)(PDW + 4)) + 6; | ||
251 | - if ((*(unsigned int *)(PDW+pespacklen)&0x00FFFFFF) != 0x00010000) | ||
252 | - { | ||
253 | - LOG_WARN("SYSTEM_START_CODE: Warning in CMpeg2Demux::Demultiplex - ((*PDW & 0x00FFFFFF) != 0x00010000).\n"); | ||
254 | - } | ||
255 | - else | ||
256 | - { | ||
257 | - m_psvideo->add((char*)PDW,pespacklen);//psͷд����Ƶ������ | ||
258 | - PDW += pespacklen; | ||
259 | - Processed +=pespacklen; | ||
260 | - m_lastiskeyfram = true; | ||
261 | - continue; | ||
262 | - } | ||
263 | - } | ||
264 | - else if (PROGRAM_STREAM_MAP == StreamID)//psm | ||
265 | - { | ||
266 | - unsigned short pespacklen = asm_swap16(*(unsigned short *)(PDW + 4)) + 6; | ||
267 | - if ((*(unsigned int *)(PDW+pespacklen)&0x00FFFFFF) != 0x00010000) | ||
268 | - { | ||
269 | - } | ||
270 | - else | ||
271 | - { | ||
272 | - unsigned short program_stream_info_length; | ||
273 | - //unsigned short elementary_stream_map_length; | ||
274 | - unsigned short* plen = (unsigned short*)(PDW + 8); | ||
275 | - program_stream_info_length = ntohs(*plen); | ||
276 | - int test = *(PDW + 8 + program_stream_info_length + 5);//192 | ||
277 | - //assert(*(PDW+8+program_stream_info_length+5) == 0xe0); | ||
278 | - | ||
279 | - //if(*(PDW + 8 + program_stream_info_length + 5) != 0xe0) | ||
280 | - //{ | ||
281 | - // continue; | ||
282 | - //} | ||
283 | - //printf("0xe0=%d, 0x1b=%d\n", *(PDW + 8 + program_stream_info_length + 5), *(PDW + 8 + program_stream_info_length + 4)); | ||
284 | - if (m_pserror > 5 && (*(PDW + 8 + program_stream_info_length + 5) != 0xe0 && *(PDW + 8 + program_stream_info_length + 5) != 0xc0))//�ж�c0��Ϊ�˼�����Ŧ�������в�ʿ������С���� | ||
285 | - { | ||
286 | - LOG_ERROR("{}", m_pserror); | ||
287 | - return -1; | ||
288 | - } | ||
289 | - if (*(PDW + 8 + program_stream_info_length + 5) != 0xe0 && *(PDW + 8 + program_stream_info_length + 5) != 0xc0) | ||
290 | - { | ||
291 | - //printf("--------------------------------1\n"); | ||
292 | - ++m_pserror; | ||
293 | - continue; | ||
294 | - } | ||
295 | - m_lastiskeyfram = true; | ||
296 | - if (*(PDW + 8 + program_stream_info_length + 4) == 0x1b || *(PDW + 8 + program_stream_info_length + 4) == 0x03) | ||
297 | - { | ||
298 | - m_streamType = VIDEO_TYPE_H264; // H264 | ||
299 | - } | ||
300 | - else if (*(PDW + 8 + program_stream_info_length + 4) == 0x24) | ||
301 | - { | ||
302 | - m_streamType = VIDEO_TYPE_H265; // H265 | ||
303 | - } | ||
304 | - else if (*(PDW+8+program_stream_info_length+4) == 0x10) | ||
305 | - { | ||
306 | - m_streamType = VIDEO_TYPE_MPEG4; // MPEG4 | ||
307 | - } | ||
308 | - else | ||
309 | - { | ||
310 | - m_streamType = STREAM_TYPE_UNKNOWN; | ||
311 | - } | ||
312 | - m_pserror = 0; | ||
313 | - m_psvideo->add((char*)PDW,pespacklen);//psͷд����Ƶ������ | ||
314 | - PDW += pespacklen; | ||
315 | - Processed +=pespacklen; | ||
316 | - continue; | ||
317 | - } | ||
318 | - } | ||
319 | - else if (0xBD == StreamID)//˽������ | ||
320 | - { | ||
321 | - unsigned short pespacklen = asm_swap16(*(unsigned short *)(PDW + 4)) + 6; | ||
322 | - | ||
323 | - if ((*(unsigned int *)(PDW+pespacklen)&0x00FFFFFF) != 0x00010000) | ||
324 | - { | ||
325 | - } | ||
326 | - else | ||
327 | - { | ||
328 | - m_psvideo->add((char*)PDW,pespacklen);//psͷд����Ƶ������ | ||
329 | - PDW += pespacklen; | ||
330 | - Processed +=pespacklen; | ||
331 | - continue; | ||
332 | - } | ||
333 | - } | ||
334 | - | ||
335 | - if ((Code >= SYSTEM_START_CODE_MIN) && | ||
336 | - (Code <= SYSTEM_START_CODE_MAX) && | ||
337 | - (Code != PACK_START_CODE) && | ||
338 | - (Code != SYSTEM_START_CODE) && | ||
339 | - (StreamID != PROGRAM_STREAM_MAP) && | ||
340 | - (StreamID != PADDING_STREAM) && | ||
341 | - (StreamID != PRIVATE_STREAM_2) && | ||
342 | - (StreamID != ECM_STREAM) && | ||
343 | - (StreamID != EMM_STREAM) && | ||
344 | - (StreamID != PROGRAM_STREAM_DIRECTORY) && | ||
345 | - (StreamID != DSM_CC_STREAM) && | ||
346 | - (StreamID != ITU_T_STREAM_E)) | ||
347 | - { | ||
348 | - PES_packet_length = asm_swap16(*(unsigned short *)(PDW + 4)); | ||
349 | - PES_header_data_length = *(PDW + 8); | ||
350 | - | ||
351 | - if (PES_packet_length == 0) | ||
352 | - PES_packet_length = fBuffer->len() - Processed/* - 4*/; | ||
353 | - else | ||
354 | - PES_packet_length += 6; | ||
355 | - | ||
356 | - if (fBuffer->len() - Processed >= PES_packet_length/* + 4*/) | ||
357 | - { | ||
358 | - PES_HEADER_tag* peshead = (PES_HEADER_tag*)PDW; | ||
359 | - uint64_t pts = 0; | ||
360 | - if (peshead->PTS_DTS_flags&0x3) | ||
361 | - { | ||
362 | - PTS_tag* ptstag = (PTS_tag*)(PDW + 9); | ||
363 | - ptstag->getPTS(pts); | ||
364 | - m_lastpts = pts/90; | ||
365 | - } | ||
366 | - | ||
367 | - Val = 6 + 3 + PES_header_data_length; | ||
368 | - | ||
369 | - if (0xE0 == StreamID) | ||
370 | - { | ||
371 | - m_esvideo->add((char*)PDW + Val, PES_packet_length - Val); | ||
372 | - m_psvideo->add((char*)PDW, PES_packet_length); | ||
373 | - } | ||
374 | - else if (0xC0 == StreamID) | ||
375 | - { | ||
376 | - if (PES_packet_length + 6 - Val > 0) | ||
377 | - { | ||
378 | - m_esaudio->add((char*)PDW + Val,PES_packet_length - Val); | ||
379 | - } | ||
380 | - else | ||
381 | - { | ||
382 | - m_esaudio->add((char*)PDW + Val,PES_packet_length - 19); | ||
383 | - } | ||
384 | - m_psaudio->add((char*)PDW,PES_packet_length+6); | ||
385 | - } | ||
386 | - | ||
387 | - fBuffer->fFirst += Processed + PES_packet_length; | ||
388 | - fBuffer->compact(); | ||
389 | - | ||
390 | - Processed = 0; | ||
391 | - PDW = (unsigned char *)fBuffer->head(); | ||
392 | - } | ||
393 | - else | ||
394 | - { | ||
395 | - break; | ||
396 | - } | ||
397 | - } | ||
398 | - else { | ||
399 | - PDW++; | ||
400 | - Processed++; | ||
401 | - } | ||
402 | - }; | ||
403 | - | ||
404 | - if (Processed) | ||
405 | - { | ||
406 | - fBuffer->fFirst += Processed; | ||
407 | - fBuffer->compact(); | ||
408 | - Processed = 0; | ||
409 | - } | ||
410 | - return (true); | ||
411 | - } | ||
412 | - catch (...) | ||
413 | - { | ||
414 | - return (-1); | ||
415 | - } | ||
416 | -} | ||
417 | - |
src/decoder/gb28181/rtp/demuxer.h deleted
1 | -/*******************************************************} | ||
2 | -{ } | ||
3 | -{ File: demuxer.h } | ||
4 | -{ Created by Tsviatko Jongov } | ||
5 | -{ http://tsviatko.jongov.com } | ||
6 | -{ Date : 25.01.2007 } | ||
7 | -{ } | ||
8 | -{ CMpeg2Demux class. } | ||
9 | -{ } | ||
10 | -{*******************************************************/ | ||
11 | - | ||
12 | -#ifndef _DEMUXER_H_ | ||
13 | -#define _DEMUXER_H_ | ||
14 | - | ||
15 | - | ||
16 | -#include <stdint.h> | ||
17 | -#include "buffer.h" | ||
18 | - | ||
19 | -//MPEG-2 start codes | ||
20 | -#define SYSTEM_START_CODE_MIN 0x000001B9 | ||
21 | -#define SYSTEM_START_CODE_MAX 0x000001FF | ||
22 | -#define PACK_START_CODE 0x000001BA | ||
23 | -#define SYSTEM_START_CODE 0x000001BB | ||
24 | - | ||
25 | -//MPEG-2 stream IDs | ||
26 | -#define PROGRAM_STREAM_MAP 0xBC | ||
27 | -#define PADDING_STREAM 0xBE | ||
28 | -#define PRIVATE_STREAM_2 0xBF | ||
29 | -#define ECM_STREAM 0xF0 | ||
30 | -#define EMM_STREAM 0xF1 | ||
31 | -#define PROGRAM_STREAM_DIRECTORY 0xFF | ||
32 | -#define DSM_CC_STREAM 0xF2 | ||
33 | -#define ITU_T_STREAM_E 0xF8 | ||
34 | - | ||
35 | -#define STREAM_TYPE_VIDEO 1 | ||
36 | -#define STREAM_TYPE_AUDIO 2 | ||
37 | - | ||
38 | - | ||
39 | -#define STREAM_TYPE_UNKNOWN 0x00 | ||
40 | -#define VIDEO_TYPE_MPEG4 0x01 | ||
41 | -#define VIDEO_TYPE_H264 0x1B | ||
42 | -#define VIDEO_TYPE_H265 0x24 | ||
43 | -#define VIDEO_TYPE_SVAC 0x80 | ||
44 | -#define AUDIO_TYPE_G711 0x90 | ||
45 | -#define AUDIO_TYPE_G722_1 0x92 | ||
46 | -#define AUDIO_TYPE_G723_1 0x93 | ||
47 | -#define AUDIO_TYPE_G729 0x99 | ||
48 | -#define AUDIO_TYPE_SVAC 0x9B | ||
49 | -//#include <BaseTsd.h> | ||
50 | - | ||
51 | -//typedef long long INT64; | ||
52 | -//typedef unsigned long long UINT64; | ||
53 | - | ||
54 | -typedef int ReceiveFunction(unsigned char streamType, void* data, int size, uint64_t pts, uint64_t localPts, bool bKey, void* userData);//es�ص� | ||
55 | -typedef int ReceiveFunction2(unsigned int streamtype, void * Data, int Size, uint64_t pts, bool iskeyfram, void* userdata);//ps�ص� | ||
56 | - | ||
57 | -static /*_inline*/ unsigned int asm_swap32(unsigned int x); | ||
58 | -static /*_inline*/ unsigned short asm_swap16(unsigned short x); | ||
59 | - | ||
60 | -class CMpeg2Demux { | ||
61 | -private: | ||
62 | - CBuffer * fBuffer; | ||
63 | - void* m_userdata; | ||
64 | - void* m_userdata2; | ||
65 | - ReceiveFunction * fReceiveFunction; | ||
66 | - ReceiveFunction2* fReceiveFunction2; | ||
67 | -// CBuffer* m_frambuf; | ||
68 | - CBuffer* m_psvideo; | ||
69 | - CBuffer* m_esvideo; | ||
70 | - CBuffer* m_psaudio; | ||
71 | - CBuffer* m_esaudio; | ||
72 | - uint64_t m_lastpts; | ||
73 | - bool m_lastiskeyfram; | ||
74 | - unsigned char m_streamType; | ||
75 | - int m_pserror = 0; | ||
76 | - int Demultiplex(); | ||
77 | - | ||
78 | - /*DWORD m_timeStamp;*/ | ||
79 | -public: | ||
80 | - CMpeg2Demux(); | ||
81 | - ~CMpeg2Demux(); | ||
82 | - int AddData(void * Data, int Size/*, DWORD pts*/); | ||
83 | - void SetReceiveFunction(ReceiveFunction * func, void* userdata); | ||
84 | - void SetReceiveFunction2(ReceiveFunction2 * func2, void* userdata2); | ||
85 | -}; | ||
86 | - | ||
87 | -#endif // _DEMUXER_H_ | ||
88 | \ No newline at end of file | 0 | \ No newline at end of file |