#include "AbstractDecoder.h" #include "logger.hpp" #include "GpuRgbMemory.hpp" #include "cuda_kernels.h" #include "utiltools.hpp" FFImgInfo* AbstractDecoder::snapshot(){ // 锁住停止队列消耗 std::lock_guard l(m_snapshot_mutex); AVFrame * gpuFrame = nullptr; bool bFirst = true; while(true){ m_queue_mutex.lock(); if(mFrameQueue.size() <= 0){ m_queue_mutex.unlock(); if(bFirst){ std::this_thread::sleep_for(std::chrono::milliseconds(100)); bFirst = false; continue; }else{ // 再进来说明前面已经等了 100 ms // 100 ms都没有等到解码数据,则退出 return nullptr; } } // 队列中数据大于1 gpuFrame = mFrameQueue.front(); m_queue_mutex.unlock(); break; } if (gpuFrame != nullptr && gpuFrame->format == AV_PIX_FMT_CUDA ){ LOG_DEBUG("decode task: gpuid: {} width: {} height: {}", m_cfg.gpuid, gpuFrame->width, gpuFrame->height); GpuRgbMemory* gpuMem = new GpuRgbMemory(3, gpuFrame->width, gpuFrame->height, getName(), m_cfg.gpuid , true); if (gpuMem->getMem() == nullptr){ LOG_ERROR("new GpuRgbMemory failed !!!"); return nullptr; } cudaSetDevice(atoi(m_cfg.gpuid.c_str())); cuda_common::setColorSpace( ITU_709, 0 ); cudaError_t cudaStatus = cuda_common::CUDAToBGR((CUdeviceptr)gpuFrame->data[0],(CUdeviceptr)gpuFrame->data[1], gpuFrame->linesize[0], gpuFrame->linesize[1], gpuMem->getMem(), gpuFrame->width, gpuFrame->height); cudaDeviceSynchronize(); if (cudaStatus != cudaSuccess) { LOG_ERROR("CUDAToBGR failed failed !!!"); return nullptr; } unsigned char * pHwRgb = gpuMem->getMem(); int channel = gpuMem->getChannel(); int width = gpuMem->getWidth(); int height = gpuMem->getHeight(); if (pHwRgb != nullptr && channel > 0 && width > 0 && height > 0){ int nSize = channel * height * width; LOG_INFO("channel:{} height:{} width:{}", channel, height, width); // unsigned char* cpu_data = new unsigned char[nSize]; unsigned char* cpu_data = (unsigned char *)av_malloc(nSize * sizeof(unsigned char)); cudaMemcpy(cpu_data, pHwRgb, nSize * sizeof(unsigned char), cudaMemcpyDeviceToHost); cudaDeviceSynchronize(); delete gpuMem; gpuMem = nullptr; FFImgInfo* imgInfo = new FFImgInfo(); imgInfo->dec_name = m_dec_name; imgInfo->pData = cpu_data; imgInfo->height = height; imgInfo->width = width; imgInfo->timestamp = UtilTools::get_cur_time_ms(); imgInfo->index = m_index; m_index++; return imgInfo; } delete gpuMem; gpuMem = nullptr; } return nullptr; } bool AbstractDecoder::isSnapTime(){ if(m_snap_time_interval <= 0){ return false; } long cur_time = UtilTools::get_cur_time_ms(); if(cur_time - m_last_snap_time > m_snap_time_interval){ return true; } return false; } void AbstractDecoder::updateLastSnapTime(){ m_last_snap_time = UtilTools::get_cur_time_ms(); } void AbstractDecoder::setSnapTimeInterval(long interval){ m_snap_time_interval = interval; m_last_snap_time = UtilTools::get_cur_time_ms(); }