Commit 746db74ca9f8f19a4d907c2c8b7f806a4f42118e
1 parent
09c2d08c
实现recode
Showing
23 changed files
with
781 additions
and
57 deletions
.gitignore
0 → 100644
.vscode/launch.json
0 → 100644
1 | +{ | |
2 | + // 使用 IntelliSense 了解相关属性。 | |
3 | + // 悬停以查看现有属性的描述。 | |
4 | + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 | |
5 | + "version": "0.2.0", | |
6 | + "configurations": [ | |
7 | + { | |
8 | + "name": "dvpp", | |
9 | + "type": "cppdbg", | |
10 | + "request": "launch", | |
11 | + "program": "${workspaceFolder}/bin/vpt_proj", | |
12 | + "args": ["/opt/cmhu/data/Street.uvf","0", "0", "1"], | |
13 | + "stopAtEntry": false, | |
14 | + "cwd": "${workspaceFolder}/bin", | |
15 | + "environment": [], | |
16 | + "externalConsole": false, | |
17 | + "MIMode": "gdb", | |
18 | + "setupCommands": [ | |
19 | + { | |
20 | + "description": "Enable pretty-printing for gdb", | |
21 | + "text": "-enable-pretty-printing", | |
22 | + "ignoreFailures": true | |
23 | + } | |
24 | + ] | |
25 | + },{ | |
26 | + "name": "test", | |
27 | + "type": "cppdbg", | |
28 | + "request": "launch", | |
29 | + "program": "${workspaceFolder}/bin/test", | |
30 | + "args": ["/opt/cmhu/data/Street.uvf","0", "0", "0"], | |
31 | + "stopAtEntry": false, | |
32 | + "cwd": "${workspaceFolder}/bin", | |
33 | + "environment": [], | |
34 | + "externalConsole": false, | |
35 | + "MIMode": "gdb", | |
36 | + "setupCommands": [ | |
37 | + { | |
38 | + "description": "Enable pretty-printing for gdb", | |
39 | + "text": "-enable-pretty-printing", | |
40 | + "ignoreFailures": true | |
41 | + } | |
42 | + ] | |
43 | + },{ | |
44 | + "name": "test_recoder", | |
45 | + "type": "cppdbg", | |
46 | + "request": "launch", | |
47 | + "program": "${workspaceFolder}/bin/test_recoder", | |
48 | + "args": ["/opt/cmhu/data/Street.uvf","0", "0", "0"], | |
49 | + "stopAtEntry": false, | |
50 | + "cwd": "${workspaceFolder}/bin", | |
51 | + "environment": [], | |
52 | + "externalConsole": false, | |
53 | + "MIMode": "gdb", | |
54 | + "setupCommands": [ | |
55 | + { | |
56 | + "description": "Enable pretty-printing for gdb", | |
57 | + "text": "-enable-pretty-printing", | |
58 | + "ignoreFailures": true | |
59 | + } | |
60 | + ] | |
61 | + } | |
62 | + ] | |
63 | +} | |
0 | 64 | \ No newline at end of file | ... | ... |
.vscode/settings.json
0 → 100644
1 | +{ | |
2 | + "files.associations": { | |
3 | + "thread": "cpp", | |
4 | + "chrono": "cpp", | |
5 | + "array": "cpp", | |
6 | + "atomic": "cpp", | |
7 | + "bit": "cpp", | |
8 | + "*.tcc": "cpp", | |
9 | + "bitset": "cpp", | |
10 | + "cctype": "cpp", | |
11 | + "clocale": "cpp", | |
12 | + "cmath": "cpp", | |
13 | + "complex": "cpp", | |
14 | + "condition_variable": "cpp", | |
15 | + "cstdarg": "cpp", | |
16 | + "cstddef": "cpp", | |
17 | + "cstdint": "cpp", | |
18 | + "cstdio": "cpp", | |
19 | + "cstdlib": "cpp", | |
20 | + "cstring": "cpp", | |
21 | + "ctime": "cpp", | |
22 | + "cwchar": "cpp", | |
23 | + "cwctype": "cpp", | |
24 | + "deque": "cpp", | |
25 | + "list": "cpp", | |
26 | + "map": "cpp", | |
27 | + "set": "cpp", | |
28 | + "unordered_map": "cpp", | |
29 | + "vector": "cpp", | |
30 | + "exception": "cpp", | |
31 | + "algorithm": "cpp", | |
32 | + "functional": "cpp", | |
33 | + "iterator": "cpp", | |
34 | + "memory": "cpp", | |
35 | + "memory_resource": "cpp", | |
36 | + "numeric": "cpp", | |
37 | + "optional": "cpp", | |
38 | + "random": "cpp", | |
39 | + "ratio": "cpp", | |
40 | + "regex": "cpp", | |
41 | + "string": "cpp", | |
42 | + "string_view": "cpp", | |
43 | + "system_error": "cpp", | |
44 | + "tuple": "cpp", | |
45 | + "type_traits": "cpp", | |
46 | + "utility": "cpp", | |
47 | + "fstream": "cpp", | |
48 | + "future": "cpp", | |
49 | + "initializer_list": "cpp", | |
50 | + "iomanip": "cpp", | |
51 | + "iosfwd": "cpp", | |
52 | + "iostream": "cpp", | |
53 | + "istream": "cpp", | |
54 | + "limits": "cpp", | |
55 | + "mutex": "cpp", | |
56 | + "new": "cpp", | |
57 | + "ostream": "cpp", | |
58 | + "shared_mutex": "cpp", | |
59 | + "sstream": "cpp", | |
60 | + "stdexcept": "cpp", | |
61 | + "streambuf": "cpp", | |
62 | + "cfenv": "cpp", | |
63 | + "cinttypes": "cpp", | |
64 | + "typeinfo": "cpp", | |
65 | + "variant": "cpp" | |
66 | + } | |
67 | +} | |
0 | 68 | \ No newline at end of file | ... | ... |
src/ai_platform/common_header.h
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | |
4 | 4 | #include <cmath> |
5 | 5 | #include <type_traits> |
6 | +#include <string> | |
6 | 7 | |
7 | 8 | struct point_t { |
8 | 9 | int x, y; |
... | ... | @@ -31,9 +32,10 @@ struct box_t { |
31 | 32 | }; |
32 | 33 | |
33 | 34 | struct RecoderInfo { |
34 | - string task_id; | |
35 | - string object_id; | |
36 | - bool bSave; | |
35 | + std::string recoderDir; | |
36 | + std::string task_id; | |
37 | + std::string object_id; | |
38 | + unsigned long long frame_nb; | |
37 | 39 | }; |
38 | 40 | |
39 | 41 | #endif // ___COMMON_HEADER_H__ |
40 | 42 | \ No newline at end of file | ... | ... |
src/decoder/AbstractDecoder.o deleted
No preview for this file type
src/decoder/Makefile
1 | 1 | XX = g++ |
2 | 2 | |
3 | 3 | |
4 | -PROJECT_ROOT= /opt/cmhu/vpt_ascend | |
4 | +PROJECT_ROOT= /opt/cmhu/vpt_ascend_arm | |
5 | 5 | |
6 | 6 | DEPEND_DIR = $(PROJECT_ROOT)/bin |
7 | 7 | SRC_ROOT = $(PROJECT_ROOT)/src |
8 | 8 | |
9 | -TARGET= $(PROJECT_ROOT)/bin/test_face.so | |
9 | +TARGET= $(PROJECT_ROOT)/bin/test_recoder | |
10 | 10 | |
11 | 11 | THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty |
12 | 12 | SPDLOG_ROOT = $(THIRDPARTY_ROOT)/spdlog-1.9.2/release |
... | ... | @@ -32,8 +32,7 @@ lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \ |
32 | 32 | lib=-lacl_dvpp -lascendcl -lacl_dvpp_mpi -lruntime -lascendalog -lc_sec -lmsprofiler -lgert -lmmpa -lascend_hal -lexe_graph -lge_executor -lgraph -lprofapi -lascend_protobuf -lerror_manager -lhybrid_executor -lregister -ldavinci_executor -lge_common -lge_common_base \ |
33 | 33 | -lplatform -lgraph_base -lqos_manager |
34 | 34 | |
35 | -LIBS= -L $(DEPEND_DIR) -lface_det_arm_with_log1\ | |
36 | - -L $(FFMPEG_ROOT)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \ | |
35 | +LIBS= -L $(FFMPEG_ROOT)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \ | |
37 | 36 | |
38 | 37 | CXXFLAGS= -g -O0 -fPIC $(include_dir) $(lib_dir) $(lib) $(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 |
39 | 38 | ... | ... |
src/decoder/dvpp/DvppDataMemory.hpp
... | ... | @@ -7,8 +7,8 @@ using namespace std; |
7 | 7 | class DvppDataMemory : public DeviceMemory |
8 | 8 | { |
9 | 9 | public: |
10 | - DvppDataMemory(int _channel, int _width, int _width_stride, int _height, int _height_stride, int _size, string _id, string _dev_id, bool _key_frame) | |
11 | - :DeviceMemory(_channel, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, false){ | |
10 | + DvppDataMemory(int _channel, int _width, int _width_stride, int _height, int _height_stride, int _size, string _id, string _dev_id, bool _key_frame, unsigned long long frame_nb) | |
11 | + :DeviceMemory(_channel, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, frame_nb, false){ | |
12 | 12 | data_size = _size; |
13 | 13 | int ret = acldvppMalloc((void **)&pHwRgb, data_size); |
14 | 14 | if(ret != ACL_ERROR_NONE){ |
... | ... | @@ -16,8 +16,8 @@ public: |
16 | 16 | } |
17 | 17 | } |
18 | 18 | |
19 | - DvppDataMemory( int _width, int _width_stride, int _height, int _height_stride, int _size, string _id, string _dev_id, bool _key_frame, unsigned char * pHwData) | |
20 | - :DeviceMemory(3, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, false){ | |
19 | + DvppDataMemory( int _width, int _width_stride, int _height, int _height_stride, int _size, string _id, string _dev_id, bool _key_frame, unsigned long long frame_nb, unsigned char * pHwData) | |
20 | + :DeviceMemory(3, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, frame_nb, false){ | |
21 | 21 | data_size = _size; |
22 | 22 | data_type = 1; |
23 | 23 | pHwRgb = pHwData; | ... | ... |
src/decoder/dvpp/DvppDecoder.cpp
... | ... | @@ -4,12 +4,14 @@ |
4 | 4 | |
5 | 5 | struct Vdec_CallBack_UserData { |
6 | 6 | uint64_t frameId; |
7 | + unsigned long long frame_nb; | |
7 | 8 | long startTime; |
8 | 9 | long sendTime; |
9 | 10 | // void* vdecOutputBuf; |
10 | 11 | DvppDecoder* self; |
11 | 12 | Vdec_CallBack_UserData() { |
12 | 13 | frameId = 0; |
14 | + frame_nb = 0; | |
13 | 15 | } |
14 | 16 | }; |
15 | 17 | |
... | ... | @@ -148,6 +150,8 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ |
148 | 150 | pix_fmt = (AVPixelFormat)codecpar->format; |
149 | 151 | m_fps = av_q2d(stream ->avg_frame_rate); |
150 | 152 | |
153 | + m_recoderManager.init(stream->time_base, avctx); | |
154 | + | |
151 | 155 | LOG_INFO("[{}]- init ffmpeg success! input:{} frame_width:{} frame_height:{} fps:{} ", m_dec_name, input_file, frame_width, frame_height, m_fps); |
152 | 156 | |
153 | 157 | return avctx; |
... | ... | @@ -336,6 +340,7 @@ void DvppDecoder::read_thread() { |
336 | 340 | ,this); |
337 | 341 | |
338 | 342 | AVPacket* pkt = nullptr; |
343 | + unsigned long long frame_nb = 0; | |
339 | 344 | while (m_bRunning){ |
340 | 345 | |
341 | 346 | if (!m_bReal){ |
... | ... | @@ -372,6 +377,9 @@ void DvppDecoder::read_thread() { |
372 | 377 | |
373 | 378 | if (video_index == pkt->stream_index){ |
374 | 379 | |
380 | + frame_nb++; | |
381 | + m_recoderManager.cache_pkt(pkt, frame_nb); | |
382 | + | |
375 | 383 | ret = av_bsf_send_packet(h264bsfc, pkt); |
376 | 384 | if(ret < 0) { |
377 | 385 | LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name); |
... | ... | @@ -392,7 +400,10 @@ void DvppDecoder::read_thread() { |
392 | 400 | } |
393 | 401 | |
394 | 402 | m_pktQueue_mutex.lock(); |
395 | - m_pktQueue.push(pkt); | |
403 | + DataPacket* data_pkt = new DataPacket(); | |
404 | + data_pkt->pkt = pkt; | |
405 | + data_pkt->frame_nb = frame_nb; | |
406 | + m_pktQueue.push(data_pkt); | |
396 | 407 | m_pktQueue_mutex.unlock(); |
397 | 408 | |
398 | 409 | bPushed = true; |
... | ... | @@ -418,9 +429,9 @@ void DvppDecoder::read_thread() { |
418 | 429 | |
419 | 430 | m_pktQueue_mutex.lock(); |
420 | 431 | while(m_pktQueue.size() > 0){ |
421 | - pkt = m_pktQueue.front(); | |
422 | - av_packet_free(&pkt); | |
423 | - pkt = nullptr; | |
432 | + DataPacket* data_pkt = m_pktQueue.front(); | |
433 | + delete data_pkt; | |
434 | + data_pkt = nullptr; | |
424 | 435 | m_pktQueue.pop(); |
425 | 436 | } |
426 | 437 | m_pktQueue_mutex.unlock(); |
... | ... | @@ -481,14 +492,14 @@ static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void |
481 | 492 | DvppDecoder* self = userData->self; |
482 | 493 | if(self != nullptr){ |
483 | 494 | |
484 | - self->doVdppVdecCallBack(input, output); | |
495 | + self->doVdppVdecCallBack(input, output, userData->frame_nb); | |
485 | 496 | } |
486 | 497 | delete userData; |
487 | 498 | userData = nullptr; |
488 | 499 | } |
489 | 500 | } |
490 | 501 | |
491 | -void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output){ | |
502 | +void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, unsigned long long frame_nb){ | |
492 | 503 | |
493 | 504 | m_vdecQueue_mutex.lock(); |
494 | 505 | if(m_vdecQueue.size() > 0){ |
... | ... | @@ -519,7 +530,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o |
519 | 530 | } |
520 | 531 | |
521 | 532 | if(width > 0 && height > 0 && outputSize > 0){ |
522 | - DvppDataMemory* mem = new DvppDataMemory(width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, (unsigned char *)outputDataDev); | |
533 | + DvppDataMemory* mem = new DvppDataMemory(width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, frame_nb, (unsigned char *)outputDataDev); | |
523 | 534 | if(mem){ |
524 | 535 | if(post_decoded_cbk) { |
525 | 536 | post_decoded_cbk(m_postDecArg, mem); |
... | ... | @@ -532,7 +543,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o |
532 | 543 | // 缓存snapshot |
533 | 544 | std::unique_lock<std::mutex> locker(m_cached_mutex); |
534 | 545 | |
535 | - m_cached_mem = new DvppDataMemory(-1, width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false); | |
546 | + m_cached_mem = new DvppDataMemory(-1, width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, 0); | |
536 | 547 | if(m_cached_mem != nullptr){ |
537 | 548 | aclrtMemcpy(m_cached_mem->getMem(), outputSize, (unsigned char *)outputDataDev, outputSize, ACL_MEMCPY_DEVICE_TO_DEVICE); |
538 | 549 | } |
... | ... | @@ -698,12 +709,12 @@ void DvppDecoder::decode_thread(){ |
698 | 709 | LOG_INFO("[{}]- decode thread exit.", m_dec_name); |
699 | 710 | } |
700 | 711 | |
701 | -#include <fstream> | |
702 | -#include <iostream> | |
703 | -#include <cstring> | |
712 | +// #include <fstream> | |
713 | +// #include <iostream> | |
714 | +// #include <cstring> | |
704 | 715 | |
705 | -static int nRecoder = 0; | |
706 | -std::ofstream outfile; | |
716 | +// static int nRecoder = 0; | |
717 | +// std::ofstream outfile; | |
707 | 718 | |
708 | 719 | int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){ |
709 | 720 | |
... | ... | @@ -716,14 +727,14 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c |
716 | 727 | } |
717 | 728 | m_vdecQueue_mutex.unlock(); |
718 | 729 | |
719 | - AVPacket * pkt = nullptr; | |
730 | + DataPacket * data_pkt = nullptr; | |
720 | 731 | m_pktQueue_mutex.lock(); |
721 | 732 | if(m_pktQueue.size() <= 0){ |
722 | 733 | m_pktQueue_mutex.unlock(); |
723 | 734 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
724 | 735 | return 1; |
725 | 736 | } |
726 | - pkt = m_pktQueue.front(); | |
737 | + data_pkt = m_pktQueue.front(); | |
727 | 738 | m_pktQueue.pop(); |
728 | 739 | m_pktQueue_mutex.unlock(); |
729 | 740 | |
... | ... | @@ -732,8 +743,8 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c |
732 | 743 | int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size); |
733 | 744 | if(ACL_ERROR_NONE != ret){ |
734 | 745 | LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret); |
735 | - av_packet_free(&pkt); | |
736 | - pkt = nullptr; | |
746 | + delete data_pkt; | |
747 | + data_pkt = nullptr; | |
737 | 748 | return 2; |
738 | 749 | } |
739 | 750 | |
... | ... | @@ -754,12 +765,12 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c |
754 | 765 | // } |
755 | 766 | |
756 | 767 | |
757 | - | |
768 | + AVPacket* pkt = data_pkt->pkt; | |
758 | 769 | ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE); |
759 | 770 | if(ACL_ERROR_NONE != ret){ |
760 | 771 | LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name); |
761 | - av_packet_free(&pkt); | |
762 | - pkt = nullptr; | |
772 | + delete data_pkt; | |
773 | + data_pkt = nullptr; | |
763 | 774 | return 2; |
764 | 775 | } |
765 | 776 | |
... | ... | @@ -767,8 +778,8 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c |
767 | 778 | ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size); |
768 | 779 | if(ret != ACL_ERROR_NONE){ |
769 | 780 | LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name); |
770 | - av_packet_free(&pkt); | |
771 | - pkt = nullptr; | |
781 | + delete data_pkt; | |
782 | + data_pkt = nullptr; | |
772 | 783 | return 2; |
773 | 784 | } |
774 | 785 | |
... | ... | @@ -793,12 +804,13 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c |
793 | 804 | Vdec_CallBack_UserData *user_data = NULL; |
794 | 805 | user_data = new Vdec_CallBack_UserData; |
795 | 806 | user_data->frameId = frame_count; |
807 | + user_data->frame_nb = data_pkt->frame_nb; | |
796 | 808 | // user_data->startTime = startTime; |
797 | 809 | user_data->sendTime = UtilTools::get_cur_time_ms(); |
798 | 810 | user_data->self = this; |
799 | 811 | ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data)); |
800 | - av_packet_free(&pkt); | |
801 | - pkt = nullptr; | |
812 | + delete data_pkt; | |
813 | + data_pkt = nullptr; | |
802 | 814 | if(ret != ACL_ERROR_NONE){ |
803 | 815 | delete user_data; |
804 | 816 | user_data = nullptr; |
... | ... | @@ -813,9 +825,9 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c |
813 | 825 | return 0; |
814 | 826 | }while (0); |
815 | 827 | |
816 | - if(pkt != nullptr){ | |
817 | - av_packet_free(&pkt); | |
818 | - pkt = nullptr; | |
828 | + if(data_pkt != nullptr){ | |
829 | + delete data_pkt; | |
830 | + data_pkt = nullptr; | |
819 | 831 | } |
820 | 832 | |
821 | 833 | // 报错情形 |
... | ... | @@ -870,4 +882,8 @@ void DvppDecoder::release_dvpp(){ |
870 | 882 | |
871 | 883 | DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance(); |
872 | 884 | pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel); |
885 | +} | |
886 | + | |
887 | +void DvppDecoder::doRecode(RecoderInfo& recoderInfo) { | |
888 | + m_recoderManager.create_recode_task2(recoderInfo); | |
873 | 889 | } |
874 | 890 | \ No newline at end of file | ... | ... |
src/decoder/dvpp/DvppDecoder.h
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | #include <mutex> |
9 | 9 | #include <condition_variable> |
10 | 10 | |
11 | +#include "FFRecoderTaskManager.h" | |
11 | 12 | |
12 | 13 | using namespace std; |
13 | 14 | |
... | ... | @@ -51,8 +52,10 @@ public: |
51 | 52 | |
52 | 53 | int getCachedQueueLength(); |
53 | 54 | |
55 | + void doRecode(RecoderInfo& recoderInfo); | |
56 | + | |
54 | 57 | public: |
55 | - void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output); | |
58 | + void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, unsigned long long frame_nb); | |
56 | 59 | void doProcessReport(); |
57 | 60 | |
58 | 61 | private: |
... | ... | @@ -96,7 +99,7 @@ private: |
96 | 99 | bool m_dec_keyframe; |
97 | 100 | |
98 | 101 | mutex m_pktQueue_mutex; |
99 | - queue<AVPacket*> m_pktQueue; | |
102 | + queue<DataPacket*> m_pktQueue; | |
100 | 103 | |
101 | 104 | // 解码 |
102 | 105 | int m_dvpp_deviceId {-1}; |
... | ... | @@ -118,4 +121,6 @@ private: |
118 | 121 | DvppDataMemory* m_cached_mem{nullptr}; |
119 | 122 | mutex m_cached_mutex; |
120 | 123 | condition_variable m_cached_cond; |
124 | + | |
125 | + FFRecoderTaskManager m_recoderManager; | |
121 | 126 | }; |
122 | 127 | \ No newline at end of file | ... | ... |
src/decoder/dvpp/DvppDecoderApi.cpp
... | ... | @@ -130,4 +130,10 @@ void DvppDecoderApi::setFinishedDecArg(const void* finishedDecArg){ |
130 | 130 | if(m_pDecoder != nullptr){ |
131 | 131 | return m_pDecoder->setFinishedDecArg(finishedDecArg); |
132 | 132 | } |
133 | +} | |
134 | + | |
135 | +void DvppDecoderApi::doRecode(RecoderInfo& recoderInfo) { | |
136 | + if(m_pDecoder != nullptr){ | |
137 | + return m_pDecoder->doRecode(recoderInfo); | |
138 | + } | |
133 | 139 | } |
134 | 140 | \ No newline at end of file | ... | ... |
src/decoder/dvpp/DvppDecoderApi.h
src/decoder/dvpp/FFRecoder.cpp1 renamed to src/decoder/dvpp/FFRecoder.cpp
... | ... | @@ -3,14 +3,6 @@ |
3 | 3 | #include <tuple> |
4 | 4 | #include <array> |
5 | 5 | #include <vector> |
6 | -extern "C" { | |
7 | - #include <libavcodec/avcodec.h> | |
8 | - #include <libavformat/avformat.h> | |
9 | - #include <libavutil/opt.h> | |
10 | - #include <libavutil/timestamp.h> | |
11 | - #include <libavutil/imgutils.h> | |
12 | - #include <libswscale/swscale.h> | |
13 | -} | |
14 | 6 | |
15 | 7 | |
16 | 8 | FFRecoder::FFRecoder() |
... | ... | @@ -156,6 +148,8 @@ bool FFRecoder::init(AVRational time_base, AVCodecContext* avctx, const char* ou |
156 | 148 | fprintf(stderr, "Write header failed!\n"); |
157 | 149 | return false; |
158 | 150 | } |
151 | + | |
152 | + return true; | |
159 | 153 | } |
160 | 154 | |
161 | 155 | void FFRecoder::uninit() |
... | ... | @@ -248,6 +242,8 @@ void FFRecoder::update_pts(AVPacket* pkt) { |
248 | 242 | } |
249 | 243 | |
250 | 244 | bool FFRecoder::write_pkt(AVPacket *pkt) { |
245 | + char errbuf[64]{ 0 }; | |
246 | + | |
251 | 247 | av_packet_rescale_ts(pkt, codec_ctx_->time_base, out_stream_->time_base); |
252 | 248 | pkt->stream_index = out_stream_->index; |
253 | 249 | update_pts(pkt); | ... | ... |
src/decoder/dvpp/FFRecoder.h1 renamed to src/decoder/dvpp/FFRecoder.h
1 | 1 | #pragma once |
2 | 2 | #include <memory> |
3 | 3 | |
4 | -class AVFrame; | |
5 | -class AVStream; | |
6 | -class AVCodecContext; | |
7 | -class AVFormatContext; | |
8 | -struct AVRational; | |
9 | -struct SwsContext; | |
10 | -struct AVPacket; | |
4 | +extern "C" { | |
5 | + #include <libavcodec/avcodec.h> | |
6 | + #include <libavformat/avformat.h> | |
7 | + #include <libavutil/opt.h> | |
8 | + #include <libavutil/timestamp.h> | |
9 | + #include <libavutil/imgutils.h> | |
10 | + #include <libswscale/swscale.h> | |
11 | +} | |
11 | 12 | |
12 | 13 | class FFRecoder |
13 | 14 | { | ... | ... |
src/decoder/dvpp/FFRecoderTaskManager.cpp
0 → 100644
1 | +#include "FFRecoderTaskManager.h" | |
2 | +#include <chrono> | |
3 | + | |
4 | +struct RecodeThreadParam { | |
5 | + FFRecoderTaskManager* _this; | |
6 | + RecodeParam param; | |
7 | +}; | |
8 | + | |
9 | +static long get_cur_time() { | |
10 | + | |
11 | + chrono::time_point<chrono::system_clock, chrono::milliseconds> tpMicro | |
12 | + = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now()); | |
13 | + | |
14 | + return tpMicro.time_since_epoch().count(); | |
15 | +} | |
16 | + | |
17 | +static string get_cur_datetime() | |
18 | +{ | |
19 | + using namespace std; | |
20 | + auto t = chrono::system_clock::to_time_t(chrono::system_clock::now()); | |
21 | + | |
22 | + char buffer[40]; | |
23 | + strftime(buffer, 80, "%Y_%m_%d_%H_%M_%S", std::localtime(&t)); | |
24 | + buffer[20] = '\0'; | |
25 | + return buffer; | |
26 | +} | |
27 | + | |
28 | +static bool is_key_frame(AVPacket *pkt) { | |
29 | + return (pkt->flags & AV_PKT_FLAG_KEY) != 0; | |
30 | +} | |
31 | + | |
32 | +FFRecoderTaskManager::FFRecoderTaskManager(){ | |
33 | + | |
34 | +} | |
35 | + | |
36 | +FFRecoderTaskManager::~FFRecoderTaskManager(){ | |
37 | + | |
38 | +} | |
39 | + | |
40 | +bool FFRecoderTaskManager::init(AVRational time_base, AVCodecContext* avctx){ | |
41 | + m_time_base = time_base; | |
42 | + m_avctx = avctx; | |
43 | + | |
44 | + m_recoder_thread = new std::thread( | |
45 | + [](void* arg) { | |
46 | + FFRecoderTaskManager* _this=(FFRecoderTaskManager*)arg; | |
47 | + if(_this != nullptr) { | |
48 | + _this->recode_thread2(); | |
49 | + }else{ | |
50 | + LOG_ERROR("recode 线程启动失败 !"); | |
51 | + } | |
52 | + return (void*)0; | |
53 | + }, this); | |
54 | + | |
55 | + return true; | |
56 | +} | |
57 | + | |
58 | +void FFRecoderTaskManager::cache_pkt(AVPacket* pkt, long long frame_nb){ | |
59 | + std::lock_guard<std::mutex> l_pkt(m_pkt_list_mtx); | |
60 | + | |
61 | + // 考虑到一个AVPacket中的数据并不很大,为减少与解码模块的耦合度,方便管理,这里做一个clone | |
62 | + AVPacket *new_pkt = av_packet_clone(pkt); | |
63 | + | |
64 | + DataPacket* newDataPkt = new DataPacket(); | |
65 | + newDataPkt->pkt = new_pkt; | |
66 | + newDataPkt->frame_nb = frame_nb; | |
67 | + m_pkt_list.emplace_back(newDataPkt); | |
68 | + | |
69 | + if(is_key_frame(pkt)){ | |
70 | + // 越来越大的值 | |
71 | + newDataPkt->isKeyFrame = true; | |
72 | + LOG_INFO("key frame_nb: {}", frame_nb); | |
73 | + } else { | |
74 | + newDataPkt->isKeyFrame = false; | |
75 | + } | |
76 | + | |
77 | + std::lock_guard<std::mutex> l_info(m_recoderinfo_list_mtx); | |
78 | + if(m_recoderinfo_list.size() <= 0){ | |
79 | + // 没有任务的时候,维持500的长度 | |
80 | + while(m_pkt_list.size() > 1000) { | |
81 | + DataPacket* dataPkt = m_pkt_list.front(); | |
82 | + delete dataPkt; | |
83 | + dataPkt = nullptr; | |
84 | + m_pkt_list.pop_front(); | |
85 | + } | |
86 | + } | |
87 | +} | |
88 | + | |
89 | +void FFRecoderTaskManager::save_intask_frame_nb(unsigned long long frame_nb) { | |
90 | + if(m_intask_frame_nb_list.size() <= 0) { | |
91 | + m_intask_frame_nb_list.push_back(frame_nb); | |
92 | + return; | |
93 | + } | |
94 | + | |
95 | + for(auto it = m_intask_frame_nb_list.begin(); it != m_intask_frame_nb_list.end(); it++) { | |
96 | + if(*it > frame_nb) { | |
97 | + m_intask_frame_nb_list.insert(it, frame_nb); | |
98 | + return; | |
99 | + } | |
100 | + } | |
101 | + | |
102 | + // 新 frame_nb 比所有的都大 | |
103 | + m_intask_frame_nb_list.push_back(frame_nb); | |
104 | +} | |
105 | + | |
106 | +void FFRecoderTaskManager::save_intask_recoderinfo(RecoderInfo info) { | |
107 | + std::lock_guard<std::mutex> l(m_recoderinfo_list_mtx); | |
108 | + if(m_recoderinfo_list.size() <= 0) { | |
109 | + m_recoderinfo_list.push_back(info); | |
110 | + return; | |
111 | + } | |
112 | + | |
113 | + for(auto it = m_recoderinfo_list.begin(); it != m_recoderinfo_list.end(); it++) { | |
114 | + if(it->frame_nb > info.frame_nb) { | |
115 | + m_recoderinfo_list.insert(it, info); | |
116 | + return; | |
117 | + } | |
118 | + } | |
119 | + | |
120 | + // 新 frame_nb 比所有的都大 | |
121 | + m_recoderinfo_list.push_back(info); | |
122 | +} | |
123 | + | |
124 | +list<DataPacket*>::iterator FFRecoderTaskManager::getStartIterator(unsigned long long frame_nb){ | |
125 | + std::lock_guard<std::mutex> l(m_pkt_list_mtx); | |
126 | + | |
127 | + auto it_first = m_pkt_list.begin(); | |
128 | + | |
129 | + long long start_frame_nb = (long long)(frame_nb - 375); | |
130 | + if(start_frame_nb <= 0) { | |
131 | + return it_first; | |
132 | + } | |
133 | + | |
134 | + auto it_second = m_pkt_list.begin(); | |
135 | + for(;it_second != m_pkt_list.end(); it_second++) { | |
136 | + DataPacket* dataPkt = *it_second; | |
137 | + if(dataPkt->isKeyFrame) { | |
138 | + it_first = it_second; | |
139 | + } | |
140 | + if(start_frame_nb >= (*it_first)->frame_nb && start_frame_nb <= (*it_second)->frame_nb) { | |
141 | + return it_first; | |
142 | + } | |
143 | + } | |
144 | + | |
145 | + return m_pkt_list.begin(); | |
146 | +} | |
147 | + | |
148 | +// 多线程版 | |
149 | +void FFRecoderTaskManager::create_recode_task(AVRational time_base, AVCodecContext* avctx, RecoderInfo& recoderInfo){ | |
150 | + | |
151 | + std::lock_guard<std::mutex> l(m_task_creat_mtx); | |
152 | + | |
153 | + RecodeParam recodeParam; | |
154 | + recodeParam.time_base = time_base; | |
155 | + recodeParam.avctx = avctx; | |
156 | + recodeParam.recoderInfo = recoderInfo; | |
157 | + | |
158 | + RecodeThreadParam* threadParam = new RecodeThreadParam(); | |
159 | + threadParam->_this = this; | |
160 | + threadParam->param = recodeParam; | |
161 | + std::thread* recode_thread = new std::thread( | |
162 | + [](void* arg) { | |
163 | + RecodeThreadParam* threadParam = (RecodeThreadParam*)arg; | |
164 | + if(threadParam != nullptr){ | |
165 | + FFRecoderTaskManager* _this=(FFRecoderTaskManager*)threadParam->_this; | |
166 | + if(_this != nullptr) { | |
167 | + _this->recode_thread(threadParam->param); | |
168 | + }else{ | |
169 | + LOG_ERROR("recode 线程启动失败 !"); | |
170 | + } | |
171 | + } | |
172 | + return (void*)0; | |
173 | + }, threadParam); | |
174 | + | |
175 | + std::string id = recoderInfo.task_id + "_" + recoderInfo.object_id + "_" + std::to_string(recoderInfo.frame_nb); | |
176 | + m_id_recoderTask[id] = recode_thread; | |
177 | + | |
178 | + save_intask_frame_nb(recoderInfo.frame_nb); | |
179 | +} | |
180 | + | |
181 | +void FFRecoderTaskManager::create_recode_task2(RecoderInfo& recoderInfo) { | |
182 | + save_intask_recoderinfo(recoderInfo); | |
183 | +} | |
184 | + | |
185 | +// 多线程版 | |
186 | +void FFRecoderTaskManager::recode_thread(RecodeParam recodeParam){ | |
187 | + { | |
188 | + // 此处确保create_recode_task执行完成,m_id_recoderTask 已经保存当前线程信息 | |
189 | + std::lock_guard<std::mutex> l(m_task_creat_mtx); | |
190 | + } | |
191 | + | |
192 | + RecoderInfo recoderInfo; | |
193 | + recoderInfo = recodeParam.recoderInfo; | |
194 | + std::string id = recoderInfo.task_id + "_" + recoderInfo.object_id + "_" + std::to_string(recoderInfo.frame_nb); | |
195 | + string file_name = recoderInfo.recoderDir + "/recoder_" + id + "_" + std::to_string(get_cur_time()) + ".mp4"; | |
196 | + FFRecoder ffrecoder; | |
197 | + bool bInit = ffrecoder.init(recodeParam.time_base, recodeParam.avctx, file_name.c_str()); | |
198 | + if (!bInit) { | |
199 | + LOG_ERROR("ffrecoder init error : {} {} {}", recoderInfo.task_id, recoderInfo.object_id, recoderInfo.frame_nb); | |
200 | + m_id_recoderTask.erase(id); | |
201 | + return; | |
202 | + } | |
203 | + LOG_INFO("record start, pkt_list size: {} id: {}", m_pkt_list.size(), id); | |
204 | + | |
205 | + int count = 0; | |
206 | + for (auto it = m_pkt_list.begin(); it != m_pkt_list.end() && count < 500; ++it) { | |
207 | + DataPacket* dataPkt = *it; | |
208 | + AVPacket* pkt = dataPkt->pkt; | |
209 | + ffrecoder.write_pkt(pkt); | |
210 | + count++; | |
211 | + } | |
212 | + | |
213 | + ffrecoder.flush(); | |
214 | + ffrecoder.uninit(); | |
215 | + | |
216 | + m_id_recoderTask.erase(id); | |
217 | + | |
218 | + LOG_INFO("record end : {}", file_name); | |
219 | +} | |
220 | + | |
221 | +void FFRecoderTaskManager::recode_thread2() { | |
222 | + | |
223 | + while(true) { | |
224 | + m_recoderinfo_list_mtx.lock(); | |
225 | + if(m_recoderinfo_list.size() <= 0){ | |
226 | + m_recoderinfo_list_mtx.unlock(); | |
227 | + std::this_thread::sleep_for(std::chrono::milliseconds(3)); | |
228 | + continue; | |
229 | + } | |
230 | + | |
231 | + auto it_param = m_recoderinfo_list.begin(); | |
232 | + RecoderInfo recoderinfo = *it_param; | |
233 | + m_recoderinfo_list.pop_front(); | |
234 | + m_recoderinfo_list_mtx.unlock(); | |
235 | + | |
236 | + auto it_data = getStartIterator(recoderinfo.frame_nb); | |
237 | + if(it_data == m_pkt_list.end()) { | |
238 | + std::this_thread::sleep_for(std::chrono::milliseconds(3)); | |
239 | + continue; | |
240 | + } | |
241 | + | |
242 | + LOG_INFO("start frame_nb: {}", (*it_data)->frame_nb); | |
243 | + | |
244 | + m_pkt_list_mtx.lock(); | |
245 | + auto it = m_pkt_list.begin(); | |
246 | + while (it != it_data) { | |
247 | + DataPacket* dataPkt = m_pkt_list.front(); | |
248 | + delete dataPkt; | |
249 | + dataPkt = nullptr; | |
250 | + m_pkt_list.pop_front(); | |
251 | + it = m_pkt_list.begin(); | |
252 | + } | |
253 | + m_pkt_list_mtx.unlock(); | |
254 | + | |
255 | + std::string id = recoderinfo.task_id + "_" + recoderinfo.object_id + "_" + std::to_string(recoderinfo.frame_nb); | |
256 | + string file_name = recoderinfo.recoderDir + "/recoder_" + id + "_" + std::to_string(get_cur_time()) + ".mp4"; | |
257 | + FFRecoder ffrecoder; | |
258 | + bool bInit = ffrecoder.init(m_time_base, m_avctx, file_name.c_str()); | |
259 | + if (!bInit) { | |
260 | + LOG_ERROR("ffrecoder init error : {} {} {}", recoderinfo.task_id, recoderinfo.object_id, recoderinfo.frame_nb); | |
261 | + continue; | |
262 | + } | |
263 | + LOG_INFO("record start, pkt_list size: {} id: {}", m_pkt_list.size(), id); | |
264 | + | |
265 | + int count = 0; | |
266 | + auto it_save = it_data; | |
267 | + unsigned long long start_frame_nb = (*it_data)->frame_nb; | |
268 | + unsigned long long end_frame_nb = (*it_data)->frame_nb; | |
269 | + for (; it_save != m_pkt_list.end() && count < 500; ++it_save) { | |
270 | + DataPacket* dataPkt = *it_save; | |
271 | + AVPacket* pkt = dataPkt->pkt; | |
272 | + ffrecoder.write_pkt(pkt); | |
273 | + count++; | |
274 | + end_frame_nb = (*it_save)->frame_nb; | |
275 | + } | |
276 | + | |
277 | + // ffrecoder.flush(); | |
278 | + ffrecoder.uninit(); | |
279 | + | |
280 | + LOG_INFO("record end, total save: {} start_frame_nb: {} end_frame_nb: {} file_path: {}", count, start_frame_nb, end_frame_nb, file_name); | |
281 | + } | |
282 | + | |
283 | +} | |
0 | 284 | \ No newline at end of file | ... | ... |
src/decoder/dvpp/FFRecoderTaskManager.h
0 → 100644
1 | +#include "FFRecoder.h" | |
2 | + | |
3 | +#include "../../ai_platform/common_header.h" | |
4 | +#include "depend_headers.h" | |
5 | + | |
6 | +#include <list> | |
7 | +#include <queue> | |
8 | +#include <map> | |
9 | +#include <string> | |
10 | +#include <thread> | |
11 | +#include <mutex> | |
12 | + | |
13 | +using namespace std; | |
14 | + | |
15 | +struct RecodeParam { | |
16 | + AVRational time_base; | |
17 | + RecoderInfo recoderInfo; | |
18 | + AVCodecContext* avctx; | |
19 | +}; | |
20 | + | |
21 | +class FFRecoderTaskManager { | |
22 | +public: | |
23 | + FFRecoderTaskManager(); | |
24 | + virtual ~FFRecoderTaskManager(); | |
25 | + | |
26 | + void cache_pkt(AVPacket* pkt, long long frame_nb); | |
27 | + void create_recode_task(AVRational time_base, AVCodecContext* avctx, RecoderInfo& recoderInfo); | |
28 | + | |
29 | + bool init(AVRational time_base, AVCodecContext* avctx); | |
30 | + void create_recode_task2(RecoderInfo& recoderInfo); | |
31 | + | |
32 | +public: | |
33 | + void recode_thread(RecodeParam param); | |
34 | + list<DataPacket*>::iterator getStartIterator(unsigned long long frame_nb); | |
35 | + | |
36 | + void recode_thread2(); | |
37 | + | |
38 | +private: | |
39 | + void save_intask_frame_nb(unsigned long long frame_nb); | |
40 | + void save_intask_recoderinfo(RecoderInfo info); | |
41 | + | |
42 | +private: | |
43 | + std::queue<int> m_key_frame_interval; | |
44 | + std::list<unsigned long long> m_keyframe_nb_list; | |
45 | + std::list<DataPacket*> m_pkt_list; | |
46 | + mutex m_pkt_list_mtx; | |
47 | + unsigned long long m_last_key_frame_nb; | |
48 | + | |
49 | + std::list<unsigned long long> m_intask_frame_nb_list; | |
50 | + | |
51 | + std::list<RecoderInfo> m_recoderinfo_list; | |
52 | + mutex m_recoderinfo_list_mtx; | |
53 | + | |
54 | + bool m_bExit{false}; | |
55 | + | |
56 | + map<string, thread*> m_id_recoderTask; | |
57 | + mutex m_task_creat_mtx; | |
58 | + | |
59 | + AVRational m_time_base; | |
60 | + AVCodecContext* m_avctx; | |
61 | + | |
62 | + thread* m_recoder_thread {nullptr}; | |
63 | +}; | |
0 | 64 | \ No newline at end of file | ... | ... |
src/decoder/dvpp/VpcPicConverter.cpp
... | ... | @@ -41,7 +41,7 @@ DvppDataMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out |
41 | 41 | int out_buf_height = ALIGN_UP(out_height, 2); |
42 | 42 | int out_buf_size = out_buf_width * out_buf_height; |
43 | 43 | |
44 | - DvppDataMemory* rgbMem = new DvppDataMemory(3, out_buf_width, out_buf_width, out_buf_height, out_buf_height, out_buf_size, "", to_string(m_devId), key_frame); | |
44 | + DvppDataMemory* rgbMem = new DvppDataMemory(3, out_buf_width, out_buf_width, out_buf_height, out_buf_height, out_buf_size, "", to_string(m_devId), key_frame, 0); | |
45 | 45 | void *outBufferDev_ = (void*)rgbMem->getMem(); |
46 | 46 | |
47 | 47 | acldvppPicDesc *outputDesc_= acldvppCreatePicDesc(); | ... | ... |
src/decoder/dvpp/depend_headers.h
... | ... | @@ -35,4 +35,18 @@ extern "C" { |
35 | 35 | #include "../interface/interface_headers.h" |
36 | 36 | #include "../interface/utiltools.hpp" |
37 | 37 | |
38 | + | |
39 | +struct DataPacket { | |
40 | + AVPacket* pkt {nullptr}; | |
41 | + unsigned long long frame_nb{0}; | |
42 | + bool isKeyFrame{false}; | |
43 | + | |
44 | + ~DataPacket(){ | |
45 | + if(pkt != nullptr) { | |
46 | + av_packet_free(&pkt); | |
47 | + pkt = nullptr; | |
48 | + } | |
49 | + } | |
50 | +}; | |
51 | + | |
38 | 52 | #endif |
39 | 53 | \ No newline at end of file | ... | ... |
src/decoder/interface/AbstractDecoder.h
... | ... | @@ -3,6 +3,8 @@ |
3 | 3 | |
4 | 4 | #include "interface_headers.h" |
5 | 5 | |
6 | +#include "../../ai_platform/common_header.h" | |
7 | + | |
6 | 8 | using namespace std; |
7 | 9 | |
8 | 10 | class AbstractDecoder{ |
... | ... | @@ -38,6 +40,8 @@ public: |
38 | 40 | virtual void setPostDecArg(const void* postDecArg) = 0; |
39 | 41 | virtual void setFinishedDecArg(const void* finishedDecArg) = 0; |
40 | 42 | |
43 | + virtual void doRecode(RecoderInfo& recoderInfo) = 0; | |
44 | + | |
41 | 45 | public: |
42 | 46 | bool isSnapTime(); |
43 | 47 | ... | ... |
src/decoder/interface/DecoderManager.cpp
... | ... | @@ -517,3 +517,23 @@ DeviceMemory* DecoderManager::snapshot_out_task(string& uri, int devId) { |
517 | 517 | |
518 | 518 | return devMem; |
519 | 519 | } |
520 | + | |
521 | + | |
522 | +void DecoderManager::doRecode(RecoderInfo& recoderInfo) { | |
523 | + string name = recoderInfo.task_id; | |
524 | + if (name.empty()){ | |
525 | + LOG_ERROR("name 为空!"); | |
526 | + return; | |
527 | + } | |
528 | + | |
529 | + std::lock_guard<std::mutex> l(m_mutex); | |
530 | + | |
531 | + auto dec = decoderMap.find(name); | |
532 | + if (dec != decoderMap.end()){ | |
533 | + dec->second->doRecode(recoderInfo); | |
534 | + return; | |
535 | + } | |
536 | + | |
537 | + LOG_ERROR("没有找到name为{}的解码器",name); | |
538 | + return; | |
539 | +} | |
520 | 540 | \ No newline at end of file | ... | ... |
src/decoder/interface/DecoderManager.h
src/decoder/interface/DeviceMemory.hpp
... | ... | @@ -10,7 +10,7 @@ using namespace std; |
10 | 10 | class DeviceMemory{ |
11 | 11 | |
12 | 12 | public: |
13 | - DeviceMemory(int _channel, int _width, int _width_stride, int _height, int _height_stride, string _id, string _dev_id, bool _key_frame, bool _isused){ | |
13 | + DeviceMemory(int _channel, int _width, int _width_stride, int _height, int _height_stride, string _id, string _dev_id, bool _key_frame, unsigned long long _frame_nb, bool _isused){ | |
14 | 14 | channel = _channel; |
15 | 15 | width = _width; |
16 | 16 | width_stride = _width_stride; |
... | ... | @@ -21,6 +21,7 @@ public: |
21 | 21 | id = _id; |
22 | 22 | device_id = _dev_id; |
23 | 23 | key_frame = _key_frame; |
24 | + frame_nb = _frame_nb; | |
24 | 25 | timestamp = UtilTools::get_cur_time_ms(); |
25 | 26 | } |
26 | 27 | |
... | ... | @@ -80,6 +81,10 @@ public: |
80 | 81 | return key_frame; |
81 | 82 | } |
82 | 83 | |
84 | + unsigned long long getFrameNb() { | |
85 | + return frame_nb; | |
86 | + } | |
87 | + | |
83 | 88 | public: |
84 | 89 | int data_size; |
85 | 90 | bool isused; |
... | ... | @@ -94,6 +99,7 @@ public: |
94 | 99 | int channel{3}; |
95 | 100 | bool key_frame; |
96 | 101 | long index; |
102 | + unsigned long long frame_nb; | |
97 | 103 | }; |
98 | 104 | |
99 | 105 | #endif |
100 | 106 | \ No newline at end of file | ... | ... |
src/decoder/test.cpp renamed to src/decoder/test.cpp1
src/decoder/test_recoder.cpp
0 → 100644
1 | +#include "./interface/DecoderManager.h" | |
2 | +#include <mutex> | |
3 | +#include <thread> | |
4 | +#include <chrono> | |
5 | + | |
6 | +using namespace std; | |
7 | + | |
8 | +struct decode_cbk_userdata{ | |
9 | + string task_id; | |
10 | + void* opaque; | |
11 | + void* opaque1; | |
12 | +}; | |
13 | + | |
14 | +deque<DeviceMemory*> m_RgbDataList; | |
15 | +mutex m_DataListMtx; | |
16 | + | |
17 | +thread* m_pAlgorthimThread{nullptr}; | |
18 | +bool m_bfinish{false}; | |
19 | +int m_devId = 0; | |
20 | +const char* task_id = "test0"; | |
21 | +int skip_frame_ = 5; | |
22 | +int m_batch_size = 20; | |
23 | + | |
24 | +void algorthim_process_thread(); | |
25 | +void algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem); | |
26 | + | |
27 | +void post_decod_cbk(const void * userPtr, DeviceMemory* devFrame){ | |
28 | + do{ | |
29 | + if(m_bfinish){ | |
30 | + break; | |
31 | + } | |
32 | + m_DataListMtx.lock(); | |
33 | + if(m_RgbDataList.size() >= 30){ | |
34 | + m_DataListMtx.unlock(); | |
35 | + std::this_thread::sleep_for(std::chrono::milliseconds(3)); | |
36 | + continue; | |
37 | + } | |
38 | + m_RgbDataList.push_back(devFrame); | |
39 | + m_DataListMtx.unlock(); | |
40 | + break; | |
41 | + }while (true); | |
42 | +} | |
43 | + | |
44 | +void decode_finished_cbk(const void * userPtr){ | |
45 | + decode_cbk_userdata* ptr = (decode_cbk_userdata*)userPtr; | |
46 | + if (ptr!= nullptr){ | |
47 | + printf("task finished: %s \n", ptr->task_id.c_str()); | |
48 | + } | |
49 | + delete ptr; | |
50 | + ptr = nullptr; | |
51 | +} | |
52 | + | |
53 | +int main(){ | |
54 | + | |
55 | + // 创建解码任务 | |
56 | + DecoderManager* pDecManager = DecoderManager::getInstance(); | |
57 | + | |
58 | + MgrDecConfig config; | |
59 | + config.name = task_id; | |
60 | + config.cfg.uri = "rtsp://admin:ad123456@192.168.60.165:554/cam/realmonitor?channel=1&subtype=0"; | |
61 | + config.cfg.post_decoded_cbk = post_decod_cbk; | |
62 | + config.cfg.decode_finished_cbk = decode_finished_cbk; | |
63 | + config.cfg.force_tcp = true; // rtsp用tcp | |
64 | + config.cfg.gpuid = to_string(m_devId); | |
65 | + config.cfg.skip_frame = skip_frame_; | |
66 | + | |
67 | + config.dec_type = DECODER_TYPE_DVPP; | |
68 | + | |
69 | + AbstractDecoder* dec = pDecManager->createDecoder(config); | |
70 | + if (!dec){ | |
71 | + printf("创建解码器失败 \n"); | |
72 | + return false; | |
73 | + } | |
74 | + | |
75 | + decode_cbk_userdata* userPtr = new decode_cbk_userdata; | |
76 | + userPtr->task_id = string(task_id); | |
77 | + pDecManager->setPostDecArg(config.name, userPtr); | |
78 | + pDecManager->setFinishedDecArg(config.name, userPtr); | |
79 | + | |
80 | + | |
81 | + int input_image_width = 0; | |
82 | + int input_image_height = 0; | |
83 | + pDecManager->getResolution(config.name, input_image_width, input_image_height); | |
84 | + | |
85 | + | |
86 | + // 创建算法线程 | |
87 | + m_pAlgorthimThread = new thread([](void* arg) { | |
88 | + algorthim_process_thread(); | |
89 | + return (void*)0; | |
90 | + } | |
91 | + , nullptr); | |
92 | + | |
93 | + pDecManager->startDecodeByName(config.name); | |
94 | + | |
95 | + while (getchar() != 'q'); | |
96 | +} | |
97 | + | |
98 | +void algorthim_process_thread(){ | |
99 | + | |
100 | + while (true){ | |
101 | + if(m_bfinish){ | |
102 | + break; | |
103 | + } | |
104 | + | |
105 | + vector<DeviceMemory*> vec_gpuMem; | |
106 | + m_DataListMtx.lock(); | |
107 | + while (!m_RgbDataList.empty()){ | |
108 | + DeviceMemory* gpuMem = m_RgbDataList.front(); | |
109 | + if(gpuMem->getMem() == nullptr){ | |
110 | + // 错误数据,直接删除 | |
111 | + delete gpuMem; | |
112 | + gpuMem = nullptr; | |
113 | + printf("mem is null \n"); | |
114 | + } else { | |
115 | + vec_gpuMem.push_back(gpuMem); | |
116 | + } | |
117 | + m_RgbDataList.pop_front(); | |
118 | + if(vec_gpuMem.size() >= m_batch_size){ | |
119 | + break; | |
120 | + } | |
121 | + } | |
122 | + m_DataListMtx.unlock(); | |
123 | + | |
124 | + if(vec_gpuMem.size() <= 0){ | |
125 | + std::this_thread::sleep_for(std::chrono::milliseconds(3)); | |
126 | + continue; | |
127 | + } | |
128 | + | |
129 | + algorthim_face_detect(vec_gpuMem); | |
130 | + | |
131 | + for(int i=0;i < vec_gpuMem.size(); i++){ | |
132 | + DeviceMemory* mem = vec_gpuMem[i]; | |
133 | + if(mem->getSize() <= 0){ | |
134 | + continue; | |
135 | + } | |
136 | + delete mem; | |
137 | + mem = nullptr; | |
138 | + } | |
139 | + vec_gpuMem.clear(); | |
140 | + | |
141 | + } | |
142 | + | |
143 | + printf("algorthim_process_thread exit. \n"); | |
144 | +} | |
145 | + | |
146 | +static int interval = 0; | |
147 | +static int obj_id = 0; | |
148 | + | |
149 | +void algorthim_face_detect(vector<DeviceMemory*> vec_gpuMem) { | |
150 | + interval ++ ; | |
151 | + | |
152 | + if(interval % 50 != 0) { | |
153 | + return; | |
154 | + } | |
155 | + | |
156 | + for(int i= 0; i < vec_gpuMem.size(); i++) { | |
157 | + DeviceMemory* mem = vec_gpuMem[i]; | |
158 | + string task_id = mem->getId(); | |
159 | + | |
160 | + RecoderInfo recoderInfo; | |
161 | + recoderInfo.task_id = task_id; | |
162 | + recoderInfo.object_id = std::to_string(obj_id); | |
163 | + recoderInfo.recoderDir = "./res/recode"; | |
164 | + recoderInfo.frame_nb = mem->getFrameNb(); | |
165 | + DecoderManager* pDecManager = DecoderManager::getInstance(); | |
166 | + pDecManager->doRecode(recoderInfo); | |
167 | + | |
168 | + obj_id++; | |
169 | + | |
170 | + } | |
171 | +} | |
0 | 172 | \ No newline at end of file | ... | ... |