Commit 79b0c737514cbf7aedd1a365c8c32cb78fc0d104
1 parent
76a86847
优化代码,防止摄像头掉线卡死
Showing
2 changed files
with
40 additions
and
8 deletions
src/decoder/dvpp/DvppDecoder.cpp
@@ -56,6 +56,22 @@ static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void | @@ -56,6 +56,22 @@ static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void | ||
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | +static int AVInterruptCallBackFun(void *param) | ||
60 | +{ | ||
61 | + DvppDecoder *pDecoder = (DvppDecoder*)param; | ||
62 | + if (nullptr == pDecoder) return 0; | ||
63 | + | ||
64 | + long long cur_ts = get_cur_time_ms(); | ||
65 | + long time_gap = cur_ts - pDecoder->get_last_read_ts(); | ||
66 | + if (time_gap > 1000*30) { | ||
67 | + LOG_WARN("摄像头异常,释放阻塞"); | ||
68 | + //通知FFMpeg可以从阻塞工作线程中释放操作 | ||
69 | + return 1; | ||
70 | + } else { | ||
71 | + //通知FFMpeg继续阻塞工作 | ||
72 | + return 0; | ||
73 | + } | ||
74 | +} | ||
59 | 75 | ||
60 | DvppDecoder::DvppDecoder(){ | 76 | DvppDecoder::DvppDecoder(){ |
61 | m_read_thread = nullptr; | 77 | m_read_thread = nullptr; |
@@ -114,9 +130,11 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ | @@ -114,9 +130,11 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ | ||
114 | av_dict_set( &options, "bufsize", "655360", 0 ); | 130 | av_dict_set( &options, "bufsize", "655360", 0 ); |
115 | av_dict_set( &options, "rtsp_transport", config.force_tcp ? "tcp" : "udp", 0 ); | 131 | av_dict_set( &options, "rtsp_transport", config.force_tcp ? "tcp" : "udp", 0 ); |
116 | av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒 | 132 | av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒 |
133 | + av_dict_set( &options, "max_delay", "500000", 0); //设置最大时延 | ||
117 | 134 | ||
118 | do{ | 135 | do{ |
119 | fmt_ctx = avformat_alloc_context(); | 136 | fmt_ctx = avformat_alloc_context(); |
137 | + // fmt_ctx->flags |= AVFMT_FLAG_NONBLOCK; | ||
120 | if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) { | 138 | if (avformat_open_input(&fmt_ctx, input_file, nullptr, &options) != 0) { |
121 | LOG_ERROR("[{}]- Cannot open input file: {}", m_dec_name, input_file); | 139 | LOG_ERROR("[{}]- Cannot open input file: {}", m_dec_name, input_file); |
122 | break; | 140 | break; |
@@ -135,6 +153,10 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ | @@ -135,6 +153,10 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ | ||
135 | m_bReal = false; | 153 | m_bReal = false; |
136 | } else { | 154 | } else { |
137 | m_bReal = true; | 155 | m_bReal = true; |
156 | + | ||
157 | + fmt_ctx->interrupt_callback.callback = AVInterruptCallBackFun; | ||
158 | + fmt_ctx->interrupt_callback.opaque = this; | ||
159 | + m_last_read_ts = get_cur_time_ms(); | ||
138 | } | 160 | } |
139 | } | 161 | } |
140 | 162 | ||
@@ -203,6 +225,12 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ | @@ -203,6 +225,12 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ | ||
203 | 225 | ||
204 | m_vdec_out_size = frame_width * frame_height * 3 / 2; | 226 | m_vdec_out_size = frame_width * frame_height * 3 / 2; |
205 | 227 | ||
228 | + if (avctx->gop_size > 0) { | ||
229 | + m_cache_gop = avctx->gop_size + 1; | ||
230 | + } else { | ||
231 | + m_cache_gop = 20; | ||
232 | + } | ||
233 | + | ||
206 | #ifdef USE_VILLAGE | 234 | #ifdef USE_VILLAGE |
207 | bool bRet = m_recoderManager.init2(frame_width, frame_height, m_fps, avctx->bit_rate); | 235 | bool bRet = m_recoderManager.init2(frame_width, frame_height, m_fps, avctx->bit_rate); |
208 | if (!bRet){ | 236 | if (!bRet){ |
@@ -403,6 +431,10 @@ float DvppDecoder::fps(){ | @@ -403,6 +431,10 @@ float DvppDecoder::fps(){ | ||
403 | return m_fps; | 431 | return m_fps; |
404 | } | 432 | } |
405 | 433 | ||
434 | +long long DvppDecoder::get_last_read_ts() { | ||
435 | + return m_last_read_ts; | ||
436 | +} | ||
437 | + | ||
406 | static int snap_count = 0; | 438 | static int snap_count = 0; |
407 | 439 | ||
408 | DeviceMemory* DvppDecoder::snapshot(){ | 440 | DeviceMemory* DvppDecoder::snapshot(){ |
@@ -532,15 +564,15 @@ void DvppDecoder::read_thread() { | @@ -532,15 +564,15 @@ void DvppDecoder::read_thread() { | ||
532 | } | 564 | } |
533 | m_decoded_data_queue_mtx.unlock(); | 565 | m_decoded_data_queue_mtx.unlock(); |
534 | 566 | ||
535 | - if(m_DvppCacheCounter.load() > 20) { | 567 | + if(m_DvppCacheCounter.load() > m_cache_gop) { |
536 | // 解码器解码不过来 | 568 | // 解码器解码不过来 |
537 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); | 569 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
538 | continue; | 570 | continue; |
539 | } | 571 | } |
572 | + } else { | ||
573 | + m_last_read_ts = get_cur_time_ms(); | ||
540 | } | 574 | } |
541 | 575 | ||
542 | - // LOG_DEBUG("[{}]- read in", m_dec_name); | ||
543 | - | ||
544 | int result = av_read_frame(fmt_ctx, pkt); | 576 | int result = av_read_frame(fmt_ctx, pkt); |
545 | if (result == AVERROR_EOF || result < 0){ | 577 | if (result == AVERROR_EOF || result < 0){ |
546 | av_packet_unref(pkt); | 578 | av_packet_unref(pkt); |
@@ -548,9 +580,7 @@ void DvppDecoder::read_thread() { | @@ -548,9 +580,7 @@ void DvppDecoder::read_thread() { | ||
548 | break; | 580 | break; |
549 | } | 581 | } |
550 | 582 | ||
551 | - // LOG_DEBUG("[{}]- read out", m_dec_name); | ||
552 | - | ||
553 | - if (m_bReal && m_DvppCacheCounter.load() > 20){ | 583 | + if (m_bReal && m_DvppCacheCounter.load() > m_cache_gop){ |
554 | // 解码器解码不过来。实时流在此处的处理会导致花屏,这是由于解码器性能问题导致,无法避免 | 584 | // 解码器解码不过来。实时流在此处的处理会导致花屏,这是由于解码器性能问题导致,无法避免 |
555 | // 实时流在这里处理是为了避免长时间不读取数据导致数据中断 | 585 | // 实时流在这里处理是为了避免长时间不读取数据导致数据中断 |
556 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); | 586 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
@@ -564,8 +594,6 @@ void DvppDecoder::read_thread() { | @@ -564,8 +594,6 @@ void DvppDecoder::read_thread() { | ||
564 | 594 | ||
565 | if (video_index == pkt->stream_index){ | 595 | if (video_index == pkt->stream_index){ |
566 | 596 | ||
567 | - LOG_DEBUG("[{}]- av_bsf_send_packet", m_dec_name); | ||
568 | - | ||
569 | ret = av_bsf_send_packet(h264bsfc, pkt); | 597 | ret = av_bsf_send_packet(h264bsfc, pkt); |
570 | if(ret < 0) { | 598 | if(ret < 0) { |
571 | LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name); | 599 | LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name); |
src/decoder/dvpp/DvppDecoder.h
@@ -65,6 +65,7 @@ public: | @@ -65,6 +65,7 @@ public: | ||
65 | public: | 65 | public: |
66 | void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData); | 66 | void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData); |
67 | void doProcessReport(); | 67 | void doProcessReport(); |
68 | + long long get_last_read_ts(); | ||
68 | 69 | ||
69 | private: | 70 | private: |
70 | AVCodecContext* init_FFmpeg(FFDecConfig config); | 71 | AVCodecContext* init_FFmpeg(FFDecConfig config); |
@@ -133,12 +134,15 @@ private: | @@ -133,12 +134,15 @@ private: | ||
133 | 134 | ||
134 | long long last_ts {0}; | 135 | long long last_ts {0}; |
135 | 136 | ||
137 | + long long m_last_read_ts {0}; | ||
138 | + | ||
136 | uint64_t m_in_count {0}; | 139 | uint64_t m_in_count {0}; |
137 | uint64_t m_out_count {0}; | 140 | uint64_t m_out_count {0}; |
138 | 141 | ||
139 | int m_frameSkip {1}; | 142 | int m_frameSkip {1}; |
140 | 143 | ||
141 | std::atomic<int> m_DvppCacheCounter{0}; | 144 | std::atomic<int> m_DvppCacheCounter{0}; |
145 | + int m_cache_gop{0}; | ||
142 | 146 | ||
143 | VpcUtils m_vpcUtils; | 147 | VpcUtils m_vpcUtils; |
144 | }; | 148 | }; |
145 | \ No newline at end of file | 149 | \ No newline at end of file |