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;
- }
|