AbstractDecoder.cpp 2.98 KB
#include "AbstractDecoder.h"

#include "logger.hpp"
#include "GpuRgbMemory.hpp"
#include "cuda_kernels.h"

#include "utiltools.hpp"


FFImgInfo* AbstractDecoder::snapshot(){

	// 锁住停止队列消耗
	std::lock_guard<std::mutex> 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();
}