Train_Identify/nvidia_ascend_engine/nvidia_engine/DecodeEngine/VideoDecodeEngine.cpp

166 lines
6.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 视频流解码引擎
* */
#include "VideoDecodeEngine.h"
using namespace std;
using namespace cv;
using namespace ai_matrix;
VideoDecodeEngine::VideoDecodeEngine() {}
VideoDecodeEngine::~VideoDecodeEngine() {}
APP_ERROR VideoDecodeEngine::Init()
{
bUseEngine_ = true;
dataSourceConfig_ = MyYaml::GetIns()->GetDataSourceConfigById(engineId_); // 获取摄像机参数
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
if (MyYaml::GetIns()->GetStringValue("gc_data_source") != "camera" || !dataSourceConfig_.bUse)
{
bUseEngine_ = false;
LogWarn << "engineId_:" << engineId_ << " not use engine";
return APP_ERR_OK;
}
LogInfo << "VideoDecodeEngine Init ok";
return APP_ERR_OK;
}
APP_ERROR VideoDecodeEngine::DeInit()
{
if (!bUseEngine_)
{
LogWarn << "engineId_:" << engineId_ << " not use engine";
return APP_ERR_OK;
}
if (hard_h264_ffmpeg_decoder_ != nullptr)
{
hard_h264_ffmpeg_decoder_->HardH264FFmpegDecoderDeInit();
delete hard_h264_ffmpeg_decoder_;
hard_h264_ffmpeg_decoder_ = nullptr;
}
LogInfo << "VideoDecodeEngine DeInit ok";
return APP_ERR_OK;
}
APP_ERROR VideoDecodeEngine::Process()
{
if (!bUseEngine_)
{
LogWarn << "engineId_:" << engineId_ << " not use engine";
return APP_ERR_OK;
}
int iRet = APP_ERR_OK;
int iSkipCount = 1;
int iNoCameraDataCnt = 0;
while (!isStop_)
{
//从上一引擎接收图像数据
std::shared_ptr<void> pVoidData0 = nullptr;
inputQueMap_[strPort0_]->pop(pVoidData0);
if (nullptr == pVoidData0)
{
usleep(10*1000); //10ms
// iNoCameraDataCnt++;
// if (iNoCameraDataCnt >= 1000) //10秒内收不到认为相机断开
// {
// LogError << "engineId:" << engineId_ << " 超过10秒获取到摄像头数据疑似摄像头断开。计数" << iNoCameraDataCnt;
// iNoCameraDataCnt = 0;
// //camera异常时构造空的解码数据push确保一直有数据流转到后面Engine
// std::shared_ptr<ProcessData> pProcessData = std::make_shared<ProcessData>();
// pProcessData->iDataSource = engineId_;
// pProcessData->i64TimeStamp = MyUtils::getins()->GetCurrentTimeMillis();
// pProcessData->iSize = 0;
// pProcessData->pData = nullptr;
// iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pProcessData));
// }
continue;
}
iNoCameraDataCnt = 0;
std::shared_ptr<ProcessData> pProcessData = std::static_pointer_cast<ProcessData>(pVoidData0);
//创建解码类
if (hard_h264_ffmpeg_decoder_ == nullptr)
{
hard_h264_ffmpeg_decoder_ = new HardH264FFmpegDecode;
int iRet = hard_h264_ffmpeg_decoder_->HardH264FFmpegDecoderInit(pProcessData->iWidth, pProcessData->iHeight, pProcessData->iRate);
if (iRet != 0)
{
LogError << "engineId:" << engineId_ << " HardH264FFmpegDecoderInit Failed";
if (hard_h264_ffmpeg_decoder_ != nullptr)
{
delete hard_h264_ffmpeg_decoder_;
hard_h264_ffmpeg_decoder_ = nullptr;
}
continue;
}
}
//构造YUV420M数据
unsigned int pYUV420MBuffer_Size = pProcessData->iWidth * pProcessData->iHeight * 3 / 2;
void *pYUV420MBuffer = nullptr;
pYUV420MBuffer = new uint8_t[pYUV420MBuffer_Size];
std::shared_ptr<void> pYUVData;
pYUVData.reset(pYUV420MBuffer, [](void *data){if(data) {delete[] data; data = nullptr;}}); //智能指针管理内存
hard_h264_ffmpeg_decoder_->pPacket_->data = static_cast<uint8_t *>(pProcessData->pData.get()); //这里填入一个指向完整H264数据帧的指针
hard_h264_ffmpeg_decoder_->pPacket_->size = pProcessData->iSize; //这个填入H264数据帧的大小
// H264硬件解码
// int iDecodeRet= hard_h264_ffmpeg_decoder_->HardH264FFmpegDecoderV2(hard_h264_ffmpeg_decoder_->pCodecCtx_, hard_h264_ffmpeg_decoder_->pFrame_,
// hard_h264_ffmpeg_decoder_->pPacket_, pYUV420MBuffer, &pYUV420MBuffer_Size);
int iDecodeRet = hard_h264_ffmpeg_decoder_->HardH264FFmpegDecoderV2(hard_h264_ffmpeg_decoder_->pCodecCtx_,
hard_h264_ffmpeg_decoder_->pSwsContext_,
hard_h264_ffmpeg_decoder_->pSrcFrame_,
hard_h264_ffmpeg_decoder_->pDstFrame_,
hard_h264_ffmpeg_decoder_->pPacket_,
pYUV420MBuffer,
&pYUV420MBuffer_Size);
if (iDecodeRet > 0)
{
if (iSkipCount++ % dataSourceConfig_.iSkipInterval != 0)
{
continue;
}
iSkipCount = 1;
//硬解码YUV转BGR
cv::Mat matYUV(pProcessData->iHeight * 3 / 2, pProcessData->iWidth, CV_8UC1);
memcpy(matYUV.data, static_cast<uint8_t *>(pYUVData.get()), pYUV420MBuffer_Size);
cv::Mat matBGR(pProcessData->iHeight, pProcessData->iWidth, CV_8UC3);
cv::cvtColor(matYUV, matBGR, cv::COLOR_YUV2BGR_I420);
cv::resize(matBGR, matBGR, cv::Size(IMAGE_WIDTH, IMAGE_HEIGHT));
unsigned int iResizeSize = IMAGE_WIDTH * IMAGE_HEIGHT * 3;
void *pResizeBGRBuffer = nullptr;
pResizeBGRBuffer = new uint8_t[iResizeSize];
memcpy(pResizeBGRBuffer, matBGR.data, iResizeSize);
pProcessData->pData.reset(pResizeBGRBuffer, [](void *data) {if(data) {delete[] data; data = nullptr;} });
pProcessData->iSize = iResizeSize;
pProcessData->iWidth = IMAGE_WIDTH;
pProcessData->iHeight = IMAGE_HEIGHT;
iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pProcessData));
if (iRet != APP_ERR_OK)
{
LogError << "push the after hard h264 decode yuv420m frame data failed...";
}
}
else
{
LogError << "engineId:" << engineId_ << " HardH264FFmpegDecoderV2 failed...iDecodeRet:" << iDecodeRet;
}
}
}