Commit 7e4bc7fdd60f47c614d2b3566007a3e8648f3c20
Merge branch 'dev-cmhu' into 'master'
实现recode 实现recode See merge request !1
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 | \ No newline at end of file | 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 | \ No newline at end of file | 68 | \ No newline at end of file |
src/ai_platform/common_header.h
@@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
3 | 3 | ||
4 | #include <cmath> | 4 | #include <cmath> |
5 | #include <type_traits> | 5 | #include <type_traits> |
6 | +#include <string> | ||
6 | 7 | ||
7 | struct point_t { | 8 | struct point_t { |
8 | int x, y; | 9 | int x, y; |
@@ -31,9 +32,10 @@ struct box_t { | @@ -31,9 +32,10 @@ struct box_t { | ||
31 | }; | 32 | }; |
32 | 33 | ||
33 | struct RecoderInfo { | 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 | #endif // ___COMMON_HEADER_H__ | 41 | #endif // ___COMMON_HEADER_H__ |
40 | \ No newline at end of file | 42 | \ No newline at end of file |
src/decoder/AbstractDecoder.o deleted
No preview for this file type
src/decoder/Makefile
1 | XX = g++ | 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 | DEPEND_DIR = $(PROJECT_ROOT)/bin | 6 | DEPEND_DIR = $(PROJECT_ROOT)/bin |
7 | SRC_ROOT = $(PROJECT_ROOT)/src | 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 | THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty | 11 | THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty |
12 | SPDLOG_ROOT = $(THIRDPARTY_ROOT)/spdlog-1.9.2/release | 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,8 +32,7 @@ lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \ | ||
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 \ | 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 | -lplatform -lgraph_base -lqos_manager | 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 | 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 | 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,8 +7,8 @@ using namespace std; | ||
7 | class DvppDataMemory : public DeviceMemory | 7 | class DvppDataMemory : public DeviceMemory |
8 | { | 8 | { |
9 | public: | 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 | data_size = _size; | 12 | data_size = _size; |
13 | int ret = acldvppMalloc((void **)&pHwRgb, data_size); | 13 | int ret = acldvppMalloc((void **)&pHwRgb, data_size); |
14 | if(ret != ACL_ERROR_NONE){ | 14 | if(ret != ACL_ERROR_NONE){ |
@@ -16,8 +16,8 @@ public: | @@ -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 | data_size = _size; | 21 | data_size = _size; |
22 | data_type = 1; | 22 | data_type = 1; |
23 | pHwRgb = pHwData; | 23 | pHwRgb = pHwData; |
src/decoder/dvpp/DvppDecoder.cpp
@@ -4,12 +4,14 @@ | @@ -4,12 +4,14 @@ | ||
4 | 4 | ||
5 | struct Vdec_CallBack_UserData { | 5 | struct Vdec_CallBack_UserData { |
6 | uint64_t frameId; | 6 | uint64_t frameId; |
7 | + unsigned long long frame_nb; | ||
7 | long startTime; | 8 | long startTime; |
8 | long sendTime; | 9 | long sendTime; |
9 | // void* vdecOutputBuf; | 10 | // void* vdecOutputBuf; |
10 | DvppDecoder* self; | 11 | DvppDecoder* self; |
11 | Vdec_CallBack_UserData() { | 12 | Vdec_CallBack_UserData() { |
12 | frameId = 0; | 13 | frameId = 0; |
14 | + frame_nb = 0; | ||
13 | } | 15 | } |
14 | }; | 16 | }; |
15 | 17 | ||
@@ -148,6 +150,8 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ | @@ -148,6 +150,8 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ | ||
148 | pix_fmt = (AVPixelFormat)codecpar->format; | 150 | pix_fmt = (AVPixelFormat)codecpar->format; |
149 | m_fps = av_q2d(stream ->avg_frame_rate); | 151 | m_fps = av_q2d(stream ->avg_frame_rate); |
150 | 152 | ||
153 | + m_recoderManager.init(stream->time_base, avctx); | ||
154 | + | ||
151 | LOG_INFO("[{}]- init ffmpeg success! input:{} frame_width:{} frame_height:{} fps:{} ", m_dec_name, input_file, frame_width, frame_height, m_fps); | 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 | return avctx; | 157 | return avctx; |
@@ -336,6 +340,7 @@ void DvppDecoder::read_thread() { | @@ -336,6 +340,7 @@ void DvppDecoder::read_thread() { | ||
336 | ,this); | 340 | ,this); |
337 | 341 | ||
338 | AVPacket* pkt = nullptr; | 342 | AVPacket* pkt = nullptr; |
343 | + unsigned long long frame_nb = 0; | ||
339 | while (m_bRunning){ | 344 | while (m_bRunning){ |
340 | 345 | ||
341 | if (!m_bReal){ | 346 | if (!m_bReal){ |
@@ -372,6 +377,9 @@ void DvppDecoder::read_thread() { | @@ -372,6 +377,9 @@ void DvppDecoder::read_thread() { | ||
372 | 377 | ||
373 | if (video_index == pkt->stream_index){ | 378 | if (video_index == pkt->stream_index){ |
374 | 379 | ||
380 | + frame_nb++; | ||
381 | + m_recoderManager.cache_pkt(pkt, frame_nb); | ||
382 | + | ||
375 | ret = av_bsf_send_packet(h264bsfc, pkt); | 383 | ret = av_bsf_send_packet(h264bsfc, pkt); |
376 | if(ret < 0) { | 384 | if(ret < 0) { |
377 | LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name); | 385 | LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name); |
@@ -392,7 +400,10 @@ void DvppDecoder::read_thread() { | @@ -392,7 +400,10 @@ void DvppDecoder::read_thread() { | ||
392 | } | 400 | } |
393 | 401 | ||
394 | m_pktQueue_mutex.lock(); | 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 | m_pktQueue_mutex.unlock(); | 407 | m_pktQueue_mutex.unlock(); |
397 | 408 | ||
398 | bPushed = true; | 409 | bPushed = true; |
@@ -418,9 +429,9 @@ void DvppDecoder::read_thread() { | @@ -418,9 +429,9 @@ void DvppDecoder::read_thread() { | ||
418 | 429 | ||
419 | m_pktQueue_mutex.lock(); | 430 | m_pktQueue_mutex.lock(); |
420 | while(m_pktQueue.size() > 0){ | 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 | m_pktQueue.pop(); | 435 | m_pktQueue.pop(); |
425 | } | 436 | } |
426 | m_pktQueue_mutex.unlock(); | 437 | m_pktQueue_mutex.unlock(); |
@@ -481,14 +492,14 @@ static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void | @@ -481,14 +492,14 @@ static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void | ||
481 | DvppDecoder* self = userData->self; | 492 | DvppDecoder* self = userData->self; |
482 | if(self != nullptr){ | 493 | if(self != nullptr){ |
483 | 494 | ||
484 | - self->doVdppVdecCallBack(input, output); | 495 | + self->doVdppVdecCallBack(input, output, userData->frame_nb); |
485 | } | 496 | } |
486 | delete userData; | 497 | delete userData; |
487 | userData = nullptr; | 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 | m_vdecQueue_mutex.lock(); | 504 | m_vdecQueue_mutex.lock(); |
494 | if(m_vdecQueue.size() > 0){ | 505 | if(m_vdecQueue.size() > 0){ |
@@ -519,7 +530,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o | @@ -519,7 +530,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o | ||
519 | } | 530 | } |
520 | 531 | ||
521 | if(width > 0 && height > 0 && outputSize > 0){ | 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 | if(mem){ | 534 | if(mem){ |
524 | if(post_decoded_cbk) { | 535 | if(post_decoded_cbk) { |
525 | post_decoded_cbk(m_postDecArg, mem); | 536 | post_decoded_cbk(m_postDecArg, mem); |
@@ -532,7 +543,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o | @@ -532,7 +543,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o | ||
532 | // 缓存snapshot | 543 | // 缓存snapshot |
533 | std::unique_lock<std::mutex> locker(m_cached_mutex); | 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 | if(m_cached_mem != nullptr){ | 547 | if(m_cached_mem != nullptr){ |
537 | aclrtMemcpy(m_cached_mem->getMem(), outputSize, (unsigned char *)outputDataDev, outputSize, ACL_MEMCPY_DEVICE_TO_DEVICE); | 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,12 +709,12 @@ void DvppDecoder::decode_thread(){ | ||
698 | LOG_INFO("[{}]- decode thread exit.", m_dec_name); | 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 | int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){ | 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,14 +727,14 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c | ||
716 | } | 727 | } |
717 | m_vdecQueue_mutex.unlock(); | 728 | m_vdecQueue_mutex.unlock(); |
718 | 729 | ||
719 | - AVPacket * pkt = nullptr; | 730 | + DataPacket * data_pkt = nullptr; |
720 | m_pktQueue_mutex.lock(); | 731 | m_pktQueue_mutex.lock(); |
721 | if(m_pktQueue.size() <= 0){ | 732 | if(m_pktQueue.size() <= 0){ |
722 | m_pktQueue_mutex.unlock(); | 733 | m_pktQueue_mutex.unlock(); |
723 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); | 734 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
724 | return 1; | 735 | return 1; |
725 | } | 736 | } |
726 | - pkt = m_pktQueue.front(); | 737 | + data_pkt = m_pktQueue.front(); |
727 | m_pktQueue.pop(); | 738 | m_pktQueue.pop(); |
728 | m_pktQueue_mutex.unlock(); | 739 | m_pktQueue_mutex.unlock(); |
729 | 740 | ||
@@ -732,8 +743,8 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c | @@ -732,8 +743,8 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c | ||
732 | int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size); | 743 | int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size); |
733 | if(ACL_ERROR_NONE != ret){ | 744 | if(ACL_ERROR_NONE != ret){ |
734 | LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret); | 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 | return 2; | 748 | return 2; |
738 | } | 749 | } |
739 | 750 | ||
@@ -754,12 +765,12 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c | @@ -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 | ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE); | 769 | ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE); |
759 | if(ACL_ERROR_NONE != ret){ | 770 | if(ACL_ERROR_NONE != ret){ |
760 | LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name); | 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 | return 2; | 774 | return 2; |
764 | } | 775 | } |
765 | 776 | ||
@@ -767,8 +778,8 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c | @@ -767,8 +778,8 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c | ||
767 | ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size); | 778 | ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size); |
768 | if(ret != ACL_ERROR_NONE){ | 779 | if(ret != ACL_ERROR_NONE){ |
769 | LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name); | 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 | return 2; | 783 | return 2; |
773 | } | 784 | } |
774 | 785 | ||
@@ -793,12 +804,13 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c | @@ -793,12 +804,13 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c | ||
793 | Vdec_CallBack_UserData *user_data = NULL; | 804 | Vdec_CallBack_UserData *user_data = NULL; |
794 | user_data = new Vdec_CallBack_UserData; | 805 | user_data = new Vdec_CallBack_UserData; |
795 | user_data->frameId = frame_count; | 806 | user_data->frameId = frame_count; |
807 | + user_data->frame_nb = data_pkt->frame_nb; | ||
796 | // user_data->startTime = startTime; | 808 | // user_data->startTime = startTime; |
797 | user_data->sendTime = UtilTools::get_cur_time_ms(); | 809 | user_data->sendTime = UtilTools::get_cur_time_ms(); |
798 | user_data->self = this; | 810 | user_data->self = this; |
799 | ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast<void *>(user_data)); | 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 | if(ret != ACL_ERROR_NONE){ | 814 | if(ret != ACL_ERROR_NONE){ |
803 | delete user_data; | 815 | delete user_data; |
804 | user_data = nullptr; | 816 | user_data = nullptr; |
@@ -813,9 +825,9 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c | @@ -813,9 +825,9 @@ int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_c | ||
813 | return 0; | 825 | return 0; |
814 | }while (0); | 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,4 +882,8 @@ void DvppDecoder::release_dvpp(){ | ||
870 | 882 | ||
871 | DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance(); | 883 | DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance(); |
872 | pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel); | 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 | \ No newline at end of file | 890 | \ No newline at end of file |
src/decoder/dvpp/DvppDecoder.h
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | #include <mutex> | 8 | #include <mutex> |
9 | #include <condition_variable> | 9 | #include <condition_variable> |
10 | 10 | ||
11 | +#include "FFRecoderTaskManager.h" | ||
11 | 12 | ||
12 | using namespace std; | 13 | using namespace std; |
13 | 14 | ||
@@ -51,8 +52,10 @@ public: | @@ -51,8 +52,10 @@ public: | ||
51 | 52 | ||
52 | int getCachedQueueLength(); | 53 | int getCachedQueueLength(); |
53 | 54 | ||
55 | + void doRecode(RecoderInfo& recoderInfo); | ||
56 | + | ||
54 | public: | 57 | public: |
55 | - void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output); | 58 | + void doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, unsigned long long frame_nb); |
56 | void doProcessReport(); | 59 | void doProcessReport(); |
57 | 60 | ||
58 | private: | 61 | private: |
@@ -96,7 +99,7 @@ private: | @@ -96,7 +99,7 @@ private: | ||
96 | bool m_dec_keyframe; | 99 | bool m_dec_keyframe; |
97 | 100 | ||
98 | mutex m_pktQueue_mutex; | 101 | mutex m_pktQueue_mutex; |
99 | - queue<AVPacket*> m_pktQueue; | 102 | + queue<DataPacket*> m_pktQueue; |
100 | 103 | ||
101 | // 解码 | 104 | // 解码 |
102 | int m_dvpp_deviceId {-1}; | 105 | int m_dvpp_deviceId {-1}; |
@@ -118,4 +121,6 @@ private: | @@ -118,4 +121,6 @@ private: | ||
118 | DvppDataMemory* m_cached_mem{nullptr}; | 121 | DvppDataMemory* m_cached_mem{nullptr}; |
119 | mutex m_cached_mutex; | 122 | mutex m_cached_mutex; |
120 | condition_variable m_cached_cond; | 123 | condition_variable m_cached_cond; |
124 | + | ||
125 | + FFRecoderTaskManager m_recoderManager; | ||
121 | }; | 126 | }; |
122 | \ No newline at end of file | 127 | \ No newline at end of file |
src/decoder/dvpp/DvppDecoderApi.cpp
@@ -130,4 +130,10 @@ void DvppDecoderApi::setFinishedDecArg(const void* finishedDecArg){ | @@ -130,4 +130,10 @@ void DvppDecoderApi::setFinishedDecArg(const void* finishedDecArg){ | ||
130 | if(m_pDecoder != nullptr){ | 130 | if(m_pDecoder != nullptr){ |
131 | return m_pDecoder->setFinishedDecArg(finishedDecArg); | 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 | \ No newline at end of file | 140 | \ No newline at end of file |
src/decoder/dvpp/DvppDecoderApi.h
@@ -39,6 +39,8 @@ public: | @@ -39,6 +39,8 @@ public: | ||
39 | 39 | ||
40 | void setPostDecArg(const void* postDecArg); | 40 | void setPostDecArg(const void* postDecArg); |
41 | void setFinishedDecArg(const void* finishedDecArg); | 41 | void setFinishedDecArg(const void* finishedDecArg); |
42 | + | ||
43 | + void doRecode(RecoderInfo& recoderInfo); | ||
42 | private: | 44 | private: |
43 | DvppDecoder* m_pDecoder; | 45 | DvppDecoder* m_pDecoder; |
44 | }; | 46 | }; |
45 | \ No newline at end of file | 47 | \ No newline at end of file |
src/decoder/dvpp/FFRecoder.cpp1 renamed to src/decoder/dvpp/FFRecoder.cpp
@@ -3,14 +3,6 @@ | @@ -3,14 +3,6 @@ | ||
3 | #include <tuple> | 3 | #include <tuple> |
4 | #include <array> | 4 | #include <array> |
5 | #include <vector> | 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 | FFRecoder::FFRecoder() | 8 | FFRecoder::FFRecoder() |
@@ -156,6 +148,8 @@ bool FFRecoder::init(AVRational time_base, AVCodecContext* avctx, const char* ou | @@ -156,6 +148,8 @@ bool FFRecoder::init(AVRational time_base, AVCodecContext* avctx, const char* ou | ||
156 | fprintf(stderr, "Write header failed!\n"); | 148 | fprintf(stderr, "Write header failed!\n"); |
157 | return false; | 149 | return false; |
158 | } | 150 | } |
151 | + | ||
152 | + return true; | ||
159 | } | 153 | } |
160 | 154 | ||
161 | void FFRecoder::uninit() | 155 | void FFRecoder::uninit() |
@@ -248,6 +242,8 @@ void FFRecoder::update_pts(AVPacket* pkt) { | @@ -248,6 +242,8 @@ void FFRecoder::update_pts(AVPacket* pkt) { | ||
248 | } | 242 | } |
249 | 243 | ||
250 | bool FFRecoder::write_pkt(AVPacket *pkt) { | 244 | bool FFRecoder::write_pkt(AVPacket *pkt) { |
245 | + char errbuf[64]{ 0 }; | ||
246 | + | ||
251 | av_packet_rescale_ts(pkt, codec_ctx_->time_base, out_stream_->time_base); | 247 | av_packet_rescale_ts(pkt, codec_ctx_->time_base, out_stream_->time_base); |
252 | pkt->stream_index = out_stream_->index; | 248 | pkt->stream_index = out_stream_->index; |
253 | update_pts(pkt); | 249 | update_pts(pkt); |
src/decoder/dvpp/FFRecoder.h1 renamed to src/decoder/dvpp/FFRecoder.h
1 | #pragma once | 1 | #pragma once |
2 | #include <memory> | 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 | class FFRecoder | 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 | \ No newline at end of file | 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 | \ No newline at end of file | 64 | \ No newline at end of file |
src/decoder/dvpp/VpcPicConverter.cpp
@@ -41,7 +41,7 @@ DvppDataMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out | @@ -41,7 +41,7 @@ DvppDataMemory* VpcPicConverter::convert2bgr(acldvppPicDesc *inputDesc_, int out | ||
41 | int out_buf_height = ALIGN_UP(out_height, 2); | 41 | int out_buf_height = ALIGN_UP(out_height, 2); |
42 | int out_buf_size = out_buf_width * out_buf_height; | 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 | void *outBufferDev_ = (void*)rgbMem->getMem(); | 45 | void *outBufferDev_ = (void*)rgbMem->getMem(); |
46 | 46 | ||
47 | acldvppPicDesc *outputDesc_= acldvppCreatePicDesc(); | 47 | acldvppPicDesc *outputDesc_= acldvppCreatePicDesc(); |
src/decoder/dvpp/depend_headers.h
@@ -35,4 +35,18 @@ extern "C" { | @@ -35,4 +35,18 @@ extern "C" { | ||
35 | #include "../interface/interface_headers.h" | 35 | #include "../interface/interface_headers.h" |
36 | #include "../interface/utiltools.hpp" | 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 | #endif | 52 | #endif |
39 | \ No newline at end of file | 53 | \ No newline at end of file |
src/decoder/interface/AbstractDecoder.h
@@ -3,6 +3,8 @@ | @@ -3,6 +3,8 @@ | ||
3 | 3 | ||
4 | #include "interface_headers.h" | 4 | #include "interface_headers.h" |
5 | 5 | ||
6 | +#include "../../ai_platform/common_header.h" | ||
7 | + | ||
6 | using namespace std; | 8 | using namespace std; |
7 | 9 | ||
8 | class AbstractDecoder{ | 10 | class AbstractDecoder{ |
@@ -38,6 +40,8 @@ public: | @@ -38,6 +40,8 @@ public: | ||
38 | virtual void setPostDecArg(const void* postDecArg) = 0; | 40 | virtual void setPostDecArg(const void* postDecArg) = 0; |
39 | virtual void setFinishedDecArg(const void* finishedDecArg) = 0; | 41 | virtual void setFinishedDecArg(const void* finishedDecArg) = 0; |
40 | 42 | ||
43 | + virtual void doRecode(RecoderInfo& recoderInfo) = 0; | ||
44 | + | ||
41 | public: | 45 | public: |
42 | bool isSnapTime(); | 46 | bool isSnapTime(); |
43 | 47 |
src/decoder/interface/DecoderManager.cpp
@@ -517,3 +517,23 @@ DeviceMemory* DecoderManager::snapshot_out_task(string& uri, int devId) { | @@ -517,3 +517,23 @@ DeviceMemory* DecoderManager::snapshot_out_task(string& uri, int devId) { | ||
517 | 517 | ||
518 | return devMem; | 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 | \ No newline at end of file | 540 | \ No newline at end of file |
src/decoder/interface/DecoderManager.h
@@ -273,6 +273,8 @@ public: | @@ -273,6 +273,8 @@ public: | ||
273 | **************************************************/ | 273 | **************************************************/ |
274 | vector<DeviceMemory*> timing_snapshot_all(); | 274 | vector<DeviceMemory*> timing_snapshot_all(); |
275 | 275 | ||
276 | + void doRecode(RecoderInfo& recoderInfo); | ||
277 | + | ||
276 | private: | 278 | private: |
277 | DecoderManager(){} | 279 | DecoderManager(){} |
278 | 280 |
src/decoder/interface/DeviceMemory.hpp
@@ -10,7 +10,7 @@ using namespace std; | @@ -10,7 +10,7 @@ using namespace std; | ||
10 | class DeviceMemory{ | 10 | class DeviceMemory{ |
11 | 11 | ||
12 | public: | 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 | channel = _channel; | 14 | channel = _channel; |
15 | width = _width; | 15 | width = _width; |
16 | width_stride = _width_stride; | 16 | width_stride = _width_stride; |
@@ -21,6 +21,7 @@ public: | @@ -21,6 +21,7 @@ public: | ||
21 | id = _id; | 21 | id = _id; |
22 | device_id = _dev_id; | 22 | device_id = _dev_id; |
23 | key_frame = _key_frame; | 23 | key_frame = _key_frame; |
24 | + frame_nb = _frame_nb; | ||
24 | timestamp = UtilTools::get_cur_time_ms(); | 25 | timestamp = UtilTools::get_cur_time_ms(); |
25 | } | 26 | } |
26 | 27 | ||
@@ -80,6 +81,10 @@ public: | @@ -80,6 +81,10 @@ public: | ||
80 | return key_frame; | 81 | return key_frame; |
81 | } | 82 | } |
82 | 83 | ||
84 | + unsigned long long getFrameNb() { | ||
85 | + return frame_nb; | ||
86 | + } | ||
87 | + | ||
83 | public: | 88 | public: |
84 | int data_size; | 89 | int data_size; |
85 | bool isused; | 90 | bool isused; |
@@ -94,6 +99,7 @@ public: | @@ -94,6 +99,7 @@ public: | ||
94 | int channel{3}; | 99 | int channel{3}; |
95 | bool key_frame; | 100 | bool key_frame; |
96 | long index; | 101 | long index; |
102 | + unsigned long long frame_nb; | ||
97 | }; | 103 | }; |
98 | 104 | ||
99 | #endif | 105 | #endif |
100 | \ No newline at end of file | 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 | \ No newline at end of file | 172 | \ No newline at end of file |