| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 | 
							- #include "CVideoDecoder.h"
 
- #include <Windows.h>
 
- extern "C"
 
- {
 
- #include "libavcodec/avcodec.h"
 
- #include "libavformat/avformat.h"
 
- #include "libswscale/swscale.h"
 
- #include "libavdevice/avdevice.h"
 
- #include "libavutil/opt.h"
 
- #include "libavfilter/avfilter.h"
 
- #include "libavfilter/buffersrc.h"
 
- #include "libavfilter/buffersink.h"
 
- #include "libavutil/imgutils.h"
 
- #include "libavutil/frame.h"
 
- };
 
- #include "CVideoDataManager.h"
 
- #include "../Include/libyuv.h"
 
- #include "FusionAndTailor.cuh"
 
- CVideoDecoder::CVideoDecoder(AVCodecContext* pDecoder, bool bHard, CVideoDataManager* pDataManager)
 
- {
 
- 	m_pDecoder = pDecoder;
 
- 	m_pDataManager = pDataManager;
 
- 	m_bHard = bHard;
 
- 	m_pDataManager->SetDecodeDataSize(m_pDecoder->width* m_pDecoder->height*3/2);
 
- 	_beginthreadex(nullptr, 0, &CVideoDecoder::DecodeThread, this, 0, 0);
 
- 	
 
- 	CUstream Cur = ((CUstream)pCuStream);
 
- 	cudaError Err = cudaStreamCreate(&(Cur));
 
- 	pCuStream = Cur;
 
- }
 
- CVideoDecoder::~CVideoDecoder()
 
- {
 
- 	if (m_pDecoder != nullptr)
 
- 	{
 
- 		avcodec_close(m_pDecoder);
 
- 		m_pDecoder = nullptr;
 
- 	}
 
- }
 
- unsigned __stdcall CVideoDecoder::DecodeThread(void* param)
 
- {
 
- 	CVideoDecoder* pThis = (CVideoDecoder*)param;
 
- 	pThis->DecodeProcessor();
 
- 	return 0;
 
- }
 
- void CVideoDecoder::DecodeProcessor()
 
- {
 
- 	while (true)
 
- 	{
 
- 		//if (m_pDataManager->GetSyncDataSize() > 0)
 
- 		{
 
- 			CPacketInfo* pPack = nullptr;
 
- 			if (m_pDataManager->GetSyncData(pPack))
 
- 			{
 
- 				uint8_t* pData = nullptr;
 
- 				DecodePacket(pPack->m_pPkt, pData);
 
- 				//DecodePacketGpu(pPack->m_pPkt, pData);
 
- 				m_pDataManager->AddDecoderData(pData, pPack->m_dPtzAngle);
 
- 				m_pDataManager->ReleaseSyncData(pPack);
 
- 			} 
 
- 		}
 
- 		Sleep(5);
 
- 	}
 
- }
 
- bool CVideoDecoder::DecodePacket(AVPacket* pkt, unsigned char* & pData)
 
- {
 
- 	int nRet = 0;
 
- 	AVFrame* tmp_frame = nullptr;
 
- 	avcodec_send_packet(m_pDecoder, pkt);
 
- 	AVFrame* pFrame = av_frame_alloc();
 
- 	nRet = avcodec_receive_frame(m_pDecoder, pFrame);
 
- 	
 
- 	pData = new unsigned char[pFrame->linesize[0] * pFrame->height *3];
 
- 	if (m_bHard)
 
- 	{
 
- 		// 如果采用的硬件加速剂,则调用avcodec_receive_frame()函数后,解码后的数据还在GPU中,所以需要通过此函数
 
- 		// 将GPU中的数据转移到CPU中来
 
- 		tmp_frame = av_frame_alloc();
 
- 		if (av_hwframe_transfer_data(tmp_frame, pFrame, 0) < 0)
 
- 		{
 
- 			return false;
 
- 		}
 
- 		if (pFrame != nullptr)
 
- 		{
 
- 			av_frame_free(&pFrame);
 
- 			pFrame = nullptr;
 
- 		}
 
- 		pFrame = tmp_frame;
 
- 		
 
- 		//libyuv::NV12ToI420(
 
- 		//	pFrame->data[0], pFrame->linesize[0],
 
- 		//	pFrame->data[1], pFrame->linesize[1],
 
- 		//	pData, pFrame->width,
 
- 		//	pData + pFrame->width * pFrame->height, pFrame->width / 2,
 
- 		//	pData + pFrame->width * pFrame->height * 5 / 4, pFrame->width / 2,
 
- 		//	pFrame->width, pFrame->height
 
- 		//);
 
- 		libyuv::NV12ToRGB24(
 
- 			pFrame->data[0], pFrame->linesize[0],
 
- 			pFrame->data[1], pFrame->linesize[1],
 
- 			pData, pFrame->width * 3,
 
- 			pFrame->width, pFrame->height
 
- 		);
 
- 	}
 
- 	else
 
- 	{
 
- 		int dst_stride_y2 = pFrame->width;
 
- 		int dst_stride_u2 = dst_stride_y2 / 2;
 
- 		int dst_stride_v2 = dst_stride_y2 / 2;
 
- 		
 
- 		libyuv::I420Copy(pFrame->data[0], pFrame->linesize[0], pFrame->data[1], pFrame->linesize[1], pFrame->data[2], pFrame->linesize[2],
 
- 			pData, pFrame->width, pData + pFrame->width * pFrame->height, pFrame->width/2, pData + pFrame->width * pFrame->height * 5 / 4, pFrame->width / 2,
 
- 			pFrame->width, pFrame->height);
 
- 	}
 
- 	
 
- 	//cv::Mat mat(pFrame->height * 3 / 2, pFrame->width, CV_8UC1, pData);
 
- 	av_frame_free(&pFrame);
 
- 	pFrame = nullptr;
 
- 	return true;
 
- }
 
- //注意该函数返回的指针指向的是显存数据,
 
- bool CVideoDecoder::DecodePacketGpu(AVPacket* pkt, unsigned char*& pData)
 
- {
 
- 	int nRet = 0;
 
- 	AVFrame* tmp_frame = nullptr;
 
- 	avcodec_send_packet(m_pDecoder, pkt);
 
- 	AVFrame* pFrame = av_frame_alloc();
 
- 	nRet = avcodec_receive_frame(m_pDecoder, pFrame);
 
- 	pFrame->format = AV_PIX_FMT_NV12;
 
- 	CUstream CurStream = (CUstream)pCuStream;
 
- 	if (m_pI420 == nullptr)
 
- 	{
 
- 		cudaMalloc(&m_pI420, pFrame->width * pFrame->height * 3 / 2);
 
- 		YUVTailorAndBlender::setColorSpace2(0);
 
- 	}
 
- 	
 
- 	YUVTailorAndBlender::TurnCUDAFormatToI420(pFrame->data[0], pFrame->data[1], 
 
- 		pFrame->linesize[0], pFrame->linesize[1], m_pI420, pFrame->width, pFrame->height, &CurStream);
 
- 	cudaError err = cudaDeviceSynchronize();
 
- 	if (pData != nullptr)
 
- 		cudaFree(pData);
 
- 	cudaMalloc((void**)&pData, pFrame->width * pFrame->height * 3 / 2);
 
- 	cudaMemcpy(pData,m_pI420 , pFrame->width * pFrame->height * 3 / 2, cudaMemcpyDeviceToDevice);
 
- 	//下载
 
- 	//cudaMemcpy(pData, m_pI420, pFrame->width * pFrame->height * 3/2, cudaMemcpyDeviceToHost);
 
- 	//FILE* file = fopen("111.yuv", "wb"); //已只读方式打开
 
- 	//fwrite(pData, 1, pFrame->height * pFrame->width, file); //写入操作
 
- 	//fwrite(pData + pFrame->height* pFrame->width, 1, pFrame->height * pFrame->width/4, file); //写入操作
 
- 	//fwrite(pData + pFrame->height * pFrame->width*5/4, 1, pFrame->height * pFrame->width/4, file); //写入操作
 
- 	//fclose(file);
 
- 	av_frame_free(&pFrame);
 
- 	return false;
 
- }
 
 
  |