//#include "LOG_manager.h" #include #include "DvppGB28181Decoder2.h" #include "common_header.h" #define ECLOSED 0 #define ECLOSING 1 #define ERUNNING 2 #define EPAUSE 3 #define EINITED 4 static void RTP_Stream_CallBack(void* userdata, uint8_t* buf, int buf_size, uint64_t pts) { DvppGB28181Decoder2* decoder = (DvppGB28181Decoder2*)userdata; decoder->stream_callback(buf, buf_size, pts); } static void RTP_Stream_End_CallBack(void* userdata) { DvppGB28181Decoder2* decoder = (DvppGB28181Decoder2*)userdata; decoder->stream_end_callback(); } DvppGB28181Decoder2::DvppGB28181Decoder2() { m_frameSkip = 1; m_dec_keyframe = false; m_post_decode_thread = 0; } DvppGB28181Decoder2::~DvppGB28181Decoder2() { close(); m_dec_keyframe = false; LOG_INFO("destroy OK--{}", m_dec_name); } void DvppGB28181Decoder2::close(){ if (m_status == ECLOSED) return; m_status = ECLOSING; LOG_DEBUG("real decode thread exit success 1--{}", m_dec_name); if(nullptr != m_rtpPtr){ if (m_rtpPtr->IsOpened()) { m_rtpPtr->Close(); LOG_DEBUG("real decode thread exit success 2--{}", m_dec_name); } delete m_rtpPtr; m_rtpPtr = nullptr; } if (m_post_decode_thread != 0) { pthread_join(m_post_decode_thread,0); m_post_decode_thread = 0; } rtpDecoder.Close(); m_status = ECLOSED; LOG_INFO("解码器关闭成功 --{}", m_dec_name); } bool DvppGB28181Decoder2::init(FFDecConfig& cfg){ m_rtpPtr = new RTPReceiver2(); if(nullptr == m_rtpPtr){ return false; } m_dec_name = cfg.dec_name; m_frameSkip = cfg.skip_frame; if (m_frameSkip < 1) m_frameSkip = 1; m_gpuid = atoi(cfg.gpuid.c_str()); m_rtpPtr->SetOutputCallback(RTP_Stream_CallBack, this); m_rtpPtr->SetVodEndCallback(RTP_Stream_End_CallBack, this); post_decoded_cbk = cfg.post_decoded_cbk; decode_finished_cbk = cfg.decode_finished_cbk; if (!rtpDecoder.Init(cfg)) { return false; } m_cfg = cfg; LOG_INFO("init - {} ", m_dec_name); m_status = EINITED; return true; } bool DvppGB28181Decoder2::start() { m_status = ERUNNING; bool bRet = m_rtpPtr->Open(m_cfg.uri, !m_cfg.force_tcp); if(bRet && rtpDecoder.start()) { pthread_create(&m_post_decode_thread,0, [](void* arg) { DvppGB28181Decoder2* a=(DvppGB28181Decoder2*)arg; a->display_thread(); return (void*)0; } ,this); return true; } close(); LOG_ERROR("[{}] - rtp receiver open failed !", m_dec_name); return false; } void DvppGB28181Decoder2::setDecKeyframe(bool bKeyframe){ m_dec_keyframe = bKeyframe; } void DvppGB28181Decoder2::stream_callback(uint8_t* buf, int buf_size, uint64_t pts) { if (m_status == EPAUSE) return; // 若设置为关键帧解码,非关键帧数据直接返回 // if(m_dec_keyframe && !isKey) return; rtpDecoder.CacheBuffer(buf, buf_size); } void DvppGB28181Decoder2::display_thread(){ int index = 0; while (isRunning()) { auto mem = rtpDecoder.GetFrame(); if(mem) { if ((m_frameSkip == 1 || index % m_frameSkip == 0) && post_decoded_cbk){ post_decoded_cbk(m_postDecArg, mem); } else { delete mem; mem = nullptr; } index++; if(index >= 100000){ index = 0; } } std::this_thread::sleep_for(std::chrono::milliseconds(10)); } LOG_INFO("[{}] - display thread exited.", m_dec_name); } void DvppGB28181Decoder2::stream_end_callback() { LOG_INFO("[{}] - stream end.", m_dec_name); m_status = ECLOSING; decode_finished_cbk(m_finishedDecArg); return; } void DvppGB28181Decoder2::setPostDecArg(const void* postDecArg){ m_postDecArg = postDecArg; } void DvppGB28181Decoder2::setFinishedDecArg(const void* finishedDecArg){ m_finishedDecArg = finishedDecArg; } void DvppGB28181Decoder2::pause() { m_status = EPAUSE; LOG_INFO("[{}] - pause", m_dec_name); } void DvppGB28181Decoder2::resume() { m_status = ERUNNING; LOG_INFO("[{}] - resume", m_dec_name); } bool DvppGB28181Decoder2::isRunning(){ if (m_status == ECLOSED || m_status == ECLOSING){ return false; } return true; } bool DvppGB28181Decoder2::isFinished(){ if (m_status == ECLOSED || m_status == ECLOSING){ return true; } return false; } bool DvppGB28181Decoder2::isPausing(){ if (m_status == EPAUSE){ return true; } return false; } bool DvppGB28181Decoder2::getResolution( int &width, int &height ){ width = frameW; height = frameH; return true; } bool DvppGB28181Decoder2::getOutResolution( int &width, int &height ) { width = frameW; height = frameH; return true; } float DvppGB28181Decoder2::fps() { return m_fps; } bool DvppGB28181Decoder2::isSurport(FFDecConfig& cfg){ // 由于是否支持需要在拿到数据后才能断定,无法事先判断,所以这个地方默认返回true return true; } DeviceMemory* DvppGB28181Decoder2::snapshot() { DeviceMemory* snapshot_mem = nullptr; int loop_times = 0; while (isRunning()) { snapshot_mem = rtpDecoder.GetFrame(); if (snapshot_mem) { break; } loop_times++; if(loop_times > 100) { // 1s都没截取到图,退出 break; } std::this_thread::sleep_for(std::chrono::milliseconds(10)); } return snapshot_mem; } void DvppGB28181Decoder2::doRecode(RecoderInfo& recoderInfo) { return rtpDecoder.doRecode(recoderInfo); } void DvppGB28181Decoder2::set_mq_callback(std::function mq_publish) { rtpDecoder.set_mq_callback(mq_publish); }