#include "DxDecoderWrap.h" #include #include #include "logger.hpp" void decoded_cbk(const void * userPtr, GPUFrame * gpuFrame){ DxDecoderWrap* _this = (DxDecoderWrap*)userPtr; if(nullptr != _this){ _this->post_decode_thread(gpuFrame); } } void decode_finished_cbk(const void * userPtr){ DxDecoderWrap* _this = (DxDecoderWrap*)userPtr; if(nullptr != _this){ _this->decode_finished_thread(); } } DxDecoderWrap::DxDecoderWrap( const DxConfig * cfg ) { m_bClose = false; m_pDec = nullptr; m_pHwData = nullptr; m_cfg.post_decoded_cbk = decoded_cbk; m_cfg.decode_finished_cbk = decode_finished_cbk; m_cfg.force_tcp = cfg->forceTcp; // rtsp用tcp m_cfg.gpuid = std::to_string(cfg->devId); m_name = cfg->name; m_decMode = cfg->decMode; CUdevice cuDevice; cuDeviceGet(&cuDevice, cfg->devId); cuCtxCreate(&m_cuda_cxt, 0, cuDevice); return; } DxDecoderWrap::~DxDecoderWrap() { DxCloseDecoder(); return; } int DxDecoderWrap::DxOpenDecoder( const char * uri, unsigned int skip ) { int ret = 0; m_pDec = new FFNvDecoder(); if ( nullptr == m_pDec ) { return -1; } m_cfg.uri = uri; m_cfg.skip_frame = skip; bool bRet= m_pDec->init(m_cfg); if (bRet) { m_pDec->setName(m_name) ; m_pDec->m_postDecArg = this; m_pDec->m_finishedDecArg = this; if(1 == m_decMode) { m_pDec->setDecKeyframe(true); } m_pDec->start(); LOG_INFO("[{}][{}]- 解码器初始化成功", m_name.c_str(), uri); return 0; } // 创建失败,关闭解码器 m_pDec->close(); delete m_pDec; m_pDec = nullptr; LOG_ERROR("[{}][{}]- 解码器初始化失败!", m_name.c_str(), uri); return -1; } int DxDecoderWrap::DxCloseDecoder() { m_bClose = true; if(m_pDec) { m_pDec->close(); delete m_pDec; m_pDec = nullptr; } m_queue_frames_mutex.lock(); while (m_queue_frames.size() > 0) { GPUFrame * decodedFrame = m_queue_frames.front(); m_queue_frames.pop(); delete decodedFrame; decodedFrame = nullptr; } m_queue_frames_mutex.unlock(); if(m_pHwData != nullptr){ cudaFree(m_pHwData); } cuCtxPopCurrent(nullptr); cuCtxDestroy(m_cuda_cxt); return 0; } int DxDecoderWrap::DxGetResolution( int &width, int &height ) { if(m_pDec) { m_pDec->getResolution(width, height); return 0; } return -1; } int DxDecoderWrap::DxGetFrameCount() { if(m_pDec != nullptr){ return m_pDec->GetFrameCount(); } return -1; } int DxDecoderWrap::PauseDecoder() { if(m_pDec) { m_pDec->pause(); } return 0; } int DxDecoderWrap::ResumeDecoder() { if(m_pDec) { m_pDec->resume(); } return 0; } bool DxDecoderWrap::DxDecoderIsRun() const { if(m_pDec) { return m_pDec->isRunning(); } return false; } bool DxDecoderWrap::DxFrameIsEmpty() { m_queue_frames_mutex.lock(); int count = m_queue_frames.size(); m_queue_frames_mutex.unlock(); return 0 == count; } int DxDecoderWrap::DxLockFrame( DxGPUFrame * frame ) { if ( NULL == frame ) { return -1; } std::lock_guard l(m_queue_frames_mutex); if(m_queue_frames.size() <= 0) { return -1; } GPUFrame * decodedFrame = m_queue_frames.front(); m_queue_frames.pop(); AVFrame* gpuFrame = decodedFrame->gpuFrame; cudaSetDevice(atoi(m_cfg.gpuid.c_str())); cuCtxPushCurrent(m_cuda_cxt); cudaError_t cudaStatus; size_t rgbSize = 3 * gpuFrame->width * gpuFrame->height * sizeof(unsigned char); if(m_pHwData == nullptr){ cudaStatus = cudaMalloc((void **)&m_pHwData, rgbSize); if (cudaStatus != cudaSuccess) { LOG_ERROR("[{}]- cudaMalloc failed !!!", m_name.c_str()); cuCtxPopCurrent(&m_cuda_cxt); return -1; } } cuda_common::setColorSpace( ITU_709, 0 ); cudaStatus = cuda_common::CUDAToBGR((CUdeviceptr)gpuFrame->data[0],(CUdeviceptr)gpuFrame->data[1], gpuFrame->linesize[0], gpuFrame->linesize[1], m_pHwData, gpuFrame->width, gpuFrame->height); cuCtxPopCurrent(&m_cuda_cxt); if (cudaStatus != cudaSuccess) { LOG_ERROR("[{}]- CUDAToBGR failed !!!", m_name.c_str()); return -1; } frame->width = gpuFrame->width; frame->height = gpuFrame->height; frame->size = rgbSize; frame->frame = m_pHwData; frame->timestamp = decodedFrame->ts; delete decodedFrame; decodedFrame = nullptr; return 0; } void DxDecoderWrap::post_decode_thread(GPUFrame * decodedFrame) { while(!m_bClose) { m_queue_frames_mutex.lock(); if(m_queue_frames.size() < 3) { // 入队 m_queue_frames.push(decodedFrame); m_queue_frames_mutex.unlock(); break; } else { m_queue_frames_mutex.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } } void DxDecoderWrap::decode_finished_thread() { m_bClose = true; }