Commit 74d1e6a8da5c1dbac8f0eff3f1d353f9bcf24161
1 parent
c8285c8d
完成gb28181大体的代码,未完成,bug可能很多
Showing
14 changed files
with
535 additions
and
382 deletions
src/decoder/dvpp/DvppDecoder.cpp
... | ... | @@ -156,6 +156,12 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ |
156 | 156 | if (avcodec_parameters_to_context(avctx, codecpar) < 0) |
157 | 157 | break; |
158 | 158 | |
159 | + int enType = getVdecType(codecpar->codec_id, codecpar->profile); | |
160 | + if(-1 == enType) { | |
161 | + break; | |
162 | + } | |
163 | + m_enType = static_cast<acldvppStreamFormat>(enType); | |
164 | + | |
159 | 165 | const AVBitStreamFilter * filter = nullptr; |
160 | 166 | if(codecpar->codec_id == AV_CODEC_ID_H264){ |
161 | 167 | filter = av_bsf_get_by_name("h264_mp4toannexb"); |
... | ... | @@ -166,12 +172,6 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ |
166 | 172 | break; |
167 | 173 | } |
168 | 174 | |
169 | - int enType = getVdecType(codecpar->codec_id, codecpar->profile); | |
170 | - if(-1 == enType) { | |
171 | - break; | |
172 | - } | |
173 | - m_enType = static_cast<acldvppStreamFormat>(enType); | |
174 | - | |
175 | 175 | int ret = av_bsf_alloc(filter, &h264bsfc); |
176 | 176 | if (ret < 0){ |
177 | 177 | break; |
... | ... | @@ -799,25 +799,8 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o |
799 | 799 | // 换成解码后数据, 这里这样做的是为了保证解码一直持续进行,避免后续操作阻碍文件读取和解码从而导致花屏 |
800 | 800 | DvppDataMemory* mem = nullptr; |
801 | 801 | if (m_bResize && (width > 1920 || height > 1080)) { |
802 | - float srcRatio = width / (float)height; | |
803 | - float stdRatio = 1920.0 / 1080.0f ; | |
804 | - int outWidth = 1920; | |
805 | - int outHeight = 1080; | |
806 | - if (srcRatio > stdRatio) { | |
807 | - outHeight = static_cast<int>(outWidth * (float)height / width) ; | |
808 | - if (outHeight % 2 == 1) | |
809 | - { | |
810 | - outHeight += 1; | |
811 | - } | |
812 | - } else if (srcRatio < stdRatio) { | |
813 | - outWidth = static_cast<int>(outHeight * (float)width / height) ; | |
814 | - if (outWidth % 2 == 1) | |
815 | - { | |
816 | - outWidth += 1; | |
817 | - } | |
818 | - } | |
819 | 802 | |
820 | - mem = m_vpcUtils.resize(output, outWidth, outHeight); | |
803 | + mem = m_vpcUtils.resize(output, out_frame_width, out_frame_height); | |
821 | 804 | if (mem) { |
822 | 805 | acldvppFree(outputDataDev); |
823 | 806 | outputDataDev = nullptr; | ... | ... |
src/decoder/dvpp/DvppStreamDecoder.cpp
... | ... | @@ -43,9 +43,12 @@ DvppStreamDecoder::DvppStreamDecoder(/* args */) |
43 | 43 | |
44 | 44 | DvppStreamDecoder::~DvppStreamDecoder() |
45 | 45 | { |
46 | + Close(); | |
46 | 47 | } |
47 | 48 | |
48 | -bool DvppStreamDecoder::init_vdpp(FFDecConfig cfg) { | |
49 | +bool DvppStreamDecoder::Init(FFDecConfig cfg) { | |
50 | + | |
51 | + m_dec_name = cfg.dec_name; | |
49 | 52 | |
50 | 53 | LOG_INFO("[{}]- Init device start...", m_dec_name); |
51 | 54 | |
... | ... | @@ -74,6 +77,8 @@ bool DvppStreamDecoder::init_vdpp(FFDecConfig cfg) { |
74 | 77 | |
75 | 78 | m_vpcUtils.init(m_deviceId); |
76 | 79 | |
80 | + decode_finished_cbk = cfg.decode_finished_cbk; | |
81 | + | |
77 | 82 | LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_deviceId, m_dvpp_channel); |
78 | 83 | return true; |
79 | 84 | }while(0); |
... | ... | @@ -235,7 +240,10 @@ void DvppStreamDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicD |
235 | 240 | } |
236 | 241 | |
237 | 242 | if(mem){ |
243 | + m_decoded_data_queue_mtx.lock(); | |
238 | 244 | m_decoded_data_queue.push(mem); |
245 | + m_decoded_data_queue_mtx.unlock(); | |
246 | + | |
239 | 247 | bCached = true; |
240 | 248 | } |
241 | 249 | } |
... | ... | @@ -251,6 +259,18 @@ void DvppStreamDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicD |
251 | 259 | CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed"); |
252 | 260 | } |
253 | 261 | |
262 | +DvppDataMemory* DvppStreamDecoder::GetFrame() { | |
263 | + DvppDataMemory* mem = nullptr; | |
264 | + m_decoded_data_queue_mtx.lock(); | |
265 | + if (m_decoded_data_queue.size() > 0) { | |
266 | + mem = m_decoded_data_queue.front(); | |
267 | + m_decoded_data_queue.pop(); | |
268 | + } | |
269 | + m_decoded_data_queue_mtx.unlock(); | |
270 | + | |
271 | + return mem; | |
272 | +} | |
273 | + | |
254 | 274 | bool DvppStreamDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) { |
255 | 275 | // create stream desc |
256 | 276 | acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc(); |
... | ... | @@ -277,7 +297,7 @@ bool DvppStreamDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) { |
277 | 297 | return true; |
278 | 298 | } |
279 | 299 | |
280 | -int DvppStreamDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb) { | |
300 | +int DvppStreamDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb, int vdec_out_size) { | |
281 | 301 | |
282 | 302 | void *vdecInputbuf = nullptr; |
283 | 303 | void *vdecOutputBuf = nullptr; |
... | ... | @@ -296,7 +316,7 @@ int DvppStreamDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pk |
296 | 316 | break; |
297 | 317 | } |
298 | 318 | |
299 | - ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size); | |
319 | + ret = acldvppMalloc((void **)&vdecOutputBuf, vdec_out_size); | |
300 | 320 | if(ret != ACL_ERROR_NONE){ |
301 | 321 | LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name); |
302 | 322 | break; |
... | ... | @@ -315,7 +335,7 @@ int DvppStreamDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pk |
315 | 335 | CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed"); |
316 | 336 | CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed"); |
317 | 337 | CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed"); |
318 | - CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed"); | |
338 | + CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, vdec_out_size), "acldvppSetPicDescSize failed"); | |
319 | 339 | |
320 | 340 | Vdec_CallBack_UserData *user_data = NULL; |
321 | 341 | user_data = new Vdec_CallBack_UserData; |
... | ... | @@ -362,21 +382,36 @@ int DvppStreamDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pk |
362 | 382 | return -1; |
363 | 383 | } |
364 | 384 | |
365 | -int DvppStreamDecoder::Decode(int videoType, char* data, int len, int isKey, uint64_t pts) { | |
385 | +int DvppStreamDecoder::SendData(int videoType, char* data, int len, int isKey, uint64_t pts) { | |
366 | 386 | |
387 | + if (m_bExit) { | |
388 | + return -1; | |
389 | + } | |
390 | + | |
391 | + if (m_DvppCacheCounter.load() > 20) { | |
392 | + // 解码器解码不过来。实时流在此处的处理会导致花屏,这是由于解码器性能问题导致,无法避免 | |
393 | + // 实时流在这里处理是为了避免长时间不读取数据导致数据中断 | |
394 | + std::this_thread::sleep_for(std::chrono::milliseconds(10)); | |
395 | + return -3; | |
396 | + } | |
397 | + | |
398 | + int ret = aclrtSetCurrentContext(m_context); | |
399 | + if(ret != ACL_ERROR_NONE){ | |
400 | + LOG_ERROR("[{}]- aclrtSetCurrentContext failed", m_dec_name); | |
401 | + return -2; | |
402 | + } | |
367 | 403 | |
368 | 404 | if (vdecChannelDesc == nullptr) { |
369 | 405 | vdecChannelDesc = aclvdecCreateChannelDesc(); |
370 | 406 | if (vdecChannelDesc == nullptr) { |
371 | 407 | LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name); |
372 | - return; | |
408 | + return -2; | |
373 | 409 | } |
374 | 410 | |
375 | - pthread_t report_thread; | |
376 | 411 | int ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this); |
377 | 412 | if(ret != 0){ |
378 | 413 | LOG_ERROR("[{}]- pthread_create failed", m_dec_name); |
379 | - return; | |
414 | + return -2; | |
380 | 415 | } |
381 | 416 | |
382 | 417 | acldvppStreamFormat enType = getVdecType(videoType); |
... | ... | @@ -391,20 +426,187 @@ int DvppStreamDecoder::Decode(int videoType, char* data, int len, int isKey, uin |
391 | 426 | CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed"); |
392 | 427 | } |
393 | 428 | |
394 | - if (vdecChannelDesc) | |
429 | + AVPacket* pkt = av_packet_alloc(); | |
430 | + av_init_packet(pkt); | |
431 | + | |
432 | + pkt->size = len; | |
433 | + pkt->data = (uint8_t*)data; | |
434 | + | |
435 | + int ret = -2; | |
436 | + | |
437 | + do | |
395 | 438 | { |
396 | - m_frame_nb++; | |
439 | + int vdec_out_size = parse_stream_info(videoType, pkt); | |
440 | + if (vdec_out_size <= 0) { | |
441 | + ret = -4; | |
442 | + break; | |
443 | + } | |
397 | 444 | |
398 | - AVPacket* pkt = av_packet_alloc(); | |
399 | - av_init_packet(pkt); | |
445 | + if (vdecChannelDesc) | |
446 | + { | |
447 | + ret = av_bsf_send_packet(h264bsfc, pkt); | |
448 | + if(ret < 0) { | |
449 | + LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name); | |
450 | + ret = -3; | |
451 | + break;; | |
452 | + } | |
453 | + | |
454 | + int nSended = -1; | |
455 | + while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) { | |
456 | + if(!m_bExit){ | |
457 | + break; | |
458 | + } | |
459 | + | |
460 | + m_frame_nb++; | |
461 | + | |
462 | + // dvpp 解码 | |
463 | + nSended = sendPkt(vdecChannelDesc, pkt, m_frame_nb, vdec_out_size); | |
464 | + } | |
465 | + | |
466 | + if(nSended < 0) { | |
467 | + // 执行出错,强行结束整个任务 | |
468 | + ret = -2; | |
469 | + } | |
470 | + | |
471 | + ret = 0; | |
472 | + } | |
473 | + } while (0); | |
474 | + | |
475 | + av_packet_free(&pkt); | |
476 | + pkt = nullptr; | |
477 | + | |
478 | + return ret; | |
479 | +} | |
480 | + | |
481 | + | |
482 | +int DvppStreamDecoder::parse_stream_info(int videoType, AVPacket* pkt) { | |
483 | + if (m_vdec_out_size > 0) { | |
484 | + return m_vdec_out_size; | |
485 | + } | |
486 | + | |
487 | + m_vdec_out_size = -1; | |
488 | + | |
489 | + AVCodecContext* avctx = nullptr; | |
490 | + const AVCodec* pAVCodec = nullptr; | |
400 | 491 | |
401 | - pkt->size = len; | |
402 | - pkt->data = (uint8_t*)data; | |
492 | + try | |
493 | + { | |
494 | + if (0 == videoType) { | |
495 | + pAVCodec = avcodec_find_decoder(AV_CODEC_ID_H264); | |
496 | + LOG_INFO("m_avCodecName is H264"); | |
497 | + } else if (1 == videoType) { | |
498 | + pAVCodec = avcodec_find_decoder(AV_CODEC_ID_H265); | |
499 | + LOG_INFO("m_avCodecName is H265"); | |
500 | + } else{ | |
501 | + LOG_INFO("m_avCodecName is unknown, videoType is {}", videoType); | |
502 | + } | |
503 | + | |
504 | + if (!pAVCodec) { | |
505 | + LOG_ERROR("frameCallback frame decode error, ERROR_DECODER_NOT_FOUND"); | |
506 | + throw -2; | |
507 | + } | |
508 | + | |
509 | + avctx = avcodec_alloc_context3(pAVCodec); | |
510 | + | |
511 | + if (avcodec_open2(avctx, pAVCodec, nullptr) < 0) { | |
512 | + LOG_ERROR("avcodec_open2 failed!"); | |
513 | + throw -2; | |
514 | + } | |
515 | + | |
516 | + //开始解码 | |
517 | + int ret = avcodec_send_packet(avctx, pkt); | |
518 | + if (ret < 0) { | |
519 | + LOG_ERROR("Real stream视频解码失败,请检查视频设备{}: avcodec_send_packet failed. ret={}", m_dec_name, ret); | |
520 | + throw -3; | |
521 | + } | |
522 | + | |
523 | + if (frameW < 1) { | |
524 | + frameW = avctx->width; | |
525 | + frameH = avctx->height; | |
526 | + if (frameW <= 0 || frameH <= 0) { | |
527 | + LOG_ERROR("[{}] frame W or H is error! ({},{})", m_dec_name, frameW, frameH); | |
528 | + throw -1; | |
529 | + } | |
530 | + | |
531 | + const AVBitStreamFilter * filter = nullptr; | |
532 | + if(VIDEO_TYPE_H264 == videoType){ | |
533 | + filter = av_bsf_get_by_name("h264_mp4toannexb"); | |
534 | + }else if(VIDEO_TYPE_H265 == videoType){ | |
535 | + filter = av_bsf_get_by_name("hevc_mp4toannexb"); | |
536 | + }else { | |
537 | + LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name); | |
538 | + throw -4; | |
539 | + } | |
540 | + | |
541 | + int ret = av_bsf_alloc(filter, &h264bsfc); | |
542 | + if (ret < 0){ | |
543 | + LOG_ERROR("av_bsf_alloc failed!"); | |
544 | + throw -2; | |
545 | + } | |
546 | + | |
547 | + avcodec_parameters_from_context(h264bsfc->par_in, avctx); | |
548 | + av_bsf_init(h264bsfc); | |
549 | + } | |
550 | + | |
551 | + m_fps = av_q2d(avctx->framerate); | |
403 | 552 | |
404 | - // dvpp 解码 | |
405 | - int nSended = sendPkt(vdecChannelDesc, pkt, m_frame_nb); | |
553 | + AVFrame* frame = av_frame_alloc(); | |
554 | + do | |
555 | + { | |
556 | + ret = avcodec_receive_frame(avctx, frame); | |
557 | + if ((ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) || ret < 0){ | |
558 | + LOG_ERROR("{} - Failed to receive frame: {}", m_dec_name, ret); | |
559 | + break; | |
560 | + } | |
561 | + | |
562 | + if (frame->width != frameW || frame->height != frameH){ | |
563 | + LOG_ERROR("AVFrame is inconsistent: width is {}, height is {}; original frameW is {}, frameH is {}--{}", frame->width, frame->height, frameW, frameH , m_dec_name); | |
564 | + break; | |
565 | + } | |
566 | + | |
567 | + m_vdec_out_size = frame->width * frame->height * 3 / 2; | |
568 | + } while (0); | |
569 | + | |
570 | + av_frame_free(&frame); | |
571 | + frame = nullptr; | |
572 | + | |
573 | + } | |
574 | + catch(const int& iError) { | |
575 | + m_vdec_out_size = iError; | |
576 | + } catch(...) { | |
577 | + m_vdec_out_size = -1; | |
578 | + } | |
579 | + | |
580 | + if(avctx){ | |
581 | + avcodec_free_context(&avctx); | |
582 | + avctx = nullptr; | |
583 | + } | |
584 | + | |
585 | + return m_vdec_out_size; | |
586 | +} | |
587 | + | |
588 | +void DvppStreamDecoder::Close() { | |
589 | + m_bExit = true; | |
590 | + | |
591 | + if (vdecChannelDesc) { | |
592 | + sendVdecEos(vdecChannelDesc); | |
593 | + | |
594 | + CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed"); | |
595 | + CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed"); | |
596 | + vdecChannelDesc = nullptr; | |
597 | + | |
598 | + m_bExitReportThd = true; | |
599 | + CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "report_thread join failed"); | |
600 | + } | |
601 | + | |
602 | + release_dvpp(); | |
603 | + | |
604 | + if(h264bsfc){ | |
605 | + av_bsf_free(&h264bsfc); | |
606 | + h264bsfc = nullptr; | |
607 | + } | |
406 | 608 | |
407 | - av_packet_free(&pkt); | |
408 | - pkt = nullptr; | |
609 | + if(decode_finished_cbk) { | |
610 | + decode_finished_cbk(m_finishedDecArg); | |
409 | 611 | } |
410 | 612 | } |
411 | 613 | \ No newline at end of file | ... | ... |
src/decoder/dvpp/DvppStreamDecoder.h
... | ... | @@ -14,9 +14,13 @@ public: |
14 | 14 | DvppStreamDecoder(/* args */); |
15 | 15 | ~DvppStreamDecoder(); |
16 | 16 | |
17 | - bool init_vdpp(FFDecConfig cfg); | |
17 | + bool Init(FFDecConfig cfg); | |
18 | 18 | |
19 | - DataFrame* Decode(int videoType, char* data, int len, int isKey, uint64_t pts); | |
19 | + int SendData(int videoType, char* data, int len, int isKey, uint64_t pts); | |
20 | + | |
21 | + void Close(); | |
22 | + | |
23 | + DvppDataMemory* GetFrame(); | |
20 | 24 | |
21 | 25 | public: |
22 | 26 | void doProcessReport(); |
... | ... | @@ -24,7 +28,9 @@ public: |
24 | 28 | |
25 | 29 | private: |
26 | 30 | bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc); |
27 | - int sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb); | |
31 | + int sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb, int vdec_out_size); | |
32 | + | |
33 | + int parse_stream_info(int videoType, AVPacket* pkt); | |
28 | 34 | |
29 | 35 | private: |
30 | 36 | string m_dec_name {""}; |
... | ... | @@ -34,12 +40,28 @@ private: |
34 | 40 | aclrtContext m_context{nullptr}; |
35 | 41 | |
36 | 42 | aclvdecChannelDesc *vdecChannelDesc {nullptr}; |
43 | + pthread_t report_thread; | |
44 | + bool m_bExitReportThd{false}; | |
37 | 45 | |
38 | 46 | int m_vdec_out_size {-1}; |
47 | + int m_fps {-1}; | |
48 | + int frameW {-1}; | |
49 | + int frameH {-1}; | |
39 | 50 | |
40 | 51 | VpcUtils m_vpcUtils; |
41 | 52 | |
42 | 53 | unsigned long m_frame_nb {0}; |
54 | + std::atomic<int> m_DvppCacheCounter{0}; | |
55 | + | |
56 | + queue<DvppDataMemory*> m_decoded_data_queue; | |
57 | + mutex m_decoded_data_queue_mtx; | |
58 | + | |
59 | + bool m_bExit {false}; | |
60 | + | |
61 | + const void * m_finishedDecArg {nullptr}; | |
62 | + DECODE_FINISHED_CALLBACK decode_finished_cbk {nullptr}; | |
63 | + | |
64 | + AVBSFContext * h264bsfc{nullptr}; | |
43 | 65 | }; |
44 | 66 | |
45 | 67 | ... | ... |
src/decoder/gb28181/GB28181Provider.cpp renamed to src/decoder/gb28181/DvppGB28181Decoder.cpp
1 | 1 | //#include "LOG_manager.h" |
2 | 2 | #include <iostream> |
3 | -#include "FFGB28181Decoder.h" | |
3 | +#include "DvppGB28181Decoder.h" | |
4 | 4 | |
5 | 5 | |
6 | 6 | |
... | ... | @@ -17,9 +17,9 @@ extern "C" { |
17 | 17 | |
18 | 18 | #include "common_header.h" |
19 | 19 | |
20 | -#include "../nvdec/FFCuContextManager.h" | |
21 | -#include "../nvdec/GpuRgbMemory.hpp" | |
22 | -#include "../nvdec/cuda_kernels.h" | |
20 | +// #include "../nvdec/FFCuContextManager.h" | |
21 | +// #include "../nvdec/GpuRgbMemory.hpp" | |
22 | +// #include "../nvdec/cuda_kernels.h" | |
23 | 23 | |
24 | 24 | #define ECLOSED 0 |
25 | 25 | #define ECLOSING 1 |
... | ... | @@ -28,24 +28,23 @@ extern "C" { |
28 | 28 | |
29 | 29 | static void RTP_Stream_CallBack(void* userdata, int videoType, char* data, int len, int isKey, uint64_t pts, uint64_t localPts) |
30 | 30 | { |
31 | - FFGB28181Decoder* decoder = (FFGB28181Decoder*)userdata; | |
31 | + DvppGB28181Decoder* decoder = (DvppGB28181Decoder*)userdata; | |
32 | 32 | decoder->stream_callback(videoType, data, len, isKey, pts, localPts); |
33 | 33 | } |
34 | 34 | |
35 | 35 | static void RTP_Stream_End_CallBack(void* userdata) |
36 | 36 | { |
37 | - FFGB28181Decoder* decoder = (FFGB28181Decoder*)userdata; | |
37 | + DvppGB28181Decoder* decoder = (DvppGB28181Decoder*)userdata; | |
38 | 38 | decoder->stream_end_callback(); |
39 | 39 | } |
40 | 40 | |
41 | -FFGB28181Decoder::FFGB28181Decoder() { | |
41 | +DvppGB28181Decoder::DvppGB28181Decoder() { | |
42 | 42 | m_frameSkip = 1; |
43 | - m_port = -1; | |
44 | 43 | m_dec_keyframe = false; |
45 | 44 | m_post_decode_thread = 0; |
46 | 45 | } |
47 | 46 | |
48 | -FFGB28181Decoder::~FFGB28181Decoder() | |
47 | +DvppGB28181Decoder::~DvppGB28181Decoder() | |
49 | 48 | { |
50 | 49 | close(); |
51 | 50 | |
... | ... | @@ -59,7 +58,7 @@ FFGB28181Decoder::~FFGB28181Decoder() |
59 | 58 | LOG_INFO("destroy OK--{}", m_dec_name); |
60 | 59 | } |
61 | 60 | |
62 | -void FFGB28181Decoder::close(){ | |
61 | +void DvppGB28181Decoder::close(){ | |
63 | 62 | if (m_status == ECLOSED || m_status == ECLOSING) return ; |
64 | 63 | |
65 | 64 | m_status = ECLOSING; |
... | ... | @@ -94,7 +93,7 @@ void FFGB28181Decoder::close(){ |
94 | 93 | LOG_INFO("解码器关闭成功 --{}", m_dec_name); |
95 | 94 | } |
96 | 95 | |
97 | -bool FFGB28181Decoder::init(FFDecConfig& cfg){ | |
96 | +bool DvppGB28181Decoder::init(FFDecConfig& cfg){ | |
98 | 97 | if(cfg.force_tcp){ |
99 | 98 | m_rtpPtr = new RTPTcpReceiver(); |
100 | 99 | }else{ |
... | ... | @@ -110,54 +109,49 @@ bool FFGB28181Decoder::init(FFDecConfig& cfg){ |
110 | 109 | |
111 | 110 | m_gpuid = atoi(cfg.gpuid.c_str()); |
112 | 111 | |
113 | - m_rtpPtr->SetDeviceID(m_dec_name); | |
114 | - | |
115 | - if(cfg.request_stream_cbk == nullptr){ | |
116 | - LOG_INFO("request_stream_cbk 为 nullptr -- {}", m_dec_name); | |
117 | - return false; | |
118 | - } | |
112 | + m_rtpPtr->SetOutputCallback(RTP_Stream_CallBack, this); | |
113 | + m_rtpPtr->SetVodEndCallback(RTP_Stream_End_CallBack, this); | |
119 | 114 | |
120 | 115 | post_decoded_cbk = cfg.post_decoded_cbk; |
121 | 116 | decode_finished_cbk = cfg.decode_finished_cbk; |
122 | - m_rtpPtr->SetRequestStreamCallback(cfg.request_stream_cbk); | |
123 | 117 | |
124 | - m_port = cfg.port; | |
118 | + if (!streamDecoder.Init(cfg)) { | |
119 | + return false; | |
120 | + } | |
125 | 121 | |
126 | 122 | m_cfg = cfg; |
127 | 123 | |
128 | - LOG_INFO("init - {} : ", m_dec_name, m_port); | |
124 | + LOG_INFO("init - {} ", m_dec_name); | |
129 | 125 | |
130 | 126 | return true; |
131 | 127 | } |
132 | 128 | |
133 | -bool FFGB28181Decoder::start() { | |
129 | +bool DvppGB28181Decoder::start() { | |
134 | 130 | |
135 | 131 | m_status = ERUNNING; |
136 | 132 | |
137 | - m_rtpPtr->SetOutputCallback(RTP_Stream_CallBack, this); | |
138 | - m_rtpPtr->SetVodEndCallback(RTP_Stream_End_CallBack, this); | |
139 | - | |
140 | - LOG_INFO("start - {} {}: ", m_dec_name, m_port); | |
141 | - | |
142 | - bool bRet = m_rtpPtr->Open((uint16_t)m_port); | |
133 | + bool bRet = m_rtpPtr->Open(m_dec_name); | |
143 | 134 | if(bRet){ |
144 | 135 | pthread_create(&m_post_decode_thread,0, |
145 | 136 | [](void* arg) |
146 | 137 | { |
147 | - FFGB28181Decoder* a=(FFGB28181Decoder*)arg; | |
148 | - a->post_decode_thread(); | |
138 | + DvppGB28181Decoder* a=(DvppGB28181Decoder*)arg; | |
139 | + a->display_thread(); | |
149 | 140 | return (void*)0; |
150 | 141 | } |
151 | 142 | ,this); |
152 | 143 | } |
144 | + | |
145 | + LOG_ERROR("[{}] - rtp receiver open failed !", m_dec_name); | |
146 | + | |
153 | 147 | return bRet; |
154 | 148 | } |
155 | 149 | |
156 | -void FFGB28181Decoder::setDecKeyframe(bool bKeyframe){ | |
150 | +void DvppGB28181Decoder::setDecKeyframe(bool bKeyframe){ | |
157 | 151 | m_dec_keyframe = bKeyframe; |
158 | 152 | } |
159 | 153 | |
160 | -void FFGB28181Decoder::stream_callback(int videoType, char* data, int len, int isKey, uint64_t pts, uint64_t localPts) { | |
154 | +void DvppGB28181Decoder::stream_callback(int videoType, char* data, int len, int isKey, uint64_t pts, uint64_t localPts) { | |
161 | 155 | if (m_status == EPAUSE) return; |
162 | 156 | |
163 | 157 | // 若设置为关键帧解码,非关键帧数据直接返回 |
... | ... | @@ -173,21 +167,24 @@ void FFGB28181Decoder::stream_callback(int videoType, char* data, int len, int i |
173 | 167 | return; |
174 | 168 | } |
175 | 169 | |
176 | - AVPacket* pkt = av_packet_alloc(); | |
177 | - av_init_packet(pkt); | |
170 | + streamDecoder.SendData(videoType, data, len, isKey, pts); | |
178 | 171 | |
179 | - pkt->size = len; | |
180 | - pkt->data = (uint8_t*)data; | |
172 | + // AVPacket* pkt = av_packet_alloc(); | |
173 | + // av_init_packet(pkt); | |
181 | 174 | |
182 | - // ffmpeg 解码 | |
183 | - ff_decode(videoType, pkt); | |
175 | + // pkt->size = len; | |
176 | + // pkt->data = (uint8_t*)data; | |
184 | 177 | |
185 | - av_packet_free(&pkt); | |
186 | - pkt = nullptr; | |
178 | + // // ffmpeg 解码 | |
179 | + // ff_decode(videoType, pkt); | |
180 | + | |
181 | + // av_packet_free(&pkt); | |
182 | + // pkt = nullptr; | |
187 | 183 | |
188 | 184 | } |
189 | 185 | |
190 | -int FFGB28181Decoder::ff_decode(int videoType, AVPacket* pkt) { | |
186 | +int DvppGB28181Decoder::ff_decode(int videoType, AVPacket* pkt) { | |
187 | + | |
191 | 188 | if (m_pAVCodecCtx == nullptr) { |
192 | 189 | LOG_INFO("frame data is zero --{}", m_dec_name); |
193 | 190 | if (VIDEO_TYPE_H264 == videoType) { |
... | ... | @@ -253,14 +250,11 @@ int FFGB28181Decoder::ff_decode(int videoType, AVPacket* pkt) { |
253 | 250 | frameH = m_pAVCodecCtx->height; |
254 | 251 | if (frameW <= 0 || frameH <= 0) { |
255 | 252 | LOG_ERROR("[{}] frame W or H is error! ({},{})", m_dec_name, frameW, frameH); |
256 | - av_packet_free(&pkt); | |
257 | - pkt = nullptr; | |
258 | 253 | return; |
259 | 254 | } |
260 | 255 | } |
261 | - // m_fps = m_pAVCodecCtx->pkt_timebase.den == 0 ? 25.0 : av_q2d(m_pAVCodecCtx->pkt_timebase); | |
256 | + | |
262 | 257 | m_fps = av_q2d(m_pAVCodecCtx->framerate); |
263 | - // LOG_DEBUG("frameW {}--frameH {}", frameW, frameH); | |
264 | 258 | |
265 | 259 | AVFrame* gpuFrame = av_frame_alloc(); |
266 | 260 | ret = avcodec_receive_frame(m_pAVCodecCtx, gpuFrame); |
... | ... | @@ -278,47 +272,37 @@ int FFGB28181Decoder::ff_decode(int videoType, AVPacket* pkt) { |
278 | 272 | return; |
279 | 273 | } |
280 | 274 | |
281 | - m_queue_mutex.lock(); | |
282 | - if(mFrameQueue.size() <= 10){ | |
283 | - mFrameQueue.push(gpuFrame); | |
284 | - }else{ | |
285 | - av_frame_free(&gpuFrame); | |
286 | - gpuFrame = nullptr; | |
287 | - } | |
288 | - m_queue_mutex.unlock(); | |
275 | + av_frame_free(&gpuFrame); | |
276 | + gpuFrame = nullptr; | |
289 | 277 | } |
290 | 278 | |
291 | -void FFGB28181Decoder::post_decode_thread(){ | |
279 | +void DvppGB28181Decoder::display_thread(){ | |
292 | 280 | |
293 | 281 | int index = 0; |
294 | 282 | while (isRunning()) |
295 | 283 | { |
296 | - if(mFrameQueue.size() > 0){ | |
297 | - std::lock_guard<std::mutex> l(m_snapshot_mutex); | |
298 | - // 取队头数据 | |
299 | - m_queue_mutex.lock(); | |
300 | - AVFrame * gpuFrame = mFrameQueue.front(); | |
301 | - mFrameQueue.pop(); | |
302 | - m_queue_mutex.unlock(); | |
303 | - // 跳帧 | |
304 | - if (m_frameSkip == 1 || index % m_frameSkip == 0){ | |
305 | - post_decoded_cbk(m_postDecArg, convert2bgr(gpuFrame)); | |
306 | - } | |
307 | - | |
308 | - av_frame_free(&gpuFrame); | |
309 | - gpuFrame = nullptr; | |
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 | + } | |
310 | 289 | |
311 | - index++; | |
290 | + index++; | |
312 | 291 | if(index >= 100000){ |
313 | 292 | index = 0; |
314 | 293 | } |
315 | - } | |
294 | + } else { | |
295 | + delete mem; | |
296 | + mem = nullptr; | |
297 | + } | |
298 | + | |
299 | + std::this_thread::sleep_for(std::chrono::milliseconds(10)); | |
316 | 300 | } |
317 | 301 | |
318 | - LOG_INFO("post decode thread exited."); | |
302 | + LOG_INFO("display thread exited."); | |
319 | 303 | } |
320 | 304 | |
321 | -void FFGB28181Decoder::stream_end_callback() | |
305 | +void DvppGB28181Decoder::stream_end_callback() | |
322 | 306 | { |
323 | 307 | LOG_INFO("send_video_eof--{}", m_dec_name); |
324 | 308 | |
... | ... | @@ -327,176 +311,60 @@ void FFGB28181Decoder::stream_end_callback() |
327 | 311 | return; |
328 | 312 | } |
329 | 313 | |
330 | -void FFGB28181Decoder::setPostDecArg(const void* postDecArg){ | |
314 | +void DvppGB28181Decoder::setPostDecArg(const void* postDecArg){ | |
331 | 315 | m_postDecArg = postDecArg; |
332 | 316 | } |
333 | 317 | |
334 | -void FFGB28181Decoder::setFinishedDecArg(const void* finishedDecArg){ | |
318 | +void DvppGB28181Decoder::setFinishedDecArg(const void* finishedDecArg){ | |
335 | 319 | m_finishedDecArg = finishedDecArg; |
336 | 320 | } |
337 | 321 | |
338 | -void FFGB28181Decoder::pause() { | |
322 | +void DvppGB28181Decoder::pause() { | |
339 | 323 | m_status = EPAUSE; |
340 | 324 | LOG_INFO("pause --{}", m_dec_name); |
341 | 325 | } |
342 | 326 | |
343 | -void FFGB28181Decoder::resume() { | |
327 | +void DvppGB28181Decoder::resume() { | |
344 | 328 | m_status = ERUNNING; |
345 | 329 | LOG_INFO("resume --{}", m_dec_name); |
346 | 330 | } |
347 | 331 | |
348 | -bool FFGB28181Decoder::isRunning(){ | |
332 | +bool DvppGB28181Decoder::isRunning(){ | |
349 | 333 | if (m_status == ECLOSED || m_status == ECLOSING){ |
350 | 334 | return false; |
351 | 335 | } |
352 | 336 | return true; |
353 | 337 | } |
354 | 338 | |
355 | -bool FFGB28181Decoder::isFinished(){ | |
339 | +bool DvppGB28181Decoder::isFinished(){ | |
356 | 340 | if (m_status == ECLOSED || m_status == ECLOSING){ |
357 | 341 | return true; |
358 | 342 | } |
359 | 343 | return false; |
360 | 344 | } |
361 | 345 | |
362 | -bool FFGB28181Decoder::isPausing(){ | |
346 | +bool DvppGB28181Decoder::isPausing(){ | |
363 | 347 | if (m_status == EPAUSE){ |
364 | 348 | return true; |
365 | 349 | } |
366 | 350 | return false; |
367 | 351 | } |
368 | 352 | |
369 | -bool FFGB28181Decoder::getResolution( int &width, int &height ){ | |
353 | +bool DvppGB28181Decoder::getResolution( int &width, int &height ){ | |
370 | 354 | width = frameW; |
371 | 355 | height = frameH; |
372 | 356 | return true; |
373 | 357 | } |
374 | 358 | |
375 | -float FFGB28181Decoder::fps() { | |
359 | +float DvppGB28181Decoder::fps() { | |
376 | 360 | return m_fps; |
377 | 361 | } |
378 | 362 | |
379 | -bool FFGB28181Decoder::isSurport(FFDecConfig& cfg){ | |
363 | +bool DvppGB28181Decoder::isSurport(FFDecConfig& cfg){ | |
380 | 364 | // 由于是否支持需要在拿到数据后才能断定,无法事先判断,所以这个地方默认返回true |
381 | 365 | return true; |
382 | 366 | } |
383 | 367 | |
384 | -int FFGB28181Decoder::getCachedQueueLength(){ | |
368 | +int DvppGB28181Decoder::getCachedQueueLength(){ | |
385 | 369 | return m_rtpPtr->GetPsFrameListSize(); |
386 | -} | |
387 | - | |
388 | -DeviceRgbMemory* FFGB28181Decoder::convert2bgr(AVFrame * gpuFrame){ | |
389 | - if (gpuFrame != nullptr && gpuFrame->format == AV_PIX_FMT_CUDA ){ | |
390 | - LOG_DEBUG("decode task: gpuid: {} width: {} height: {}", m_cfg.gpuid, gpuFrame->width, gpuFrame->height); | |
391 | - GpuRgbMemory* gpuMem = new GpuRgbMemory(3, gpuFrame->width, gpuFrame->height, getName(), m_cfg.gpuid, false, true); | |
392 | - | |
393 | - do{ | |
394 | - if (gpuMem->getMem() == nullptr){ | |
395 | - LOG_ERROR("new GpuRgbMemory failed !!!"); | |
396 | - break; | |
397 | - } | |
398 | - | |
399 | - cudaSetDevice(atoi(m_cfg.gpuid.c_str())); | |
400 | - cuda_common::setColorSpace( ITU_709, 0 ); | |
401 | - cudaError_t cudaStatus = cuda_common::CUDAToBGR((CUdeviceptr)gpuFrame->data[0],(CUdeviceptr)gpuFrame->data[1], gpuFrame->linesize[0], gpuFrame->linesize[1], gpuMem->getMem(), gpuFrame->width, gpuFrame->height); | |
402 | - cudaDeviceSynchronize(); | |
403 | - if (cudaStatus != cudaSuccess) { | |
404 | - LOG_ERROR("CUDAToBGR failed failed !!!"); | |
405 | - break; | |
406 | - } | |
407 | - | |
408 | - return gpuMem; | |
409 | - }while(0); | |
410 | - | |
411 | - delete gpuMem; | |
412 | - gpuMem = nullptr; | |
413 | - } | |
414 | - | |
415 | - return nullptr; | |
416 | -} | |
417 | - | |
418 | -FFImgInfo* FFGB28181Decoder::snapshot(){ | |
419 | - | |
420 | - // 锁住停止队列消耗 | |
421 | - std::lock_guard<std::mutex> l(m_snapshot_mutex); | |
422 | - | |
423 | - AVFrame * gpuFrame = nullptr; | |
424 | - | |
425 | - bool bFirst = true; | |
426 | - while(true){ | |
427 | - m_queue_mutex.lock(); | |
428 | - if(mFrameQueue.size() <= 0){ | |
429 | - m_queue_mutex.unlock(); | |
430 | - if(bFirst){ | |
431 | - std::this_thread::sleep_for(std::chrono::milliseconds(100)); | |
432 | - bFirst = false; | |
433 | - continue; | |
434 | - }else{ | |
435 | - // 再进来说明前面已经等了 100 ms | |
436 | - // 100 ms都没有等到解码数据,则退出 | |
437 | - return nullptr; | |
438 | - } | |
439 | - } | |
440 | - | |
441 | - // 队列中数据大于1 | |
442 | - gpuFrame = mFrameQueue.front(); | |
443 | - m_queue_mutex.unlock(); | |
444 | - break; | |
445 | - } | |
446 | - | |
447 | - if (gpuFrame != nullptr && gpuFrame->format == AV_PIX_FMT_CUDA ){ | |
448 | - LOG_DEBUG("decode task: gpuid: {} width: {} height: {}", m_cfg.gpuid, gpuFrame->width, gpuFrame->height); | |
449 | - GpuRgbMemory* gpuMem = new GpuRgbMemory(3, gpuFrame->width, gpuFrame->height, getName(), m_cfg.gpuid , false, true); | |
450 | - | |
451 | - if (gpuMem->getMem() == nullptr){ | |
452 | - LOG_ERROR("new GpuRgbMemory failed !!!"); | |
453 | - return nullptr; | |
454 | - } | |
455 | - | |
456 | - cudaSetDevice(atoi(m_cfg.gpuid.c_str())); | |
457 | - cuda_common::setColorSpace( ITU_709, 0 ); | |
458 | - cudaError_t cudaStatus = cuda_common::CUDAToBGR((CUdeviceptr)gpuFrame->data[0],(CUdeviceptr)gpuFrame->data[1], gpuFrame->linesize[0], gpuFrame->linesize[1], gpuMem->getMem(), gpuFrame->width, gpuFrame->height); | |
459 | - cudaDeviceSynchronize(); | |
460 | - if (cudaStatus != cudaSuccess) { | |
461 | - LOG_ERROR("CUDAToBGR failed failed !!!"); | |
462 | - return nullptr; | |
463 | - } | |
464 | - | |
465 | - unsigned char * pHwRgb = gpuMem->getMem(); | |
466 | - int channel = gpuMem->getChannel(); | |
467 | - int width = gpuMem->getWidth(); | |
468 | - int height = gpuMem->getHeight(); | |
469 | - | |
470 | - if (pHwRgb != nullptr && channel > 0 && width > 0 && height > 0){ | |
471 | - int nSize = channel * height * width; | |
472 | - | |
473 | - LOG_INFO("channel:{} height:{} width:{}", channel, height, width); | |
474 | - // unsigned char* cpu_data = new unsigned char[nSize]; | |
475 | - | |
476 | - unsigned char* cpu_data = (unsigned char *)av_malloc(nSize * sizeof(unsigned char)); | |
477 | - | |
478 | - cudaMemcpy(cpu_data, pHwRgb, nSize * sizeof(unsigned char), cudaMemcpyDeviceToHost); | |
479 | - cudaDeviceSynchronize(); | |
480 | - | |
481 | - delete gpuMem; | |
482 | - gpuMem = nullptr; | |
483 | - | |
484 | - FFImgInfo* imgInfo = new FFImgInfo(); | |
485 | - imgInfo->dec_name = m_dec_name; | |
486 | - imgInfo->pData = cpu_data; | |
487 | - imgInfo->height = height; | |
488 | - imgInfo->width = width; | |
489 | - imgInfo->timestamp = UtilTools::get_cur_time_ms(); | |
490 | - imgInfo->index = m_index; | |
491 | - | |
492 | - m_index++; | |
493 | - | |
494 | - return imgInfo; | |
495 | - } | |
496 | - | |
497 | - delete gpuMem; | |
498 | - gpuMem = nullptr; | |
499 | - } | |
500 | - | |
501 | - return nullptr; | |
502 | 370 | } |
503 | 371 | \ No newline at end of file | ... | ... |
src/decoder/gb28181/GB28181Provider.h renamed to src/decoder/gb28181/DvppGB28181Decoder.h
1 | 1 | #ifndef _GB28181_DECODER_H_ |
2 | 2 | #define _GB28181_DECODER_H_ |
3 | 3 | |
4 | +#include <atomic> | |
5 | +#include <mutex> | |
6 | + | |
4 | 7 | #include "RTPReceiver.h" |
8 | +#include "../dvpp/DvppStreamDecoder.h" | |
5 | 9 | |
6 | 10 | #include "common_header.h" |
7 | 11 | #include "../interface/AbstractDecoder.h" |
8 | 12 | |
9 | -#include <atomic> | |
10 | -#include <mutex> | |
11 | 13 | |
12 | 14 | struct AVFormatContext; |
13 | 15 | struct AVCodecContext; |
14 | 16 | struct AVCodec; |
15 | 17 | struct AVFrame; |
16 | 18 | struct AVDictionary; |
19 | +struct AVPacket; | |
17 | 20 | |
18 | 21 | using namespace std; |
19 | 22 | |
20 | -class FFGB28181Decoder: public AbstractDecoder | |
23 | +class DvppGB28181Decoder: public AbstractDecoder | |
21 | 24 | { |
22 | 25 | public: |
23 | - FFGB28181Decoder(); | |
24 | - ~FFGB28181Decoder(); | |
26 | + DvppGB28181Decoder(); | |
27 | + ~DvppGB28181Decoder(); | |
25 | 28 | |
26 | 29 | bool init(FFDecConfig& cfg); |
27 | 30 | void close(); |
... | ... | @@ -44,8 +47,6 @@ public: |
44 | 47 | |
45 | 48 | DECODER_TYPE getDecoderType(){ return DECODER_TYPE_GB28181; } |
46 | 49 | |
47 | - FFImgInfo* snapshot(); | |
48 | - | |
49 | 50 | void setName(string nm){ |
50 | 51 | m_dec_name = nm; |
51 | 52 | } |
... | ... | @@ -60,18 +61,16 @@ public: |
60 | 61 | public: |
61 | 62 | void stream_callback(int videoType, char* data, int len, int isKey, uint64_t pts, uint64_t localPts); |
62 | 63 | void stream_end_callback(); |
63 | - void post_decode_thread(); | |
64 | + void display_thread(); | |
64 | 65 | |
65 | 66 | private: |
66 | - DeviceRgbMemory* convert2bgr(AVFrame * gpuFrame); | |
67 | - int ff_decode(); | |
67 | + int ff_decode(int videoType, AVPacket* pkt); | |
68 | 68 | |
69 | 69 | private: |
70 | - string m_dec_name; | |
70 | + string m_dec_name; // 必须为28181编码 | |
71 | 71 | FFDecConfig m_cfg; |
72 | 72 | |
73 | - RTPReceiver* m_rtpPtr; | |
74 | - int m_port; | |
73 | + RTPReceiver* m_rtpPtr {nullptr}; | |
75 | 74 | |
76 | 75 | uint64_t m_startPts {}; |
77 | 76 | uint64_t m_lastPts {}; //上一次pts的值 |
... | ... | @@ -98,6 +97,10 @@ private: |
98 | 97 | mutex m_snapshot_mutex; |
99 | 98 | |
100 | 99 | bool m_dec_keyframe; |
100 | + | |
101 | + DvppStreamDecoder streamDecoder; | |
102 | + | |
103 | + int m_gpuid {0}; | |
101 | 104 | }; |
102 | 105 | |
103 | 106 | #endif // _GB28181_DECODER_H_ | ... | ... |
src/decoder/gb28181/main.cpp
... | ... | @@ -105,8 +105,6 @@ bool start_rtp(string deviceId, int m_port) { |
105 | 105 | return false; |
106 | 106 | } |
107 | 107 | |
108 | - m_rtpPtr->SetDeviceID(deviceId); | |
109 | - | |
110 | 108 | m_rtpPtr->SetRequestStreamCallback(RequestStream); |
111 | 109 | |
112 | 110 | |
... | ... | @@ -115,7 +113,7 @@ bool start_rtp(string deviceId, int m_port) { |
115 | 113 | m_rtpPtr->SetVodEndCallback(RTP_Stream_End_CallBack, nullptr); |
116 | 114 | |
117 | 115 | |
118 | - bool bRet = m_rtpPtr->Open(m_port); | |
116 | + bool bRet = m_rtpPtr->Open(deviceId); | |
119 | 117 | if(bRet){ |
120 | 118 | // pthread_create(&m_post_decode_thread,0, |
121 | 119 | // [](void* arg) |
... | ... | @@ -140,7 +138,7 @@ bool RequestStream(const char* deviceId, int rtp_port) { |
140 | 138 | return false; |
141 | 139 | } |
142 | 140 | |
143 | - int ret = sipServer.RequestInvite_TCP_a(vec_device[0], rtp_port); | |
141 | + int ret = sipServer.RequestInvite_TCP_a(vec_device[0].id.c_str(), rtp_port); | |
144 | 142 | if (ret > 0) |
145 | 143 | { |
146 | 144 | return true; |
... | ... | @@ -152,7 +150,7 @@ bool RequestStream(const char* deviceId, int rtp_port) { |
152 | 150 | int main(int argc, char *argv[]) { |
153 | 151 | |
154 | 152 | ServerInfo info( |
155 | - "SY_SipServer", | |
153 | + "SY_Sip_Server", | |
156 | 154 | "12345678", |
157 | 155 | "192.168.60.179", |
158 | 156 | 15060, |
... | ... | @@ -164,7 +162,6 @@ int main(int argc, char *argv[]) { |
164 | 162 | |
165 | 163 | |
166 | 164 | sipServer.Init(info); |
167 | - sipServer.Start(); | |
168 | 165 | |
169 | 166 | std::this_thread::sleep_for(std::chrono::seconds(5)); |
170 | 167 | |
... | ... | @@ -191,7 +188,7 @@ int main(int argc, char *argv[]) { |
191 | 188 | int rtp_port = 30026;//allocRtpPort(); |
192 | 189 | start_rtp(vec_device[0].id, rtp_port); |
193 | 190 | |
194 | - sipServer.RequestInvite_UDP(vec_device[0], rtp_port); | |
191 | + sipServer.RequestInvite_UDP(vec_device[0].id.c_str(), rtp_port); | |
195 | 192 | } |
196 | 193 | break; |
197 | 194 | case 'b': | ... | ... |
src/decoder/gb28181/rtp/RTPReceiver.cpp
... | ... | @@ -4,8 +4,16 @@ |
4 | 4 | |
5 | 5 | #include "../common_header.h" |
6 | 6 | |
7 | +#ifdef __linux__ | |
8 | +#include "arpa/inet.h" | |
9 | +#endif | |
10 | + | |
7 | 11 | #define BUFFERSIZE_1024 1024 |
8 | -const int kVideoFrameSize = BUFFERSIZE_1024*BUFFERSIZE_1024*5*2; | |
12 | + | |
13 | +const int kVideoFrameSize = BUFFERSIZE_1024*BUFFERSIZE_1024*5*2; | |
14 | + | |
15 | +const int MIN_RTP_PORT = 10000 ; | |
16 | +const int MAX_RTP_PORT = 60000; | |
9 | 17 | |
10 | 18 | // PS解包器回调 |
11 | 19 | static int ReceivePESFunction(unsigned char streamid, void * data, int size, uint64_t pts, uint64_t localPts, bool key, void* param) |
... | ... | @@ -73,13 +81,13 @@ int RTPReceiver::InitPS(){ |
73 | 81 | return -1; |
74 | 82 | } |
75 | 83 | |
76 | - LOG_INFO("[{}] InitPS finished", m_deviceID); | |
84 | + LOG_INFO("[{}] InitPS finished", m_SipChannelId); | |
77 | 85 | |
78 | 86 | return 0; |
79 | 87 | } |
80 | 88 | |
81 | 89 | void RTPReceiver::ClosePsThread(){ |
82 | - LOG_INFO("[{}] 3.", m_deviceID); | |
90 | + LOG_INFO("[{}] 3.", m_SipChannelId); | |
83 | 91 | m_bPsExit = true; |
84 | 92 | // PS解包线程退出 |
85 | 93 | if (m_psThreadPtr->joinable()) |
... | ... | @@ -89,7 +97,7 @@ void RTPReceiver::ClosePsThread(){ |
89 | 97 | m_psThreadPtr = nullptr; |
90 | 98 | } |
91 | 99 | |
92 | - LOG_INFO("[{}] ps demux thread quit", m_deviceID); | |
100 | + LOG_INFO("[{}] ps demux thread quit", m_SipChannelId); | |
93 | 101 | } |
94 | 102 | |
95 | 103 | // 处理去除了PS头的数据 |
... | ... | @@ -125,7 +133,7 @@ void RTPReceiver::OnPsDemux(unsigned char streamId, BYTE *data, int len, bool ke |
125 | 133 | //{ |
126 | 134 | // byte_buffer bb(64); |
127 | 135 | // bb << ERROR_REALSTREAM_INTERRUPT << "This session have a long time no decoding"; |
128 | - // LOG_INFO("[{}] Long time no decoding!!!m_notToDecodCount=[{}]", m_deviceID, m_notToDecodCount); | |
136 | + // LOG_INFO("[{}] Long time no decoding!!!m_notToDecodCount=[{}]", m_SipChannelId, m_notToDecodCount); | |
129 | 137 | // |
130 | 138 | // if (m_usrParam) |
131 | 139 | // { |
... | ... | @@ -135,7 +143,7 @@ void RTPReceiver::OnPsDemux(unsigned char streamId, BYTE *data, int len, bool ke |
135 | 143 | // //通知网关关闭句柄 |
136 | 144 | // if(!((VideoSession *)GetUsrParam())->streamHandle().empty()) |
137 | 145 | // { |
138 | - // LOG_INFO("[{}] ---->Notify hisense gateway release handle = {} !<----", m_deviceID, ((VideoSession *)GetUsrParam())->streamHandle()); | |
146 | + // LOG_INFO("[{}] ---->Notify hisense gateway release handle = {} !<----", m_SipChannelId, ((VideoSession *)GetUsrParam())->streamHandle()); | |
139 | 147 | |
140 | 148 | // if (((VideoSession *)GetUsrParam())->video_type() == EREAL) |
141 | 149 | // real_stream_stop(((VideoSession *)GetUsrParam())->streamHandle()); |
... | ... | @@ -172,10 +180,10 @@ void RTPReceiver::OnPsDemux(unsigned char streamId, BYTE *data, int len, bool ke |
172 | 180 | // 解PS包线程 |
173 | 181 | int RTPReceiver::OnPsProcess() |
174 | 182 | { |
175 | - LOG_INFO("[{}] started.", m_deviceID); | |
183 | + LOG_INFO("[{}] started.", m_SipChannelId); | |
176 | 184 | while (!m_bPsExit) { |
177 | 185 | m_psFrameMutex.lock(); |
178 | - // LOG_DEBUG("[{}] PS frame size : {}", m_deviceID, m_psVideoFrames.size()); | |
186 | + // LOG_DEBUG("[{}] PS frame size : {}", m_SipChannelId, m_psVideoFrames.size()); | |
179 | 187 | if (m_psVideoFrames.size() <= 0){ |
180 | 188 | m_psFrameMutex.unlock(); |
181 | 189 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
... | ... | @@ -189,15 +197,15 @@ int RTPReceiver::OnPsProcess() |
189 | 197 | int nRet = m_psParser.AddData(frame->buf_, frame->len_); |
190 | 198 | if (nRet == -1) |
191 | 199 | { |
192 | - LOG_INFO("m_psParser return -1--{}", m_deviceID); | |
200 | + LOG_INFO("m_psParser return -1--{}", m_SipChannelId); | |
193 | 201 | } |
194 | 202 | else if (nRet == -2) |
195 | 203 | { |
196 | - LOG_INFO("m_psParser return -2--{}", m_deviceID); | |
204 | + LOG_INFO("m_psParser return -2--{}", m_SipChannelId); | |
197 | 205 | } |
198 | 206 | else if (nRet == -3) |
199 | 207 | { |
200 | - LOG_INFO("m_psParser return -3--{}", m_deviceID); | |
208 | + LOG_INFO("m_psParser return -3--{}", m_SipChannelId); | |
201 | 209 | } |
202 | 210 | |
203 | 211 | delete frame; |
... | ... | @@ -209,15 +217,11 @@ int RTPReceiver::OnPsProcess() |
209 | 217 | |
210 | 218 | m_hVodEndFunc(m_usrParam); |
211 | 219 | |
212 | - LOG_INFO("[{}] exited.", m_deviceID); | |
220 | + LOG_INFO("[{}] exited.", m_SipChannelId); | |
213 | 221 | |
214 | 222 | return 0; |
215 | 223 | } |
216 | 224 | |
217 | -void RTPReceiver::SetDeviceID(string deviceID){ | |
218 | - m_deviceID = deviceID; | |
219 | -} | |
220 | - | |
221 | 225 | int RTPReceiver::GetPsFrameListSize() |
222 | 226 | { |
223 | 227 | std::lock_guard<std::mutex> l(m_psFrameMutex); |
... | ... | @@ -232,7 +236,7 @@ void RTPReceiver::ClearPsVideoFrameList() |
232 | 236 | delete f; |
233 | 237 | m_psVideoFrames.pop(); |
234 | 238 | } |
235 | - LOG_INFO("[{}] cleared ps video frame list!", m_deviceID); | |
239 | + LOG_INFO("[{}] cleared ps video frame list!", m_SipChannelId); | |
236 | 240 | } |
237 | 241 | |
238 | 242 | int RTPReceiver::ParsePacket(RTPPacket* packet){ |
... | ... | @@ -258,7 +262,7 @@ int RTPReceiver::ParsePacket(RTPPacket* packet){ |
258 | 262 | break; |
259 | 263 | } |
260 | 264 | |
261 | - // LOG_DEBUG("[{}] ParsePacket GetPayloadLength", m_deviceID); | |
265 | + // LOG_DEBUG("[{}] ParsePacket GetPayloadLength", m_SipChannelId); | |
262 | 266 | |
263 | 267 | if (mark) |
264 | 268 | { |
... | ... | @@ -272,7 +276,7 @@ int RTPReceiver::ParsePacket(RTPPacket* packet){ |
272 | 276 | std::lock_guard<std::mutex> l(m_psFrameMutex); |
273 | 277 | if (m_psVideoFrames.size() < 100) |
274 | 278 | { |
275 | - // LOG_DEBUG("[{}]ParsePacket push", m_deviceID); | |
279 | + // LOG_DEBUG("[{}]ParsePacket push", m_SipChannelId); | |
276 | 280 | m_psVideoFrames.push(new Frame(frameBuf, offset, false)); |
277 | 281 | } |
278 | 282 | else { |
... | ... | @@ -282,7 +286,7 @@ int RTPReceiver::ParsePacket(RTPPacket* packet){ |
282 | 286 | else{ |
283 | 287 | //若此时解码线程已经退出,不再往m_psVideoFrames推送帧,且退出当前线程 |
284 | 288 | free(frameBuf); |
285 | - LOG_INFO("ParsePacket quit, device_id:{}", m_deviceID); | |
289 | + LOG_INFO("ParsePacket quit, device_id:{}", m_SipChannelId); | |
286 | 290 | return 1; |
287 | 291 | } |
288 | 292 | offset = 0; |
... | ... | @@ -294,4 +298,44 @@ int RTPReceiver::ParsePacket(RTPPacket* packet){ |
294 | 298 | } while (0); |
295 | 299 | |
296 | 300 | return 0; |
301 | +} | |
302 | + | |
303 | +int RTPReceiver::allocRtpPort() { | |
304 | + | |
305 | + int s_rtpPort = MIN_RTP_PORT; | |
306 | + | |
307 | + srand((unsigned int)time(NULL)); | |
308 | + s_rtpPort = MIN_RTP_PORT + (rand() % MIN_RTP_PORT); | |
309 | + | |
310 | + if (s_rtpPort % 2) | |
311 | + ++s_rtpPort; | |
312 | + | |
313 | + while (true) | |
314 | + { | |
315 | + s_rtpPort = s_rtpPort >= MAX_RTP_PORT ? MIN_RTP_PORT : s_rtpPort; | |
316 | + | |
317 | + for (int i = 0; i < 2; i++) { | |
318 | + sockaddr_in sRecvAddr; | |
319 | + int s = socket(AF_INET, SOCK_DGRAM, 0); | |
320 | + | |
321 | + sRecvAddr.sin_family = AF_INET; | |
322 | + sRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); | |
323 | + sRecvAddr.sin_port = htons(s_rtpPort + i); | |
324 | + | |
325 | + int nResult = bind(s, (sockaddr *)&sRecvAddr, sizeof(sRecvAddr)); | |
326 | + if (nResult != 0) { | |
327 | + break; | |
328 | + } | |
329 | + | |
330 | + nResult = close(s); | |
331 | + if (nResult != 0) { | |
332 | + LOG_ERROR("[{}] - closesocket failed : {}", m_SipChannelId, nResult); | |
333 | + return -1; | |
334 | + } | |
335 | + } | |
336 | + | |
337 | + s_rtpPort += 2; | |
338 | + } | |
339 | + | |
340 | + return s_rtpPort; | |
297 | 341 | } |
298 | 342 | \ No newline at end of file | ... | ... |
src/decoder/gb28181/rtp/RTPReceiver.h
... | ... | @@ -87,7 +87,7 @@ public: |
87 | 87 | RTPReceiver(); |
88 | 88 | virtual ~RTPReceiver(); |
89 | 89 | |
90 | - virtual bool Open(int localPort) = 0; | |
90 | + virtual bool Open(string channel_id) = 0; | |
91 | 91 | virtual bool IsOpened() = 0; |
92 | 92 | virtual void Close() = 0; |
93 | 93 | |
... | ... | @@ -97,10 +97,10 @@ public: |
97 | 97 | |
98 | 98 | void SetRequestStreamCallback(CallBack_Request_Stream cb); |
99 | 99 | |
100 | - void SetDeviceID(string deviceID); | |
101 | - | |
102 | 100 | int GetPsFrameListSize(); |
103 | 101 | |
102 | + int allocRtpPort(); | |
103 | + | |
104 | 104 | public: |
105 | 105 | void OnPsDemux(unsigned char streamId, BYTE *data, int len, bool key, uint64_t pts, uint64_t localPts); |
106 | 106 | int OnPsProcess(); |
... | ... | @@ -126,7 +126,7 @@ public: |
126 | 126 | std::queue<Frame*> m_psVideoFrames; |
127 | 127 | mutex m_psFrameMutex; |
128 | 128 | |
129 | - string m_deviceID; | |
129 | + string m_SipChannelId; | |
130 | 130 | int m_rtp_port{-1}; |
131 | 131 | |
132 | 132 | CMpeg2Demux m_psParser; | ... | ... |
src/decoder/gb28181/rtp/RTPTcpReceiver.cpp
1 | 1 | #include"RTPTcpReceiver.h" |
2 | 2 | |
3 | 3 | #include "../common_header.h" |
4 | +#include "../sip/SipServer.h" | |
4 | 5 | |
5 | 6 | |
6 | 7 | // class TcpRTPSession : public RTPSession |
... | ... | @@ -128,20 +129,29 @@ RTPTcpReceiver::~RTPTcpReceiver(){ |
128 | 129 | } |
129 | 130 | } |
130 | 131 | |
131 | -bool RTPTcpReceiver::Open(int localPort){ | |
132 | - if(0 != initSession(localPort)){ | |
132 | +bool RTPTcpReceiver::Open(string channel_id){ | |
133 | + m_SipChannelId = channel_id; | |
134 | + | |
135 | + int rtpPort = allocRtpPort(); | |
136 | + if (rtpPort < 0) { | |
137 | + return false; | |
138 | + } | |
139 | + | |
140 | + m_rtp_port = rtpPort; | |
141 | + | |
142 | + if(0 != initSession(m_rtp_port)){ | |
133 | 143 | return false; |
134 | 144 | } |
135 | 145 | |
136 | 146 | m_bOpened = true; |
137 | 147 | |
138 | - LOG_INFO("[{}] started.", m_deviceID); | |
148 | + LOG_INFO("[{}] started.", m_SipChannelId); | |
139 | 149 | |
140 | 150 | return true; |
141 | 151 | } |
142 | 152 | |
143 | 153 | bool RTPTcpReceiver::IsOpened(){ |
144 | - LOG_INFO("[{}] isopng:{} ", m_deviceID, m_bOpened); | |
154 | + LOG_INFO("[{}] isopng:{} ", m_SipChannelId, m_bOpened); | |
145 | 155 | return m_bOpened; |
146 | 156 | } |
147 | 157 | |
... | ... | @@ -160,7 +170,7 @@ void RTPTcpReceiver::close_task(){ |
160 | 170 | |
161 | 171 | m_bAccepted = true; |
162 | 172 | |
163 | - LOG_DEBUG("[{}] 1.", m_deviceID); | |
173 | + LOG_DEBUG("[{}] 1.", m_SipChannelId); | |
164 | 174 | |
165 | 175 | // rtp接收线程退出 |
166 | 176 | if (m_rtpThread.joinable()) |
... | ... | @@ -168,13 +178,13 @@ void RTPTcpReceiver::close_task(){ |
168 | 178 | m_rtpThread.join(); |
169 | 179 | } |
170 | 180 | |
171 | - LOG_DEBUG("[{}] 2.", m_deviceID); | |
181 | + LOG_DEBUG("[{}] 2.", m_SipChannelId); | |
172 | 182 | |
173 | 183 | ClosePsThread(); |
174 | 184 | |
175 | 185 | m_bOpened = false; |
176 | 186 | |
177 | - LOG_INFO("[{}] closed.", m_deviceID); | |
187 | + LOG_INFO("[{}] closed.", m_SipChannelId); | |
178 | 188 | } |
179 | 189 | |
180 | 190 | bool RTPTcpReceiver::isClosing(){ |
... | ... | @@ -196,13 +206,13 @@ int RTPTcpReceiver::initSession(int localPort){ |
196 | 206 | int nRet = bind(m_nListener, (sockaddr*)&serverAddr, sizeof(serverAddr)); |
197 | 207 | if (nRet == -1) |
198 | 208 | { |
199 | - LOG_ERROR("[{}] 绑定端口失败: {}", m_deviceID, localPort); | |
209 | + LOG_ERROR("[{}] 绑定端口失败: {}", m_SipChannelId, localPort); | |
200 | 210 | return -1; |
201 | 211 | } |
202 | 212 | |
203 | 213 | if (listen(m_nListener, 1) == -1) |
204 | 214 | { |
205 | - LOG_ERROR("[{}] listen 失败", m_deviceID); | |
215 | + LOG_ERROR("[{}] listen 失败", m_SipChannelId); | |
206 | 216 | return -1; |
207 | 217 | } |
208 | 218 | |
... | ... | @@ -219,25 +229,23 @@ int RTPTcpReceiver::initSession(int localPort){ |
219 | 229 | if (status < 0) |
220 | 230 | { |
221 | 231 | // 若status = -59 ,需运行 export LOGNAME=root ,见 https://blog.csdn.net/m0_37876242/article/details/128588162 |
222 | - LOG_ERROR("[{}] create session error: {}", m_deviceID, status); | |
232 | + LOG_ERROR("[{}] create session error: {}", m_SipChannelId, status); | |
223 | 233 | return -1; |
224 | 234 | } |
225 | 235 | |
226 | - m_rtp_port = localPort; | |
227 | - | |
228 | 236 | m_rtpThread = std::thread(rtp_revc_thread_, this); |
229 | 237 | m_listenFinishThread = std::thread(listen_finish_thread_, this); |
230 | 238 | |
231 | 239 | InitPS(); |
232 | 240 | |
233 | - // bool bRet = RequestStream(); | |
234 | - // if (!bRet) | |
235 | - // { | |
236 | - // LOG_INFO("[{}] 请求流失败!", m_deviceID); | |
237 | - // return -1; | |
238 | - // } | |
241 | + bool bRet = RequestStream(); | |
242 | + if (!bRet) | |
243 | + { | |
244 | + LOG_INFO("[{}] 请求流失败!", m_SipChannelId); | |
245 | + return -1; | |
246 | + } | |
239 | 247 | |
240 | - LOG_INFO("[{}] 初始化成功, congratulations !!!", m_deviceID); | |
248 | + LOG_INFO("[{}] 初始化成功, congratulations !!!", m_SipChannelId); | |
241 | 249 | |
242 | 250 | return 0; |
243 | 251 | } |
... | ... | @@ -248,13 +256,13 @@ int RTPTcpReceiver::OnRtpRecv() |
248 | 256 | return -1; |
249 | 257 | } |
250 | 258 | |
251 | - LOG_INFO("[{}] OnRtpRecv started, m_nListener : {}", m_deviceID, m_nListener); | |
259 | + LOG_INFO("[{}] OnRtpRecv started, m_nListener : {}", m_SipChannelId, m_nListener); | |
252 | 260 | |
253 | 261 | sockaddr_in clientAddr; |
254 | 262 | int nLen = sizeof(sockaddr_in); |
255 | 263 | SocketType nServer = -1; |
256 | 264 | |
257 | - LOG_INFO("[{}] Poll started.", m_deviceID); | |
265 | + LOG_INFO("[{}] Poll started.", m_SipChannelId); | |
258 | 266 | int reconn_times = 0; |
259 | 267 | int reaccept_times = 0; |
260 | 268 | bool bReconn = false; |
... | ... | @@ -264,49 +272,49 @@ int RTPTcpReceiver::OnRtpRecv() |
264 | 272 | goto end_flag; |
265 | 273 | } |
266 | 274 | |
267 | - // while (!bReconn){ | |
268 | - // if(m_bRtpExit){ | |
269 | - // goto end_flag; | |
270 | - // } | |
271 | - | |
272 | - // reconn_times++; | |
273 | - // if(reconn_times > 10){ | |
274 | - // // 10次请求都失败,结束任务 | |
275 | - // m_bRtpExit = true; | |
276 | - // goto end_flag; | |
277 | - // } | |
278 | - // LOG_DEBUG("[{}] RequestStream...", m_deviceID); | |
279 | - // bReconn = RequestStream(); | |
280 | - // if (bReconn){ | |
281 | - // LOG_DEBUG("[{}] RequestStream, True", m_deviceID); | |
282 | - // continue; | |
283 | - // } | |
284 | - // LOG_DEBUG("[{}] RequestStream, False", m_deviceID); | |
275 | + while (!bReconn){ | |
276 | + if(m_bRtpExit){ | |
277 | + goto end_flag; | |
278 | + } | |
279 | + | |
280 | + reconn_times++; | |
281 | + if(reconn_times > 10){ | |
282 | + // 10次请求都失败,结束任务 | |
283 | + m_bRtpExit = true; | |
284 | + goto end_flag; | |
285 | + } | |
286 | + LOG_DEBUG("[{}] RequestStream...", m_SipChannelId); | |
287 | + bReconn = RequestStream(); | |
288 | + if (bReconn){ | |
289 | + LOG_DEBUG("[{}] RequestStream, True", m_SipChannelId); | |
290 | + continue; | |
291 | + } | |
292 | + LOG_DEBUG("[{}] RequestStream, False", m_SipChannelId); | |
285 | 293 | |
286 | - // std::this_thread::sleep_for(std::chrono::seconds(5)); | |
287 | - // } | |
294 | + std::this_thread::sleep_for(std::chrono::seconds(5)); | |
295 | + } | |
288 | 296 | |
289 | - LOG_DEBUG("[{}] accepting...", m_deviceID); | |
297 | + LOG_DEBUG("[{}] accepting...", m_SipChannelId); | |
290 | 298 | nServer = accept(m_nListener, (sockaddr*)&clientAddr, (socklen_t * ) &nLen); |
291 | 299 | if (-1 == nServer){ |
292 | 300 | reaccept_times++; |
293 | - LOG_DEBUG("[{}] reaccept_times = {}", m_deviceID, reaccept_times); | |
301 | + LOG_DEBUG("[{}] reaccept_times = {}", m_SipChannelId, reaccept_times); | |
294 | 302 | if(reaccept_times > 600){ |
295 | - LOG_DEBUG("[{}] reaccept_times > 600", m_deviceID); | |
303 | + LOG_DEBUG("[{}] reaccept_times > 600", m_SipChannelId); | |
296 | 304 | bReconn = false; |
297 | 305 | reaccept_times = 0; |
298 | 306 | } |
299 | 307 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); |
300 | 308 | continue; |
301 | 309 | } |
302 | - LOG_DEBUG("[{}] accept success", m_deviceID); | |
310 | + LOG_DEBUG("[{}] accept success", m_SipChannelId); | |
303 | 311 | m_rtpSessionPtr->AddDestination(RTPTCPAddress(nServer)); |
304 | 312 | m_bAccepted = true; |
305 | 313 | bReconn = false; |
306 | 314 | reconn_times = 0; |
307 | 315 | reaccept_times = 0; |
308 | 316 | |
309 | - LOG_INFO("[{}] nServer={}", m_deviceID, nServer); | |
317 | + LOG_INFO("[{}] nServer={}", m_SipChannelId, nServer); | |
310 | 318 | break; |
311 | 319 | } |
312 | 320 | |
... | ... | @@ -319,7 +327,7 @@ int RTPTcpReceiver::OnRtpRecv() |
319 | 327 | |
320 | 328 | while ((pack = m_rtpSessionPtr->GetNextPacket()) != NULL) |
321 | 329 | { |
322 | - // LOG_DEBUG("[{}] time: {} ", m_deviceID, UtilTools::get_cur_time_ms()); | |
330 | + // LOG_DEBUG("[{}] time: {} ", m_SipChannelId, UtilTools::get_cur_time_ms()); | |
323 | 331 | ParsePacket(pack); |
324 | 332 | |
325 | 333 | m_rtpSessionPtr->DeletePacket(pack); |
... | ... | @@ -344,7 +352,7 @@ end_flag: |
344 | 352 | close(m_nListener); |
345 | 353 | } |
346 | 354 | |
347 | - LOG_INFO("[{}] OnRtpRecv exited.", m_deviceID); | |
355 | + LOG_INFO("[{}] OnRtpRecv exited.", m_SipChannelId); | |
348 | 356 | |
349 | 357 | return 0; |
350 | 358 | } |
... | ... | @@ -362,9 +370,11 @@ bool RTPTcpReceiver::ReConnect(){ |
362 | 370 | } |
363 | 371 | |
364 | 372 | bool RTPTcpReceiver::RequestStream(){ |
365 | - if (m_callback_request_stream){ | |
366 | - return m_callback_request_stream(m_deviceID.c_str(), m_rtp_port); | |
367 | - } | |
368 | - | |
369 | - return false; | |
373 | + SipServer* pServer = SipServer::getInstance(); | |
374 | + int ret = -1; | |
375 | + if (pServer){ | |
376 | + ret = pServer->RequestInvite_UDP(m_SipChannelId.c_str(), m_rtp_port); | |
377 | + } | |
378 | + | |
379 | + return (ret > 0) ; | |
370 | 380 | } |
371 | 381 | \ No newline at end of file | ... | ... |
src/decoder/gb28181/rtp/RTPTcpReceiver.h
src/decoder/gb28181/rtp/RTPUdpReceiver.cpp
... | ... | @@ -7,6 +7,7 @@ |
7 | 7 | #include <chrono> |
8 | 8 | |
9 | 9 | #include "../common_header.h" |
10 | +#include "../sip/SipServer.h" | |
10 | 11 | |
11 | 12 | |
12 | 13 | using namespace std; |
... | ... | @@ -86,44 +87,58 @@ RTPUdpReceiver::~RTPUdpReceiver() |
86 | 87 | } |
87 | 88 | } |
88 | 89 | |
89 | -bool RTPUdpReceiver::Open(int localPort) | |
90 | +bool RTPUdpReceiver::Open(string channel_id) | |
90 | 91 | { |
92 | + m_SipChannelId = channel_id; | |
93 | + | |
94 | + int rtpPort = allocRtpPort(); | |
95 | + if (rtpPort < 0) { | |
96 | + return false; | |
97 | + } | |
98 | + m_rtp_port = rtpPort; | |
99 | + | |
91 | 100 | m_sessparamsPtr->SetUsePollThread(true); |
92 | 101 | m_sessparamsPtr->SetMinimumRTCPTransmissionInterval(10); |
93 | 102 | m_sessparamsPtr->SetOwnTimestampUnit(1.0/90000.0); |
94 | 103 | m_sessparamsPtr->SetAcceptOwnPackets(true); |
95 | 104 | |
96 | - m_transparamsPtr->SetPortbase(localPort); | |
105 | + m_transparamsPtr->SetPortbase(m_rtp_port); | |
97 | 106 | m_transparamsPtr->SetRTPReceiveBuffer(kRtpRecvBufferSize); |
98 | 107 | |
99 | - LOG_INFO("[{}] port: {}", m_deviceID, localPort); | |
108 | + LOG_INFO("[{}] port: {}", m_SipChannelId, m_rtp_port); | |
100 | 109 | |
101 | 110 | int err = m_rtpSessionPtr->Create(*m_sessparamsPtr, m_transparamsPtr); |
102 | - if (err != 0) | |
103 | - { | |
104 | - LOG_ERROR("[{}] Create error: {}", m_deviceID, err); | |
111 | + if (err != 0) { | |
112 | + LOG_ERROR("[{}] Create error: {}", m_SipChannelId, err); | |
105 | 113 | return false; |
106 | 114 | } |
107 | 115 | |
108 | 116 | m_rtpThreadPtr = new std::thread(rtp_revc_thread_, this); |
109 | - if (nullptr == m_rtpThreadPtr) | |
110 | - { | |
111 | - LOG_ERROR("[{}] Create m_rtpThreadPtr error", m_deviceID); | |
117 | + if (nullptr == m_rtpThreadPtr) { | |
118 | + LOG_ERROR("[{}] Create m_rtpThreadPtr error", m_SipChannelId); | |
112 | 119 | return false; |
113 | 120 | } |
114 | - | |
115 | 121 | |
116 | - if (InitPS() != 0) | |
117 | - { | |
122 | + if (InitPS() != 0) { | |
118 | 123 | return false; |
119 | 124 | } |
120 | 125 | |
121 | 126 | m_bOpened = true; |
122 | - LOG_INFO("[{}] Open ok", m_deviceID); | |
127 | + LOG_INFO("[{}] Open ok", m_SipChannelId); | |
123 | 128 | |
124 | 129 | return true; |
125 | 130 | } |
126 | 131 | |
132 | +bool RTPUdpReceiver::RequestStream() { | |
133 | + SipServer* pServer = SipServer::getInstance(); | |
134 | + int ret = -1; | |
135 | + if (pServer){ | |
136 | + ret = pServer->RequestInvite_UDP(m_SipChannelId.c_str(), m_rtp_port); | |
137 | + } | |
138 | + | |
139 | + return (ret > 0) ; | |
140 | +} | |
141 | + | |
127 | 142 | bool RTPUdpReceiver::IsOpened() |
128 | 143 | { |
129 | 144 | return m_bOpened; |
... | ... | @@ -146,7 +161,7 @@ void RTPUdpReceiver::Close() |
146 | 161 | |
147 | 162 | m_bOpened = false; |
148 | 163 | |
149 | - LOG_INFO("[{}] closed.", m_deviceID); | |
164 | + LOG_INFO("[{}] closed.", m_SipChannelId); | |
150 | 165 | } |
151 | 166 | |
152 | 167 | // 收RTP包线程 |
... | ... | @@ -156,7 +171,7 @@ int RTPUdpReceiver::OnRtpRecv() |
156 | 171 | return -1; |
157 | 172 | } |
158 | 173 | |
159 | - LOG_INFO("[{}] OnRtpRecv started.", m_deviceID); | |
174 | + LOG_INFO("[{}] OnRtpRecv started.", m_SipChannelId); | |
160 | 175 | while (!m_bRtpExit) |
161 | 176 | { |
162 | 177 | //try |
... | ... | @@ -166,7 +181,7 @@ int RTPUdpReceiver::OnRtpRecv() |
166 | 181 | |
167 | 182 | if (m_rtpSessionPtr->GotoFirstSourceWithData()) |
168 | 183 | { |
169 | - // LOG_INFO("OnRtpRecv GotoFirstSourceWithData --{}", m_deviceID); | |
184 | + // LOG_INFO("OnRtpRecv GotoFirstSourceWithData --{}", m_SipChannelId); | |
170 | 185 | last_recv_ts = UtilTools::get_cur_time_ms(); |
171 | 186 | m_idleCount = 0; |
172 | 187 | m_noDataCount = 0; |
... | ... | @@ -175,7 +190,7 @@ int RTPUdpReceiver::OnRtpRecv() |
175 | 190 | RTPPacket* packet; |
176 | 191 | while ((packet = m_rtpSessionPtr->GetNextPacket()) != NULL) |
177 | 192 | { |
178 | - // LOG_INFO("OnRtpRecv GetNextPacket --{}", m_deviceID); | |
193 | + // LOG_INFO("OnRtpRecv GetNextPacket --{}", m_SipChannelId); | |
179 | 194 | int ret = ParsePacket(packet); |
180 | 195 | m_rtpSessionPtr->DeletePacket(packet); |
181 | 196 | |
... | ... | @@ -206,7 +221,7 @@ int RTPUdpReceiver::OnRtpRecv() |
206 | 221 | // //由于record_stream_status这个函数返回值不准确,所以增加一个进度条大于80% |
207 | 222 | // if(record_stream_status(((VideoSession *)GetUsrParam())->streamHandle())) |
208 | 223 | // { |
209 | - // LOG_INFO("************Record stream is finished**{}**m_progress = {}********", m_deviceID, ((VideoSession *)GetUsrParam())->progress()); | |
224 | + // LOG_INFO("************Record stream is finished**{}**m_progress = {}********", m_SipChannelId, ((VideoSession *)GetUsrParam())->progress()); | |
210 | 225 | // m_idleCount = -1; |
211 | 226 | // m_hVodEndFunc(m_usrParam); |
212 | 227 | // record_stream_stop(((VideoSession *)GetUsrParam())->streamHandle()); |
... | ... | @@ -217,7 +232,7 @@ int RTPUdpReceiver::OnRtpRecv() |
217 | 232 | // //如果此时进度大于80% 算完成吧 |
218 | 233 | // if(((VideoSession *)GetUsrParam())->progress() > 0.80) |
219 | 234 | // { |
220 | - // LOG_INFO("************Record stream is overtime**{}**m_progress = {}********", m_deviceID, ((VideoSession *)GetUsrParam())->progress()); | |
235 | + // LOG_INFO("************Record stream is overtime**{}**m_progress = {}********", m_SipChannelId, ((VideoSession *)GetUsrParam())->progress()); | |
221 | 236 | |
222 | 237 | // m_idleCount = 0; |
223 | 238 | // m_hVodEndFunc(m_usrParam); |
... | ... | @@ -227,7 +242,7 @@ int RTPUdpReceiver::OnRtpRecv() |
227 | 242 | // else |
228 | 243 | // { |
229 | 244 | // m_idleCount = -1; |
230 | - // //LOG_ERROR("************post ERROR_REALSTREAM_INTERRUPT to structure****{}********", m_deviceID); | |
245 | + // //LOG_ERROR("************post ERROR_REALSTREAM_INTERRUPT to structure****{}********", m_SipChannelId); | |
231 | 246 | // //发送流中断 |
232 | 247 | // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Record time video streaming interruption!"); |
233 | 248 | // } |
... | ... | @@ -238,7 +253,7 @@ int RTPUdpReceiver::OnRtpRecv() |
238 | 253 | // |
239 | 254 | // if (m_noDataCount < -200000)//任务开始时没收到流 |
240 | 255 | // { |
241 | - // //LOG_ERROR("************m_hVodEndFunc(m_usrParam)!!!m_hVodEndFunc(m_usrParam)********{}******", m_deviceID); | |
256 | + // //LOG_ERROR("************m_hVodEndFunc(m_usrParam)!!!m_hVodEndFunc(m_usrParam)********{}******", m_SipChannelId); | |
242 | 257 | // m_noDataCount = -1; |
243 | 258 | |
244 | 259 | // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Record time video streaming interruption2!"); |
... | ... | @@ -256,7 +271,7 @@ int RTPUdpReceiver::OnRtpRecv() |
256 | 271 | // uint64_t cts = UtilTools::get_cur_time_ms(); |
257 | 272 | // float duration_not_recv = (cts - last_recv_ts) / 1000.0; |
258 | 273 | // |
259 | - // //LOG_ERROR("************I haven't got stream from hik gateway exceed {}s,send eof********{}******", duration_not_recv, m_deviceID); | |
274 | + // //LOG_ERROR("************I haven't got stream from hik gateway exceed {}s,send eof********{}******", duration_not_recv, m_SipChannelId); | |
260 | 275 | // m_idleCount = -1; |
261 | 276 | |
262 | 277 | // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Real time video streaming interruption!"); |
... | ... | @@ -264,7 +279,7 @@ int RTPUdpReceiver::OnRtpRecv() |
264 | 279 | // |
265 | 280 | // if (m_noDataCount < -200000)//任务开始时没收到流 |
266 | 281 | // { |
267 | - // //LOG_ERROR("************m_noDataCount < -200000********{}******", m_deviceID); | |
282 | + // //LOG_ERROR("************m_noDataCount < -200000********{}******", m_SipChannelId); | |
268 | 283 | // m_noDataCount = -1; |
269 | 284 | |
270 | 285 | // //throw GeneralException2(ERROR_REALSTREAM_INTERRUPT, "Real time video streaming interruption2!"); |
... | ... | @@ -275,7 +290,7 @@ int RTPUdpReceiver::OnRtpRecv() |
275 | 290 | //} |
276 | 291 | // catch (GeneralException2& e) |
277 | 292 | //{ |
278 | - // //LOG_ERROR("---> video streaming interruption!<---{}, error: {}", m_deviceID, e.err_msg()); | |
293 | + // //LOG_ERROR("---> video streaming interruption!<---{}, error: {}", m_SipChannelId, e.err_msg()); | |
279 | 294 | |
280 | 295 | // byte_buffer bb(64); |
281 | 296 | // bb << VasCmd::VAS_CMD_REALSTREAM_INTERRUPT << e.err_msg(); |
... | ... | @@ -287,7 +302,7 @@ int RTPUdpReceiver::OnRtpRecv() |
287 | 302 | // ((VideoSession *)GetUsrParam())->msgChan()->send_msg(bb.data_ptr(), bb.data_size()); |
288 | 303 | // } |
289 | 304 | // catch (GeneralException2& e) { |
290 | - // //LOG_ERROR("[{}] send vas cmd VAS_CMD_REALSTREAM_INTERRUPT error: {}, {}", m_deviceID, e.err_code(), e.err_str()); | |
305 | + // //LOG_ERROR("[{}] send vas cmd VAS_CMD_REALSTREAM_INTERRUPT error: {}, {}", m_SipChannelId, e.err_code(), e.err_str()); | |
291 | 306 | // } |
292 | 307 | // } |
293 | 308 | |
... | ... | @@ -295,7 +310,7 @@ int RTPUdpReceiver::OnRtpRecv() |
295 | 310 | // if(!((VideoSession *)GetUsrParam())->streamHandle().empty()) |
296 | 311 | // { |
297 | 312 | |
298 | - // LOG_INFO("---->Notify hisense gateway release handle = {} !<----{}", ((VideoSession *)GetUsrParam())->streamHandle().c_str(), m_deviceID); | |
313 | + // LOG_INFO("---->Notify hisense gateway release handle = {} !<----{}", ((VideoSession *)GetUsrParam())->streamHandle().c_str(), m_SipChannelId); | |
299 | 314 | // if (((VideoSession *)GetUsrParam())->video_type() == VideoType::EREAL) |
300 | 315 | // real_stream_stop(((VideoSession *)GetUsrParam())->streamHandle()); |
301 | 316 | // |
... | ... | @@ -315,7 +330,7 @@ int RTPUdpReceiver::OnRtpRecv() |
315 | 330 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
316 | 331 | } |
317 | 332 | |
318 | - LOG_INFO("[{}] OnRtpRecv exited.", m_deviceID); | |
333 | + LOG_INFO("[{}] OnRtpRecv exited.", m_SipChannelId); | |
319 | 334 | |
320 | 335 | return 0; |
321 | 336 | } | ... | ... |
src/decoder/gb28181/rtp/RTPUdpReceiver.h
... | ... | @@ -37,10 +37,12 @@ public: |
37 | 37 | RTPUdpReceiver(); |
38 | 38 | ~RTPUdpReceiver(); |
39 | 39 | |
40 | - virtual bool Open(int localPort); | |
40 | + virtual bool Open(string channel_id); | |
41 | 41 | virtual bool IsOpened() ; |
42 | 42 | virtual void Close() ; |
43 | 43 | |
44 | + bool RequestStream(); | |
45 | + | |
44 | 46 | public: |
45 | 47 | int OnRtpRecv(); |
46 | 48 | |
... | ... | @@ -58,6 +60,8 @@ private: |
58 | 60 | |
59 | 61 | RTPSessionParams* m_sessparamsPtr; |
60 | 62 | RTPUDPv4TransmissionParams* m_transparamsPtr; |
63 | + | |
64 | + string m_sip_channel_id; | |
61 | 65 | }; |
62 | 66 | |
63 | 67 | #endif // _RTP_UDP_RECEIVER_H_ | ... | ... |
src/decoder/gb28181/sip/SipServer.cpp
... | ... | @@ -73,6 +73,9 @@ SipServer::~SipServer() { |
73 | 73 | bool SipServer::Init(ServerInfo info) { |
74 | 74 | mInfo = info; |
75 | 75 | LOG_INFO("{}:{}", mInfo.getIp(), mInfo.getPort()); |
76 | + | |
77 | + m_event_loop_thread = new std::thread(event_loop_thread, this); | |
78 | + | |
76 | 79 | return true; |
77 | 80 | } |
78 | 81 | |
... | ... | @@ -174,10 +177,6 @@ int SipServer::init_sip_server() { |
174 | 177 | return 0; |
175 | 178 | } |
176 | 179 | |
177 | -void SipServer::Start() { | |
178 | - m_event_loop_thread = new std::thread(event_loop_thread, this); | |
179 | -} | |
180 | - | |
181 | 180 | void SipServer::event_loop() { |
182 | 181 | |
183 | 182 | if(this->init_sip_server() !=0 ){ |
... | ... | @@ -370,7 +369,7 @@ int SipServer::request_bye(eXosip_event_t* evtp) { |
370 | 369 | return ret; |
371 | 370 | } |
372 | 371 | |
373 | -int SipServer::RequestInvite_UDP(const DeviceInfo& device, int rtpPort) { | |
372 | +int SipServer::RequestInvite_UDP(const char* dst_channel, int rtpPort) { | |
374 | 373 | |
375 | 374 | if (mClientMap.size() <= 0){ |
376 | 375 | return -1; |
... | ... | @@ -388,8 +387,6 @@ int SipServer::RequestInvite_UDP(const DeviceInfo& device, int rtpPort) { |
388 | 387 | char sdp[2048] = { 0 }; |
389 | 388 | char head[1024] = { 0 }; |
390 | 389 | |
391 | - const char* dst_channel = "34020000001310004065"; | |
392 | - | |
393 | 390 | sprintf(from, "sip:%s@%s:%d", mInfo.getSipId().c_str(), mInfo.getIp().c_str(), mInfo.getPort()); |
394 | 391 | sprintf(to, "sip:%s@%s:%d", dst_channel, client->getIp().c_str(), client->getPort()); |
395 | 392 | snprintf(sdp, 2048, |
... | ... | @@ -430,7 +427,7 @@ int SipServer::RequestInvite_UDP(const DeviceInfo& device, int rtpPort) { |
430 | 427 | return ret; |
431 | 428 | } |
432 | 429 | |
433 | -int SipServer::RequestInvite_TCP_a(const DeviceInfo& device, int rtpPort) { | |
430 | +int SipServer::RequestInvite_TCP_a(const char* dst_channel, int rtpPort) { | |
434 | 431 | if (mClientMap.size() <= 0){ |
435 | 432 | return -1; |
436 | 433 | } |
... | ... | @@ -447,7 +444,7 @@ int SipServer::RequestInvite_TCP_a(const DeviceInfo& device, int rtpPort) { |
447 | 444 | char sdp[2048] = { 0 }; |
448 | 445 | char head[1024] = { 0 }; |
449 | 446 | |
450 | - const char* dst_channel = "34020000001320000001"; | |
447 | + // const char* dst_channel = "34020000001320000001"; | |
451 | 448 | |
452 | 449 | sprintf(from, "sip:%s@%s:%d", mInfo.getSipId().c_str(), mInfo.getIp().c_str(), mInfo.getPort()); |
453 | 450 | sprintf(to, "sip:%s@%s:%d", dst_channel, client->getIp().c_str(), client->getPort()); | ... | ... |
src/decoder/gb28181/sip/SipServer.h
... | ... | @@ -116,11 +116,19 @@ private: |
116 | 116 | |
117 | 117 | class SipServer { |
118 | 118 | public: |
119 | + static SipServer* getInstance(){ | |
120 | + static SipServer* singleton = nullptr; | |
121 | + if (singleton == nullptr){ | |
122 | + singleton = new SipServer(); | |
123 | + } | |
124 | + return singleton; | |
125 | + } | |
126 | + | |
127 | +public: | |
119 | 128 | SipServer(); |
120 | 129 | ~SipServer(); |
121 | -public: | |
130 | + | |
122 | 131 | bool Init(ServerInfo info); |
123 | - void Start(); | |
124 | 132 | |
125 | 133 | Client* GetClientByDevice(string device); |
126 | 134 | void DeleteClientByDevice(string device); |
... | ... | @@ -129,9 +137,9 @@ public: |
129 | 137 | |
130 | 138 | std::map<std::string, Client*> GetClientMap(); |
131 | 139 | |
132 | - int RequestInvite_UDP(const DeviceInfo& device, int rtpPort); | |
140 | + int RequestInvite_UDP(const char* dst_channel, int rtpPort); | |
133 | 141 | |
134 | - int RequestInvite_TCP_a(const DeviceInfo& device, int rtpPort); | |
142 | + int RequestInvite_TCP_a(const char* dst_channel, int rtpPort); | |
135 | 143 | |
136 | 144 | void cacheCatalog(); |
137 | 145 | ... | ... |