diff --git a/.gitignore b/.gitignore index b5764cc..ab9ab8e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ data/* src/Makefile .gitignore src/decoder/Makefile +bin/test_dec diff --git a/.vscode/launch.json b/.vscode/launch.json index 3218e56..2a6efea 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -58,6 +58,24 @@ "ignoreFailures": true } ] + },{ + "name": "test_dec", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/bin/test_dec", + "args": ["/opt/cmhu/data/Street.uvf","0", "0", "0"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}/bin", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] } ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index c68926a..aef4e1c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -62,6 +62,7 @@ "cfenv": "cpp", "cinttypes": "cpp", "typeinfo": "cpp", - "variant": "cpp" + "variant": "cpp", + "bsf_internal.h": "c" } } \ No newline at end of file diff --git a/src/decoder/Makefile b/build/decoder/Makefile index 563ae93..563ae93 100644 --- a/src/decoder/Makefile +++ b/build/decoder/Makefile diff --git a/src/demo/Makefile b/build/demo/Makefile index 3584297..75419d0 100755 --- a/src/demo/Makefile +++ b/build/demo/Makefile @@ -15,7 +15,7 @@ JSON_ROOT = $(THIRDPARTY_ROOT)/jsoncpp-1.9.5/release FFMPEG_ROOT = $(THIRDPARTY_ROOT)/ffmpeg-4.4.4/release RABBITMQ_CLIENT_ROOT = $(THIRDPARTY_ROOT)/rabbitmq-c-0.11.0/release -DEFS = -DENABLE_DVPP_INTERFACE -DPOST_USE_RABBITMQ -DUSE_VILLAGE +DEFS = -DENABLE_DVPP_INTERFACE include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \ -I $(SPDLOG_ROOT)/include \ diff --git a/src/Makefile b/build/src/Makefile index c1d2d34..6b71795 100755 --- a/src/Makefile +++ b/build/src/Makefile @@ -16,8 +16,8 @@ FFMPEG_ROOT = $(THIRDPARTY_ROOT)/ffmpeg-4.4.4/release RABBITMQ_CLIENT_ROOT = $(THIRDPARTY_ROOT)/rabbitmq-c-0.11.0/release AUTHORITY_DIR = $(THIRDPARTY_ROOT)/atlas_lic-aarch64-20220112/atlas_lic -DEFS = -DENABLE_DVPP_INTERFACE -DWITH_FACE_DET_SS -DPOST_USE_RABBITMQ -DUSE_VILLAGE -# DEFS = -DENABLE_DVPP_INTERFACE -DWITH_FACE_DET_SS -DPOST_USE_RABBITMQ +# DEFS = -DENABLE_DVPP_INTERFACE -DWITH_FACE_DET_SS -DPOST_USE_RABBITMQ -DUSE_VILLAGE +DEFS = -DENABLE_DVPP_INTERFACE include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \ -I $(SPDLOG_ROOT)/include \ @@ -33,7 +33,7 @@ lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \ -L/usr/local/Ascend/ascend-toolkit/latest/runtime/lib64 \ -L/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64 \ -L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64/stub \ - + 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 \ -lplatform -lgraph_base -lqos_manager diff --git a/src/ai_platform/MultiSourceProcess.cpp b/src/ai_platform/MultiSourceProcess.cpp index b836383..a1a5805 100755 --- a/src/ai_platform/MultiSourceProcess.cpp +++ b/src/ai_platform/MultiSourceProcess.cpp @@ -1316,6 +1316,7 @@ void CMultiSourceProcess::timing_snapshot_thread(){ jpegUtil.jpeg_encode(vpcDesc, fpath_ori); acldvppDestroyPicDesc(vpcDesc); + vpcDesc = nullptr; #ifdef POST_USE_RABBITMQ auto json_str = helpers::gen_json::gen_vtsnapshot_json(task_id, fpath_ori); diff --git a/src/decoder/dvpp/DvppDataMemory.hpp b/src/decoder/dvpp/DvppDataMemory.hpp index ba26cc1..257fd9e 100755 --- a/src/decoder/dvpp/DvppDataMemory.hpp +++ b/src/decoder/dvpp/DvppDataMemory.hpp @@ -1,18 +1,22 @@ #include +#include "depend_headers.h" #include "dvpp_headers.h" using namespace std; +// static int snap_free = 0; + class DvppDataMemory : public DeviceMemory { public: 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) :DeviceMemory(_channel, _width, _width_stride, _height, _height_stride, _id, _dev_id, _key_frame, frame_nb, false){ data_size = _size; + data_type = 1; int ret = acldvppMalloc((void **)&pHwRgb, data_size); if(ret != ACL_ERROR_NONE){ - cout << "acldvppMalloc failed" << endl; + LOG_ERROR("[{}]- acldvppMalloc failed", id); } } @@ -23,14 +27,48 @@ public: pHwRgb = pHwData; } + + + DvppDataMemory(DvppDataMemory* pSrc):DeviceMemory(-1, pSrc->getWidth(), pSrc->getWidthStride(), pSrc->getHeight(), pSrc->getHeightStride(), pSrc->getId(), pSrc->getDeviceId(), pSrc->isKeyFrame(), pSrc->getFrameNb(), false){ + if(pSrc == nullptr) { + LOG_ERROR("[{}]- pSrc is nullptr", pSrc->getId()); + return; + } + + data_size = pSrc->getSize(); + int ret = acldvppMalloc((void **)&pHwRgb, data_size); + if(ret != ACL_ERROR_NONE){ + LOG_ERROR("[{}]- acldvppMalloc failed", pSrc->getId()); + return; + } + + ret = aclrtMemcpy(pHwRgb, data_size, pSrc->getMem(), pSrc->getSize(), ACL_MEMCPY_DEVICE_TO_DEVICE); + if(ret != ACL_ERROR_NONE){ + acldvppFree(pHwRgb); + LOG_ERROR("[{}]- aclrtMemcpy failed", pSrc->getId()); + return; + } + + data_type = 2; + timestamp = UtilTools::get_cur_time_ms(); + } + ~DvppDataMemory(){ + // if (data_type == 2) + // { + // snap_free++; + // LOG_INFO("[{}]- snap_free: {}", getId(), snap_free); + // } if (pHwRgb) { int ret = acldvppFree(pHwRgb); if(ret != ACL_ERROR_NONE){ - cout << "acldvppFree failed" << endl; + LOG_ERROR("[{}]- acldvppFree failed", id); } pHwRgb = nullptr; } + + + } public: diff --git a/src/decoder/dvpp/DvppDecoder.cpp b/src/decoder/dvpp/DvppDecoder.cpp index 672e4fa..dc3577a 100755 --- a/src/decoder/dvpp/DvppDecoder.cpp +++ b/src/decoder/dvpp/DvppDecoder.cpp @@ -13,13 +13,14 @@ + struct Vdec_CallBack_UserData { uint64_t frameId; unsigned long long frame_nb; long startTime; long sendTime; - // void* vdecOutputBuf; DvppDecoder* self; + Vdec_CallBack_UserData() { frameId = 0; frame_nb = 0; @@ -57,13 +58,11 @@ static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void DvppDecoder::DvppDecoder(){ - m_read_thread = 0; - m_cached_mem = nullptr; + m_read_thread = nullptr; fmt_ctx = nullptr; m_bRunning = false; - stream = nullptr; video_index = -1; pix_fmt = AV_PIX_FMT_NONE; m_dec_name = ""; @@ -74,11 +73,12 @@ DvppDecoder::DvppDecoder(){ m_bFinished = false; m_dec_keyframe = false; m_fps = 0.0; - - m_bSnapShoting = false; } DvppDecoder::~DvppDecoder(){ + close(); + + LOG_DEBUG("[{}]- ~DvppDecoder() in_count:{} out_count:{}", m_dec_name, m_in_count, m_out_count); } bool DvppDecoder::init(FFDecConfig cfg){ @@ -106,32 +106,21 @@ bool DvppDecoder::init(FFDecConfig cfg){ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) - av_register_all(); -#endif -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100) - avcodec_register_all(); -#endif - - avformat_network_init(); - - const char* uri = config.uri.c_str(); - fstream infile; - infile.open(uri, ios::in); - if (!infile.fail()){ - m_bReal = false; - infile.close(); - } else { - m_bReal = true; - } + const char* input_file = config.uri.c_str(); + FILE* infile = fopen(input_file, "r"); + if(nullptr != infile) { + m_bReal = false; + fclose(infile); + infile = nullptr; + } else { + m_bReal = true; + } // 打开输入视频文件 AVDictionary *options = nullptr; av_dict_set( &options, "bufsize", "655360", 0 ); av_dict_set( &options, "rtsp_transport", config.force_tcp ? "tcp" : "udp", 0 ); av_dict_set( &options, "stimeout", "30000000", 0 ); // 单位为 百万分之一秒 - - const char* input_file = uri; do{ fmt_ctx = avformat_alloc_context(); @@ -154,9 +143,8 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ LOG_ERROR("[{}]- Cannot find a video stream in the input file!", m_dec_name); break; } - AVCodec *vcodec = avcodec_find_decoder(decoder->id); - avctx = avcodec_alloc_context3(vcodec); + avctx = avcodec_alloc_context3(decoder); if(avctx == nullptr){ LOG_ERROR("[{}]- alloc AVCodecContext failed!", m_dec_name); break; @@ -195,10 +183,8 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ frame_width = codecpar->width; frame_height = codecpar->height; pix_fmt = (AVPixelFormat)codecpar->format; - // m_fps = av_q2d(stream ->avg_frame_rate); if (stream->avg_frame_rate.den) { - // m_fps = stream->avg_frame_rate.num / stream->avg_frame_rate.den; m_fps = av_q2d(stream ->avg_frame_rate); } else { m_fps = 0.0; @@ -309,14 +295,12 @@ bool DvppDecoder::isSurport(FFDecConfig& cfg){ bool DvppDecoder::start(){ m_bRunning = true; - pthread_create(&m_read_thread,0, - [](void* arg) + m_read_thread = new std::thread([](void* arg) { DvppDecoder* a=(DvppDecoder*)arg; a->read_thread(); return (void*)0; - } - ,this); + }, this); return true; } @@ -324,8 +308,10 @@ bool DvppDecoder::start(){ void DvppDecoder::close(){ m_bRunning=false; - if(m_read_thread != 0){ - pthread_join(m_read_thread,0); + if(m_read_thread != nullptr){ + m_read_thread->join(); + delete m_read_thread; + m_read_thread = nullptr; } } @@ -371,20 +357,42 @@ float DvppDecoder::fps(){ return m_fps; } +static int snap_count = 0; + DeviceMemory* DvppDecoder::snapshot(){ - // 注意内部有锁 - // 开始抓拍 - m_bSnapShoting = true; - std::unique_lock locker(m_cached_mutex); - while (m_cached_mem == nullptr) - m_cached_cond.wait_for(locker, std::chrono::seconds(1)); // Unlock mutex and wait to be notified - locker.unlock(); + int ret = aclrtSetCurrentContext(m_context); + if(ret != ACL_ERROR_NONE){ + LOG_ERROR("[{}]- aclrtSetCurrentContext failed", m_dec_name); + return nullptr; + } - DeviceMemory* mem = m_cached_mem; - m_cached_mem = nullptr; + // 注意有锁 + DeviceMemory* snapshot_mem = nullptr; + int loop_times = 0; + while(m_bRunning) { + m_decoded_data_queue_mtx.lock(); + if(m_decoded_data_queue.size() <= 0) { + m_decoded_data_queue_mtx.unlock(); + loop_times++; + if(loop_times > 100) { + // 1s都没截取到图,退出 + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + continue; + } + + DvppDataMemory* mem = m_decoded_data_queue.front(); + snapshot_mem = new DvppDataMemory(mem); + m_decoded_data_queue_mtx.unlock(); - return mem; + snap_count++; + LOG_INFO("[{}]- snap_count:{} ", m_dec_name, snap_count); + break; + } + + return snapshot_mem; } int DvppDecoder::getCachedQueueLength(){ @@ -397,14 +405,16 @@ void DvppDecoder::release_ffmpeg() { av_bsf_free(&h264bsfc); h264bsfc = nullptr; } - if (fmt_ctx){ - avformat_close_input(&fmt_ctx); - fmt_ctx = nullptr; - } if(avctx){ avcodec_free_context(&avctx); avctx = nullptr; } + if (fmt_ctx){ + avformat_close_input(&fmt_ctx); + fmt_ctx = nullptr; + } + + LOG_DEBUG("[{}]- release_ffmpeg", m_dec_name); } void DvppDecoder::read_thread() { @@ -420,18 +430,16 @@ void DvppDecoder::read_thread() { } m_bExitDisplayThd = false; - pthread_t display_thread; - pthread_create(&display_thread,0, + std::thread display_thread = std::thread( [](void* arg) { DvppDecoder* a=(DvppDecoder*)arg; a->display_thread(); return (void*)0; - } - ,this); - + }, + this + ); - aclrtContext ctx = nullptr; aclrtStream stream = nullptr; aclvdecChannelDesc *vdecChannelDesc = nullptr; @@ -456,7 +464,8 @@ void DvppDecoder::read_thread() { CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed"); CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed"); - AVPacket* pkt = nullptr; + AVPacket* pkt = av_packet_alloc(); + av_init_packet( pkt ); unsigned long long frame_nb = 0; while (m_bRunning){ @@ -476,20 +485,15 @@ void DvppDecoder::read_thread() { m_decoded_data_queue_mtx.unlock(); } - pkt = av_packet_alloc(); - av_init_packet( pkt ); - int result = av_read_frame(fmt_ctx, pkt); if (result == AVERROR_EOF || result < 0){ - av_packet_free(&pkt); - pkt = nullptr; + av_packet_unref(pkt); LOG_WARN("[{}]- Failed to read frame!", m_dec_name); break; } if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) { - av_packet_free(&pkt); - pkt = nullptr; + av_packet_unref(pkt); continue; } @@ -498,17 +502,12 @@ void DvppDecoder::read_thread() { ret = av_bsf_send_packet(h264bsfc, pkt); if(ret < 0) { LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name); - av_packet_free(&pkt); - pkt = nullptr; + av_packet_unref(pkt); continue; } int nSended = -1; while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) { - if(pkt->size > g_pkt_size){ - LOG_ERROR("[{}]- pkt size 大于最大预设值!", m_dec_name); - break; - } if(!m_bRunning){ break; @@ -527,8 +526,14 @@ void DvppDecoder::read_thread() { } // 音频等其他分量的情形 - av_packet_free(&pkt); - pkt = nullptr; + av_packet_unref(pkt); + } + + av_packet_free(&pkt); + pkt = nullptr; + + if (vdecChannelDesc) { + sendVdecEos(vdecChannelDesc); } while(m_bRunning && m_decoded_data_queue.size() > 0) { @@ -537,9 +542,9 @@ void DvppDecoder::read_thread() { } while (0); - if (vdecChannelDesc) { - sendVdecEos(vdecChannelDesc); + LOG_INFO("[{}]- release.", m_dec_name); + if (vdecChannelDesc) { CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed"); CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed"); vdecChannelDesc = nullptr; @@ -551,16 +556,15 @@ void DvppDecoder::read_thread() { CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "report_thread join failed"); m_bExitDisplayThd = true; - CHECK_NOT_RETURN(pthread_join(display_thread, nullptr), "display_thread join failed"); + display_thread.join(); - if(stream){ + if(stream){ CHECK_NOT_RETURN(aclrtDestroyStream(stream), "aclrtDestroyStream failed"); } if (ctx){ CHECK_NOT_RETURN(aclrtDestroyContext(ctx), "aclrtDestroyContext failed"); } - m_recoderManager.close(); @@ -583,7 +587,7 @@ int DvppDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, uns acldvppStreamDesc *input_stream_desc = nullptr; acldvppPicDesc *output_pic_desc = nullptr; do{ - int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size); + int ret = acldvppMalloc((void **)&vdecInputbuf, pkt->size); if(ACL_ERROR_NONE != ret){ LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret); break; @@ -624,6 +628,8 @@ int DvppDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, uns user_data->sendTime = UtilTools::get_cur_time_ms(); user_data->self = this; + m_in_count++; + ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast(user_data)); if(ret != ACL_ERROR_NONE){ LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name); @@ -687,8 +693,9 @@ void DvppDecoder::doProcessReport(){ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, unsigned long long frame_nb){ - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed"); + m_out_count++; + CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed"); void *inputDataDev = acldvppGetStreamDescData(input); acldvppFree(inputDataDev); @@ -712,11 +719,12 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o bool bCached = false; if(width > 0 && height > 0 && outputSize > 0){ + if (!m_bReal) { - while(m_bRunning) { + while(!m_bExitReportThd) { // 非实时流,即为文件情形,因为不存在花屏问题,为保证不丢帧,这里做个循环等待 m_decoded_data_queue_mtx.lock(); - if(m_decoded_data_queue.size() > 5){ + if(m_decoded_data_queue.size() >= 5){ m_decoded_data_queue_mtx.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(5)); continue; @@ -731,7 +739,7 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o // 换成解码后数据, 这里这样做的是为了保证解码一直持续进行,避免后续操作阻碍文件读取和解码从而导致花屏 m_decoded_data_queue_mtx.lock(); - if(m_decoded_data_queue.size() <= 25) { + if(m_decoded_data_queue.size() <= 5) { 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); if(mem){ m_decoded_data_queue.push(mem); @@ -740,20 +748,6 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o } m_decoded_data_queue_mtx.unlock(); - if(m_bSnapShoting){ - // 缓存snapshot - std::unique_lock locker(m_cached_mutex); - - m_cached_mem = new DvppDataMemory(-1, width, width_stride, height, height_stride, outputSize, m_dec_name, to_string(m_dvpp_deviceId), false, 0); - if(m_cached_mem != nullptr){ - aclrtMemcpy(m_cached_mem->getMem(), outputSize, (unsigned char *)outputDataDev, outputSize, ACL_MEMCPY_DEVICE_TO_DEVICE); - } - - locker.unlock(); - m_cached_cond.notify_one(); - m_bSnapShoting = false; - } - } if(!bCached) { @@ -802,6 +796,7 @@ void DvppDecoder::display_thread(){ std::this_thread::sleep_for(std::chrono::milliseconds(5)); continue; } + DvppDataMemory* mem = m_decoded_data_queue.front(); m_decoded_data_queue.pop(); m_decoded_data_queue_mtx.unlock(); @@ -814,12 +809,14 @@ void DvppDecoder::display_thread(){ } } + m_decoded_data_queue_mtx.lock(); while (m_decoded_data_queue.size() > 0){ DvppDataMemory* mem = m_decoded_data_queue.front(); m_decoded_data_queue.pop(); delete mem; mem = nullptr; } + m_decoded_data_queue_mtx.unlock(); LOG_INFO("[{}]- display_thread exit.", m_dec_name); } @@ -830,10 +827,14 @@ void DvppDecoder::release_dvpp(){ if(ret != ACL_ERROR_NONE){ LOG_ERROR("[{}]- aclrtDestroyContext failed !", m_dec_name); } + m_context = nullptr; } - DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance(); - pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel); + if(m_dvpp_channel >= 0){ + DvppSourceManager* pSrcMgr = DvppSourceManager::getInstance(); + pSrcMgr->releaseChannel(m_dvpp_deviceId, m_dvpp_channel); + m_dvpp_channel = -1; + } } void DvppDecoder::doRecode(RecoderInfo& recoderInfo) { diff --git a/src/decoder/dvpp/DvppDecoder.h b/src/decoder/dvpp/DvppDecoder.h index 5439257..a4b7faf 100755 --- a/src/decoder/dvpp/DvppDecoder.h +++ b/src/decoder/dvpp/DvppDecoder.h @@ -6,7 +6,8 @@ #include #include -#include +#include +#include #include "FFRecoderTaskManager.h" @@ -14,7 +15,8 @@ using namespace std; typedef void(*RECEIVER_FINISHED_CALLBACK)(const void* userPtr); -const int g_pkt_size = 1024 * 1024; // 单个AVPacket大小的最大值 + +struct Vdec_CallBack_UserData; class DvppDecoder{ public: @@ -78,7 +80,7 @@ private: FFDecConfig m_cfg; string m_dec_name; - const void * m_finishedDecArg; + const void * m_finishedDecArg {nullptr}; DECODE_FINISHED_CALLBACK decode_finished_cbk {nullptr}; bool m_bFinished{false}; @@ -89,7 +91,6 @@ private: bool m_bExitDisplayThd{false}; // 读取数据 - AVStream* stream{nullptr}; int video_index{-1}; AVFormatContext *fmt_ctx{nullptr}; AVPixelFormat pix_fmt; @@ -98,12 +99,12 @@ private: int frame_width{0}; int frame_height{0}; - bool m_bReal; // 是否实时流 + bool m_bReal {false}; // 是否实时流 float m_fps{0.0}; - pthread_t m_read_thread{0}; + std::thread* m_read_thread{nullptr}; - bool m_dec_keyframe; + bool m_dec_keyframe {false}; // 解码 int m_dvpp_deviceId {-1}; @@ -111,21 +112,18 @@ private: aclrtContext m_context{nullptr}; acldvppStreamFormat m_enType; - const void * m_postDecArg; + const void * m_postDecArg {nullptr}; POST_DECODE_CALLBACK post_decoded_cbk {nullptr}; int m_vdec_out_size {-1}; - // 截图 - bool m_bSnapShoting{false}; - DvppDataMemory* m_cached_mem{nullptr}; - mutex m_cached_mutex; - condition_variable m_cached_cond; - FFRecoderTaskManager m_recoderManager; queue m_decoded_data_queue; mutex m_decoded_data_queue_mtx; long long last_ts {0}; + + int m_in_count {0}; + int m_out_count {0}; }; \ No newline at end of file diff --git a/src/decoder/dvpp/FFRecoderTaskManager.cpp b/src/decoder/dvpp/FFRecoderTaskManager.cpp index 7849618..3c35f9a 100644 --- a/src/decoder/dvpp/FFRecoderTaskManager.cpp +++ b/src/decoder/dvpp/FFRecoderTaskManager.cpp @@ -34,7 +34,7 @@ FFRecoderTaskManager::FFRecoderTaskManager(){ } FFRecoderTaskManager::~FFRecoderTaskManager(){ - + LOG_DEBUG("~FFRecoderTaskManager()"); } bool FFRecoderTaskManager::init(AVStream* stream, AVCodecContext* avctx){ @@ -264,6 +264,7 @@ void FFRecoderTaskManager::close() { if (m_recoder_thread) { m_recoder_thread->join(); + delete m_recoder_thread; m_recoder_thread = nullptr; } diff --git a/src/decoder/interface/DecoderManager.cpp b/src/decoder/interface/DecoderManager.cpp index d04e68f..489720c 100755 --- a/src/decoder/interface/DecoderManager.cpp +++ b/src/decoder/interface/DecoderManager.cpp @@ -13,6 +13,21 @@ using namespace std; +DecoderManager::~DecoderManager(){ + closeAllDecoder(); + avformat_network_deinit(); +} + +void DecoderManager::init() { + #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) + av_register_all(); +#endif +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 10, 100) + avcodec_register_all(); +#endif + + avformat_network_init(); +} AbstractDecoder* DecoderManager::createDecoder(MgrDecConfig config){ diff --git a/src/decoder/interface/DecoderManager.h b/src/decoder/interface/DecoderManager.h index 735fb9d..d3efbea 100755 --- a/src/decoder/interface/DecoderManager.h +++ b/src/decoder/interface/DecoderManager.h @@ -33,14 +33,14 @@ public: static DecoderManager* singleton = nullptr; if (singleton == nullptr){ singleton = new DecoderManager(); + singleton->init(); } return singleton; } - ~DecoderManager() - { - closeAllDecoder(); - } + ~DecoderManager(); + + void init(); /************************************************** * 接口:createDecoder diff --git a/src/decoder/interface/DeviceMemory.hpp b/src/decoder/interface/DeviceMemory.hpp index d739cc5..a7e3863 100755 --- a/src/decoder/interface/DeviceMemory.hpp +++ b/src/decoder/interface/DeviceMemory.hpp @@ -26,7 +26,7 @@ public: } virtual ~DeviceMemory(){} - + int getSize() { return data_size; } diff --git a/src/decoder/test_decoder.cpp b/src/decoder/test_decoder.cpp index bc91df2..7760ebf 100644 --- a/src/decoder/test_decoder.cpp +++ b/src/decoder/test_decoder.cpp @@ -2,6 +2,7 @@ #include #include #include +#include "../common/logger.hpp" using namespace std; @@ -25,16 +26,18 @@ int m_batch_size = 20; void algorthim_process_thread(); +void snap_shot_thread(); + void post_decod_cbk(const void * userPtr, DeviceMemory* devFrame){ do{ if(m_bfinish){ - break; + break; } m_DataListMtx.lock(); if(m_RgbDataList.size() >= 30){ - m_DataListMtx.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(3)); - continue; + m_DataListMtx.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + continue; } m_RgbDataList.push_back(devFrame); m_DataListMtx.unlock(); @@ -46,13 +49,13 @@ void decode_finished_cbk(const void * userPtr){ decode_cbk_userdata* ptr = (decode_cbk_userdata*)userPtr; if (ptr!= nullptr){ printf("task finished: %s \n", ptr->task_id.c_str()); + delete ptr; + ptr = nullptr; } - delete ptr; - ptr = nullptr; } -int main(){ - +bool create_task(string task_id) { + // 创建解码任务 DecoderManager* pDecManager = DecoderManager::getInstance(); @@ -73,17 +76,34 @@ int main(){ return false; } - decode_cbk_userdata* userPtr = new decode_cbk_userdata; - userPtr->task_id = string(task_id); - pDecManager->setPostDecArg(config.name, userPtr); - pDecManager->setFinishedDecArg(config.name, userPtr); + // decode_cbk_userdata* userPtr = new decode_cbk_userdata; + // userPtr->task_id = string(task_id); + // pDecManager->setPostDecArg(config.name, userPtr); + // pDecManager->setFinishedDecArg(config.name, userPtr); + + dec->setSnapTimeInterval(1000); int input_image_width = 0; int input_image_height = 0; pDecManager->getResolution(config.name, input_image_width, input_image_height); - + pDecManager->startDecodeByName(config.name); + // pDecManager->closeAllDecoder(); + + return true; +} + +int main(){ + + set_default_logger(LogLevel(0), "test_decode","logs/main.log", 64 * 1024 * 1024, 64 * 1024 * 1024); + LOG_INFO("编译时间:{} {}", __DATE__, __TIME__); + + printf("start... \n"); + + DecoderManager* pDecManager = DecoderManager::getInstance(); + + // 创建算法线程 m_pAlgorthimThread = new thread([](void* arg) { algorthim_process_thread(); @@ -91,15 +111,47 @@ int main(){ } , nullptr); - pDecManager->startDecodeByName(config.name); + thread snap_thread = thread([](void* arg) { + snap_shot_thread(); + return (void*)0; + } + , nullptr); + + - while (getchar() != 'q'); + char ch = 'a'; + int task_id = 1; + + while (ch != 'q') { + ch = getchar(); + switch (ch) + { + case '4': + for (size_t i = 0; i < 4; i++) + { + create_task(to_string(task_id)); + task_id++; + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + break; + case 'a': + create_task(to_string(task_id)); + task_id++; + std::this_thread::sleep_for(std::chrono::seconds(1)); + break; + case 'c': + pDecManager->closeAllDecoder(); + break; + default: + break; + } + } } void do_work(vector vec_gpuMem){ for(int i=0;i < vec_gpuMem.size(); i++){ DeviceMemory* mem = vec_gpuMem[i]; - printf("width:%d height:%d ts:%lld \n", mem->getWidth(), mem->getHeight(), mem->getTimesstamp()); + // printf("task:%s width:%d height:%d ts:%lld \n", mem->getId().c_str(), mem->getWidth(), mem->getHeight(), mem->getTimesstamp()); } } @@ -145,9 +197,32 @@ void algorthim_process_thread(){ delete mem; mem = nullptr; } - vec_gpuMem.clear(); + // vec_gpuMem.clear(); + + vector().swap(vec_gpuMem); } printf("algorthim_process_thread exit. \n"); +} + +void snap_shot_thread(){ + DecoderManager* pDecManager = DecoderManager::getInstance(); + while (true){ + if(m_bfinish){ + break; + } + + vector vec_devMem = pDecManager->timing_snapshot_all(); + for(auto devMem : vec_devMem){ + delete devMem; + devMem = nullptr; + } + // vec_devMem.clear(); + + vector().swap(vec_devMem); + + std::this_thread::sleep_for(std::chrono::milliseconds(600)); + + } } \ No newline at end of file diff --git a/src/decoder/test_recoder.cpp b/src/decoder/test_recoder.cpp2 index d373aa8..d373aa8 100644 --- a/src/decoder/test_recoder.cpp +++ b/src/decoder/test_recoder.cpp2 diff --git a/src/demo/demo.cpp b/src/demo/demo.cpp index 7b1ba1b..00d950f 100755 --- a/src/demo/demo.cpp +++ b/src/demo/demo.cpp @@ -63,8 +63,8 @@ void init_mq_conn(void *handle) { #endif // #ifdef POST_USE_RABBITMQ void set_task_params(task_param &tparam, const unsigned &idx, const algorithm_type_t &algor_type) { - auto algor_init_params = new algor_init_config_param_t; switch (algor_type) { + auto algor_init_params = new algor_init_config_param_t; case algorithm_type_t::NONMOTOR_VEHICLE_NOHELMET: { auto algor_params = new algor_config_param_manned_incident; @@ -874,7 +874,7 @@ void set_task_params(task_param &tparam, const unsigned &idx, const algorithm_ty auto algor_params = new algor_config_param_road_work; { - algor_params->frame_stride = 5; + algor_params->frame_stride = 1; } auto basic_params = new algor_basic_config_param_t; @@ -1022,6 +1022,24 @@ string createTask(void *handle, std::vector algor_vec, int gi, if (result_code != 0) printf("[Error]: "); printf("--- task_id: %s result code: %d\n", tparam.task_id, result_code); + + + // 释放参数 + for (size_t idx = 0; idx < algor_vec.size(); ++idx) { + if(tparam.algor_config_params[idx].algor_type == algorithm_type_t::VIDEO_TIMING_SNAPSHOT) { + algor_config_param_road_work* algor_param = (algor_config_param_road_work*)tparam.algor_config_params[idx].algor_init_config_param->algor_param; + delete algor_param; + algor_basic_config_param_t* basic_param = (algor_basic_config_param_t*)tparam.algor_config_params[idx].algor_init_config_param->basic_param; + delete basic_param; + + algor_init_config_param_t* config_param = tparam.algor_config_params[idx].algor_init_config_param; + delete config_param; + } + } + delete[] tparam.algor_config_params; + + + return task_id_str; } @@ -1083,7 +1101,7 @@ void test_gpu(int gpuID){ algorithm_type_t::VEHICLE_SOLIDLINETURNAROUND, algorithm_type_t::VEHICLE_NOTDECELERATION}; // std::vector algor_vec3 = {algorithm_type_t::NONMOTOR_VEHICLE_NOHELMET, algorithm_type_t::NONMOTOR_VEHICLE_OVERMAN, algorithm_type_t::TRICYCLE_MANNED, algorithm_type_t::TRUCK_MANNED, algorithm_type_t::NONMOTOR_VEHICLE_USEPHONE, // algorithm_type_t::NONMOTOR_VEHICLE_REFIT, algorithm_type_t::PERSON_RUNNING_REDLIGHTS, algorithm_type_t::NONMOTOR_RUNNING_REDLIGHTS}; - std::vector algor_vec3 = {algorithm_type_t::VEHICLE_SOLIDLINETURNAROUND, algorithm_type_t::VEHICLE_NOTDECELERATION}; + std::vector algor_vec3 = {algorithm_type_t::VIDEO_TIMING_SNAPSHOT}; /* int repeat_num = 1000; @@ -1156,10 +1174,10 @@ void test_gpu(int gpuID){ { case 'a': createTask(handle, algor_vec3, 4, false); - createTask(handle, algor_vec3, 5, false); - createTask(handle, algor_vec3, 6, false); - createTask(handle, algor_vec3, 7, false); - createTask(handle, algor_vec3, 8, false); + // createTask(handle, algor_vec3, 5, false); + // createTask(handle, algor_vec3, 6, false); + // createTask(handle, algor_vec3, 7, false); + // createTask(handle, algor_vec3, 8, false); break; case 'c': close_all_task(handle);