2024-01-23 02:46:26 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* 视频流解码引擎
|
|
|
|
|
|
* */
|
|
|
|
|
|
|
|
|
|
|
|
#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;
|
2024-05-22 09:25:51 +00:00
|
|
|
|
int iSkipCount = 1;
|
2024-01-23 02:46:26 +00:00
|
|
|
|
int iNoCameraDataCnt = 0;
|
|
|
|
|
|
while (!isStop_)
|
|
|
|
|
|
{
|
|
|
|
|
|
//从上一引擎接收图像数据
|
|
|
|
|
|
std::shared_ptr<void> pVoidData0 = nullptr;
|
|
|
|
|
|
inputQueMap_[strPort0_]->pop(pVoidData0);
|
|
|
|
|
|
if (nullptr == pVoidData0)
|
|
|
|
|
|
{
|
|
|
|
|
|
usleep(10*1000); //10ms
|
|
|
|
|
|
|
2024-05-22 09:25:51 +00:00
|
|
|
|
// 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));
|
|
|
|
|
|
// }
|
2024-01-23 02:46:26 +00:00
|
|
|
|
|
|
|
|
|
|
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;}}); //智能指针管理内存
|
|
|
|
|
|
|
2024-05-22 09:25:51 +00:00
|
|
|
|
hard_h264_ffmpeg_decoder_->pPacket_->data = static_cast<uint8_t *>(pProcessData->pData.get()); //这里填入一个指向完整H264数据帧的指针
|
|
|
|
|
|
hard_h264_ffmpeg_decoder_->pPacket_->size = pProcessData->iSize; //这个填入H264数据帧的大小
|
2024-01-23 02:46:26 +00:00
|
|
|
|
|
|
|
|
|
|
// 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_,
|
2024-05-22 09:25:51 +00:00
|
|
|
|
hard_h264_ffmpeg_decoder_->pSwsContext_,
|
2024-01-23 02:46:26 +00:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|