diff --git a/src/decoder/Makefile b/src/decoder/Makefile old mode 100755 new mode 100644 index c4487de..563ae93 --- a/src/decoder/Makefile +++ b/src/decoder/Makefile @@ -1,21 +1,20 @@ XX = g++ -PROJECT_ROOT= /opt/cmhu/vpt_ascend_arm +PROJECT_ROOT= /home/cmhu/vpt_ascend_arm DEPEND_DIR = $(PROJECT_ROOT)/bin SRC_ROOT = $(PROJECT_ROOT)/src -TARGET= $(PROJECT_ROOT)/bin/test_face +TARGET= $(PROJECT_ROOT)/bin/test_dec THIRDPARTY_ROOT = $(PROJECT_ROOT)/3rdparty SPDLOG_ROOT = $(THIRDPARTY_ROOT)/spdlog-1.9.2/release OPENCV_ROOT = $(THIRDPARTY_ROOT)/opencv_4_1 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 -DWITH_FACE_DET_SS -DPOST_USE_RABBITMQ +DEFS = -DENABLE_DVPP_INTERFACE include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \ -I $(SPDLOG_ROOT)/include \ @@ -23,7 +22,6 @@ include_dir=-I/usr/local/Ascend/ascend-toolkit/6.3.RC1/aarch64-linux/include \ -I $(OPENCV_ROOT)/include \ -I $(JSON_ROOT)/include \ -I $(FFMPEG_ROOT)/include \ - -I $(RABBITMQ_CLIENT_ROOT)/include \ lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/runtime/lib64 \ -L/usr/local/Ascend/ascend-toolkit/latest/lib64 \ @@ -31,28 +29,17 @@ lib_dir=-L/usr/local/Ascend/ascend-toolkit/6.3.RC1/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 +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 -lregister -lge_common \ + -lplatform -lqos_manager -LIBS= -L $(SPDLOG_ROOT)/lib -l:libspdlog.a \ - -L $(DEPEND_DIR) -lvpt_det_vdec -lsycheck -lface_det_vdec -lhs_tri_process -lhs_truck_process -lhs_motor_process\ - -L $(OPENCV_ROOT)/lib -lopencv_world\ - -L $(JSON_ROOT)/lib -ljsoncpp \ - -L $(FFMPEG_ROOT)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \ - -L $(RABBITMQ_CLIENT_ROOT)/lib/aarch64-linux-gnu -lrabbitmq \ +LIBS= -L $(FFMPEG_ROOT)/lib -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice \ 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 -SRCS:=$(wildcard $(SRC_ROOT)/ai_platform/*.cpp) \ - $(wildcard $(SRC_ROOT)/decoder/interface/*.cpp) \ +SRCS:=$(wildcard $(SRC_ROOT)/decoder/interface/*.cpp) \ $(wildcard $(SRC_ROOT)/decoder/dvpp/*.cpp) \ - $(wildcard $(SRC_ROOT)/ai_engine_module/sort/*.cpp) \ - $(wildcard $(SRC_ROOT)/ai_engine_module/*.cpp) \ - $(wildcard $(SRC_ROOT)/util/*.cpp) \ - $(wildcard $(SRC_ROOT)/reprocessing_module/*.cpp) \ - $(wildcard $(SRC_ROOT)/reprocessing_module/rbmq/*.cpp) \ $(wildcard $(SRC_ROOT)/decoder/*.cpp) \ OBJS = $(patsubst %.cpp, %.o, $(notdir $(SRCS))) @@ -69,24 +56,6 @@ $(TARGET):$(OBJS) %.o:$(SRC_ROOT)/decoder/interface/%.cpp $(XX) $(CXXFLAGS) -c $< -%.o:$(SRC_ROOT)/ai_platform/%.cpp - $(XX) $(CXXFLAGS) -c $< - -%.o:$(SRC_ROOT)/ai_engine_module/sort/%.cpp - $(XX) $(CXXFLAGS) -c $< - -%.o:$(SRC_ROOT)/ai_engine_module/%.cpp - $(XX) $(CXXFLAGS) -c $< - -%.o:$(SRC_ROOT)/util/%.cpp - $(XX) $(CXXFLAGS) -c $< - -%.o:$(SRC_ROOT)/reprocessing_module/%.cpp - $(XX) $(CXXFLAGS) -c $< - -%.o:$(SRC_ROOT)/reprocessing_module/rbmq/%.cpp - $(XX) $(CXXFLAGS) -c $< - %.o:$(SRC_ROOT)/decoder/%.cpp $(XX) $(CXXFLAGS) -c $< diff --git a/src/decoder/dvpp/DvppDecoder.cpp b/src/decoder/dvpp/DvppDecoder.cpp index e1ea7fb..96e0bfb 100755 --- a/src/decoder/dvpp/DvppDecoder.cpp +++ b/src/decoder/dvpp/DvppDecoder.cpp @@ -2,6 +2,17 @@ #include "DvppSourceManager.h" +#define CHECK_AND_RETURN(ret, message) \ + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return ret;} +#define CHECK_NOT_RETURN(ret, message) \ + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message);} +#define CHECK_AND_RETURN_NOVALUE(ret, message) \ + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return;} +#define CHECK_AND_BREAK(ret, message) \ + if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); break;} + + + struct Vdec_CallBack_UserData { uint64_t frameId; unsigned long long frame_nb; @@ -15,6 +26,36 @@ struct Vdec_CallBack_UserData { } }; + +static long get_cur_time_ms() { + chrono::time_point tpMicro + = chrono::time_point_cast(chrono::system_clock::now()); + return tpMicro.time_since_epoch().count(); +} + +static void *ReportThd(void *arg) +{ + DvppDecoder *self = (DvppDecoder *)arg; + if(nullptr != self){ + self->doProcessReport(); + } + return (void *)0; +} + +static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData) +{ + Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData; + if(nullptr != userData){ + DvppDecoder* self = userData->self; + if(self != nullptr){ + self->doVdppVdecCallBack(input, output, userData->frame_nb); + } + delete userData; + userData = nullptr; + } +} + + DvppDecoder::DvppDecoder(){ m_read_thread = 0; m_cached_mem = nullptr; @@ -137,6 +178,12 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ break; } + int enType = getVdecType(codecpar->codec_id, codecpar->profile); + if(-1 == enType) { + break; + } + m_enType = static_cast(enType); + int ret = av_bsf_alloc(filter, &h264bsfc); if (ret < 0){ break; @@ -148,7 +195,14 @@ 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); + // 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; + } #ifdef USE_VILLAGE bool bRet = m_recoderManager.init(stream, avctx); @@ -169,28 +223,51 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ return nullptr; } +int DvppDecoder::getVdecType(int videoType, int profile) +{ + int streamFormat = H264_MAIN_LEVEL; + + // VDEC only support H265 main level,264 baseline level,main level,high level + if (videoType == AV_CODEC_ID_HEVC) { + streamFormat = H265_MAIN_LEVEL; + } else if (videoType == AV_CODEC_ID_H264) { + switch (profile) { + case FF_PROFILE_H264_BASELINE: + streamFormat = H264_BASELINE_LEVEL; + break; + case FF_PROFILE_H264_MAIN: + streamFormat = H264_MAIN_LEVEL; + break; + case FF_PROFILE_H264_HIGH: + case FF_PROFILE_H264_HIGH_10: + case FF_PROFILE_H264_HIGH_10_INTRA: + case FF_PROFILE_H264_MULTIVIEW_HIGH: + case FF_PROFILE_H264_HIGH_422: + case FF_PROFILE_H264_HIGH_422_INTRA: + case FF_PROFILE_H264_STEREO_HIGH: + case FF_PROFILE_H264_HIGH_444: + case FF_PROFILE_H264_HIGH_444_PREDICTIVE: + case FF_PROFILE_H264_HIGH_444_INTRA: + streamFormat = H264_HIGH_LEVEL; + break; + default: + LOG_INFO("Not support h264 profile {}, use as mp", profile); + streamFormat = H264_MAIN_LEVEL; + break; + } + } else { + streamFormat = -1; + LOG_ERROR("Not support stream, type {}, profile {}", videoType, profile); + } + + return streamFormat; +} + bool DvppDecoder::init_vdpp(FFDecConfig cfg, AVCodecContext* avctx) { LOG_INFO("[{}]- Init device start...", m_dec_name); m_dvpp_deviceId = atoi(cfg.gpuid.c_str()); - - if(avctx->codec_id == AV_CODEC_ID_H264){ - // 66:Baseline,77:Main,>=100:High - if(avctx->profile == 77){ - enType = H264_MAIN_LEVEL; - }else if(avctx->profile < 77){ - enType = H264_BASELINE_LEVEL; - }else{ - enType = H264_HIGH_LEVEL; - } - }else if(avctx->codec_id == AV_CODEC_ID_HEVC){ - // h265只有main - enType = H265_MAIN_LEVEL; - }else { - LOG_ERROR("[{}]- codec_id is not supported!", m_dec_name); - return false; - } post_decoded_cbk = cfg.post_decoded_cbk; @@ -214,7 +291,7 @@ AVCodecContext* DvppDecoder::init_FFmpeg(FFDecConfig config){ LOG_ERROR("[{}]-该设备channel已经用完了!", m_dec_name); return false; } - m_vdec_out_size = avctx->width * avctx->height * 3 / 2; + m_vdec_out_size = frame_width * frame_height * 3 / 2; LOG_INFO("[{}]- init vdpp success! device:{} channel:{}", m_dec_name, m_dvpp_deviceId, m_dvpp_channel); return true; @@ -332,136 +409,252 @@ void DvppDecoder::release_ffmpeg() { void DvppDecoder::read_thread() { - int frame_count = 0; int ret = -1; - pthread_t m_decode_thread; - pthread_create(&m_decode_thread,0, + m_bExitReportThd = false; + pthread_t report_thread; + ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this); + if(ret != 0){ + LOG_ERROR("[{}]- pthread_create failed", m_dec_name); + return; + } + + m_bExitDisplayThd = false; + pthread_t display_thread; + pthread_create(&display_thread,0, [](void* arg) { DvppDecoder* a=(DvppDecoder*)arg; - a->decode_thread(); + a->display_thread(); return (void*)0; } ,this); - AVPacket* pkt = nullptr; - unsigned long long frame_nb = 0; - while (m_bRunning){ - if (!m_bReal){ - if (m_bPause){ - std::this_thread::sleep_for(std::chrono::milliseconds(3)); - continue; - } - } - - m_pktQueue_mutex.lock(); - if(m_pktQueue.size() > 10){ - m_pktQueue_mutex.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - continue; + + aclrtContext ctx = nullptr; + aclrtStream stream = nullptr; + aclvdecChannelDesc *vdecChannelDesc = nullptr; + + do { + CHECK_AND_BREAK(aclrtSetDevice(m_dvpp_deviceId), "aclrtSetDevice failed"); + CHECK_AND_BREAK(aclrtCreateContext(&ctx, m_dvpp_deviceId), "aclrtCreateContext failed"); + CHECK_AND_BREAK(aclrtCreateStream(&stream), "aclrtCreateStream failed"); + + vdecChannelDesc = aclvdecCreateChannelDesc(); + if (vdecChannelDesc == nullptr) { + LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name); + break; } - m_pktQueue_mutex.unlock(); - pkt = av_packet_alloc(); - av_init_packet( pkt ); + // 创建 channel dec结构体 + // 通道ID在dvpp层面为0~31 + CHECK_AND_BREAK(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed"); + CHECK_AND_BREAK(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed"); + CHECK_AND_BREAK(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed"); + CHECK_AND_BREAK(aclvdecSetChannelDescEnType(vdecChannelDesc, m_enType), "aclvdecSetChannelDescEnType failed"); + CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed"); + CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed"); + + AVPacket* pkt = nullptr; + unsigned long long frame_nb = 0; + while (m_bRunning){ - int result = av_read_frame(fmt_ctx, pkt); - if (result == AVERROR_EOF || result < 0){ - av_packet_free(&pkt); - pkt = nullptr; - LOG_ERROR("[{}]- Failed to read frame!", m_dec_name); - break; - } + if (!m_bReal){ + if (m_bPause){ + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + continue; + } - if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) { - av_packet_free(&pkt); - pkt = nullptr; - continue; - } + // 非实时流,即为文件情形,因为不存在花屏问题,为保证不丢帧,这里做个循环等待 + m_decoded_data_queue_mtx.lock(); + if(m_decoded_data_queue.size() > 5){ + m_decoded_data_queue_mtx.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + continue; + } + m_decoded_data_queue_mtx.unlock(); + } + + pkt = av_packet_alloc(); + av_init_packet( pkt ); - if (video_index == pkt->stream_index){ + int result = av_read_frame(fmt_ctx, pkt); + if (result == AVERROR_EOF || result < 0){ + av_packet_free(&pkt); + pkt = nullptr; + LOG_WARN("[{}]- Failed to read frame!", m_dec_name); + break; + } - ret = av_bsf_send_packet(h264bsfc, pkt); - if(ret < 0) { - LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name); + if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) { av_packet_free(&pkt); pkt = nullptr; continue; } - bool bPushed = false; - while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) { - if(pkt->size > g_pkt_size){ - LOG_ERROR("[{}]- pkt size 大于最大预设值!", m_dec_name); - break; - } + if (video_index == pkt->stream_index){ - if(!m_bRunning){ - break; - } + 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; + continue; + } - frame_nb++; -#ifdef USE_VILLAGE - m_recoderManager.cache_pkt(pkt, frame_nb); -#endif + 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; + } - m_pktQueue_mutex.lock(); - DataPacket* data_pkt = new DataPacket(); - data_pkt->pkt = pkt; - data_pkt->frame_nb = frame_nb; - m_pktQueue.push(data_pkt); - m_pktQueue_mutex.unlock(); + if(!m_bRunning){ + break; + } - bPushed = true; - frame_count++; - } + frame_nb++; + #ifdef USE_VILLAGE + m_recoderManager.cache_pkt(pkt, frame_nb); + #endif + nSended = sendPkt(vdecChannelDesc, pkt, frame_nb); + } - if(!bPushed){ - av_packet_free(&pkt); - pkt = nullptr; - } - } else { - // 音频等其他分量的情形 - av_packet_free(&pkt); + if(nSended < 0) { + break; + } + } + + // 音频等其他分量的情形 + av_packet_free(&pkt); pkt = nullptr; - } - } + } + + while(m_bRunning && m_decoded_data_queue.size() > 0) { + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + } + + } while (0); + + if (vdecChannelDesc) { + sendVdecEos(vdecChannelDesc); + + CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed"); + CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed"); + vdecChannelDesc = nullptr; + } m_bRunning=false; - if(m_decode_thread != 0){ - pthread_join(m_decode_thread,0); - } + m_bExitReportThd = true; + 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"); - m_pktQueue_mutex.lock(); - while(m_pktQueue.size() > 0){ - DataPacket* data_pkt = m_pktQueue.front(); - delete data_pkt; - data_pkt = nullptr; - m_pktQueue.pop(); + if(stream){ + CHECK_NOT_RETURN(aclrtDestroyStream(stream), "aclrtDestroyStream failed"); } - m_pktQueue_mutex.unlock(); - if(decode_finished_cbk) { - decode_finished_cbk(m_finishedDecArg); + if (ctx){ + CHECK_NOT_RETURN(aclrtDestroyContext(ctx), "aclrtDestroyContext failed"); } + m_recoderManager.close(); + + release_ffmpeg(); + release_dvpp(); + + m_bFinished = true; LOG_INFO("[{}]- read thread exit.", m_dec_name); - m_bFinished = true; - release_ffmpeg(); + + if(decode_finished_cbk) { + decode_finished_cbk(m_finishedDecArg); + } } -static void *ReportThd(void *arg) -{ - DvppDecoder *self = (DvppDecoder *)arg; - if(nullptr != self){ - self->doProcessReport(); - } - return (void *)0; +int DvppDecoder::sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb){ + + void *vdecInputbuf = nullptr; + void *vdecOutputBuf = nullptr; + acldvppStreamDesc *input_stream_desc = nullptr; + acldvppPicDesc *output_pic_desc = nullptr; + do{ + int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size); + if(ACL_ERROR_NONE != ret){ + LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret); + break; + } + + ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE); + if(ACL_ERROR_NONE != ret){ + LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name); + break; + } + + ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size); + if(ret != ACL_ERROR_NONE){ + LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name); + break; + } + + input_stream_desc = acldvppCreateStreamDesc(); + if (input_stream_desc == nullptr) { + LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name); + break; + } + output_pic_desc = acldvppCreatePicDesc(); + if (output_pic_desc == nullptr) { + LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name); + break; + } + CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed"); + CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed"); + CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed"); + CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed"); + + Vdec_CallBack_UserData *user_data = NULL; + user_data = new Vdec_CallBack_UserData; + user_data->frameId = frame_nb; + user_data->frame_nb = frame_nb; + // user_data->startTime = startTime; + user_data->sendTime = UtilTools::get_cur_time_ms(); + user_data->self = this; + + 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); + delete user_data; + user_data = nullptr; + return 1; + } + + return 0; + }while (0); + + if (vdecInputbuf){ + acldvppFree(vdecInputbuf); + vdecInputbuf = nullptr; + } + + // 报错情形 + if(input_stream_desc){ + CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed"); + } + + if (vdecOutputBuf){ + acldvppFree(vdecOutputBuf); + vdecOutputBuf = nullptr; + } + + if(output_pic_desc){ + CHECK_NOT_RETURN(acldvppDestroyPicDesc(output_pic_desc), "acldvppDestroyPicDesc failed"); + } + + return -1; } void DvppDecoder::doProcessReport(){ @@ -481,9 +674,6 @@ void DvppDecoder::doProcessReport(){ return ; } - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(ctx), "aclrtSetCurrentContext failed"); - // 阻塞等待vdec线程开始 - while (!m_bExitReportThd) { aclrtProcessReport(1000); } @@ -495,40 +685,14 @@ void DvppDecoder::doProcessReport(){ LOG_INFO("doProcessReport exit."); } -static void VdecCallback(acldvppStreamDesc *input, acldvppPicDesc *output, void *pUserData) -{ - Vdec_CallBack_UserData *userData = (Vdec_CallBack_UserData *) pUserData; - if(nullptr != userData){ - DvppDecoder* self = userData->self; - if(self != nullptr){ - - self->doVdppVdecCallBack(input, output, userData->frame_nb); - } - delete userData; - userData = nullptr; - } -} - - -static long get_cur_time_ms() { - chrono::time_point tpMicro - = chrono::time_point_cast(chrono::system_clock::now()); - return tpMicro.time_since_epoch().count(); -} - void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *output, unsigned long long frame_nb){ - m_vdecQueue_mutex.lock(); - if(m_vdecQueue.size() > 0){ - void* inputData = m_vdecQueue.front(); - acldvppFree(inputData); - inputData = nullptr; - m_vdecQueue.pop(); - } - m_vdecQueue_mutex.unlock(); + CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed"); - CHECK_AND_RETURN_NOVALUE(aclrtSetCurrentContext(m_context), "aclrtSetCurrentContext failed"); + void *inputDataDev = acldvppGetStreamDescData(input); + acldvppFree(inputDataDev); + inputDataDev = nullptr; void *outputDataDev = acldvppGetPicDescData(output); uint32_t outputSize = acldvppGetPicDescSize(output); @@ -547,35 +711,16 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o } bool bCached = false; - if(width > 0 && height > 0 && outputSize > 0){ - if (!m_bReal) { - while(m_bRunning) { - // 非实时流,即为文件情形,因为不存在花屏问题,为保证不丢帧,这里做个循环等待 - m_decoded_data_queue_mtx.lock(); - if(m_decoded_data_queue.size() > 5){ - m_decoded_data_queue_mtx.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - continue; - } - m_decoded_data_queue_mtx.unlock(); - break; - } - } - // cout << m_dec_name << " 解码时间间隔: " << get_cur_time_ms() - last_ts << endl; // last_ts = get_cur_time_ms(); // 换成解码后数据, 这里这样做的是为了保证解码一直持续进行,避免后续操作阻碍文件读取和解码从而导致花屏 - m_decoded_data_queue_mtx.lock(); - 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); - bCached = true; - } + 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); + bCached = true; } - m_decoded_data_queue_mtx.unlock(); if(m_bSnapShoting){ // 缓存snapshot @@ -604,246 +749,6 @@ void DvppDecoder::doVdppVdecCallBack(acldvppStreamDesc *input, acldvppPicDesc *o CHECK_AND_RETURN_NOVALUE(acldvppDestroyPicDesc(output), "acldvppDestroyPicDesc failed"); } -void DvppDecoder::decode_thread(){ - - long startTime = UtilTools::get_cur_time_ms(); - - int ret = -1; - - m_bExitReportThd = false; - pthread_t report_thread; - ret = pthread_create(&report_thread, nullptr, ReportThd, (void *)this); - if(ret != 0){ - LOG_ERROR("[{}]- pthread_create failed", m_dec_name); - return; - } - - pthread_t display_thread; - pthread_create(&display_thread,0, - [](void* arg) - { - DvppDecoder* a=(DvppDecoder*)arg; - a->display_thread(); - return (void*)0; - } - ,this); - - aclrtSetDevice(m_dvpp_deviceId); - aclrtContext ctx; - ret = aclrtCreateContext(&ctx, m_dvpp_deviceId); - if (ret != ACL_ERROR_NONE) { - // cout << "aclrtCreateContext failed " << endl; - LOG_ERROR("aclrtCreateContext failed !"); - return ; - } - - // 创建aclvdecChannelDesc类型的数据 - aclvdecChannelDesc *vdecChannelDesc = aclvdecCreateChannelDesc(); - if (vdecChannelDesc == nullptr) { - LOG_ERROR("[{}]- aclvdecCreateChannelDesc failed", m_dec_name); - return; - } - do{ - // 创建 channel dec结构体 - // 通道ID在dvpp层面为0~31 - CHECK_AND_BREAK(aclvdecSetChannelDescChannelId(vdecChannelDesc, m_dvpp_channel), "aclvdecSetChannelDescChannelId failed"); - CHECK_AND_BREAK(aclvdecSetChannelDescThreadId(vdecChannelDesc, report_thread), "aclvdecSetChannelDescThreadId failed"); - CHECK_AND_BREAK(aclvdecSetChannelDescCallback(vdecChannelDesc, VdecCallback), "aclvdecSetChannelDescCallback failed"); - CHECK_AND_BREAK(aclvdecSetChannelDescEnType(vdecChannelDesc, enType), "aclvdecSetChannelDescEnType failed"); - CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed"); - CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed"); - - uint64_t frame_count = 0; - bool bBreak = false; - while (m_bRunning) { - if (m_bPause){ - std::this_thread::sleep_for(std::chrono::milliseconds(3)); - continue; - } - int ret = sentFrame(vdecChannelDesc, frame_count); - if(ret == 2){ - bBreak = true; - break; - }else if(ret == 1){ - continue; - } - - frame_count++; - } - - // 尽量保证数据全部解码完成 - int sum = 0; - if(!bBreak){ - aclrtSetDevice(m_dvpp_deviceId); - aclrtSetCurrentContext(ctx); - while(m_pktQueue.size() > 0){ - int ret = sentFrame(vdecChannelDesc, frame_count); - if(ret == 2){ - break; - } - std::this_thread::sleep_for(std::chrono::milliseconds(3)); - sum++; - if(sum > 40){ - // 避免卡死 - break; - } - } - } - - sendVdecEos(vdecChannelDesc); - - CHECK_NOT_RETURN(aclvdecDestroyChannel(vdecChannelDesc), "aclvdecDestroyChannel failed"); - }while(0); - - CHECK_NOT_RETURN(aclvdecDestroyChannelDesc(vdecChannelDesc), "aclvdecDestroyChannelDesc failed"); - - // report_thread 需后于destroy退出 - m_bRunning = false; - m_bExitReportThd = true; - CHECK_NOT_RETURN(pthread_join(report_thread, nullptr), "pthread_join failed"); - CHECK_NOT_RETURN(pthread_join(display_thread, nullptr), "pthread_join failed"); - - // 最后清理一遍未解码的数据 - m_vdecQueue_mutex.lock(); - if(m_vdecQueue.size() > 0){ - void* inputData = m_vdecQueue.front(); - acldvppFree(inputData); - inputData = nullptr; - m_vdecQueue.pop(); - } - m_vdecQueue_mutex.unlock(); - - release_dvpp(); - - ret = aclrtDestroyContext(ctx); - if(ret != ACL_ERROR_NONE){ - LOG_ERROR("aclrtDestroyContext failed !"); - } - - LOG_INFO("[{}]- decode thread exit.", m_dec_name); -} - -int DvppDecoder::sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count){ - - // 此处需要判断 m_vdecQueue 队列长度,避免占用过多显存 - m_vdecQueue_mutex.lock(); - if(m_vdecQueue.size() > 20){ - m_vdecQueue_mutex.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - return 1; - } - m_vdecQueue_mutex.unlock(); - - DataPacket * data_pkt = nullptr; - m_pktQueue_mutex.lock(); - if(m_pktQueue.size() <= 0){ - m_pktQueue_mutex.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - return 1; - } - data_pkt = m_pktQueue.front(); - m_pktQueue.pop(); - m_pktQueue_mutex.unlock(); - - // 解码 - void *vdecInputbuf = nullptr; - int ret = acldvppMalloc((void **)&vdecInputbuf, g_pkt_size); - if(ACL_ERROR_NONE != ret){ - LOG_ERROR("[{}]- acldvppMalloc failed!, ret:{}", m_dec_name, ret); - delete data_pkt; - data_pkt = nullptr; - return 2; - } - - AVPacket* pkt = data_pkt->pkt; - ret = aclrtMemcpy(vdecInputbuf, pkt->size, pkt->data, pkt->size, ACL_MEMCPY_HOST_TO_DEVICE); - if(ACL_ERROR_NONE != ret){ - LOG_ERROR("[{}]- aclrtMemcpy failed", m_dec_name); - delete data_pkt; - data_pkt = nullptr; - return 2; - } - - void *vdecOutputBuf = nullptr; - ret = acldvppMalloc((void **)&vdecOutputBuf, m_vdec_out_size); - if(ret != ACL_ERROR_NONE){ - LOG_ERROR("[{}]- acldvppMalloc failed", m_dec_name); - delete data_pkt; - data_pkt = nullptr; - return 2; - } - - acldvppStreamDesc *input_stream_desc = nullptr; - acldvppPicDesc *output_pic_desc = nullptr; - do{ - input_stream_desc = acldvppCreateStreamDesc(); - if (input_stream_desc == nullptr) { - LOG_ERROR("[{}]- acldvppCreateStreamDesc failed", m_dec_name); - break; - } - output_pic_desc = acldvppCreatePicDesc(); - if (output_pic_desc == nullptr) { - LOG_ERROR("[{}]- acldvppCreatePicDesc failed", m_dec_name); - break; - } - CHECK_AND_BREAK(acldvppSetStreamDescData(input_stream_desc, vdecInputbuf), "acldvppSetStreamDescData failed"); - CHECK_AND_BREAK(acldvppSetStreamDescSize(input_stream_desc, pkt->size), "acldvppSetStreamDescSize failed"); - CHECK_AND_BREAK(acldvppSetPicDescData(output_pic_desc, vdecOutputBuf), "acldvppSetPicDescData failed"); - CHECK_AND_BREAK(acldvppSetPicDescSize(output_pic_desc, m_vdec_out_size), "acldvppSetPicDescSize failed"); - - Vdec_CallBack_UserData *user_data = NULL; - user_data = new Vdec_CallBack_UserData; - user_data->frameId = frame_count; - user_data->frame_nb = data_pkt->frame_nb; - // user_data->startTime = startTime; - user_data->sendTime = UtilTools::get_cur_time_ms(); - user_data->self = this; - - m_vdecQueue_mutex.lock(); - ret = aclvdecSendFrame(vdecChannelDesc, input_stream_desc, output_pic_desc, nullptr, reinterpret_cast(user_data)); - delete data_pkt; - data_pkt = nullptr; - if(ret != ACL_ERROR_NONE){ - LOG_ERROR("[{}]- aclvdecSendFrame failed", m_dec_name); - m_vdecQueue_mutex.unlock(); - delete user_data; - user_data = nullptr; - break; - } - - m_vdecQueue.push(vdecInputbuf); - m_vdecQueue_mutex.unlock(); - - return 0; - }while (0); - - if(data_pkt != nullptr){ - delete data_pkt; - data_pkt = nullptr; - } - - if (vdecInputbuf){ - acldvppFree(vdecInputbuf); - vdecInputbuf = nullptr; - } - - // 报错情形 - if(input_stream_desc){ - CHECK_NOT_RETURN(acldvppDestroyStreamDesc(input_stream_desc), "acldvppDestroyStreamDesc failed"); - } - - if (vdecOutputBuf){ - acldvppFree(vdecOutputBuf); - vdecOutputBuf = nullptr; - } - - if(output_pic_desc){ - CHECK_NOT_RETURN(acldvppDestroyPicDesc(output_pic_desc), "acldvppDestroyPicDesc failed"); - } - - return 1; -} - bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) { // create stream desc acldvppStreamDesc *streamInputDesc = acldvppCreateStreamDesc(); @@ -872,7 +777,7 @@ bool DvppDecoder::sendVdecEos(aclvdecChannelDesc *vdecChannelDesc) { void DvppDecoder::display_thread(){ LOG_INFO("[{}]- display_thread start...", m_dec_name); - while(m_bRunning) { + while(!m_bExitDisplayThd) { m_decoded_data_queue_mtx.lock(); if(m_decoded_data_queue.size() <= 0) { m_decoded_data_queue_mtx.unlock(); @@ -898,7 +803,7 @@ void DvppDecoder::display_thread(){ mem = nullptr; } - LOG_INFO("[{}]- display_thread end.", m_dec_name); + LOG_INFO("[{}]- display_thread exit.", m_dec_name); } void DvppDecoder::release_dvpp(){ diff --git a/src/decoder/dvpp/DvppDecoder.h b/src/decoder/dvpp/DvppDecoder.h index 6a3e7c8..c16ec55 100755 --- a/src/decoder/dvpp/DvppDecoder.h +++ b/src/decoder/dvpp/DvppDecoder.h @@ -66,13 +66,14 @@ private: void release_ffmpeg(); void read_thread(); - void decode_thread(); - int sentFrame(aclvdecChannelDesc *vdecChannelDesc, uint64_t frame_count); + int sendPkt(aclvdecChannelDesc *vdecChannelDesc, AVPacket* pkt, unsigned long long frame_nb); bool sendVdecEos(aclvdecChannelDesc *vdecChannelDesc); void release_dvpp(); void display_thread(); + int getVdecType(int videoType, int profile); + private: FFDecConfig m_cfg; string m_dec_name; @@ -84,6 +85,7 @@ private: bool m_bRunning{false}; bool m_bPause{false}; bool m_bExitReportThd{false}; + bool m_bExitDisplayThd{false}; // 读取数据 AVStream* stream{nullptr}; @@ -102,17 +104,11 @@ private: bool m_dec_keyframe; - mutex m_pktQueue_mutex; - queue m_pktQueue; - // 解码 int m_dvpp_deviceId {-1}; int m_dvpp_channel {-1}; aclrtContext m_context{nullptr}; - acldvppStreamFormat enType; - - mutex m_vdecQueue_mutex; - queue m_vdecQueue; + acldvppStreamFormat m_enType; const void * m_postDecArg; POST_DECODE_CALLBACK post_decoded_cbk {nullptr}; diff --git a/src/decoder/dvpp/VpcPicConverter.cpp b/src/decoder/dvpp/VpcPicConverter.cpp index c06c215..9913e65 100755 --- a/src/decoder/dvpp/VpcPicConverter.cpp +++ b/src/decoder/dvpp/VpcPicConverter.cpp @@ -3,6 +3,15 @@ #define ALIGN_UP(val, align) (((val) % (align) == 0) ? (val) : (((val) / (align) + 1) * (align))) +#define CHECK_AND_RETURN(ret, message) \ + if(ret != 0) {LOG_ERROR("{}", message); return ret;} +#define CHECK_NOT_RETURN(ret, message) \ + if(ret != 0) {LOG_ERROR("{}", message);} +#define CHECK_AND_RETURN_NOVALUE(ret, message) \ + if(ret != 0) {LOG_ERROR("{}", message); return;} +#define CHECK_AND_BREAK(ret, message) \ + if(ret != 0) {LOG_ERROR("{}", message); break;} + VpcPicConverter::VpcPicConverter(){ } diff --git a/src/decoder/dvpp/dvpp_headers.h b/src/decoder/dvpp/dvpp_headers.h index 3d981af..85a80c5 100755 --- a/src/decoder/dvpp/dvpp_headers.h +++ b/src/decoder/dvpp/dvpp_headers.h @@ -26,15 +26,6 @@ #include "acl/acl.h" #include "acl/ops/acl_dvpp.h" - -#define CHECK_AND_RETURN(ret, message) \ - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return ret;} -#define CHECK_NOT_RETURN(ret, message) \ - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message);} -#define CHECK_AND_RETURN_NOVALUE(ret, message) \ - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); return;} -#define CHECK_AND_BREAK(ret, message) \ - if(ret != 0) {LOG_ERROR("[{}]- {}", m_dec_name, message); break;} #endif diff --git a/src/decoder/test_decoder.cpp b/src/decoder/test_decoder.cpp new file mode 100644 index 0000000..bc91df2 --- /dev/null +++ b/src/decoder/test_decoder.cpp @@ -0,0 +1,153 @@ +#include "./interface/DecoderManager.h" +#include +#include +#include + +using namespace std; + +struct decode_cbk_userdata{ + string task_id; + void* opaque; + void* opaque1; +}; + +deque m_RgbDataList; +mutex m_DataListMtx; + +thread* m_pAlgorthimThread{nullptr}; + +bool m_bfinish{false}; +int m_devId = 0; +const char* task_id = "test0"; +int skip_frame_ = 5; +int m_batch_size = 20; + + +void algorthim_process_thread(); + +void post_decod_cbk(const void * userPtr, DeviceMemory* devFrame){ + do{ + if(m_bfinish){ + break; + } + m_DataListMtx.lock(); + if(m_RgbDataList.size() >= 30){ + m_DataListMtx.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + continue; + } + m_RgbDataList.push_back(devFrame); + m_DataListMtx.unlock(); + break; + }while (true); +} + +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; +} + +int main(){ + + // 创建解码任务 + DecoderManager* pDecManager = DecoderManager::getInstance(); + + MgrDecConfig config; + config.name = task_id; + config.cfg.uri = "/data/share/data/Street.uvf"; + config.cfg.post_decoded_cbk = post_decod_cbk; + config.cfg.decode_finished_cbk = decode_finished_cbk; + config.cfg.force_tcp = true; // rtsp用tcp + config.cfg.gpuid = to_string(m_devId); + config.cfg.skip_frame = skip_frame_; + + config.dec_type = DECODER_TYPE_DVPP; + + AbstractDecoder* dec = pDecManager->createDecoder(config); + if (!dec){ + printf("创建解码器失败 \n"); + 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); + + + int input_image_width = 0; + int input_image_height = 0; + pDecManager->getResolution(config.name, input_image_width, input_image_height); + + + // 创建算法线程 + m_pAlgorthimThread = new thread([](void* arg) { + algorthim_process_thread(); + return (void*)0; + } + , nullptr); + + pDecManager->startDecodeByName(config.name); + + while (getchar() != 'q'); +} + +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()); + } +} + +void algorthim_process_thread(){ + + while (true){ + if(m_bfinish){ + break; + } + + vector vec_gpuMem; + m_DataListMtx.lock(); + while (!m_RgbDataList.empty()){ + DeviceMemory* gpuMem = m_RgbDataList.front(); + if(gpuMem->getMem() == nullptr){ + // 错误数据,直接删除 + delete gpuMem; + gpuMem = nullptr; + printf("mem is null \n"); + } else { + vec_gpuMem.push_back(gpuMem); + } + m_RgbDataList.pop_front(); + if(vec_gpuMem.size() >= m_batch_size){ + break; + } + } + m_DataListMtx.unlock(); + + if(vec_gpuMem.size() <= 0){ + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + continue; + } + + // do work + do_work(vec_gpuMem); + + for(int i=0;i < vec_gpuMem.size(); i++){ + DeviceMemory* mem = vec_gpuMem[i]; + if(mem->getSize() <= 0){ + continue; + } + delete mem; + mem = nullptr; + } + vec_gpuMem.clear(); + + } + + printf("algorthim_process_thread exit. \n"); +} \ No newline at end of file diff --git a/src/decoder/test_recoder.cpp0 b/src/decoder/test_recoder.cpp0 new file mode 100644 index 0000000..d373aa8 --- /dev/null +++ b/src/decoder/test_recoder.cpp0 @@ -0,0 +1,248 @@ +#include "./interface/DecoderManager.h" +#include +#include +#include + +using namespace std; + +struct decode_cbk_userdata{ + string task_id; + void* opaque; + void* opaque1; +}; + +deque m_RgbDataList; +mutex m_DataListMtx; + +thread* m_pAlgorthimThread{nullptr}; +thread* m_recodeThread{nullptr}; +bool m_bfinish{false}; +int m_devId = 0; +const char* task_id = "test0"; +int skip_frame_ = 5; +int m_batch_size = 20; + +deque m_recoderinfo_queue; +mutex m_recoderinfo_queue_mtx; + +void algorthim_process_thread(); +void recode_thread(); +void algorthim_face_detect(vector vec_gpuMem); + +void test_recode_thread(); + +void post_decod_cbk(const void * userPtr, DeviceMemory* devFrame){ + do{ + if(m_bfinish){ + break; + } + m_DataListMtx.lock(); + if(m_RgbDataList.size() >= 30){ + m_DataListMtx.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + continue; + } + m_RgbDataList.push_back(devFrame); + m_DataListMtx.unlock(); + break; + }while (true); +} + +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; +} + +int main(){ + + // 创建解码任务 + DecoderManager* pDecManager = DecoderManager::getInstance(); + + MgrDecConfig config; + config.name = task_id; + config.cfg.uri = "/opt/cmhu/data/公安局老桥头_CVR15F89410_1465819864_1B.mp4"; + config.cfg.post_decoded_cbk = post_decod_cbk; + config.cfg.decode_finished_cbk = decode_finished_cbk; + config.cfg.force_tcp = true; // rtsp用tcp + config.cfg.gpuid = to_string(m_devId); + config.cfg.skip_frame = skip_frame_; + + config.dec_type = DECODER_TYPE_DVPP; + + AbstractDecoder* dec = pDecManager->createDecoder(config); + if (!dec){ + printf("创建解码器失败 \n"); + 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); + + + int input_image_width = 0; + int input_image_height = 0; + pDecManager->getResolution(config.name, input_image_width, input_image_height); + + + // 创建算法线程 + m_pAlgorthimThread = new thread([](void* arg) { + algorthim_process_thread(); + return (void*)0; + } + , nullptr); + + // m_recodeThread = new thread([](void* arg) { + // recode_thread(); + // return (void*)0; + // } + // , nullptr); + + m_recodeThread = new thread([](void* arg) { + test_recode_thread(); + return (void*)0; + } + , nullptr); + + pDecManager->startDecodeByName(config.name); + + while (getchar() != 'q'); +} + +void algorthim_process_thread(){ + + while (true){ + if(m_bfinish){ + break; + } + + vector vec_gpuMem; + m_DataListMtx.lock(); + while (!m_RgbDataList.empty()){ + DeviceMemory* gpuMem = m_RgbDataList.front(); + if(gpuMem->getMem() == nullptr){ + // 错误数据,直接删除 + delete gpuMem; + gpuMem = nullptr; + printf("mem is null \n"); + } else { + vec_gpuMem.push_back(gpuMem); + } + m_RgbDataList.pop_front(); + if(vec_gpuMem.size() >= m_batch_size){ + break; + } + } + m_DataListMtx.unlock(); + + if(vec_gpuMem.size() <= 0){ + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + continue; + } + + algorthim_face_detect(vec_gpuMem); + + for(int i=0;i < vec_gpuMem.size(); i++){ + DeviceMemory* mem = vec_gpuMem[i]; + if(mem->getSize() <= 0){ + continue; + } + delete mem; + mem = nullptr; + } + vec_gpuMem.clear(); + + } + + printf("algorthim_process_thread exit. \n"); +} + +static int interval = 0; +static int obj_id = 0; + +void algorthim_face_detect(vector vec_gpuMem) { + interval ++ ; + + if(interval % 50 != 0) { + return; + } + + for(int i= 0; i < vec_gpuMem.size(); i++) { + DeviceMemory* mem = vec_gpuMem[i]; + string task_id = mem->getId(); + + RecoderInfo recoderInfo; + recoderInfo.task_id = task_id; + recoderInfo.object_id = std::to_string(obj_id); + recoderInfo.recoderPath = "./res/recode"; + recoderInfo.frame_nb = mem->getFrameNb(); + + m_recoderinfo_queue_mtx.lock(); + m_recoderinfo_queue.push_back(recoderInfo); + m_recoderinfo_queue_mtx.unlock(); + + obj_id++; + + } +} + +void test_recode_thread() { + unsigned long long frame_index = 0; + while(true) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + DeviceMemory* mem = nullptr; + m_DataListMtx.lock(); + while (!m_RgbDataList.empty()){ + DeviceMemory* gpuMem = m_RgbDataList.front(); + if(gpuMem->getMem() == nullptr){ + // 错误数据,直接删除 + delete gpuMem; + gpuMem = nullptr; + printf("mem is null \n"); + } else { + frame_index ++ ; + if (frame_index % 50 == 0) { + RecoderInfo recoderInfo; + recoderInfo.task_id = gpuMem->getId(); + recoderInfo.object_id = std::to_string(obj_id); + recoderInfo.recoderPath = "./res/recode"; + recoderInfo.frame_nb = gpuMem->getFrameNb(); + + DecoderManager* pDecManager = DecoderManager::getInstance(); + pDecManager->doRecode(recoderInfo); + + obj_id++; + } + delete gpuMem; + gpuMem = nullptr; + } + m_RgbDataList.pop_front(); + } + m_DataListMtx.unlock(); + } +} + +void recode_thread() { + while(true) { + + m_recoderinfo_queue_mtx.lock(); + if(m_recoderinfo_queue.size() <= 0) { + m_recoderinfo_queue_mtx.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + continue; + } + + RecoderInfo info = m_recoderinfo_queue.front(); + m_recoderinfo_queue.pop_front(); + m_recoderinfo_queue_mtx.unlock(); + + DecoderManager* pDecManager = DecoderManager::getInstance(); + pDecManager->doRecode(info); + } +} \ No newline at end of file