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 | 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 | 46 | LOG_DEBUG("real decode thread exit success 1--{}", m_dec_name); |
47 | 47 | |
48 | 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 | 52 | delete m_rtpPtr; |
55 | 53 | m_rtpPtr = nullptr; |
56 | 54 | } |
57 | 55 | |
56 | + rtpDecoder.Close(); | |
57 | + | |
58 | 58 | if (m_post_decode_thread != 0) { |
59 | 59 | pthread_join(m_post_decode_thread,0); |
60 | 60 | m_post_decode_thread = 0; |
61 | 61 | } |
62 | 62 | |
63 | - rtpDecoder.Close(); | |
64 | - | |
65 | 63 | m_status = ECLOSED; |
66 | 64 | |
67 | 65 | LOG_INFO("解码器关闭成功 --{}", m_dec_name); |
... | ... | @@ -90,6 +88,8 @@ bool DvppGB28181Decoder2::init(FFDecConfig& cfg){ |
90 | 88 | return false; |
91 | 89 | } |
92 | 90 | |
91 | + rtpDecoder.SetFinishedCallback(RTP_Stream_End_CallBack, this); | |
92 | + | |
93 | 93 | m_cfg = cfg; |
94 | 94 | |
95 | 95 | LOG_INFO("init - {} ", m_dec_name); |
... | ... | @@ -160,6 +160,8 @@ void DvppGB28181Decoder2::display_thread(){ |
160 | 160 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
161 | 161 | } |
162 | 162 | |
163 | + decode_finished_cbk(m_finishedDecArg); | |
164 | + | |
163 | 165 | LOG_INFO("[{}] - display thread exited.", m_dec_name); |
164 | 166 | } |
165 | 167 | |
... | ... | @@ -169,8 +171,6 @@ void DvppGB28181Decoder2::stream_end_callback() |
169 | 171 | |
170 | 172 | m_status = ECLOSING; |
171 | 173 | |
172 | - decode_finished_cbk(m_finishedDecArg); | |
173 | - | |
174 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 0 | \ No newline at end of file |