#include "AbstractDecoder.h" #include "logger.hpp" #include "GpuRgbMemory.hpp" #include "cuda_kernels.h" #include static long get_cur_time() { chrono::time_point tpMicro = chrono::time_point_cast(chrono::system_clock::now()); return tpMicro.time_since_epoch().count(); } FFImgInfo* AbstractDecoder::snapshot(){ // 锁住停止队列消耗 std::lock_guard l(m_snapshot_mutex); AVFrame * gpuFrame = nullptr; bool bFirst = true; while(true){ m_queue_mutex.lock(); LOG_DEBUG("decode task:{} queue_size: {}", getName(), mFrameQueue.size()); 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* frame = mFrameQueue.front(); gpuFrame = frame->gpuFrame; m_queue_mutex.unlock(); break; } if (gpuFrame != nullptr && gpuFrame->format == AV_PIX_FMT_CUDA ){ LOG_DEBUG("decode task:{} gpuid: {} width: {} height: {}", getName(), 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 !!!"); delete gpuMem; gpuMem = nullptr; 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 = get_cur_time(); 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 = get_cur_time(); if(cur_time - m_last_snap_time > m_snap_time_interval){ return true; } return false; } void AbstractDecoder::updateLastSnapTime(){ m_last_snap_time = get_cur_time(); } void AbstractDecoder::setSnapTimeInterval(long interval){ m_snap_time_interval = interval; m_last_snap_time = get_cur_time(); }