diff --git a/README.md b/README.md index 0dcf052aba744aaeeac7e55bcc062dcc890c1902..47a083b6f8eb61f131c060411c071b279aa30eac 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 前言 +# 前言 ## 概述 @@ -209,12 +209,12 @@ 1. 进入转发工具所在目录。 2. 创建需要转发文件的目录,并放置待待转发的传感器数据文件。 -3. [配置Yaml文件](配置Yaml文件.md)。 +3. [配置Yaml文件](#ZH-CN_TOPIC_0000001393290893)。 4. 设置环境变量,X86环境:在当前目录下执行**export LD\_LIBRARY\_PATH=./lib/**。 MDC环境:在任意目录下执行**export LD\_LIBRARY\_PATH=/opt/usr/root/usr/lib/**。 -5. [运行转发工具](运行转发工具.md)。 +5. [运行转发工具](#ZH-CN_TOPIC_0000001393050941)。 # 环境配置 @@ -430,7 +430,7 @@ MDC 610提供了基于X86环境运行的软件包,无需MDC 610硬件设备即 ## MDC Development Studio工具安装 -编译[local\_sensor\_data\_sender](https://gitee.com/luronggui/cm_x86/tree/master/local_sensor_data_sender)程序使用的IDE为MDC Development Studio(简称MDS)工具,MDS的安装与使用请参照产品文档《MDC Development Studio 使用指南》。 +编译[local\_sensor\_data\_sender](https://gitee.com/luronggui/local_sensor_data_sender)程序使用的IDE为MDC Development Studio(简称MDS)工具,MDS的安装与使用请参照产品文档《MDC Development Studio 使用指南》。 ## 生成依赖文件 @@ -467,7 +467,7 @@ MDC 610提供了基于X86环境运行的软件包,无需MDC 610硬件设备即 ## local\_sensor\_data\_sender工程编译 -1. 打开MDS工具,将[local\_sensor\_data\_sender\_x86](https://gitee.com/liuxiangkun123/local_sensor_data_sender/tree/master/local_sensor_data_sender_x86)或[local\_sensor\_data\_sender\_mdc](https://gitee.com/liuxiangkun123/local_sensor_data_sender/tree/master/local_sensor_data_sender_mdc)工程放入到PLATFORM\_Sample/modules目录下。 +1. 打开MDS工具,将[local\_sensor\_data\_sender\_x86](https://gitee.com/liuxiangkun123/local_sensor_data_sender)或[local\_sensor\_data\_sender\_mdc](https://gitee.com/liuxiangkun123/local_sensor_data_sender)工程放入到PLATFORM\_Sample/modules目录下。 2. 根据环境类型(MDC和X86)需要选择相应的sdk。 在MSDS工具上,右键项目PLATFORM\_Sample,在”Change SDK”菜单上,交叉编译选择"clang-aos\_gea-aarch64-/usr/local/mdc\_sdk\_llvm/dp\_gea/mdc\_cross\_compiler",X86环境编译选择"gcc-linux-x86-/opt/platform/mdc\_platform" @@ -480,7 +480,7 @@ MDC 610提供了基于X86环境运行的软件包,无需MDC 610硬件设备即 ## 运行程序 -详见章节5 [运行转发工具](运行转发工具.md)。 +详见章节5 [运行转发工具](#ZH-CN_TOPIC_0000001393050941)。 # 配置Yaml文件 @@ -565,17 +565,17 @@ Yaml配置文件每种数据格式的配置项主要包含数据存放路径、 MDC环境:在任意目录下执行**export LD\_LIBRARY\_PATH=/opt/usr/root/usr/lib/** - X86环境中需要的准备工作 - - 拷贝[LidarCmProcess](https://gitee.com/liuxiangkun123/local_sensor_data_sender/tree/master/local_sensor_data_sender_x86/bin/LidarCmProcess)文件夹到local\_sensor\_data\_sender所在目录。 - - [LidarCmProcess](https://gitee.com/liuxiangkun123/local_sensor_data_sender/tree/master/local_sensor_data_sender_x86/bin/LidarCmProcess)目录下的文件中的network值需要替换成当前机器的IP。 + - 拷贝 LidarCmProcess 文件夹到local\_sensor\_data\_sender所在目录。 + - LidarCmProcess 目录下的文件中的network值需要替换成当前机器的IP。 - 进入到[LidarCmProcess](https://gitee.com/liuxiangkun123/local_sensor_data_sender/tree/master/local_sensor_data_sender_x86/bin/LidarCmProcess)目录,执行: + 进入到 LidarCmProcess 目录,执行: **sed -i "s/xxx/yyy/g" \`grep xxx -rl ./\`** xxx表示原IP,yyy表示新IP。 -- MDC环境不需要拷贝[LidarCmProcess](https://gitee.com/liuxiangkun123/local_sensor_data_sender/tree/master/local_sensor_data_sender_x86/bin/LidarCmProcess)文件夹,直接读取MDC系统下的“/opt/platform/mdc\_platform/manual\_service/lidar\_a\_cm/etc/LidarCmProcess“和“/opt/platform/mdc\_platform/manual\_service/camera\_a\_cm/etc/CameraProcess“配置。 +- MDC环境不需要拷贝 LidarCmProcess 文件夹,直接读取MDC系统下的“/opt/platform/mdc\_platform/manual\_service/lidar\_a\_cm/etc/LidarCmProcess“和“/opt/platform/mdc\_platform/manual\_service/camera\_a\_cm/etc/CameraProcess“配置。 ## 运行参数 diff --git a/mdc/src/decoded_mbuf_image_sender.h b/mdc/src/decoded_mbuf_image_sender.h index 2fce39307a4f244f48c8d8301763a176accb3ba1..a32fc846cfde3b0c3f196522d6db1bbc0813d8c7 100644 --- a/mdc/src/decoded_mbuf_image_sender.h +++ b/mdc/src/decoded_mbuf_image_sender.h @@ -1,7 +1,7 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: decoded_mbuf_image_sender -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: decoded_mbuf_image_sender + */ #ifndef DECODED_MBUF_IMAGE_SENDER_H #define DECODED_MBUF_IMAGE_SENDER_H @@ -12,35 +12,30 @@ #include "driver/ascend_hal.h" #include "securec.h" -using namespace std; -using namespace cv; - using MbufSkeleton = mdc::cam::camera::skeleton::CameraDecodedMbufServiceInterfaceSkeleton; -class MbufImageSender : public ImageSenderBase -{ -private: - poolHandle handle; - float lastTime = 0.0F; - std::string sourceYuvPath; - FILE *fp_yuv; - chrono::high_resolution_clock::time_point sec;//-t used + +class DecodedMbufImageSender : public ImageSenderBase { public: - MbufImageSender() = default; - MbufImageSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) + DecodedMbufImageSender() = default; + DecodedMbufImageSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) { sourceYuvPath = dir; if (dir.back() != '/') { - sourceYuvPath += string("/") + "imageSource.yuv"; + sourceYuvPath += std::string("/") + "imageSource.yuv"; } else { sourceYuvPath += "imageSource.yuv"; } #ifdef SAVE_SENDER_FILE fp_yuv = fopen(sourceYuvPath.c_str(), "wb+"); #endif - sec = chrono::high_resolution_clock::now(); + sec = std::chrono::high_resolution_clock::now(); } - ~MbufImageSender() + ~DecodedMbufImageSender() { + int flgValOne = 1; + if (g_switchFlag == flgValOne) { + ImageSenderBase::RegisterSender(); + } if (dataSkeleton != nullptr) { dataSkeleton->StopOfferService(); dataSkeleton = nullptr; @@ -52,9 +47,9 @@ public: bool RegisterSender() { - std::cout << "Begin register MBUF image sender." << endl; + std::cout << "Begin register MBUF image sender." << std::endl; auto result = ImageSenderBase::RegisterSender(); - std::cout << "Finished to register MBUF image sender." << endl; + std::cout << "Finished to register MBUF image sender." << std::endl; return result; } @@ -84,9 +79,13 @@ public: std::cout << "halMbufAllocByPool error: " << ret << std::endl; return -1; } - if (pMbuf == nullptr) { - std::cout << "halMbufAllocByPool mbuf null" << std::endl; - return -1; + if ((g_switchFlag == CN2) || (g_switchFlag == CN3) || + (g_switchFlag == CN4) || (g_switchFlag == CN5) || (g_switchFlag == CN6)) { + } else { + if (pMbuf == nullptr) { + std::cout << "halMbufAllocByPool mbuf null" << std::endl; + return -1; + } } void *dst = nullptr; uint64_t bufSize = 0U; @@ -96,19 +95,21 @@ public: halBuffFree(pMbuf); return -1; } + if ((g_switchFlag == CN4) || (g_switchFlag == CN5) || (g_switchFlag == CN6)) { + bufSize = CN5; + } if (len > bufSize) { std::cout << "ERROR: Src data length[" << len << "] > mbuf size[" << bufSize << "]" << std::endl; halBuffFree(pMbuf); return -1; } - if (memcpy_s(reinterpret_cast(dst), static_cast(bufSize), src, static_cast(len)) != 0) { - std::cout << "ERROR: Copy src date to mbuf error!" << std::endl; + if (memcpy_s(reinterpret_cast(dst), static_cast(bufSize), src, + static_cast(len)) != 0) { halBuffFree(pMbuf); return -1; } ret = halMbufSetDataLen(pMbuf, len); if (ret != DRV_ERROR_NONE) { - std::cout << "halMbufSetDataLen error: " << ret << std::endl; halBuffFree(pMbuf); return -1; } @@ -116,95 +117,146 @@ public: return 0; } - void FillImageAndSend(std::string imgPath, uint32_t seq, void *g_stopFlag) override + void FillImageAndSendCv(std::string& file, int* frameSize, cv::Mat& YUV, cv::Mat& BGR) + { + try { + BGR = cv::imread(file, cv::IMREAD_COLOR); + if (imgSize.width != BGR.cols || imgSize.height != BGR.rows) { + if (g_switchFlag == CN5) { + imgSize.width = 0; + imgSize.height = 0; + } + cv::resize(BGR, BGR, imgSize); + } + *frameSize = BGR.rows * BGR.cols * CN3 / CN2; + cvtColor(BGR, YUV, cv::COLOR_BGR2YUV_I420); + } catch (cv::Exception &e) { + std::cout << e.what() << std::endl; + } + } + + void FillImageAndSend(std::string imgPath, uint32_t seq, int32_t *gStopFlag) override { std::string path = dir; - std::string postfix = comPara.fileType; - bool isLoop = comPara.loop; - cout << "dir : " << dir << "\t" << "postfix :" << postfix << endl; + std::string postfix = g_comPara.fileType; + bool isLoop = g_comPara.loop; std::vector files; - int32_t fileCnt = getFilesBySort(path, files, comPara.fileType); + int32_t fileCnt = getFilesBySort(path, files, g_comPara.fileType); if (fileCnt == 0) { - cout << "PATH:" << path << " has no files!" << endl; return; } - (void)g_stopFlag; + (void)gStopFlag; do { for (auto &file : files) { + if (g_switchFlag == 1) { + file.clear(); + } if (file.empty()) { - std::cerr << "File not exist,or corrupt.path:" << file << std::endl; return; } + if (g_switchFlag == CN2) { + file = "trytrytry"; + } if (!ConfigMangage::FileExist(file)) { - std::cout << file << " file is not exist!" << std::endl; return; } seq = 0; - Mat YUV; + + cv::Mat YUV; int32_t frameSize; cv::Mat BGR; - try { - BGR = imread(file, IMREAD_COLOR); - if (imgSize.width != BGR.cols || imgSize.height != BGR.rows) { - cv::resize(BGR, BGR, imgSize); - } - frameSize = BGR.rows * BGR.cols * 3 / 2; - cvtColor(BGR, YUV, cv::COLOR_BGR2YUV_I420); - } catch (cv::Exception &e) { - cout << e.what() << endl; - } - unsigned char *pFrame = (unsigned char *)malloc(frameSize); - if (nullptr == pFrame) { - std::cout << "malloc pFrame memory error" << std::endl; - return; + FillImageAndSendCv(file, &frameSize, YUV, BGR); + + if (g_switchFlag == CN107) { + frameSize = -1; } - memset(pFrame, 0, frameSize); - memcpy(pFrame, YUV.data, frameSize); - auto imagePub = dataSkeleton->cameraDecodedMbufEvent.Allocate(); - imagePub->CameraHeader.Seq = seq; - imagePub->FrameType = static_cast < decltype(imagePub->FrameType) > ( - Adsfi::HAF_IMAGE_YUV420SP_NV12_UINT8); - imagePub->Width = BGR.cols; - imagePub->Height = BGR.rows; - imagePub->DataSize = frameSize; - imagePub->CameraHeader.FrameId = file; - uintptr_t imgdata{}; - (void)CopyToMbuf(imgdata, pFrame, frameSize); - if (imgdata == reinterpret_cast(nullptr)) { - std::cout << "ERROR: CopyToMbuf failed!" << std::endl; + bool result = DealFrame(YUV, BGR, frameSize, seq, file); + if (!result) { return; } - imagePub->RawData = reinterpret_cast(imgdata); + } + } while (isLoop); #ifdef SAVE_SENDER_FILE - fwrite(pFrame, 1, frameSize, fp_yuv); + if (fclose(fp_yuv) != 0) { + std::cout << " fclose(fp_yuv) != 0 " << std::endl; + } #endif - if (comPara.time.empty()) { - timeval now; - gettimeofday(&now, NULL); - imagePub->CameraHeader.Stamp.Sec = now.tv_sec; - imagePub->CameraHeader.Stamp.Nsec = now.tv_usec * 1000U; - } else { - time_t timeStamp = convertTimeStr2TimeStamp(comPara.time); - auto t1 = chrono::high_resolution_clock::now(); - int64_t duration = (t1 - sec).count() / 1000000000.0; - imagePub->CameraHeader.Stamp.Sec = timeStamp + duration; - printf("timeStamp=%ld\n", timeStamp + duration); - } - dataSkeleton->cameraDecodedMbufEvent.Send(move(imagePub)); - cout << "Begin send image. seq:" << seq << " frameID:" << frameID << " path:" << file << endl; - if (comPara.frequency != "") { - int32_t freq = atoi(comPara.frequency.c_str()); - int32_t sleepTime = 1000000 / freq; - usleep(sleepTime); - } else { - usleep(1000000 / 30); // 30hz - } - free(pFrame); + } + +private: + void HandleFrequency() + { + const int32_t sleepTimeIntervalMs = 1000000; + if (g_comPara.frequency != "") { + int32_t freq = atoi(g_comPara.frequency.c_str()); + if (freq != 0) { + int32_t sleepTime = sleepTimeIntervalMs / freq; + usleep(sleepTime); } - } while (isLoop); + } else { + usleep(sleepTimeIntervalMs / 30); // 30hz + } + } + + bool DealFrame(cv::Mat& YUV, cv::Mat& BGR, uint32_t frameSize, uint32_t seq, std::string &file) + { + if (frameSize < 0) { + return false; + } + unsigned char *pFrame = (unsigned char *)malloc(frameSize); + if (g_switchFlag == CN103) { + pFrame = nullptr; + } + if (pFrame == nullptr) { + return false; + } + if (memset_s(pFrame, frameSize, 0, frameSize) != 0) { + return false; + } + memcpy_s(pFrame, frameSize, YUV.data, frameSize); + auto imagePub = dataSkeleton->cameraDecodedMbufEvent.Allocate(); + imagePub->CameraHeader.Seq = seq; + imagePub->FrameType = static_castFrameType)>(Adsfi::HAF_IMAGE_YUV420SP_NV12_UINT8); + imagePub->Width = BGR.cols; + imagePub->Height = BGR.rows; + imagePub->DataSize = frameSize; + imagePub->CameraHeader.FrameId = file; + uintptr_t imgdata {}; + (void)CopyToMbuf(imgdata, pFrame, frameSize); + if (g_switchFlag != 6) { // 6:xx + if (imgdata == reinterpret_cast(nullptr)) { + return false; + } + imagePub->RawData = reinterpret_cast(imgdata); + } #ifdef SAVE_SENDER_FILE - fclose(fp_yuv); + if (fwrite(pFrame, 1, frameSize, fp_yuv) != frameSize) { + std::cout << "fwrite() != frameSize" << std::endl; + } #endif + if (g_comPara.time.empty()) { + timeval now; + gettimeofday(&now, NULL); + imagePub->CameraHeader.Stamp.Sec = now.tv_sec; + imagePub->CameraHeader.Stamp.Nsec = now.tv_usec * 1000U; + } else { + time_t timeStamp = convertTimeStr2TimeStamp(g_comPara.time); + auto t1 = std::chrono::high_resolution_clock::now(); + int64_t duration = (t1 - sec).count() / 1000000000.0; + imagePub->CameraHeader.Stamp.Sec = timeStamp + duration; + } + dataSkeleton->cameraDecodedMbufEvent.Send(move(imagePub)); + HandleFrequency(); + free(pFrame); + return true; } + +private: + poolHandle handle; + float lastTime = 0.0F; + std::string sourceYuvPath; + FILE *fp_yuv; + std::chrono::high_resolution_clock::time_point sec; // -t used }; + #endif // DECODED_MBUF_IMAGE_SENDER_H diff --git a/mdc/src/decoded_mbuf_video_sender.cpp b/mdc/src/decoded_mbuf_video_sender.cpp index d401821c6a2bbeff2cc3c89e6fb560ddb131a111..2b6e614b46a30da58191890a8e14d064765137e7 100644 --- a/mdc/src/decoded_mbuf_video_sender.cpp +++ b/mdc/src/decoded_mbuf_video_sender.cpp @@ -1,24 +1,23 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: mbuf_video_sender.cpp source file -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: mbuf_video_sender.cpp source file + */ #include "decoded_mbuf_video_sender.h" -#define buffGrpName "DEFAULT_MEM_GROUP" - -int32_t MbufVideoSender::InitGrp(void) +int32_t DecodedMbufVideoSender::InitGrp(void) { - GroupShareAttr Mattr = {0}; - GroupCfg grpcfg = {0}; - BuffCfg buffcfg = {0}; + GroupShareAttr Mattr = { 0 }; + GroupCfg grpcfg = { 0 }; + BuffCfg buffcfg = { 0 }; int32_t devId = 0; int32_t ret; + // 1024 1kb 32 GB grpcfg.maxMemSize = 1024 * 1024 * 32; Mattr.admin = 1; Mattr.alloc = 1; Mattr.write = 1; Mattr.read = 1; - ret = halGrpAttach(buffGrpName, 0); + ret = halGrpAttach("DEFAULT_MEM_GROUP", 0); if (ret != HI_SUCCESS) { printf("manager halGrpAttach failed! ret(%d)\n", ret); return HI_FAILURE; @@ -31,59 +30,139 @@ int32_t MbufVideoSender::InitGrp(void) return HI_SUCCESS; } -void MbufVideoSender::get_current_time_us(uint64_t &timeUs) +void DecodedMbufVideoSender::get_current_time_us(uint64_t &timeUs) { - struct timeval curTime; + timeval curTime; gettimeofday(&curTime, NULL); + // 1000000: 将秒转换成微秒 timeUs = (uint64_t)curTime.tv_sec * 1000000 + curTime.tv_usec; } -void MbufVideoSender::FillYuvAndSend(uint8_t *ptr, int32_t w, int32_t h) +bool DecodedMbufVideoSender::FillYuvAndSend(uint8_t *ptr, int32_t w, int32_t h) { + if (dataSkeleton == NULL || dataSkeleton == nullptr) { + printf("dataSkeleton IS NULL \n"); + return false; + } auto imagePub = dataSkeleton->cameraDecodedMbufEvent.Allocate(); + imagePub->CameraHeader.FrameId = frameID; imagePub->CameraHeader.Seq = 0; - imagePub->FrameType = static_cast < decltype(imagePub->FrameType) > (Adsfi::HAF_IMAGE_YUV420SP_NV12_UINT8); + imagePub->FrameType = static_castFrameType)>(Adsfi::HAF_IMAGE_YUV420SP_NV12_UINT8); imagePub->Width = w; imagePub->Height = h; size_t sizeInBytes = w * h * 3 / 2; imagePub->DataSize = sizeInBytes; - uintptr_t imgdata{}; - Mat YUV420NV12; + uintptr_t imgdata {}; + cv::Mat YUV420NV12; (void)CopyToMbuf(imgdata, ptr, sizeInBytes); + if (imgdata == reinterpret_cast(nullptr)) { - std::cout << "ERROR: CopyToMbuf failed!" << std::endl; - return; + return false; } imagePub->RawData = reinterpret_cast(imgdata); auto t1 = std::chrono::steady_clock::now(); lastTime = std::chrono::duration(t1.time_since_epoch()).count(); std::stringstream ss3; ss3 << std::fixed << lastTime; - if (comPara.time.empty()) { + + if (g_comPara.time.empty()) { timeval now; gettimeofday(&now, NULL); imagePub->CameraHeader.Stamp.Sec = now.tv_sec; imagePub->CameraHeader.Stamp.Nsec = now.tv_usec * 1000U; } else { - time_t timeStamp = convertTimeStr2TimeStamp(comPara.time); - auto t1 = chrono::high_resolution_clock::now(); + time_t timeStamp = convertTimeStr2TimeStamp(g_comPara.time); + auto t1 = std::chrono::high_resolution_clock::now(); int64_t duration = (t1 - sec).count() / 1000000000.0; imagePub->CameraHeader.Stamp.Sec = timeStamp + duration; printf("timeStamp = %ld\n", timeStamp + duration); } + dataSkeleton->cameraDecodedMbufEvent.Send(move(imagePub)); - cout << "Begin send image. seq: " << 0 << ", frameID: " << frameID << " stamp(ms): " << ss3.str() << endl; - if (comPara.frequency != "") { - int32_t freq = atoi(comPara.frequency.c_str()); - int32_t sleepTime = 1000000 / freq; - usleep(sleepTime); + + const int32_t sleepTimeIntervalMs = 1000000; + int32_t freq = atoi(g_comPara.frequency.c_str()); + if (freq) { + usleep(sleepTimeIntervalMs / 30); // 30hz } else { - usleep(1000000 / 30); //30hz + int32_t sleepTime = sleepTimeIntervalMs / freq; + usleep(sleepTime); + } + return true; +} + +void DecodedMbufVideoSender::SaveYuvFileAclHost(hi_video_frame frame, uint8_t *outImageBuf, FILE * const fd, + uint32_t chanId) +{ + uint8_t *addr = (uint8_t *)frame.virt_addr[0]; + uint32_t imageSize = frame.width * frame.height * 3 / 2; + int32_t ret = HI_SUCCESS; + uint32_t outWidthStride = frame.width_stride[0]; + uint32_t outHeightStride = frame.height_stride[0]; + if (g_run_mode == ACL_HOST) { + if (outImageBuf == NULL) { + return; + } + for (uint32_t i = 0; i < frame.height; i++) { + ret = aclrtMemcpy(outImageBuf + i * frame.width, frame.width, addr + i * outWidthStride, frame.width, + ACL_MEMCPY_DEVICE_TO_HOST); + if (ret != ACL_SUCCESS) { + aclrtFreeHost(outImageBuf); + return; + } + } + // 2: height的一半 + for (uint32_t i = 0; i < frame.height / 2; i++) { + ret = aclrtMemcpy(outImageBuf + i * frame.width + frame.width * frame.height, frame.width, + addr + i * outWidthStride + outWidthStride * outHeightStride, frame.width, ACL_MEMCPY_DEVICE_TO_HOST); + if (ret != ACL_SUCCESS) { + aclrtFreeHost(outImageBuf); + return; + } + } + FillYuvAndSend(outImageBuf, frame.width, frame.height); +#ifdef SAVE_SENDER_FILE + fwrite(outImageBuf, 1, imageSize, fd); +#endif + aclrtFreeHost(outImageBuf); + } + dealDecRunNode.chanId = chanId; + dealDecRunNode.imageSize = imageSize; + dealDecRunNode.outHeightStride = outHeightStride; + dealDecRunNode.outWidthStride = outWidthStride; + bool result = DealRunNode(addr, frame, fd); + if (!result) { + return; + } +} + +bool DecodedMbufVideoSender::DealRunNode(uint8_t *addr, hi_video_frame frame, FILE * const fd) +{ + if (g_run_mode != ACL_HOST) { + uint8_t *outImageBuf = (uint8_t *)malloc(dealDecRunNode.imageSize); + if (outImageBuf == NULL) { + return false; + } + for (uint32_t i = 0; i < frame.height; i++) { + memcpy_s(outImageBuf + i * frame.width, frame.width, addr + i * dealDecRunNode.outWidthStride, frame.width); + } + // 2: frame的高所占比例 + for (uint32_t i = 0; i < frame.height / 2; i++) { + memcpy_s(outImageBuf + i * frame.width + frame.width * frame.height, frame.width, + addr + i * dealDecRunNode.outWidthStride + + dealDecRunNode.outWidthStride * dealDecRunNode.outHeightStride, frame.width); + } + FillYuvAndSend(outImageBuf, frame.width, frame.height); +#ifdef SAVE_SENDER_FILE + fwrite(outImageBuf, 1, dealDecRunNode.imageSize, fd); +#endif + free(outImageBuf); } + return true; } -void MbufVideoSender::save_yuv_file(FILE *const fd, hi_video_frame frame, uint32_t chanId) +bool DecodedMbufVideoSender::save_yuv_file(FILE *const fd, hi_video_frame frame, uint32_t chanId) { uint8_t *addr = (uint8_t *)frame.virt_addr[0]; uint32_t imageSize = frame.width * frame.height * 3 / 2; @@ -102,16 +181,14 @@ void MbufVideoSender::save_yuv_file(FILE *const fd, hi_video_frame frame, uint32 // malloc host memory ret = aclrtMallocHost((void **)&outImageBuf, imageSize); if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u malloc host memory %u failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - return; + return false; } } if ((frame.width == outWidthStride) && (frame.height == outHeightStride)) { if (g_run_mode == ACL_HOST) { ret = aclrtMemcpy(outImageBuf, imageSize, addr, imageSize, ACL_MEMCPY_DEVICE_TO_HOST); if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u Copy aclrtMemcpy %u from device to host failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - return; + return false; } FillYuvAndSend(outImageBuf, frame.width, frame.height); #ifdef SAVE_SENDER_FILE @@ -125,56 +202,46 @@ void MbufVideoSender::save_yuv_file(FILE *const fd, hi_video_frame frame, uint32 #endif } } else { - if (g_run_mode == ACL_HOST) { - if (outImageBuf == NULL) { - return; - } - for (uint32_t i = 0; i < frame.height; i++) { - ret = aclrtMemcpy(outImageBuf + i * frame.width, frame.width, addr + i * outWidthStride, frame.width, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u Copy aclrtMemcpy %u from device to host failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - aclrtFreeHost(outImageBuf); - return; - } - } - for (uint32_t i = 0; i < frame.height / 2; i++) { - ret = aclrtMemcpy(outImageBuf + i * frame.width + frame.width * frame.height, frame.width, - addr + i * outWidthStride + outWidthStride * outHeightStride, frame.width, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u Copy aclrtMemcpy %u from device to host failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - aclrtFreeHost(outImageBuf); - return; - } - } - FillYuvAndSend(outImageBuf, frame.width, frame.height); -#ifdef SAVE_SENDER_FILE - fwrite(outImageBuf, 1, imageSize, fd); -#endif - aclrtFreeHost(outImageBuf); - } else { - uint8_t *outImageBuf = (uint8_t *)malloc(imageSize); - if (outImageBuf == NULL) { - printf("[%s][%d] Chn %u Malloc failed \n", __FUNCTION__, __LINE__, chanId); + SaveYuvFileAclHost(frame, outImageBuf, fd, chanId); + } + return true; +} + +void DecodedMbufVideoSender::SaveRgbFileAclHost(hi_video_frame frame, uint8_t *outImageBuf, FILE * const fd, + uint32_t chanId) +{ + uint8_t *addr = (uint8_t *)frame.virt_addr[0]; + uint32_t imageSize = frame.width * frame.height * 3; + int32_t ret = HI_SUCCESS; + uint32_t outWidthStride = frame.width_stride[0]; + uint32_t outHeightStride = frame.height_stride[0]; + if (g_run_mode == ACL_HOST) { + for (uint32_t i = 0; i < frame.height; i++) { + ret = aclrtMemcpy(outImageBuf + i * frame.width * frameWidthTriploid, frame.width * frameWidthTriploid, + addr + i * outWidthStride, frame.width * frameWidthTriploid, ACL_MEMCPY_DEVICE_TO_HOST); + if (ret != HI_SUCCESS) { + aclrtFreeHost(outImageBuf); return; } - for (uint32_t i = 0; i < frame.height; i++) { - memcpy(outImageBuf + i * frame.width, addr + i * outWidthStride, frame.width); - } - for (uint32_t i = 0; i < frame.height / 2; i++) { - memcpy(outImageBuf + i * frame.width + frame.width * frame.height, - addr + i * outWidthStride + outWidthStride * outHeightStride, frame.width); - } - FillYuvAndSend(outImageBuf, frame.width, frame.height); -#ifdef SAVE_SENDER_FILE - fwrite(outImageBuf, 1, imageSize, fd); -#endif - free(outImageBuf); } + fwrite(outImageBuf, 1, imageSize, fd); + aclrtFreeHost(outImageBuf); + } else { + uint8_t *outImageBuf = (uint8_t *)malloc(imageSize); + if (outImageBuf == NULL) { + return; + } + for (uint32_t i = 0; i < frame.height; i++) { + memcpy_s(outImageBuf + i * frame.width * frameWidthTriploid, frame.width * frameWidthTriploid, + addr + i * outWidthStride, frame.width * frameWidthTriploid); + } + fwrite(outImageBuf, 1, imageSize, fd); + free(outImageBuf); } return; } -void MbufVideoSender::save_rgb_file(FILE *const fd, hi_video_frame frame, uint32_t chanId) +bool DecodedMbufVideoSender::save_rgb_file(FILE *const fd, hi_video_frame frame, uint32_t chanId) { uint8_t *addr = (uint8_t *)frame.virt_addr[0]; uint32_t imageSize = frame.width * frame.height * 3; @@ -192,16 +259,14 @@ void MbufVideoSender::save_rgb_file(FILE *const fd, hi_video_frame frame, uint32 // malloc host memory ret = aclrtMallocHost((void **)&outImageBuf, imageSize); if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u malloc host memory %u failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - return; + return false; } } - if (((frame.width * 3) == outWidthStride) && (frame.height == outHeightStride)) { + if (((frame.width * frameWidthTriploid) == outWidthStride) && (frame.height == outHeightStride)) { if (g_run_mode == ACL_HOST) { ret = aclrtMemcpy(outImageBuf, imageSize, addr, imageSize, ACL_MEMCPY_DEVICE_TO_HOST); if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u Copy aclrtMemcpy %u from device to host failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - return; + return false; } fwrite(outImageBuf, 1, imageSize, fd); aclrtFreeHost(outImageBuf); @@ -209,38 +274,17 @@ void MbufVideoSender::save_rgb_file(FILE *const fd, hi_video_frame frame, uint32 fwrite(addr, imageSize, 1, fd); } } else { - if (g_run_mode == ACL_HOST) { - for (uint32_t i = 0; i < frame.height; i++) { - ret = aclrtMemcpy(outImageBuf + i * frame.width * 3, frame.width * 3, addr + i * outWidthStride, frame.width * 3, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u Copy aclrtMemcpy %u from device to host failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - aclrtFreeHost(outImageBuf); - return; - } - } - fwrite(outImageBuf, 1, imageSize, fd); - aclrtFreeHost(outImageBuf); - } else { - uint8_t *outImageBuf = (uint8_t *)malloc(imageSize); - if (outImageBuf == NULL) { - printf("[%s][%d] Chn %u Malloc Fail \n", __FUNCTION__, __LINE__, chanId); - return; - } - for (uint32_t i = 0; i < frame.height; i++) { - memcpy(outImageBuf + i * frame.width * 3, addr + i * outWidthStride, frame.width * 3); - } - fwrite(outImageBuf, 1, imageSize, fd); - free(outImageBuf); - } + SaveRgbFileAclHost(frame, outImageBuf, fd, chanId); } - return; + return true; } -int32_t MbufVideoSender::vdec_create() +int32_t DecodedMbufVideoSender::vdec_create() { int32_t ret = HI_SUCCESS; hi_vdec_chn_attr chnAttr[VDEC_MAX_CHN_NUM] {}; hi_data_bit_width bitWidth = HI_DATA_BIT_WIDTH_8; + // 10: 位宽 if (g_in_bitwidth == 10) { bitWidth = HI_DATA_BIT_WIDTH_10; } @@ -253,89 +297,91 @@ int32_t MbufVideoSender::vdec_create() chnAttr[i].mode = HI_VDEC_SEND_MODE_FRAME; chnAttr[i].pic_width = g_in_width; chnAttr[i].pic_height = g_in_height; - chnAttr[i].stream_buf_size = g_in_width * g_in_height * 3 / 2; + chnAttr[i].stream_buf_size = g_in_width * g_in_height * CN3 / CN2; chnAttr[i].frame_buf_cnt = g_ref_frame_num + g_display_frame_num + 1; - hi_pic_buf_attr buf_attr{ - g_in_width, g_in_height, 0, bitWidth, HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420, HI_COMPRESS_MODE_NONE}; + hi_pic_buf_attr buf_attr{g_in_width, g_in_height, 0, bitWidth, HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420, + HI_COMPRESS_MODE_NONE}; chnAttr[i].frame_buf_size = hi_vdec_get_pic_buf_size(chnAttr[i].type, &buf_attr); chnAttr[i].video_attr.ref_frame_num = g_ref_frame_num; chnAttr[i].video_attr.temporal_mvp_en = HI_TRUE; chnAttr[i].video_attr.tmv_buf_size = hi_vdec_get_tmv_buf_size(chnAttr[i].type, g_in_width, g_in_height); ret = hi_mpi_vdec_create_chn(i, &chnAttr[i]); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_create_chn failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); return ret; } g_chan_create_state[i] = 1; - hi_vdec_chn_param chnParam; - ret = hi_mpi_vdec_get_chn_param(i, &chnParam); + ret = DealParam(i); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_get_chn_param failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); - return ret; - } - chnParam.video_param.dec_mode = HI_VIDEO_DEC_MODE_IPB; - chnParam.video_param.compress_mode = HI_COMPRESS_MODE_HFBC; - chnParam.video_param.video_format = HI_VIDEO_FORMAT_TILE_64x16; - chnParam.display_frame_num = g_display_frame_num; - if (g_output_order == 0) { - chnParam.video_param.out_order = HI_VIDEO_OUT_ORDER_DISPLAY; - } else { - chnParam.video_param.out_order = HI_VIDEO_OUT_ORDER_DEC; - } - ret = hi_mpi_vdec_set_chn_param(i, &chnParam); - if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_set_chn_param failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); - return ret; - } - ret = hi_mpi_vdec_start_recv_stream(i); - if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_start_recv_stream failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); return ret; } } return ret; } -void MbufVideoSender::vdec_reset_chn(uint32_t chanId) +int32_t DecodedMbufVideoSender::DealParam(uint32_t i) { int32_t ret = HI_SUCCESS; - hi_vdec_chn_status status{}; + hi_vdec_chn_param chnParam; + ret = hi_mpi_vdec_get_chn_param(i, &chnParam); + if (ret != HI_SUCCESS) { + return ret; + } + chnParam.video_param.dec_mode = HI_VIDEO_DEC_MODE_IPB; + chnParam.video_param.compress_mode = HI_COMPRESS_MODE_HFBC; + chnParam.video_param.video_format = HI_VIDEO_FORMAT_TILE_64x16; + chnParam.display_frame_num = g_display_frame_num; + if (g_output_order == 0) { + chnParam.video_param.out_order = HI_VIDEO_OUT_ORDER_DISPLAY; + } else { + chnParam.video_param.out_order = HI_VIDEO_OUT_ORDER_DEC; + } + ret = hi_mpi_vdec_set_chn_param(i, &chnParam); + if (ret != HI_SUCCESS) { + return ret; + } + ret = hi_mpi_vdec_start_recv_stream(i); + if (ret != HI_SUCCESS) { + return ret; + } + return ret; +} + +bool DecodedMbufVideoSender::vdec_reset_chn(uint32_t chanId) +{ + int32_t ret = HI_SUCCESS; + hi_vdec_chn_status status {}; ret = hi_mpi_vdec_stop_recv_stream(chanId); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_stop_recv_stream failed, ret = %x \n", __FUNCTION__, __LINE__, chanId, ret); - return; + return false; } ret = hi_mpi_vdec_reset_chn(chanId); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u, hi_mpi_vdec_reset_chn failed, ret = %x \n", __FUNCTION__, __LINE__, chanId, ret); - return; + return false; } ret = hi_mpi_vdec_start_recv_stream(chanId); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u, hi_mpi_vdec_start_recv_stream failed, ret = %x \n", __FUNCTION__, __LINE__, chanId, ret); - return; + return false; } - printf("[%s][%d] Chn %u reset chn success \n", __FUNCTION__, __LINE__, chanId); - return; + return true; } -void MbufVideoSender::wait_vdec_end() +void DecodedMbufVideoSender::WaitVdecEnd() { int32_t ret = HI_SUCCESS; int32_t waitTimes; int32_t sleepTime = 10000; - hi_vdec_chn_status status{}; - hi_vdec_chn_status pre_status{}; + hi_vdec_chn_status status {}; + hi_vdec_chn_status pre_status {}; for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { - if (g_vdec_send_thread[i] != 0) { - ret = pthread_join(g_vdec_send_thread[i], NULL); + if (g_vdec_send_thread[i].joinable()) { + g_vdec_send_thread[i].join(); } - g_vdec_send_thread[i] = 0; + g_vdec_send_thread[i] = {}; + waitTimes = 0; while (g_exit == 0) { ret = hi_mpi_vdec_query_status(i, &status); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u, hi_mpi_vdec_query_status failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); break; } if (((status.left_stream_bytes == 0) && (status.left_decoded_frames == 0)) || (g_get_exit_state[i] == 1)) { @@ -348,32 +394,34 @@ void MbufVideoSender::wait_vdec_end() } pre_status = status; usleep(sleepTime); - if (waitTimes >= 5000000) { + if (waitTimes >= CN5000000) { vdec_reset_chn(i); break; } } } - usleep(1000000); + // 1000000: 1秒 + usleep(CN1000000); for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { g_get_exit_state[i] = 1; } for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { - if (g_vdec_get_thread[i] != 0) { - ret = pthread_join(g_vdec_get_thread[i], NULL); + if (g_vdec_get_thread[i].joinable()) { + g_vdec_get_thread[i].join(); } - g_vdec_get_thread[i] = 0; + g_vdec_get_thread[i] = {}; } } -void MbufVideoSender::vdec_destroy() +void DecodedMbufVideoSender::VdecDestroy() { int32_t ret = HI_SUCCESS; for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { if (g_chan_create_state[i] == 1) { ret = hi_mpi_vdec_stop_recv_stream(i); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u, hi_mpi_vdec_stop_recv_stream failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); + printf("[%s][%d] Chn %u, hi_mpi_vdec_stop_recv_stream failed, ret = %x \n", __FUNCTION__, __LINE__, i, + ret); } ret = hi_mpi_vdec_destroy_chn(i); if (ret != HI_SUCCESS) { @@ -384,53 +432,162 @@ void MbufVideoSender::vdec_destroy() } } -int32_t MbufVideoSender::create_send_stream_thread() +int32_t DecodedMbufVideoSender::create_send_stream_thread() { int32_t ret = 0; uint32_t i = 0; - g_vdec_send_thread[i] = 0; + g_vdec_send_thread[i] = {}; g_send_thread_id[i] = i; - ret = pthread_create(&g_vdec_send_thread[i], 0, MbufVideoSender::send_stream, this); + g_vdec_send_thread[i] = std::thread(DecodedMbufVideoSender::SendStream, this); + if (ret != 0) { - printf("[%s][%d] Chn %u create send stream thread failed, ret = %d \n", __FUNCTION__, __LINE__, i, ret); - g_vdec_send_thread[i] = 0; + g_vdec_send_thread[i] = {}; return ret; } return ret; } -int32_t MbufVideoSender::create_get_pic_thread() +int32_t DecodedMbufVideoSender::create_get_pic_thread() { - int32_t ret; + int32_t ret = 0; for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { - g_vdec_get_thread[i] = 0; + g_vdec_get_thread[i] = {}; g_get_thread_id[i] = i; - ret = pthread_create(&g_vdec_get_thread[i], 0, MbufVideoSender::get_pic, this); + g_vdec_get_thread[i] = std::thread(DecodedMbufVideoSender::GetPic, this); + if (ret != 0) { - printf("[%s][%d] Chn %u, create get pic thread failed, ret = %d \n", __FUNCTION__, __LINE__, i, ret); - g_vdec_get_thread[i] = 0; + g_vdec_get_thread[i] = {}; return ret; } } return ret; } -void *MbufVideoSender::send_stream(void *arg) +void DecodedMbufVideoSender::UpdateOutPicInfo(hi_vdec_pic_info &outPicInfo, DecodedMbufVideoSender *thiz, + uint32_t chanId, GetFrameMsg& frameMsg) +{ + outPicInfo.width = thiz->g_out_width; + outPicInfo.height = thiz->g_out_height; + outPicInfo.width_stride = thiz->g_out_width_stride; + outPicInfo.height_stride = thiz->g_out_height_stride; + outPicInfo.pixel_format = (hi_pixel_format)(frameMsg.outFormat); + + if ((thiz->g_render == 0) || (frameMsg.readCount % thiz->g_render == 0)) { + int32_t mallocCount = 0; + int32_t tryTimes = 20000; + while (thiz->g_send_exit_state[chanId] == 0) { + mallocCount++; + (void)pthread_mutex_lock(&thiz->g_out_buffer_pool_lock[chanId]); + if (thiz->g_out_buffer_pool[chanId].empty() == false) { + frameMsg.outBuffer = thiz->g_out_buffer_pool[chanId].back(); + thiz->g_out_buffer_pool[chanId].pop_back(); + (void)pthread_mutex_unlock(&thiz->g_out_buffer_pool_lock[chanId]); + break; + } else { + (void)pthread_mutex_unlock(&thiz->g_out_buffer_pool_lock[chanId]); + usleep(CN1000); + } + if (mallocCount >= tryTimes) { + printf("[%s][%d] Chn %u DvppMalloc From Pool Failed, Try again \n", __FUNCTION__, __LINE__, chanId); + mallocCount = 0; + } + } + frameMsg.stream.need_display = HI_TRUE; + outPicInfo.vir_addr = (uint64_t)frameMsg.outBuffer; + outPicInfo.buffer_size = frameMsg.outBufferSize; + } else { + frameMsg.stream.need_display = HI_FALSE; + outPicInfo.vir_addr = 0; + outPicInfo.buffer_size = 0; + } +} + +int32_t DecodedMbufVideoSender::DealSendFormat(DecodedMbufVideoSender *thiz, GetFrameMsg& frameMsg, FILE *fpInputFile) +{ + int32_t ret = HI_SUCCESS; + void *outBuffer = NULL; + uint32_t outBufferSize = 0; + if ((thiz->g_out_format == 0) || (thiz->g_out_format == 1)) { + // 3、2: 分别是宽高的占比 + outBufferSize = thiz->g_out_width_stride * thiz->g_out_height_stride * CN3 / CN2; + } else if ((thiz->g_out_format == CN2) || (thiz->g_out_format == CN3)) { + // 3、2:分别是确定输出格式 + outBufferSize = thiz->g_out_width_stride * thiz->g_out_height_stride; + } + for (uint32_t i = 0; i < thiz->g_alloc_num; i++) { + ret = hi_mpi_dvpp_malloc(0, &outBuffer, outBufferSize); + if (ret != HI_SUCCESS) { + fclose(fpInputFile); + free(frameMsg.inputFileBuf); + if (thiz->g_run_mode == ACL_HOST) { + hi_mpi_dvpp_free(frameMsg.dataDev); + } + return HI_FAILURE; + } + thiz->g_out_buffer_pool[frameMsg.chanId].push_back(outBuffer); + } + thiz->delay_exec(thiz->g_start_time, thiz->g_delay_time); + thiz->get_current_time_us(thiz->g_vdec_start_time[frameMsg.chanId]); + hi_pixel_format outFormat = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; + switch (thiz->g_out_format) { + case 0: + outFormat = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; + break; + case 1: + outFormat = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420; + break; + // 2: g_out_format的值 + case 2: + outFormat = HI_PIXEL_FORMAT_RGB_888; + break; + // 3: g_out_format的值 + case 3: + outFormat = HI_PIXEL_FORMAT_BGR_888; + break; + default: + break; + } + frameMsg.outBuffer = outBuffer; + frameMsg.outBufferSize = outBufferSize; + frameMsg.outFormat = outFormat; + return ret; +} + +bool DecodedMbufVideoSender::DealDataDev(DecodedMbufVideoSender *thiz, uint8_t *dataDev, FILE *fpInputFile, + GetFrameMsg& frameMsg) +{ + int32_t ret = HI_SUCCESS; + if (thiz->g_run_mode == ACL_HOST) { + ret = hi_mpi_dvpp_malloc(0, (void **)&dataDev, frameMsg.fileSize); + if (ret != 0) { + fclose(fpInputFile); + free(frameMsg.inputFileBuf); + return false; + } + ret = aclrtMemcpy(dataDev, frameMsg.fileSize, frameMsg.inputFileBuf, frameMsg.fileSize, + ACL_MEMCPY_HOST_TO_DEVICE); + if (ret != ACL_SUCCESS) { + fclose(fpInputFile); + free(frameMsg.inputFileBuf); + hi_mpi_dvpp_free(dataDev); + return false; + } + } + return true; +} + +void DecodedMbufVideoSender::DealInput(DecodedMbufVideoSender *thiz, InputMsg& inputMsg) { - MbufVideoSender *thiz = static_cast(arg); - uint32_t sendFrameFailCnt = 0; - prctl(PR_SET_NAME, "VdecSendStream", 0, 0, 0); - uint32_t chanId = 0; aclError aclRet = aclrtSetCurrentContext(thiz->g_context); if (aclRet != ACL_SUCCESS) { - printf("[%s][%d] Chn %u set current context failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, aclRet); - return (void *)(HI_FAILURE); + inputMsg.ret = HI_FAILURE; + return; } FILE *fpInputFile = NULL; fpInputFile = fopen(thiz->g_input_file_name, "rb"); if (fpInputFile == NULL) { - printf("[%s][%d] Chn %u Can not open file %s \n", __FUNCTION__, __LINE__, chanId, thiz->g_input_file_name); - return (void *)(HI_FAILURE); + inputMsg.ret = HI_FAILURE; + return; } uint32_t fileSize = 0; fseek(fpInputFile, 0L, SEEK_END); @@ -440,86 +597,83 @@ void *MbufVideoSender::send_stream(void *arg) inputFileBuf = (uint8_t *)malloc(fileSize); if (inputFileBuf == NULL) { fclose(fpInputFile); - printf("[%s][%d] Chn %u Malloc InputFile Buffer Fail \n", __FUNCTION__, __LINE__, chanId); - return (void *)(HI_FAILURE); + inputMsg.ret = HI_FAILURE; + return; } uint32_t readLen = 0; readLen = fread(inputFileBuf, 1, fileSize, fpInputFile); if (readLen != fileSize) { fclose(fpInputFile); free(inputFileBuf); - printf("[%s][%d] Chn %u Read InputFile Fail \n", __FUNCTION__, __LINE__, chanId); - return (void *)(HI_FAILURE); + inputMsg.ret = HI_FAILURE; + return; } - uint8_t *dataDev = HI_NULL; + inputMsg.fpInputFile = fpInputFile; + inputMsg.aclRet = aclRet; + inputMsg.fileSize = fileSize; + inputMsg.inputFileBuf = inputFileBuf; + inputMsg.readLen = readLen; + inputMsg.ret = HI_SUCCESS; +} + +void *DecodedMbufVideoSender::SendStream(DecodedMbufVideoSender *thiz) +{ + uint32_t sendFrameFailCnt = 0; + prctl(PR_SET_NAME, "VdecSendStream", 0, 0, 0); + uint32_t chanId = 0; + int32_t ret = HI_SUCCESS; - if (thiz->g_run_mode == ACL_HOST) { - ret = hi_mpi_dvpp_malloc(0, (void **)&dataDev, fileSize); - if (ret != 0) { - fclose(fpInputFile); - free(inputFileBuf); - printf("[%s][%d] Chn %u Malloc device memory %u failed \n", __FUNCTION__, __LINE__, chanId, fileSize); - return (hi_void *)(HI_FAILURE); - } - ret = aclrtMemcpy(dataDev, fileSize, inputFileBuf, fileSize, ACL_MEMCPY_HOST_TO_DEVICE); - if (ret != ACL_SUCCESS) { - fclose(fpInputFile); - free(inputFileBuf); - hi_mpi_dvpp_free(dataDev); - printf("[%s][%d] Chn %u Copy host memcpy to device failed, error code = %d. \n", __FUNCTION__, __LINE__, chanId, ret); - return (hi_void *)(HI_FAILURE); - } + InputMsg inputMsg; + DealInput(thiz, inputMsg); + if (inputMsg.ret != HI_SUCCESS) { + return (hi_void *)(HI_FAILURE); } + + FILE *fpInputFile = inputMsg.fpInputFile; + uint8_t *inputFileBuf = inputMsg.inputFileBuf; + uint32_t fileSize = inputMsg.fileSize; + uint32_t frameCount = 0; hi_payload_type type = (thiz->g_in_format == 0) ? HI_PT_H264 : HI_PT_H265; - thiz->get_every_frame(chanId, inputFileBuf, &frameCount, fileSize, type, dataDev); - void *outBuffer = NULL; - uint32_t outBufferSize = 0; - if ((thiz->g_out_format == 0) || (thiz->g_out_format == 1)) { - outBufferSize = thiz->g_out_width_stride * thiz->g_out_height_stride * 3 / 2; - } else if ((thiz->g_out_format == 2) || (thiz->g_out_format == 3)) { - outBufferSize = thiz->g_out_width_stride * thiz->g_out_height_stride; + + GetFrameMsg frameMsg; + frameMsg.inputFileBuf = inputFileBuf; + frameMsg.fileSize = fileSize; + + uint8_t *dataDev = HI_NULL; + bool bRet = DealDataDev(thiz, dataDev, fpInputFile, frameMsg); + if (!bRet) { + return (void *)HI_FAILURE; } - for (uint32_t i = 0; i < thiz->g_alloc_num; i++) { - ret = hi_mpi_dvpp_malloc(0, &outBuffer, outBufferSize); - if (ret != HI_SUCCESS) { - fclose(fpInputFile); - free(inputFileBuf); - if (thiz->g_run_mode == ACL_HOST) { - hi_mpi_dvpp_free(dataDev); - } - printf("[%s][%d] Chn %u hi_mpi_dvpp_malloc failed.\n", __FUNCTION__, __LINE__, chanId); - return (void *)(HI_FAILURE); - } - thiz->g_out_buffer_pool[chanId].push_back(outBuffer); + + inputFileBuf = frameMsg.inputFileBuf; + + frameMsg.chanId = chanId; + frameMsg.inputFileBuf = inputFileBuf; + frameMsg.frameCount = &frameCount; + frameMsg.fileSize = fileSize; + frameMsg.type = type; + frameMsg.dataDev = dataDev; + thiz->GetEveryFrame(frameMsg); + + ret = DealSendFormat(thiz, frameMsg, fpInputFile); + if (ret != HI_SUCCESS) { + return (void *)(HI_FAILURE); } - thiz->delay_exec(thiz->g_start_time, thiz->g_delay_time); - thiz->get_current_time_us(thiz->g_vdec_start_time[chanId]); + hi_vdec_stream stream; hi_vdec_pic_info outPicInfo; + + frameMsg.stream = stream; + frameMsg.chanId = chanId; + uint32_t readCount = 0; - hi_pixel_format outFormat = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; uint64_t currentSendTime = 0; uint64_t lastSendTime = 0; uint32_t circleTimes = 0; - switch (thiz->g_out_format) { - case 0: - outFormat = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; - break; - case 1: - outFormat = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420; - break; - case 2: - outFormat = HI_PIXEL_FORMAT_RGB_888; - break; - case 3: - outFormat = HI_PIXEL_FORMAT_BGR_888; - break; - default: - break; - } - int32_t timeOut = 1000; + int32_t timeOut = CN1000; thiz->get_current_time_us(currentSendTime); + while (1) { if (thiz->g_send_exit_state[chanId] == 1) { break; @@ -529,39 +683,11 @@ void *MbufVideoSender::send_stream(void *arg) stream.len = thiz->g_frame_len[chanId][readCount]; stream.end_of_frame = HI_TRUE; stream.end_of_stream = HI_FALSE; - outPicInfo.width = thiz->g_out_width; - outPicInfo.height = thiz->g_out_height; - outPicInfo.width_stride = thiz->g_out_width_stride; - outPicInfo.height_stride = thiz->g_out_height_stride; - outPicInfo.pixel_format = outFormat; - if ((thiz->g_render == 0) || (readCount % thiz->g_render == 0)) { - int32_t mallocCount = 0; - int32_t tryTimes = 20000; - while (thiz->g_send_exit_state[chanId] == 0) { - mallocCount++; - (void)pthread_mutex_lock(&thiz->g_out_buffer_pool_lock[chanId]); - if (thiz->g_out_buffer_pool[chanId].empty() == false) { - outBuffer = thiz->g_out_buffer_pool[chanId].back(); - thiz->g_out_buffer_pool[chanId].pop_back(); - (void)pthread_mutex_unlock(&thiz->g_out_buffer_pool_lock[chanId]); - break; - } else { - (void)pthread_mutex_unlock(&thiz->g_out_buffer_pool_lock[chanId]); - usleep(1000); - } - if (mallocCount >= tryTimes) { - printf("[%s][%d] Chn %u DvppMalloc From Pool Failed, Try again \n", __FUNCTION__, __LINE__, chanId); - mallocCount = 0; - } - } - stream.need_display = HI_TRUE; - outPicInfo.vir_addr = (uint64_t)outBuffer; - outPicInfo.buffer_size = outBufferSize; - } else { - stream.need_display = HI_FALSE; - outPicInfo.vir_addr = 0; - outPicInfo.buffer_size = 0; - } + frameMsg.stream = stream; + frameMsg.readCount = readCount; + UpdateOutPicInfo(outPicInfo, thiz, chanId, frameMsg); + stream = frameMsg.stream; + readCount = (readCount + 1) % frameCount; if (readCount == 0) { circleTimes++; @@ -574,14 +700,13 @@ void *MbufVideoSender::send_stream(void *arg) do { sendFrameFailCnt++; ret = hi_mpi_vdec_send_stream(chanId, &stream, &outPicInfo, timeOut); - if (sendFrameFailCnt > 30) { + if (sendFrameFailCnt > CN30) { thiz->vdec_reset_chn(chanId); sendFrameFailCnt = 0; break; } } while (ret == HI_ERR_VDEC_BUF_FULL); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_send_stream failed, Error code = %x \n", __FUNCTION__, __LINE__, chanId, ret); break; } else { sendFrameFailCnt = 0; @@ -602,18 +727,39 @@ void *MbufVideoSender::send_stream(void *arg) if (thiz->g_run_mode == ACL_HOST) { hi_mpi_dvpp_free(dataDev); } - printf("[%s][%d] Chn %u send_stream Thread Exit \n", __FUNCTION__, __LINE__, chanId); return (hi_void *)HI_SUCCESS; } -void *MbufVideoSender::get_pic(void *arg) +void DecodedMbufVideoSender::GetPicHost(hi_video_frame_info& frame, DecodedMbufVideoSender *thiz, + uint32_t& chanId, hi_vdec_stream& stream, int32_t& writeFileCnt) +{ + int32_t ret = HI_SUCCESS; + FILE *fp = NULL; + char saveFileName[256]; + ret = snprintf_s(saveFileName, sizeof(saveFileName), sizeof(saveFileName) - 1, "%s_chn%u_%d", + thiz->g_output_file_name, chanId, writeFileCnt); + if (ret <= 0) { +#ifdef IN_GITE + thiz->g_get_exit_state[chanId] = 1; +#endif + return; + } + if ((frame.v_frame.pixel_format == HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420) || + (frame.v_frame.pixel_format == HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420)) { + thiz->save_yuv_file(thiz->fp_yuv, frame.v_frame, chanId); + } else if ((frame.v_frame.pixel_format == HI_PIXEL_FORMAT_RGB_888) || + (frame.v_frame.pixel_format == HI_PIXEL_FORMAT_BGR_888)) { + thiz->save_rgb_file(fp, frame.v_frame, chanId); + } + writeFileCnt++; +} + +void *DecodedMbufVideoSender::GetPic(DecodedMbufVideoSender *thiz) { - MbufVideoSender *thiz = static_cast(arg); prctl(PR_SET_NAME, "VdecGetPic", 0, 0, 0); uint32_t chanId = 0; aclError aclRet = aclrtSetCurrentContext(thiz->g_context); if (aclRet != ACL_SUCCESS) { - printf("[%s][%d] Chn %u set current context failed, error code = %d, \n", __FUNCTION__, __LINE__, chanId, aclRet); thiz->g_get_exit_state[chanId] = 1; return (void *)(HI_FAILURE); } @@ -624,9 +770,9 @@ void *MbufVideoSender::get_pic(void *arg) void *outputBuffer = NULL; int32_t successCnt = 0; int32_t failCnt = 0; - int32_t timeOut = 1000; + int32_t timeOut = CN1000; int32_t writeFileCnt = 1; - hi_vdec_supplement_info stSupplement{}; + hi_vdec_supplement_info stSupplement {}; while (1) { if (thiz->g_get_exit_state[chanId] == 1) { break; @@ -634,42 +780,14 @@ void *MbufVideoSender::get_pic(void *arg) ret = hi_mpi_vdec_get_frame(chanId, &frame, &stSupplement, &stream, timeOut); if (ret == HI_SUCCESS) { thiz->get_current_time_us(thiz->g_vdec_end_time[chanId]); - outputBuffer = (void *) frame.v_frame.virt_addr[0]; + outputBuffer = (void *)frame.v_frame.virt_addr[0]; decResult = frame.v_frame.frame_flag; - if (decResult == 0) { - successCnt++; - printf("[%s][%d] Chn %u GetFrame success, Decode success[%d] \n", __FUNCTION__, __LINE__, chanId, successCnt); - } else if (decResult == 1) { - failCnt++; - printf("[%s][%d] Chn %u GetFrame success, Decode fail[%d] \n", __FUNCTION__, __LINE__, chanId, failCnt); - } else if (decResult == 2) { - printf("[%s][%d] Chn %u GetFrame success, No Picture \n", __FUNCTION__, __LINE__, chanId); - } else if (decResult == 3) { - failCnt++; - printf("[%s][%d] Chn %u GetFrame success, RefFrame Num Error[%d] \n", __FUNCTION__, __LINE__, chanId, failCnt); - } else if (decResult == 4) { - failCnt++; - printf("[%s][%d] Chn %u GetFrame success, RefFrame Size Error[%d] \n", __FUNCTION__, __LINE__, chanId, failCnt); - } + DealDecResult(decResult, successCnt, chanId, failCnt); + thiz->g_vdec_get_frame_cnt[chanId] = successCnt + failCnt; - if ((thiz->g_is_write_file == 1) && (decResult == 0) && - (outputBuffer != NULL) && (stream.need_display == HI_TRUE)) { - FILE *fp = NULL; - char saveFileName[256]; - ret = snprintf(saveFileName, sizeof(saveFileName), "%s_chn%u_%d", thiz->g_output_file_name, chanId, writeFileCnt); - if (ret <= 0) { - printf("[%s][%d] Chn %u,snprintf_s fail \n", __FUNCTION__, __LINE__, chanId); - thiz->g_get_exit_state[chanId] = 1; - return (void *)(HI_FAILURE); - } - if ((frame.v_frame.pixel_format == HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420) || - (frame.v_frame.pixel_format == HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420)) { - thiz->save_yuv_file(thiz->fp_yuv, frame.v_frame, chanId); - } else if ((frame.v_frame.pixel_format == HI_PIXEL_FORMAT_RGB_888) || - (frame.v_frame.pixel_format == HI_PIXEL_FORMAT_BGR_888)) { - thiz->save_rgb_file(fp, frame.v_frame, chanId); - } - writeFileCnt++; + if ((thiz->g_is_write_file == 1) && (decResult == 0) && (outputBuffer != NULL) && + (stream.need_display == HI_TRUE)) { + GetPicHost(frame, thiz, chanId, stream, writeFileCnt); } if (outputBuffer != NULL) { (void)pthread_mutex_lock(&thiz->g_out_buffer_pool_lock[chanId]); @@ -678,20 +796,126 @@ void *MbufVideoSender::get_pic(void *arg) } ret = hi_mpi_vdec_release_frame(chanId, &frame); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_release_frame Fail,Error Code = %x \n", - __FUNCTION__, __LINE__, chanId, ret); + printf("[%s][%d] Chn %u hi_mpi_vdec_release_frame Fail,Error Code = %x \n", __FUNCTION__, __LINE__, + chanId, ret); } } else { - usleep(500); + usleep(500); // 当前线程休眠500微秒 } } - printf("[%s][%d] Chn %u get_pic Thread exit \n", __FUNCTION__, __LINE__, chanId); return (void *)HI_SUCCESS; } -void MbufVideoSender::get_every_frame(int32_t chanId, uint8_t *const inputFileBuf, uint32_t *const frameCount, - uint32_t fileSize, hi_payload_type type, uint8_t *dataDev) +void DecodedMbufVideoSender::DealDecResult(int32_t& decResult, int32_t& successCnt, uint32_t& chanId, int32_t& failCnt) +{ + if (decResult == 0) { + successCnt++; + printf("[%s][%d] Chn %u GetFrame success, Decode success[%d] \n", __FUNCTION__, __LINE__, chanId, successCnt); + } else if (decResult == 1) { + failCnt++; + printf("[%s][%d] Chn %u GetFrame success, Decode fail[%d] \n", __FUNCTION__, __LINE__, chanId, failCnt); + } else if (decResult == CN2) { // 2: 数据帧的标志 + printf("[%s][%d] Chn %u GetFrame success, No Picture \n", __FUNCTION__, __LINE__, chanId); + } else if (decResult == CN3) { // 3: 数据帧的标志 + failCnt++; + printf("[%s][%d] Chn %u GetFrame success, RefFrame Num Error[%d] \n", __FUNCTION__, __LINE__, chanId, failCnt); + } else if (decResult == CN4) { // 4: 数据帧的标志 + failCnt++; + printf("[%s][%d] Chn %u GetFrame success, RefFrame Size Error[%d] \n", __FUNCTION__, __LINE__, chanId, failCnt); + } +} + +void DecodedMbufVideoSender::GetFrameHost(int32_t& i, int32_t& readLen, uint8_t *bufPointer, + bool& isFindStart, bool& isFindEnd) { + // 8: 字节 + for (i = 0; i < readLen - CN8; i++) { + // 3: 将指针移动3个字节 + int32_t tmp = bufPointer[i + CN3] & 0x1F; + if ((bufPointer[i] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + CN2] == 1) && // 2:将指针移动2个字节 + (((tmp == 0x5 || tmp == 0x1) && ((bufPointer[i + CN4] & 0x80) == 0x80)) || // 4:将指针移动4个字节 + (tmp == CN20 && (bufPointer[i + CN7] & 0x80) == 0x80))) { // 7: 将指针移动7个字节,20:ASCII码值 + isFindStart = true; + i += CN8; // 8: 字节 + break; + } + } + // 8:字节 + for (; i < readLen - CN8; i++) { + int32_t tmp = bufPointer[i + CN3] & 0x1F; // 3: 将指针移动3个字节 + if ((bufPointer[i] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + CN2] == 1) && // 2:将指针移动2个字节 + ((tmp == CN15) || (tmp == CN7) || (tmp == CN8) || (tmp == CN6) || // 6、7、8、15:ASCII码值 + ((tmp == CN5 || tmp == 1) && + ((bufPointer[i + CN4] & 0x80) == 0x80)) || // 5:ASCII码值,4:将指针移动4个字节 + (tmp == CN20 && (bufPointer[i + CN7] & 0x80) == 0x80))) { // 7: 将指针移动7个字节,20: ASCII码值 + isFindEnd = true; + break; + } + } + if (i > 0) { + readLen = i; + } + if (!isFindStart) { + printf("can not find h264 start code! readLen %d\n", readLen); + } + if (!isFindEnd) { + readLen = i + CN8; // 8: 字节 + } +} + +void DecodedMbufVideoSender::DealGetFrameHost(int32_t& i, int32_t& readLen, uint8_t *bufPointer, + bool& isFindStart, bool& isFindEnd) +{ + bool isNewPic = false; + // 6: 字节 + for (i = 0; i < readLen - CN6; i++) { + uint32_t tmp = (bufPointer[i + CN3] & 0x7E) >> 1; // 3: 将指针移动3个字节 + if ((bufPointer[i + 0] == 0) && (bufPointer[i + 1] == 0) && + (bufPointer[i + CN2] == 1) && // 2: 将指针移动2个字节 + (tmp >= 0 && tmp <= CN21) && // 21: ASCII码值 + ((bufPointer[i + CN5] & 0x80) == 0x80)) { // 5: 将指针移动5个字节 + isNewPic = true; + } + if (isNewPic == true) { + isFindStart = true; + i += CN6; // 6: 字节 + break; + } + } + + // 6: 字节 + for (; i < readLen - CN6; i++) { + uint32_t tmp = (bufPointer[i + CN3] & 0x7E) >> 1; // 3: 将指针移动3个字节 + isNewPic = ((bufPointer[i + 0] == 0) && (bufPointer[i + 1] == 0) && + (bufPointer[i + CN2] == 1) && // 2: 指针移动2个字节 + ((tmp == CN32) || (tmp == CN33) || // 32、3: ASCII码值 + (tmp == CN34) || (tmp == CN39) || (tmp == CN40) || // 34、39、40: ASCII码值 + ((tmp >= 0 && tmp <= CN21) && // 21: ASCII码值 + (bufPointer[i + CN5] & 0x80) == 0x80))); // 5: 将指针移动5个字节 + if (isNewPic == true) { + isFindEnd = true; + break; + } + } + if (i > 0) { + readLen = i; + } + if (!isFindStart) { + printf("can not find h265 start code! readLen %d! \n", readLen); + } + if (!isFindEnd) { + readLen = i + CN6; // 6: 字节 + } +} + +void DecodedMbufVideoSender::GetEveryFrame(GetFrameMsg& frameMsg) +{ + int32_t chanId = frameMsg.chanId; + uint8_t * const inputFileBuf = frameMsg.inputFileBuf; + uint32_t * const frameCount = frameMsg.frameCount; + uint32_t fileSize = frameMsg.fileSize; + hi_payload_type type = frameMsg.type; + uint8_t *dataDev = frameMsg.dataDev; int32_t i = 0; int32_t usedBytes = 0; int32_t readLen = 0; @@ -699,6 +923,7 @@ void MbufVideoSender::get_every_frame(int32_t chanId, uint8_t *const inputFileBu uint8_t *bufPointer = NULL; bool isFindStart = false; bool isFindEnd = false; + while (1) { isFindStart = false; isFindEnd = false; @@ -708,74 +933,16 @@ void MbufVideoSender::get_every_frame(int32_t chanId, uint8_t *const inputFileBu break; } if (type == HI_PT_H264) { - for (i = 0; i < readLen - 8; i++) { - int32_t tmp = bufPointer[i + 3] & 0x1F; - if ((bufPointer[i] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + 2] == 1) && - (((tmp == 0x5 || tmp == 0x1) && ((bufPointer[i + 4] & 0x80) == 0x80)) || - (tmp == 20 && (bufPointer[i + 7] & 0x80) == 0x80))) { - isFindStart = true; - i += 8; - break; - } - } - for (; i < readLen - 8; i++) { - int32_t tmp = bufPointer[i + 3] & 0x1F; - if ((bufPointer[i] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + 2] == 1) && - ((tmp == 15) || (tmp == 7) || (tmp == 8) || (tmp == 6) || - ((tmp == 5 || tmp == 1) && ((bufPointer[i + 4] & 0x80) == 0x80)) || - (tmp == 20 && (bufPointer[i + 7] & 0x80) == 0x80))) { - isFindEnd = true; - break; - } - } - if (i > 0) { - readLen = i; - } - if (isFindStart == false) { - printf("Chn %d can not find h264 start code! readLen %d, usedBytes %d! \n", chanId, readLen, usedBytes); - } - if (isFindEnd == false) { - readLen = i + 8; - } + GetFrameHost(i, readLen, bufPointer, isFindStart, isFindEnd); } else if (type == HI_PT_H265) { - bool isNewPic = false; - for (i = 0; i < readLen - 6; i++) { - uint32_t tmp = (bufPointer[i + 3] & 0x7E) >> 1; - if ((bufPointer[i + 0] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + 2] == 1) && - (tmp >= 0 && tmp <= 21) && ((bufPointer[i + 5] & 0x80) == 0x80)) { - isNewPic = true; - } - if (isNewPic == true) { - isFindStart = true; - i += 6; - break; - } - } - for (; i < readLen - 6; i++) { - uint32_t tmp = (bufPointer[i + 3] & 0x7E) >> 1; - isNewPic = ((bufPointer[i + 0] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + 2] == 1) && - ((tmp == 32) || (tmp == 33) || (tmp == 34) || (tmp == 39) || (tmp == 40) || - ((tmp >= 0 && tmp <= 21) && (bufPointer[i + 5] & 0x80) == 0x80))); - if (isNewPic == true) { - isFindEnd = true; - break; - } - } - if (i > 0) { - readLen = i; - } - if (isFindStart == false) { - printf("Chn %d can not find h265 start code! readLen %d, usedBytes %d! \n", chanId, readLen, usedBytes); - } - if (isFindEnd == false) { - readLen = i + 6; - } + DealGetFrameHost(i, readLen, bufPointer, isFindStart, isFindEnd); } if (g_run_mode == ACL_HOST) { g_frame_addr[chanId][count] = (bufPointer - inputFileBuf) + dataDev; } else { g_frame_addr[chanId][count] = bufPointer; } + g_frame_len[chanId][count] = readLen; count++; usedBytes = usedBytes + readLen; @@ -783,46 +950,41 @@ void MbufVideoSender::get_every_frame(int32_t chanId, uint8_t *const inputFileBu *frameCount = count; } -void MbufVideoSender::delay_exec(uint64_t execTime, int32_t seconds) +void DecodedMbufVideoSender::delay_exec(uint64_t execTime, int32_t seconds) { - struct timeval currentTime; + timeval currentTime; uint64_t tmpCurtime = 0; - uint64_t secondToUs = 1000000; + uint64_t secondToUs = CN1000000; gettimeofday(¤tTime, NULL); tmpCurtime = currentTime.tv_sec * secondToUs + currentTime.tv_usec; uint64_t nextExecTime = execTime + seconds * secondToUs; while (tmpCurtime < nextExecTime) { - usleep(500); + usleep(500); // 500:0.5ms gettimeofday(¤tTime, NULL); tmpCurtime = currentTime.tv_sec * secondToUs + currentTime.tv_usec; } return; } -void MbufVideoSender::show_decode_performance() +void DecodedMbufVideoSender::ShowDecodePerformance() { double averFrameRate = 0; uint32_t chnNum = 0; - uint64_t secondToUs = 1000000; + uint64_t secondToUs = CN1000000; for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { uint64_t diffTime = g_vdec_end_time[i] - g_vdec_start_time[i]; if (diffTime == 0) { continue; } - printf("\033[0;33m -------------------------------------------------------- \033[0;39m\n"); double actualFrameRate = ((double)g_vdec_get_frame_cnt[i] * secondToUs) / diffTime; - printf("\033[0;33m chnId %u, actualFrameRate %.1f, SendFrameCnt %lu, DiffTime %lu \033[0;39m\n", - i, actualFrameRate, g_vdec_get_frame_cnt[i], diffTime); - printf("\033[0;33m -------------------------------------------------------- \033[0;39m\n"); averFrameRate += actualFrameRate; chnNum++; } averFrameRate = averFrameRate / chnNum; - printf("\033[0;33m ChanNum = %u, Average FrameRate = %.1f fps \033[0;39m\n", chnNum, averFrameRate); return; } -int32_t MbufVideoSender::get_option(int32_t argc, char **argv) +int32_t DecodedMbufVideoSender::get_option(int32_t argc, char **argv) { int32_t ret = HI_SUCCESS; while (1) { @@ -851,12 +1013,23 @@ int32_t MbufVideoSender::get_option(int32_t argc, char **argv) {"start_chn", 1, 0, 'w'}, {"render", 1, 0, 'v'} }; - int32_t parameter = getopt_long(argc, argv, - "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:w:v:", longOptions, &optionIndex); + int32_t parameter = + getopt_long(argc, argv, "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:w:v:", longOptions, &optionIndex); if (parameter == -1) { break; } - switch (parameter) { + option_switch_al(parameter); + option_switch_mv(parameter); + if (ret != HI_SUCCESS) { + return ret; + } + } + return ret; +} + +void DecodedMbufVideoSender::option_switch_al(int32_t parameter) +{ + switch (parameter) { case 'a': g_in_width = atoi(optarg); break; @@ -864,7 +1037,9 @@ int32_t MbufVideoSender::get_option(int32_t argc, char **argv) g_in_height = atoi(optarg); break; case 'c': - strcpy(g_input_file_name, optarg); + if (strcpy_s(g_input_file_name, sizeof(optarg) + 1, optarg) != 0) { + std::cout<< "strcpy_s g_input_file_name failed, filename: " < 4096) || (g_in_width < 128)) { + // 4096、128:输入内容的宽 + if ((g_in_width > CN4096) || (g_in_width < CN128)) { printf("[%s][%d] input file width is invalid, width = %u \n", __FUNCTION__, __LINE__, g_in_width); - return HI_FAILURE; + return (void)HI_FAILURE; } - if ((g_in_height > 4096) || (g_in_height < 128)) { + // 4096、128:输入内容的高 + if ((g_in_height > CN4096) || (g_in_height < CN128)) { printf("[%s][%d] input file height is invalid, height = %u \n", __FUNCTION__, __LINE__, g_in_height); - return HI_FAILURE; + return (void)HI_FAILURE; } if ((g_in_format != 0) && (g_in_format != 1)) { printf("[%s][%d] input format is invalid, format = %u \n", __FUNCTION__, __LINE__, g_in_format); - return HI_FAILURE; + return (void)HI_FAILURE; } - if ((g_in_bitwidth != 8) && (g_in_bitwidth != 10)) { + // 8、10:输入内容的位宽 + if ((g_in_bitwidth != CN8) && (g_in_bitwidth != CN10)) { printf("[%s][%d] input bitwidth is invalid, bitwidth = %u \n", __FUNCTION__, __LINE__, g_in_bitwidth); - return HI_FAILURE; + return (void)HI_FAILURE; } - if ((g_out_width != 0) && ((g_out_width > 4096) || (g_out_width < 10))) { + // 4096、10:输入内容的宽 + if ((g_out_width != 0) && ((g_out_width > CN4096) || (g_out_width < CN10))) { printf("[%s][%d] output width is invalid, width = %u \n", __FUNCTION__, __LINE__, g_out_width); - return HI_FAILURE; + return (void)HI_FAILURE; } - if ((g_out_height != 0) && ((g_out_height > 4096) || (g_out_height < 6))) { + // 4096、6:输入内容的高 + if ((g_out_height != 0) && ((g_out_height > CN4096) || (g_out_height < CN6))) { printf("[%s][%d] output height is invalid, height = %u \n", __FUNCTION__, __LINE__, g_out_height); - return HI_FAILURE; + return (void)HI_FAILURE; } - if (g_out_format > 3) { + // 3:输出信息的格式 + if (g_out_format > CN3) { printf("[%s][%d] output format is invalid, format = %u \n", __FUNCTION__, __LINE__, g_out_format); - return HI_FAILURE; + return (void)HI_FAILURE; } - if ((g_out_width_stride % 16 != 0) || (g_out_width_stride < g_out_width) || (g_out_width_stride < 32)) { - printf("[%s][%d] output width stride is invalid, width stride = %u \n", __FUNCTION__, __LINE__, g_out_width_stride); - return HI_FAILURE; + // 16:步长,输入数据的宽度要是16的整数倍,32:输出的数据宽 + if ((g_out_width_stride % CN16 != 0) || (g_out_width_stride < g_out_width) || (g_out_width_stride < CN32)) { + return (void)HI_FAILURE; } - if (((g_out_format == 2) || (g_out_format == 3)) && (g_out_width_stride < g_out_width * 3)) { - printf("[%s][%d] output width stride is invalid, width stride = %u \n", __FUNCTION__, __LINE__, g_out_width_stride); - return HI_FAILURE; + // 2、3:输出信息的格式,3:宽度占比 + if (((g_out_format == CN2) || (g_out_format == CN3)) && (g_out_width_stride < g_out_width * CN3)) { + return (void)HI_FAILURE; } - if (((g_out_height_stride % 2 != 0) && ((g_out_format == 0) || (g_out_format == 1))) || - (g_out_height_stride < g_out_height)) { - printf("[%s][%d] output height stride is invalid, height stride = %u \n", __FUNCTION__, __LINE__, g_out_height_stride); - return HI_FAILURE; + // 2:高度占比 + if (((g_out_height_stride % CN2 != 0) && ((g_out_format == 0) || (g_out_format == 1))) || + (g_out_height_stride < g_out_height)) { + return (void)HI_FAILURE; } +} + +int32_t DecodedMbufVideoSender::check_option() +{ + // 输出内容的格式 + CheckOptionFormat(); if (g_is_write_file > 1) { - printf("[%s][%d] write file parameter is invalid, isWriteFile = %u \n", __FUNCTION__, __LINE__, g_is_write_file); return HI_FAILURE; } - if ((g_chn_num > 96) || (g_chn_num < 1)) { + // 96:chan num + if ((g_chn_num > CN96) || (g_chn_num < 1)) { printf("[%s][%d] chan num is invalid, chan num = %u \n", __FUNCTION__, __LINE__, g_chn_num); return HI_FAILURE; } - if (g_ref_frame_num > 16) { + // 16: RefFrame num + if (g_ref_frame_num > CN16) { printf("[%s][%d] RefFrame num is invalid, RefFrame num = %u \n", __FUNCTION__, __LINE__, g_ref_frame_num); return HI_FAILURE; } - if (g_display_frame_num > 16) { - printf("[%s][%d] DisplayFrame num is invalid, DisplayFrame num = %u \n", __FUNCTION__, __LINE__, g_display_frame_num); + // 16:显示的帧数 + if (g_display_frame_num > CN16) { return HI_FAILURE; } - if (g_output_order > 2) { + // 2:输出顺序 + if (g_output_order > CN2) { printf("[%s][%d] output order is invalid, output order = %u \n", __FUNCTION__, __LINE__, g_output_order); return HI_FAILURE; } @@ -1004,7 +1199,7 @@ int32_t MbufVideoSender::check_option() return HI_SUCCESS; } -void MbufVideoSender::print_parameter() +void DecodedMbufVideoSender::PrintParameter() { printf("\n/****************************Vdec Parameter****************************/\n"); printf("InputFileName: %s \n", g_input_file_name); @@ -1031,30 +1226,29 @@ void MbufVideoSender::print_parameter() printf("/**********************************************************************/\n"); } -void MbufVideoSender::vdec_handle_signal(int32_t signo) +void DecodedMbufVideoSender::vdec_handle_signal(int32_t signo) { for (int32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { g_send_exit_state[i] = 1; } g_exit = 1; - printf("Program Exit Abnormally! \n"); } -void MbufVideoSender::init_outbuffer_lock() +void DecodedMbufVideoSender::InitOutbufferLock() { for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { pthread_mutex_init(&g_out_buffer_pool_lock[i], NULL); } } -void MbufVideoSender::destroy_outbuffer_lock() +void DecodedMbufVideoSender::DestroyOutbufferLock() { for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { pthread_mutex_destroy(&g_out_buffer_pool_lock[i]); } } -void MbufVideoSender::release_outbuffer(uint32_t chanId) +void DecodedMbufVideoSender::release_outbuffer(uint32_t chanId) { void *outBuffer = NULL; while (g_out_buffer_pool[chanId].empty() == false) { @@ -1064,80 +1258,78 @@ void MbufVideoSender::release_outbuffer(uint32_t chanId) } } -void MbufVideoSender::get_start_time() +void DecodedMbufVideoSender::GetStartTime() { - struct timeval currentTime; + timeval currentTime; gettimeofday(¤tTime, NULL); - g_start_time = currentTime.tv_sec * 1000000 + currentTime.tv_usec; + g_start_time = currentTime.tv_sec * sleepTimeIntervalMs + currentTime.tv_usec; } -int32_t MbufVideoSender::hi_dvpp_init() +int32_t DecodedMbufVideoSender::hi_dvpp_init() { int32_t s32Ret = ACL_SUCCESS; aclError aclRet = aclInit(NULL); + // 100002:重复初始化或重复加载 if ((aclRet != ACL_SUCCESS) && (aclRet != 100002)) { - printf("[%s][%d] aclInit failed, error code = %d. \n", __FUNCTION__, __LINE__, aclRet); return HI_FAILURE; } - printf("[%s][%d] aclInit success \n", __FUNCTION__, __LINE__); aclRet = aclrtSetDevice(0); if (aclRet != ACL_SUCCESS) { - printf("[%s][%d] aclrtSetDevice 0 failed, error code = %d \n", __FUNCTION__, __LINE__, aclRet); aclFinalize(); return HI_FAILURE; } - printf("[%s][%d] aclrtSetDevice 0 success \n", __FUNCTION__, __LINE__); aclRet = aclrtCreateContext(&g_context, 0); if (aclRet != ACL_SUCCESS) { - printf("[%s][%d] aclrtCreateContext failed, error code = %d \n", __FUNCTION__, __LINE__, aclRet); aclrtResetDevice(0); aclFinalize(); return HI_FAILURE; } - printf("[%s][%d] aclrtCreateContext success \n", __FUNCTION__, __LINE__); int32_t ret = hi_mpi_sys_init(); if (ret != HI_SUCCESS) { - printf("[%s][%d] hi_mpi_sys_init failed, error code = %x \n", __FUNCTION__, __LINE__, ret); +#ifdef IN_GITE aclrtDestroyContext(g_context); +#endif aclrtResetDevice(0); aclFinalize(); return HI_FAILURE; } aclRet = aclrtGetRunMode(&g_run_mode); if (aclRet != HI_SUCCESS) { - printf("[%s][%d] aclrtGetRunMode failed, error code = %x. \n", __FUNCTION__, __LINE__, aclRet); hi_mpi_sys_exit(); aclrtDestroyContext(g_context); aclrtResetDevice(0); aclFinalize(); return HI_FAILURE; } - printf("[%s][%d] Dvpp system init success \n", __FUNCTION__, __LINE__); return HI_SUCCESS; } -void MbufVideoSender::hi_dvpp_deinit() +int32_t DecodedMbufVideoSender::HiDvppDeinit() { int32_t ret = hi_mpi_sys_exit(); if (ret != HI_SUCCESS) { printf("[%s][%d] hi_mpi_sys_exit failed, error code = %x. \n", __FUNCTION__, __LINE__, ret); + return ret; } aclError aclRet = aclrtDestroyContext(g_context); if (aclRet != ACL_SUCCESS) { printf("[%s][%d] aclrtDestroyContext failed, error code = %d. \n", __FUNCTION__, __LINE__, aclRet); + return aclRet; } aclRet = aclrtResetDevice(0); if (aclRet != ACL_SUCCESS) { printf("[%s][%d] aclrtResetDevice 0 failed, error code = %d. \n", __FUNCTION__, __LINE__, aclRet); + return aclRet; } aclRet = aclFinalize(); + // 100037:重复去初始化 if ((aclRet != ACL_SUCCESS) && (aclRet != 100037)) { printf("[%s][%d] aclFinalize failed, error code = %d. \n", __FUNCTION__, __LINE__, aclRet); } - printf("[%s][%d] Dvpp system exit success \n", __FUNCTION__, __LINE__); + return aclRet; } -void MbufVideoSender::stop_send_stream_thread() +void DecodedMbufVideoSender::StopSendStreamThread() { for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { g_send_exit_state[i] = 1; @@ -1145,7 +1337,7 @@ void MbufVideoSender::stop_send_stream_thread() g_exit = 1; } -void MbufVideoSender::stop_get_pic_thread() +void DecodedMbufVideoSender::StopGetPicThread() { for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { g_get_exit_state[i] = 1; @@ -1153,3 +1345,4 @@ void MbufVideoSender::stop_get_pic_thread() } g_exit = 1; } + diff --git a/mdc/src/decoded_mbuf_video_sender.h b/mdc/src/decoded_mbuf_video_sender.h index 95f0e2ce09bac2243d9d5a88030b8ab53f56e454..593897e7663e486246d6e99b2507f0ab77c281e0 100644 --- a/mdc/src/decoded_mbuf_video_sender.h +++ b/mdc/src/decoded_mbuf_video_sender.h @@ -1,107 +1,87 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: decoded_mbuf_yuv_sender head file -*/ -#ifndef DECODED_MBUF_YUV_SENDER_H -#define DECODED_MBUF_YUV_SENDER_H -#include "image_sender_base.h" -#include "mdc/cam/camera/cameradecodedmbufserviceinterface_skeleton.h" -#include "util.h" -#include "core/types.h" -#include "driver/ascend_hal.h" -#include "securec.h" + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: decoded_mbuf_yuv_sender head file + */ +#ifndef DECODED_MBUF_VIDEO_SENDER_H +#define DECODED_MBUF_VIDEO_SENDER_H #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include #include - +#include #include "acl.h" #include "acl_rt.h" #include "hi_dvpp.h" +#include "image_sender_base.h" +#include "mdc/cam/camera/cameradecodedmbufserviceinterface_skeleton.h" +#include "util.h" +#include "core/types.h" +#include "driver/ascend_hal.h" +#include "securec.h" + #include "driver/ascend_hal.h" #include "driver/ascend_hal_define.h" -using namespace std; -using namespace cv; const int32_t MAX_NAME_LENGTH = 500; -using MbufSkeleton = mdc::cam::camera::skeleton::CameraDecodedMbufServiceInterfaceSkeleton; -class MbufVideoSender : public ImageSenderBase -{ - typedef void *(*pFUNC)(void *); -private: - poolHandle handle; - float lastTime = 0.0F; - char g_input_file_name[MAX_NAME_LENGTH] = "test264.h264"; - char g_output_file_name[MAX_NAME_LENGTH] = "./outfile"; - uint32_t g_in_width = 3840; // input stream width - uint32_t g_in_height = 2160; // input stream height - uint32_t g_in_format = 0; - uint32_t g_in_bitwidth = 8; - uint32_t g_out_width = 0; - uint32_t g_out_height = 0; - uint32_t g_out_format = 0; - uint32_t g_out_width_stride = 4096; - uint32_t g_out_height_stride = 4096; - uint32_t g_is_write_file = 1; - uint32_t g_chn_num = 1; - uint32_t g_ref_frame_num = 8; - uint32_t g_display_frame_num = 2; - uint32_t g_output_order = 0; - uint32_t g_send_times = 1; - uint32_t g_send_interval = 0; - uint32_t g_delay_time = 1; - uint32_t g_alloc_num = 20; - uint32_t g_start_chn_num = 0; - uint32_t g_render = 0; - uint32_t g_exit = 0; +struct GetFrameMsg { + uint32_t chanId = 0; + uint8_t *inputFileBuf = nullptr; + uint32_t *frameCount = nullptr; + uint32_t fileSize = 0; + hi_payload_type type = HI_PT_H264; + uint8_t *dataDev = nullptr; - uint32_t g_chan_create_state[VDEC_MAX_CHN_NUM] = {0}; - uint64_t g_start_time = 0; + void *outBuffer = nullptr; + uint32_t outBufferSize = 0; + uint32_t outFormat = 0; + hi_vdec_stream stream; + uint32_t readCount = 0; +}; - std::vector g_out_buffer_pool[VDEC_MAX_CHN_NUM]; - pthread_mutex_t g_out_buffer_pool_lock[VDEC_MAX_CHN_NUM]; +struct InputMsg { + FILE *fpInputFile = NULL; + aclError aclRet = ACL_SUCCESS; + uint32_t fileSize = 0; + uint8_t *inputFileBuf = NULL; + uint32_t readLen = 0; + int32_t ret = HI_SUCCESS; +}; - uint32_t g_send_exit_state[VDEC_MAX_CHN_NUM] = {0}; - uint32_t g_get_exit_state[VDEC_MAX_CHN_NUM] = {0}; +struct DealDecRunNode { + uint32_t imageSize; + uint32_t chanId; + uint32_t outWidthStride; + uint32_t outHeightStride; +}; - pthread_t g_vdec_send_thread[VDEC_MAX_CHN_NUM] = {0}; - pthread_t g_vdec_get_thread[VDEC_MAX_CHN_NUM] = {0}; - uint32_t g_send_thread_id[VDEC_MAX_CHN_NUM] = {0}; - uint32_t g_get_thread_id[VDEC_MAX_CHN_NUM] = {0}; +using MbufSkeleton = mdc::cam::camera::skeleton::CameraDecodedMbufServiceInterfaceSkeleton; - uint8_t *g_frame_addr[VDEC_MAX_CHN_NUM][9999]; - uint64_t g_frame_len[VDEC_MAX_CHN_NUM][9999]; - uint64_t g_vdec_start_time[VDEC_MAX_CHN_NUM] = {0}; - uint64_t g_vdec_end_time[VDEC_MAX_CHN_NUM] = {0}; - uint64_t g_vdec_get_frame_cnt[VDEC_MAX_CHN_NUM] = {0}; +class DecodedMbufVideoSender : public ImageSenderBase { + using PFunc = void *(*)(void *); - aclrtRunMode g_run_mode = ACL_HOST; - std::string sourceYuvPath; - FILE *fp_yuv; - chrono::high_resolution_clock::time_point sec; public: aclrtContext g_context = NULL; public: - MbufVideoSender() = default; - MbufVideoSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) + DecodedMbufVideoSender() = default; + DecodedMbufVideoSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) { g_in_width = s.width; g_in_height = s.height; g_out_width = s.width; g_out_height = s.height; - if (comPara.fileType == "h264") { + if (g_comPara.fileType == "h264") { g_in_format = 0; - } else if (comPara.fileType == "h265") { + } else if (g_comPara.fileType == "h265") { g_in_format = 1; } g_out_format = 0; @@ -110,16 +90,16 @@ public: g_out_height_stride = s.height; sourceYuvPath = dir; if (dir.back() != '/') { - sourceYuvPath += string("/") + "videoSource.yuv"; + sourceYuvPath += std::string("/") + "videoSource.yuv"; } else { sourceYuvPath += "videoSource.yuv"; } #ifdef SAVE_SENDER_FILE fp_yuv = fopen(sourceYuvPath.c_str(), "wb+"); #endif - sec = chrono::high_resolution_clock::now(); + sec = std::chrono::high_resolution_clock::now(); } - ~MbufVideoSender() + ~DecodedMbufVideoSender() { if (dataSkeleton != nullptr) { dataSkeleton->StopOfferService(); @@ -132,32 +112,38 @@ public: bool RegisterSender() { - std::cout << "Begin register MBUF image sender." << endl; + std::cout << "Begin register MBUF image sender." << std::endl; auto result = ImageSenderBase::RegisterSender(); - std::cout << "Finished to register MBUF image sender." << endl; + std::cout << "Finished to register MBUF image sender." << std::endl; return result; } - void VdecDecoded() + bool VdecDecoded() { std::string path = dir; - std::string postfix = comPara.fileType; - bool isLoop = comPara.loop; - cout << "dir : " << dir << "\t" << " postfix : " << postfix << endl; + std::string postfix = g_comPara.fileType; + bool isLoop = g_comPara.loop; std::vector files; - int32_t fileCnt = getFilesBySort(path, files, comPara.fileType); + int32_t fileCnt = getFilesBySort(path, files, g_comPara.fileType); if (fileCnt == 0) { - cout << "PATH:" << path << " has no files!" << endl; - return; + std::cout << "PATH:" << path << " has no files!" << std::endl; + return false; } do { for (auto &file : files) { if (file.empty()) { std::cerr << "File not exist, or corrupt.path: " << file << std::endl; - return; + return false; + } + errno_t ret = memset_s(g_input_file_name, sizeof(g_input_file_name), 0, MAX_NAME_LENGTH); + if (ret != EOK) { + std::cout << "memset_s failed:" << ret << std::endl; + return false; + } + if (strcpy_s(g_input_file_name, file.length() + 1, file.c_str()) != 0) { + std::cout << "strcpy_s g_input_file_name failed, file_name:" << g_input_file_name << std::endl; + return false; } - memset(g_input_file_name, 0, MAX_NAME_LENGTH); - strcpy(g_input_file_name, file.c_str()); VdecInit(); InitThreadPara(); VdecProcess(); @@ -165,22 +151,25 @@ public: } } while (isLoop); #ifdef SAVE_SENDER_FILE - fclose(fp_yuv); + if (fclose(fp_yuv) != 0) { + std::cout << " fclose(fp_yuv) != 0 " << std::endl; + } #endif + return true; } void InitThreadPara() { g_send_exit_state[VDEC_MAX_CHN_NUM] = {0}; g_get_exit_state[VDEC_MAX_CHN_NUM] = {0}; - g_vdec_send_thread[VDEC_MAX_CHN_NUM] = {0}; - g_vdec_get_thread[VDEC_MAX_CHN_NUM] = {0}; + g_vdec_send_thread[VDEC_MAX_CHN_NUM] = {}; + g_vdec_get_thread[VDEC_MAX_CHN_NUM] = {}; g_send_thread_id[VDEC_MAX_CHN_NUM] = {0}; g_get_thread_id[VDEC_MAX_CHN_NUM] = {0}; } int32_t VdecInit() { - print_parameter(); + PrintParameter(); int32_t ret = HI_SUCCESS; ret = hi_dvpp_init(); if (ret != HI_SUCCESS) { @@ -190,34 +179,35 @@ public: ret = vdec_create(); if (ret != HI_SUCCESS) { printf("[%s][%d] VdecStart failed \n", __FUNCTION__, __LINE__); - vdec_destroy(); - hi_dvpp_deinit(); + VdecDestroy(); + HiDvppDeinit(); return -1; } - init_outbuffer_lock(); - get_start_time(); + InitOutbufferLock(); + GetStartTime(); return ret; } void VdecUninit() { - wait_vdec_end(); - show_decode_performance(); - destroy_outbuffer_lock(); - vdec_destroy(); - hi_dvpp_deinit(); + WaitVdecEnd(); + ShowDecodePerformance(); + DestroyOutbufferLock(); + VdecDestroy(); + HiDvppDeinit(); } - void VdecProcess() + int32_t VdecProcess() { int32_t ret = HI_SUCCESS; ret = create_send_stream_thread(); if (ret != 0) { - stop_send_stream_thread(); + StopSendStreamThread(); } else { ret = create_get_pic_thread(); if (ret != 0) { - stop_get_pic_thread(); + StopGetPicThread(); } } + return ret; } int32_t BufCreatePool(const uint32_t blkSize, const uint32_t blkNum) { @@ -261,7 +251,8 @@ public: halBuffFree(pMbuf); return -1; } - if (memcpy_s(reinterpret_cast(dst), static_cast(bufSize), src, static_cast(len)) != 0) { + if (memcpy_s(reinterpret_cast(dst), static_cast(bufSize), src, + static_cast(len)) != 0) { std::cout << "Error: Copy src data to mbuf error!" << std::endl; halBuffFree(pMbuf); return -1; @@ -275,38 +266,114 @@ public: mbuf = reinterpret_cast(pMbuf); return 0; } - void FillImageAndSend(std::string imgPath, uint32_t seq, void *g_stopFlag) override {} + void FillImageAndSend(std::string imgPath, uint32_t seq, int32_t *gStopFlag) override {} + public: int32_t get_option(int32_t argc, char **argv); + void option_switch_al(int32_t parameter); + void option_switch_mv(int32_t parameter); int32_t check_option(); - void print_parameter(); + void CheckOptionFormat(); + void PrintParameter(); void vdec_handle_signal(int32_t signo); int32_t vdec_create(); - void vdec_destroy(); + void VdecDestroy(); int32_t create_send_stream_thread(); int32_t create_get_pic_thread(); - void stop_send_stream_thread(); - void stop_get_pic_thread(); - static void *send_stream(void *arg); - static void *get_pic(void *arg); - void get_every_frame(int32_t chanId, uint8_t *const inputFileBuf, uint32_t *const frameCount, uint32_t fileSize, - hi_payload_type type, uint8_t *devData); + void StopSendStreamThread(); + void StopGetPicThread(); + static void *SendStream(DecodedMbufVideoSender *thiz); + static void *GetPic(DecodedMbufVideoSender *thiz); + void GetEveryFrame(GetFrameMsg& frameMsg); void delay_exec(uint64_t execTime, int32_t seconds); - void wait_vdec_end(); - void show_decode_performance(); - void get_start_time(); - void init_outbuffer_lock(); - void destroy_outbuffer_lock(); + void WaitVdecEnd(); + void ShowDecodePerformance(); + void GetStartTime(); + void InitOutbufferLock(); + void DestroyOutbufferLock(); void release_outbuffer(uint32_t chanId); int32_t hi_dvpp_init(); - void hi_dvpp_deinit(); + int32_t HiDvppDeinit(); + +private: + poolHandle handle; + float lastTime = 0.0F; + const int32_t frameWidthTriploid = 3; + + const int32_t sleepTimeIntervalMs { 1000000 }; + + char g_input_file_name[MAX_NAME_LENGTH] = "test264.h264"; + char g_output_file_name[MAX_NAME_LENGTH] = "./outfile"; + uint32_t g_in_width = 3840; // input stream width + uint32_t g_in_height = 2160; // input stream height + uint32_t g_in_format = 0; + uint32_t g_in_bitwidth = 8; + uint32_t g_out_width = 0; + uint32_t g_out_height = 0; + uint32_t g_out_format = 0; + uint32_t g_out_width_stride = 4096; + uint32_t g_out_height_stride = 4096; + uint32_t g_is_write_file = 1; + uint32_t g_chn_num = 1; + uint32_t g_ref_frame_num = 8; + uint32_t g_display_frame_num = 2; + uint32_t g_output_order = 0; + uint32_t g_send_times = 1; + uint32_t g_send_interval = 0; + uint32_t g_delay_time = 1; + uint32_t g_alloc_num = 20; + uint32_t g_start_chn_num = 0; + uint32_t g_render = 0; + uint32_t g_exit = 0; + + uint32_t g_chan_create_state[VDEC_MAX_CHN_NUM] = {0}; + uint64_t g_start_time = 0; + + std::vector g_out_buffer_pool[VDEC_MAX_CHN_NUM]; + pthread_mutex_t g_out_buffer_pool_lock[VDEC_MAX_CHN_NUM]; + + uint32_t g_send_exit_state[VDEC_MAX_CHN_NUM] = {0}; + uint32_t g_get_exit_state[VDEC_MAX_CHN_NUM] = {0}; + + std::thread g_vdec_send_thread[VDEC_MAX_CHN_NUM] = {}; + std::thread g_vdec_get_thread[VDEC_MAX_CHN_NUM] = {}; + uint32_t g_send_thread_id[VDEC_MAX_CHN_NUM] = {0}; + uint32_t g_get_thread_id[VDEC_MAX_CHN_NUM] = {0}; + + uint8_t *g_frame_addr[VDEC_MAX_CHN_NUM][9999]; + uint64_t g_frame_len[VDEC_MAX_CHN_NUM][9999]; + uint64_t g_vdec_start_time[VDEC_MAX_CHN_NUM] = {0}; + uint64_t g_vdec_end_time[VDEC_MAX_CHN_NUM] = {0}; + uint64_t g_vdec_get_frame_cnt[VDEC_MAX_CHN_NUM] = {0}; + + aclrtRunMode g_run_mode = ACL_HOST; + std::string sourceYuvPath; + FILE *fp_yuv; + std::chrono::high_resolution_clock::time_point sec; + DealDecRunNode dealDecRunNode; + private: int32_t InitGrp(void); void get_current_time_us(uint64_t &timeUs); - void save_yuv_file(FILE *const fd, hi_video_frame frame, uint32_t chanId); - void FillYuvAndSend(uint8_t *ptr, int32_t w, int32_t h); - void save_rgb_file(FILE *const fd, hi_video_frame frame, uint32_t chanId); - void vdec_reset_chn(uint32_t chanId); + bool save_yuv_file(FILE *const fd, hi_video_frame frame, uint32_t chanId); + void SaveRgbFileAclHost(hi_video_frame frame, uint8_t *outImageBuf, FILE * const fd, uint32_t chanId); + void SaveYuvFileAclHost(hi_video_frame frame, uint8_t *outImageBuf, FILE * const fd, uint32_t chanId); + bool DealRunNode(uint8_t *addr, hi_video_frame frame, FILE * const fd); + static void GetPicHost(hi_video_frame_info& frame, DecodedMbufVideoSender *thiz, + uint32_t& chanId, hi_vdec_stream& stream, int32_t& writeFileCnt); + static void UpdateOutPicInfo(hi_vdec_pic_info &outPicInfo, DecodedMbufVideoSender *thiz, uint32_t chanId, + GetFrameMsg& frameMsg); + static int32_t DealSendFormat(DecodedMbufVideoSender *thiz, GetFrameMsg& frameMsg, FILE *fpInputFile); + static bool DealDataDev(DecodedMbufVideoSender *thiz, uint8_t *dataDev, FILE *fpInputFile, + GetFrameMsg& frameMsg); + static void DealInput(DecodedMbufVideoSender *thiz, InputMsg& inputMsg); + void GetFrameHost(int32_t& i, int32_t& readLen, uint8_t *bufPointer, bool& isFindStart, bool& isFindEnd); + void DealGetFrameHost(int32_t& i, int32_t& readLen, uint8_t *bufPointer, bool& isFindStart, bool& isFindEnd); + bool FillYuvAndSend(uint8_t *ptr, int32_t w, int32_t h); + bool save_rgb_file(FILE *const fd, hi_video_frame frame, uint32_t chanId); + bool vdec_reset_chn(uint32_t chanId); + int32_t DealParam(uint32_t index); + static void DealDecResult(int32_t& decResult, int32_t& successCnt, uint32_t& chanId, int32_t& failCnt); }; -#endif //DECODED_MBUF_YUV_SENDER_H +#endif // DECODED_MBUF_VIDEO_SENDER_H diff --git a/mdc/src/decoded_mbuf_yuv_sender.h b/mdc/src/decoded_mbuf_yuv_sender.h index 46cf5ab7e4d734a2e8f5257517ed54f5f41047f7..c642dc5a6b69c85451fe2d4c80ea4913e897aba4 100644 --- a/mdc/src/decoded_mbuf_yuv_sender.h +++ b/mdc/src/decoded_mbuf_yuv_sender.h @@ -1,9 +1,9 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: mbuf_yuv_sender.h head file -*/ -#ifndef MODULES_CAMERA_SAMPLE_IMAGE_SENDER_MBUF_YUV_SENDER_H_ -#define MODULES_CAMERA_SAMPLE_IMAGE_SENDER_MBUF_YUV_SENDER_H_ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: mbuf_yuv_sender.h head file + */ +#ifndef DECODED_MBUF_YUV_SENDER_H +#define DECODED_MBUF_YUV_SENDER_H #include "image_sender_base.h" #include "mdc/cam/camera/cameradecodedmbufserviceinterface_skeleton.h" @@ -12,35 +12,25 @@ #include "driver/ascend_hal.h" #include "securec.h" -using namespace std; -using namespace cv; - using MbufSkeleton = mdc::cam::camera::skeleton::CameraDecodedMbufServiceInterfaceSkeleton; -class MbufYuvSender : public ImageSenderBase -{ -private: - poolHandle handle; - float lastTime = 0.0F; - chrono::high_resolution_clock::time_point sec;//-t used - std::string sourceYuvPath; - FILE *fp_yuv; +class DecodedMbufYuvSender : public ImageSenderBase { public: - MbufYuvSender() = default; - MbufYuvSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) + DecodedMbufYuvSender() = default; + DecodedMbufYuvSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) { sourceYuvPath = dir; if (dir.back() != '/') { - sourceYuvPath += string("/") + "yuvSource.yuv"; + sourceYuvPath += std::string("/") + "yuvSource.yuv"; } else { sourceYuvPath += "yuvSource.yuv"; } #ifdef SAVE_SENDER_FILE fp_yuv = fopen(sourceYuvPath.c_str(), "wb+"); #endif - sec = chrono::high_resolution_clock::now(); + sec = std::chrono::high_resolution_clock::now(); } - ~MbufYuvSender() + ~DecodedMbufYuvSender() { if (dataSkeleton != nullptr) { dataSkeleton->StopOfferService(); @@ -53,9 +43,9 @@ public: bool RegisterSender() { - std::cout << "Begin register MBUF image sender." << endl; + std::cout << "Begin register MBUF image sender." << std::endl; auto result = ImageSenderBase::RegisterSender(); - std::cout << "Finished to register MBUF image sender." << endl; + std::cout << "Finished to register MBUF image sender." << std::endl; return result; } @@ -82,36 +72,29 @@ public: Mbuf *pMbuf = nullptr; int32_t ret = halMbufAllocByPool(handle, &pMbuf); if (ret != DRV_ERROR_NONE) { - std::cout << "halMbufAllocByPool error: " << ret << std::endl; return -1; } if (pMbuf == nullptr) { - std::cout << "halMbufAllocByPool mbuf null" << std::endl; return -1; } void *dst = nullptr; uint64_t bufSize = 0U; ret = halMbufGetDataPtr(pMbuf, &dst, &bufSize); if (ret != 0 || dst == nullptr) { - std::cout << "MbufGetDataPtr error: " << ret << std::endl; halBuffFree(pMbuf); return -1; } if (len > bufSize) { - std::cout << "ERROR: Src data length[" << len << "] > mbuf size[" << bufSize << "]" << std::endl; halBuffFree(pMbuf); return -1; } - if (memcpy_s( - reinterpret_cast(dst), static_cast(bufSize), src, static_cast(len)) != - 0) { - std::cout << "ERROR: Copy src date to mbuf error!" << std::endl; + if (memcpy_s(reinterpret_cast(dst), static_cast(bufSize), src, + static_cast(len)) != 0) { halBuffFree(pMbuf); return -1; } ret = halMbufSetDataLen(pMbuf, len); if (ret != DRV_ERROR_NONE) { - std::cout << "halMbufSetDataLen error: " << ret << std::endl; halBuffFree(pMbuf); return -1; } @@ -119,87 +102,137 @@ public: return 0; } - void FillImageAndSend(std::string yuvPath, uint32_t seq, void *g_stopFlag) override + void FillImageAndSend(std::string yuvPath, uint32_t seq, int32_t *gStopFlag) override { - (void)g_stopFlag; + (void)gStopFlag; std::string path = dir; - std::string postfix = comPara.fileType; - bool isLoop = comPara.loop; - cout << "dir: " << dir << "\t" << "postfix :" << postfix << endl; + bool isLoop = g_comPara.loop; std::vector files; - int32_t fileCnt = getFilesBySort(path, files, comPara.fileType); + int32_t fileCnt = getFilesBySort(path, files, g_comPara.fileType); if (fileCnt == 0) { - cout << "PATH:" << path << " has no files!" << endl; return; } + do { for (auto &file : files) { - int32_t w = imgSize.width; - int32_t h = imgSize.height; - FILE *yuv_file; - yuv_file = fopen(file.c_str(), "rb"); + FILE *yuv_file = fopen(file.c_str(), "rb"); + if (g_switchFlag == CN40) + yuv_file = nullptr; if (yuv_file == nullptr) { - cout << "Open yuv file failed!" << endl; + std::cout << "Open yuv file failed!" << std::endl; return; } - int32_t frameSize = w * h * 3 / 2; - fseek(yuv_file, 0, SEEK_END); + + int32_t frameSize = imgSize.width * imgSize.height * 3 / 2; + if (fseek(yuv_file, 0, SEEK_END) != 0) { + std::cout << "fseek yuv file failed!" << std::endl; + return; + } + int32_t fileSize = ftell(yuv_file); + const int32_t size = -1L; + if (g_switchFlag == CN41) + fileSize = size; + if (fileSize == size) { + std::cout << "ftell yuv file failed!" << std::endl; + return; + } + rewind(yuv_file); int32_t frameCount = fileSize / frameSize; - char *yuvBuff = (char *)malloc(frameSize * sizeof(char)); for (int32_t i = 0; i < frameCount; i++) { - Mat YUV420NV12; - YUV420NV12.create(h * 1.5, w, CV_8UC1); - memset(yuvBuff, 0, frameSize); - fread(yuvBuff, sizeof(char), frameSize, yuv_file); - memcpy(YUV420NV12.data, yuvBuff, frameSize); - auto imagePub = dataSkeleton->cameraDecodedMbufEvent.Allocate(); - imagePub->CameraHeader.Seq = seq; - imagePub->FrameType = static_cast < decltype(imagePub->FrameType) > (Adsfi::HAF_IMAGE_YUV420SP_NV12_UINT8); - imagePub->Width = w; - imagePub->Height = h; - imagePub->DataSize = frameSize; - imagePub->CameraHeader.FrameId = file; - uintptr_t imgdata{}; - (void)CopyToMbuf(imgdata, YUV420NV12.data, frameSize); - if (imgdata == reinterpret_cast(nullptr)) { - std::cout << "ERROR: CopyToMbuf failed!" << std::endl; - return; - } - imagePub->RawData = reinterpret_cast(imgdata); -#ifdef SAVE_SENDER_FILE - fwrite(YUV420NV12.data, 1, frameSize, fp_yuv); -#endif - if (comPara.time.empty()) { - timeval now; - gettimeofday(&now, NULL); - imagePub->CameraHeader.Stamp.Sec = now.tv_sec; - imagePub->CameraHeader.Stamp.Nsec = now.tv_usec * 1000U; - } else { - time_t timeStamp = convertTimeStr2TimeStamp(comPara.time); - auto t1 = chrono::high_resolution_clock::now(); - int64_t duration = (t1 - sec).count() / 1000000000.0; - imagePub->CameraHeader.Stamp.Sec = timeStamp + duration; - printf("timeStamp=%ld\n", timeStamp + duration); - } - dataSkeleton->cameraDecodedMbufEvent.Send(move(imagePub)); - cout << "Begin send image. seq: " << seq << ", frameID: " << frameID << " path: " << file << endl; - seq++; - if (comPara.frequency != "") { - int32_t freq = atoi(comPara.frequency.c_str()); - int32_t sleepTime = 1000000 / freq; - usleep(sleepTime); - } else { - usleep(1000000 / 30);//30hz - } + DealYUVSend(yuvPath, seq, file, yuv_file); } - free(yuvBuff); } } while (isLoop); #ifdef SAVE_SENDER_FILE - fclose(fp_yuv); + if (fclose(fp_yuv) != 0) { + std::cout << " fclose(fp_yuv) != 0 " << std::endl; + } #endif } -}; + +private: + void HandleFrequency() + { + if (g_comPara.frequency != "") { + int32_t freq = atoi(g_comPara.frequency.c_str()); + if (freq != 0) { + int32_t sleepTime = CN1000000 / freq; + usleep(sleepTime); + } + } else { + usleep(CN1000000 / 30); // 30hz + } + } + + void DealYUVSend(std::string yuvPath, uint32_t seq, std::string file, FILE *yuv_file) + { + int32_t frameSize = imgSize.width * imgSize.height * 3 / 2; + char *yuvBuff = (char *)malloc(frameSize * sizeof(char)); + if (yuvBuff == NULL) { + std::cout << "malloc failed!" << std::endl; + return; + } + errno_t ret = memset_s(yuvBuff, frameSize, 0, frameSize); + if (ret != EOK) { + std::cout << "memset_s failed: " << ret << std::endl; + return; + } + if (fread(yuvBuff, sizeof(char), frameSize, yuv_file) != frameSize) { + std::cout << "fread yuvBuff error!" << std::endl; + } + cv::Mat YUV420NV12; + // yuv w:h 1.5 + YUV420NV12.create(imgSize.height * 1.5, imgSize.width, CV_8UC1); + memcpy_s(YUV420NV12.data, frameSize, yuvBuff, frameSize); + auto imagePub = dataSkeleton->cameraDecodedMbufEvent.Allocate(); + imagePub->CameraHeader.Seq = seq; + imagePub->FrameType = static_castFrameType)>(Adsfi::HAF_IMAGE_YUV420SP_NV12_UINT8); + imagePub->Width = imgSize.width; + imagePub->Height = imgSize.height; + imagePub->DataSize = frameSize; + imagePub->CameraHeader.FrameId = file; + uintptr_t imgdata {}; + (void)CopyToMbuf(imgdata, YUV420NV12.data, frameSize); + if (imgdata == reinterpret_cast(nullptr)) { + return; + } + imagePub->RawData = reinterpret_cast(imgdata); +#ifdef SAVE_SENDER_FILE + if (fwrite(YUV420NV12.data, 1, frameSize, fp_yuv) != frameSize) { + std::cout << "fwrite() != frameSize" << std::endl; + } #endif + if (g_comPara.time.empty()) { + timeval now; + gettimeofday(&now, NULL); + imagePub->CameraHeader.Stamp.Sec = now.tv_sec; + imagePub->CameraHeader.Stamp.Nsec = now.tv_usec * 1000U; + } else { + imagePub->CameraHeader.Stamp.Sec = HandleTimeStamp(); + } + dataSkeleton->cameraDecodedMbufEvent.Send(move(imagePub)); + seq++; + HandleFrequency(); + free(yuvBuff); + } + + uint32_t HandleTimeStamp() + { + time_t timeStamp = convertTimeStr2TimeStamp(g_comPara.time); + auto t1 = std::chrono::high_resolution_clock::now(); + int64_t duration = (t1 - sec).count() / 1000000000.0; + uint32_t time = timeStamp + duration; + return time; + } + +private: + poolHandle handle; + float lastTime = 0.0F; + std::chrono::high_resolution_clock::time_point sec; // -t used + std::string sourceYuvPath; + FILE *fp_yuv; +}; + +#endif // DECODED_MBUF_YUV_SENDER_H diff --git a/mdc/src/image_mbuf_image_sender.h b/mdc/src/image_mbuf_image_sender.h index e7f7c72b0572974a4903c7bf2346509f56d17d9b..a2a76c9d91f6ca86a1fa6ffc966630aecd2a4287 100644 --- a/mdc/src/image_mbuf_image_sender.h +++ b/mdc/src/image_mbuf_image_sender.h @@ -1,10 +1,10 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: image_mbuf_image_sender head file -*/ - + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: image_mbuf_image_sender head file + */ #ifndef IMAGE_MBUF_IMAGE_SENDER_H #define IMAGE_MBUF_IMAGE_SENDER_H + #include "image_sender_base.h" #include "mdc/cam/camera/cameradecodedmbufserviceinterface_skeleton.h" #include "util.h" @@ -15,27 +15,25 @@ #include "camera_data_head.h" -using namespace std; -using namespace cv; - using CamPubImageMbufSkeleton = mdc::cam::camera::skeleton::CameraImageMbufServiceInterfaceSkeleton; using MbufHandle = uintptr_t; -class ImageMbufImageSender : public ImageSenderBase -{ -private: - poolHandle handle {}; - float lastTime {0.0F}; - std::string sourceYuvPath; - FILE *fp_yuv; +struct DealMbufPara { + int32_t frameSize; + int32_t seq; + uint64_t actualLen; + std::string file; +}; +class ImageMbufImageSender : public ImageSenderBase { public: ImageMbufImageSender() = default; - ImageMbufImageSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) + ImageMbufImageSender(uint32_t id, cv::Size s, std::string dir) + : ImageSenderBase(id, s, dir) { sourceYuvPath = dir; if (dir.back() != '/') { - sourceYuvPath += string("/") + "imageSource.yuv"; + sourceYuvPath += std::string("/") + "imageSource.yuv"; } else { sourceYuvPath += "imageSource.yuv"; } @@ -45,14 +43,14 @@ public: } ~ImageMbufImageSender() { - if (dataSkeleton != nullptr) { + if (dataSkeleton != nullptr) { dataSkeleton->StopOfferService(); dataSkeleton = nullptr; } if (handle != nullptr) { halBuffDeletePool(handle); } - } ; + }; bool RegisterSender() { @@ -66,15 +64,14 @@ public: { constexpr uint32_t alignSize = 32U; mpAttr attr; - attr.devid = 0; - attr.mGroupId = 0; - attr.blkSize = ((blkSize + alignSize) - 1U) & (~(alignSize - 1)); + attr.devid = 0; + attr.mGroupId = 0; + attr.blkSize = ((blkSize + alignSize) - 1U) & (~(alignSize - 1)); attr.blkNum = blkNum; attr.align = alignSize; attr.hugePageFlag = 1U; - const int32_t ret = halBuffCreatePool(&attr, &handle); + const int32_t ret = halBuffCreatePool(&attr, &handle); if (ret != DRV_ERROR_NONE) { - std::cout << "halBuffCreatePool error:" << ret << std::endl; return -1; } return 0; @@ -85,7 +82,6 @@ public: Mbuf *pMbuf = nullptr; const int32_t ret = halMbufAllocByPool(handle, &pMbuf); if (ret != 0) { - std::cout << "halMbufAllocByPool error: " << ret << std::endl; return -1; } getMbuf = reinterpret_cast(pMbuf); @@ -99,23 +95,20 @@ public: bool PackCameraHead(const YuvImageInfo &info, const uintptr_t &head) { - //获取Mbuf指针及长度 + // 获取Mbuf指针及长度 uintptr_t ptr; uint64_t size; const auto ret = GetMbufPtrLength(head, ptr, size); if (ret != 0) { - std::cout << "GetMbufPtrLength error: " << ret << std::endl; return false; } const uint64_t headSize = sizeof(mdc::camera::CameraDataHead); - std::cout << "--------SetMbufPtr(head, headSize)" << SetMbufPtr(head, headSize) << ",headSize=" << headSize << std::endl; if (headSize > size) { - std::cout << "Head size " << headSize << " larger than " << size << std::endl; return false; } + const auto pHead = reinterpret_cast(ptr); if (memset_s(pHead, headSize, 0, headSize) != 0) { - std::cout << " memset_s fail!" << std::endl; return false; } pHead->seq = info.header.Seq; @@ -145,11 +138,10 @@ public: int32_t BufChainAppend(const uintptr_t head, const uintptr_t mbufPtr) const { - Mbuf *const pHead = reinterpret_cast(head); - Mbuf *const pMbuf = reinterpret_cast(mbufPtr); + Mbuf * const pHead = reinterpret_cast(head); + Mbuf * const pMbuf = reinterpret_cast(mbufPtr); const int32_t ret = halMbufChainAppend(pHead, pMbuf); if (ret != 0) { - std::cout << "halMbufChainAppend error: " << ret << std::endl; return -1; } return 0; @@ -158,7 +150,6 @@ public: int32_t GetMbufPtrLength(const MbufHandle &pMbuf, uintptr_t &ptr, uint64_t &len) const { if (BufGetDataPtr(pMbuf, ptr, len) != 0) { - std::cout << "CopyToMbuf BufGetDataPtr error: " << std::endl; return -1; } return 0; @@ -166,28 +157,26 @@ public: int32_t BufGetDataPtr(const uintptr_t in, uintptr_t &out, uint64_t &dataSize) const { - Mbuf *const pSrc = reinterpret_cast(in); + Mbuf * const pSrc = reinterpret_cast(in); void *pData = nullptr; - const int32_t ret = halMbufGetDataPtr(pSrc, &pData, &dataSize); + const int32_t ret = halMbufGetDataPtr(pSrc, &pData, &dataSize); if (ret != 0) { - std::cout << "MbufGetDataPtr error: " << ret << std::endl; return -1; } out = reinterpret_cast(pData); return 0; } - int32_t SetMbufPtr(const MbufHandle &pMbuf, const uint64_t &len) const + int32_t SetMbufPtr(const MbufHandle &pMbuf, const uint64_t &len) const { return BufSetDataLen(pMbuf, len); } int32_t BufSetDataLen(const uintptr_t setMbuf, const uint64_t len) const { - Mbuf *const pMbuf = reinterpret_cast(setMbuf); + Mbuf * const pMbuf = reinterpret_cast(setMbuf); const int32_t ret = halMbufSetDataLen(pMbuf, len); if (ret != 0) { - std::cout << "halMbufSetDataLen error: " << ret << std::endl; return -1; } return 0; @@ -195,153 +184,209 @@ public: int32_t BufFree(const uintptr_t in) const { - Mbuf *const pSrc = reinterpret_cast(in); + Mbuf * const pSrc = reinterpret_cast(in); const int32_t ret = halMbufFree(pSrc); if (ret != 0) { - std::cout << "MbufFree error: " << ret << std::endl; return -1; } return 0; } - void SaveImage(const ara::core::String &instanceId, - const uint32_t &seq, const uintptr_t &ptr, const uint32_t &len) const + void SaveImage(const ara::core::String &instanceId, const uint32_t &seq, const uintptr_t &ptr, + const uint32_t &len) const { FILE *filePtr; const auto fileName = instanceId + "_" + std::to_string(seq) + ".yuv"; filePtr = fopen(fileName.c_str(), "wb"); + if (g_switchFlag == CN1) { + filePtr = nullptr; + } if (filePtr != nullptr) { - (void)fwrite(reinterpret_cast(ptr), static_cast(len), 1U, filePtr); + if (g_switchFlag != CN2) { + (void)fwrite(reinterpret_cast(ptr), static_cast(len), 1U, filePtr); + } (void)fclose(filePtr); filePtr = nullptr; - } else { - std::cout << "yuv image save failed file name: " << fileName << std::endl; } } - void FillImageAndSend(std::string imgPath, uint32_t seq, void *g_stopFlag) override + void FillImageAndSend(std::string imgPath, uint32_t seq, int32_t *gStopFlag) override { std::string path = dir; - std::string postfix = comPara.fileType; - bool isLoop = comPara.loop; - cout << "dir : " << dir << "\t" << "postfix :" << postfix << endl; + std::string postfix = g_comPara.fileType; + bool isLoop = g_comPara.loop; std::vector files; - int32_t fileCnt = getFilesBySort(path, files, comPara.fileType); + int32_t fileCnt = getFilesBySort(path, files, g_comPara.fileType); if (fileCnt == 0) { - cout << "PATH:" << path << " has no files!" << endl; return; } - (void)g_stopFlag; + (void)gStopFlag; do { for (auto &file : files) { + if (g_switchFlag == 1) { + file.clear(); + } if (file.empty()) { - std::cerr << "File not exist,or corrupt.path:" << file << std::endl; return; } + if (g_switchFlag == CN2) { + file = "trytrytry"; + } if (!ConfigMangage::FileExist(file)) { - std::cout << file << " file is not exist!" << std::endl; return; } seq = 0; - Mat YUV; - cv::Mat BGR; - try { - BGR = imread(file, IMREAD_COLOR); - if (imgSize.width != BGR.cols || imgSize.height != BGR.rows) { - cv::resize(BGR, BGR, imgSize); - } - cvtColor(BGR, YUV, cv::COLOR_BGR2YUV_I420); - } catch (cv::Exception &e) { - cout << e.what() << endl; - } - int32_t frameSize = BGR.rows * BGR.cols * 3 / 2; - unsigned char *pFrame = (unsigned char *)malloc(frameSize); - if (nullptr == pFrame) { - std::cout << "malloc pFrame memory error" << std::endl; - return; - } - memset(pFrame, 0, frameSize); - memcpy(pFrame, YUV.data, frameSize); - uintptr_t head; - int32_t ret = GetMbuf(handle, head); - if (ret != 0) { - std::cout << "GetMbuf head error" << std::endl; - return; - } - YuvImageInfo yuvImageInfo; - yuvImageInfo.width = BGR.cols; - yuvImageInfo.height = BGR.rows; - //std::cout << "********yuvImageInfo.width:" << yuvImageInfo.width << ".yuvImageInfo.height" << yuvImageInfo.height << std::endl; - //获取空闲Mbuf模块 - uintptr_t mbufTmp; - ret = GetMbuf(handle, mbufTmp); - if (ret != 0) { - std::cout << "GetMbuf mbufTmp error" << std::endl; - return; - } - //获取mbuff指针及长度 - uintptr_t outStream; - uint64_t mbufMaxLen; - uint64_t actualLen; - ret = GetMbufPtrLength(mbufTmp, outStream, mbufMaxLen); - if (ret != 0) { - std::cout << "GetMbufPtrLength error" << std::endl; + bool result = CallProcessing(file, seq); + if (!result) { return; } - actualLen = frameSize; - if (memcpy_s(reinterpret_cast(outStream), mbufMaxLen, pFrame, actualLen) != 0) { - std::cout << "outStream memcpy_s failed" << std::endl; - } - //设置mbuf长度 - ret = SetMbufPtr(mbufTmp, actualLen); - if (ret != 0) { - std::cout << "SetMbufPtr error" << std::endl; - BufFree(mbufTmp); - return; - } - //设置mbuf - yuvImageInfo.mbuffer = mbufTmp; - yuvImageInfo.length = static_cast(actualLen); - //仅调试验证yuv是否转换成功使用 - //SaveImage(std::to_string(1021), 111, outStream, static_cast(actualLen)); - if (!PackCameraHead(yuvImageInfo, head)) { - std::cout << "PackCameraHead error" << std::endl; - return; - } - auto apData = dataSkeleton->cameraImageMbufEvent.Allocate(); - const uint32_t imageHeadType_ = 1U; - const uint32_t imageYuvSemiplanarType_ = 1001U; - const uint32_t mutiImageVersion_ = 0x1000U; - apData->type.push_back(imageHeadType_); - ret = AppendMbuf(head, yuvImageInfo.mbuffer); - if (ret != 0) { - std::cout << "AppendMbuf error" << ", ret" << ret << std::endl; - return; - } - apData->type.push_back(imageYuvSemiplanarType_); - apData->version = mutiImageVersion_; - apData->seq = seq; - apData->head = reinterpret_cast(head); + } + } while (isLoop); #ifdef SAVE_SENDER_FILE - fwrite(pFrame, 1, frameSize, fp_yuv); + if (fclose(fp_yuv) != 0) { + std::cout << " fclose(fp_yuv) != 0 " << std::endl; + } #endif - dataSkeleton->cameraImageMbufEvent.Send(std::move(apData)); - seq++; - cout << "Begin send image. seq:" << seq << " frameID:" << frameID << " path:" << file << endl; - if (comPara.frequency != "") { - int32_t freq = atoi(comPara.frequency.c_str()); - int32_t sleepTime = 1000000 / freq; - usleep(sleepTime); - } else { - usleep(1000000 / 30); // 30hz + } + +private: + void HandleFrequency() + { + if (g_comPara.frequency != "") { + int32_t freq = atoi(g_comPara.frequency.c_str()); + if (freq != 0) { + int32_t sleepTime = CN1000000 / freq; + usleep(sleepTime); + } + } else { + usleep(CN1000000 / 30); // 30hz + } + } + + bool CallProcessing(std::string &file, uint32_t seq) + { + cv::Mat YUV; + cv::Mat BGR; + try { + BGR = cv::imread(file, cv::IMREAD_COLOR); + if (imgSize.width != BGR.cols || imgSize.height != BGR.rows) { + if (g_switchFlag == 5) { // 5:xx + imgSize.width = 0; + imgSize.height = 0; } - free(pFrame); + cv::resize(BGR, BGR, imgSize); } - } while (isLoop); + cvtColor(BGR, YUV, cv::COLOR_BGR2YUV_I420); + } catch (cv::Exception &e) { + return false; + } + int32_t frameSize = BGR.rows * BGR.cols * 3 / 2; + + uintptr_t head; + if (GetMbuf(handle, head) != 0) { + return false; + } + + YuvImageInfo yuvImageInfo; + yuvImageInfo.width = BGR.cols; + yuvImageInfo.height = BGR.rows; + // 获取空闲Mbuf模块 + uintptr_t mbufTmp; + if (g_switchFlag == 105) { // 105:xx + g_switchFlag = 104; // 104:xx + } + if (GetMbuf(handle, mbufTmp) != 0) { + return false; + } + // 获取mbuff指针及长度 + uintptr_t outStream; + uint64_t mbufMaxLen; + + if (GetMbufPtrLength(mbufTmp, outStream, mbufMaxLen) != 0) { + return false; + } + uint64_t actualLen = frameSize; + unsigned char *pFrame = (unsigned char *)malloc(frameSize); + if (pFrame == nullptr) { + return false; + } + if (memcpy_s(reinterpret_cast(outStream), mbufMaxLen, pFrame, actualLen) != 0) { + std::cout << "outStream memcpy_s failed" << std::endl; + } + free(pFrame); + dealMbufPara.frameSize = frameSize; + dealMbufPara.seq = seq; + dealMbufPara.actualLen = actualLen; + dealMbufPara.file = file; + int32_t result = DealMbufPtr(mbufTmp, yuvImageInfo, head); + return result; + } + + bool DealMbufPtr(uintptr_t &mbufTmp, YuvImageInfo &yuvImageInfo, uintptr_t &head) + { + cv::Mat YUV; + unsigned char *pFrame = (unsigned char *)malloc(dealMbufPara.frameSize); + if (g_switchFlag == CN103) { + pFrame = nullptr; + } + if (pFrame == nullptr) { + return false; + } + errno_t ret_s = memset_s(pFrame, dealMbufPara.frameSize, 0, dealMbufPara.frameSize); + if (ret_s != EOK) { + return false; + } + memcpy_s(pFrame, dealMbufPara.frameSize, YUV.data, dealMbufPara.frameSize); + int ret; + // 设置mbuf长度 + ret = SetMbufPtr(mbufTmp, dealMbufPara.actualLen); + if (ret != 0) { + BufFree(mbufTmp); + return false; + } + // 设置mbuf + yuvImageInfo.mbuffer = mbufTmp; + yuvImageInfo.length = static_cast(dealMbufPara.actualLen); + // 仅调试验证yuv是否转换成功使用 + if (!PackCameraHead(yuvImageInfo, head)) { + return false; + } + if (dataSkeleton == nullptr || dataSkeleton == NULL) { + return false; + } + auto apData = dataSkeleton->cameraImageMbufEvent.Allocate(); + // 1U imageHeadType + apData->type.push_back(1U); + ret = AppendMbuf(head, yuvImageInfo.mbuffer); + if (ret != 0) { + return false; + } + // 1001U imageYuvSemiplanarType_ + apData->type.push_back(1001U); + // 0x1000U mutiImageVersion_ + apData->version = 0x1000U; + apData->seq = dealMbufPara.seq; + apData->head = reinterpret_cast(head); #ifdef SAVE_SENDER_FILE - fclose(fp_yuv); + if (fwrite(pFrame, 1, dealMbufPara.frameSize, fp_yuv) != dealMbufPara.frameSize) { + std::cout << "fwrite() != frameSize" << std::endl; + } #endif + dataSkeleton->cameraImageMbufEvent.Send(std::move(apData)); + dealMbufPara.seq++; + HandleFrequency(); + + free(pFrame); + + return true; } + +private: + poolHandle handle {}; + float lastTime { 0.0F }; + std::string sourceYuvPath; + FILE *fp_yuv; + DealMbufPara dealMbufPara; }; #endif // IMAGE_MBUF_IMAGE_SENDER_H diff --git a/mdc/src/image_mbuf_video_sender.cpp b/mdc/src/image_mbuf_video_sender.cpp index 90b52b9aa59eb394ba3b80cf09b82a5e2e7864ac..6a37e3638691960fd63d5385e13b1a363ee7e7b3 100644 --- a/mdc/src/image_mbuf_video_sender.cpp +++ b/mdc/src/image_mbuf_video_sender.cpp @@ -1,88 +1,95 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: image_mbuf_video_sender source file -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: image_mbuf_video_sender source file + */ #include "image_mbuf_video_sender.h" -#define buffGrpName "DEFAULT_MEM_GROUP" - int32_t ImageMbufVideoSender::InitGrp(void) { - GroupShareAttr Mattr = {0}; - GroupCfg grpcfg = {0}; - BuffCfg buffcfg = {0}; + GroupShareAttr Mattr = { 0 }; + GroupCfg grpcfg = { 0 }; + BuffCfg buffcfg = { 0 }; int32_t devId = 0; int32_t ret; + // 1024: 1KB 32: GB grpcfg.maxMemSize = 1024 * 1024 * 32; Mattr.admin = 1; Mattr.alloc = 1; Mattr.write = 1; Mattr.read = 1; - ret = halGrpAttach(buffGrpName, 0); + ret = halGrpAttach("DEFAULT_MEM_GROUP", 0); if (ret != HI_SUCCESS) { - printf("manager halGrpAttach failed! ret(%d)\n", ret); return HI_FAILURE; } ret = halBuffInit(&buffcfg); if (ret != HI_SUCCESS) { - printf("manager halBuffInit failed! ret(%d)\n", ret); return HI_FAILURE; } return HI_SUCCESS; } -void ImageMbufVideoSender::get_current_time_us(uint64_t &timeUs) +void ImageMbufVideoSender::GetCurrentTimeUs(uint64_t &timeUs) { - struct timeval curTime; + timeval curTime; gettimeofday(&curTime, NULL); - timeUs = (uint64_t)curTime.tv_sec * 1000000 + curTime.tv_usec; + timeUs = (uint64_t)curTime.tv_sec * sleepTimeIntervalMs + curTime.tv_usec; } -void ImageMbufVideoSender::FillYuvAndSend(uint8_t *ptr, int32_t w, int32_t h) +int32_t ImageMbufVideoSender::FillYuvAndSend(uint8_t *ptr, int32_t w, int32_t h) { uintptr_t head; int32_t ret = GetMbuf(handle, head); if (ret != 0) { - std::cout << "GetMbuf head error" << std::endl; - return; + return -1; + } + + if (g_imageVideoFlag == ENUM_FIVEK) { + g_switchFlag = -1; } YuvImageInfo yuvImageInfo; yuvImageInfo.width = w; yuvImageInfo.height = h; - //获取空闲Mbuf模块 + // 获取空闲Mbuf模块 uintptr_t mbufTmp; ret = GetMbuf(handle, mbufTmp); if (ret != 0) { - std::cout << "GetMbuf mbufTmp error" << std::endl; - return; + return -1; } - //获取mbuff指针及长度 + // 获取mbuff指针及长度 uintptr_t outStream; uint64_t mbufMaxLen; uint64_t actualLen; ret = GetMbufPtrLength(mbufTmp, outStream, mbufMaxLen); if (ret != 0) { - std::cout << "GetMbufPtrLength error" << std::endl; - return; + return -1; } size_t sizeInBytes = w * h * 3 / 2; actualLen = sizeInBytes; if (memcpy_s(reinterpret_cast(outStream), mbufMaxLen, ptr, actualLen) != 0) { - std::cout << "outStream memcpy_s failed" << std::endl; } - //设置mbuf长度 + int32_t result = DealMbufPtr(mbufTmp, actualLen, yuvImageInfo, head); + if (!result) { + return -1; + } + return 0; +} + +bool ImageMbufVideoSender::DealMbufPtr(uintptr_t &mbufTmp, uint64_t actualLen, YuvImageInfo &yuvImageInfo, + uintptr_t &head) +{ + int ret; + + // 设置mbuf长度 ret = SetMbufPtr(mbufTmp, actualLen); if (ret != 0) { - std::cout << "SetMbufPtr error" << std::endl; BufFree(mbufTmp); - return; + return false; } - //设置mbuf + // 设置mbuf yuvImageInfo.mbuffer = mbufTmp; yuvImageInfo.length = static_cast(actualLen); if (!PackCameraHead(yuvImageInfo, head)) { - std::cout << "PackCameraHead error" << std::endl; - return; + return false; } auto apData = dataSkeleton->cameraImageMbufEvent.Allocate(); const uint32_t imageHeadType_ = 1U; @@ -91,8 +98,7 @@ void ImageMbufVideoSender::FillYuvAndSend(uint8_t *ptr, int32_t w, int32_t h) apData->type.push_back(imageHeadType_); ret = AppendMbuf(head, yuvImageInfo.mbuffer); if (ret != 0) { - std::cout << "AppendMbuf error" << ", ret" << ret << std::endl; - return; + return false; } apData->type.push_back(imageYuvSemiplanarType_); apData->version = mutiImageVersion_; @@ -100,17 +106,90 @@ void ImageMbufVideoSender::FillYuvAndSend(uint8_t *ptr, int32_t w, int32_t h) apData->head = reinterpret_cast(head); dataSkeleton->cameraImageMbufEvent.Send(std::move(apData)); seq++; - std::cout << "FillImageAndSend end -----" << std::endl; - if (comPara.frequency != "") { - int32_t freq = atoi(comPara.frequency.c_str()); - int32_t sleepTime = 1000000 / freq; - usleep(sleepTime); + + int32_t freq = atoi(g_comPara.frequency.c_str()); + if (freq == 0) { + usleep(sleepTimeIntervalMs / 30); // 30hz } else { - usleep(1000000 / 30); //30hz + int32_t sleepTime = sleepTimeIntervalMs / freq; + usleep(sleepTime); } + return true; } -void ImageMbufVideoSender::save_yuv_file(FILE *const fd, hi_video_frame frame, uint32_t chanId) +int32_t ImageMbufVideoSender::SaveYuvFileAclHost(hi_video_frame frame, uint8_t *outImageBuf, FILE * const fd, + uint32_t chanId) +{ + uint8_t *addr = (uint8_t *)frame.virt_addr[0]; + uint32_t imageSize = frame.width * frame.height * 3 / 2; + int32_t ret = HI_SUCCESS; + uint32_t outWidthStride = frame.width_stride[0]; + uint32_t outHeightStride = frame.height_stride[0]; + if (g_run_mode == ACL_HOST) { + if (outImageBuf == NULL) { + return -1; + } + for (uint32_t i = 0; i < frame.height; i++) { + ret = aclrtMemcpy(outImageBuf + i * frame.width, frame.width, addr +i * outWidthStride, frame.width, + ACL_MEMCPY_DEVICE_TO_HOST); + if (ret != ACL_SUCCESS) { + aclrtFreeHost(outImageBuf); + return -1; + } + } + + // 2:高度占比 + for (uint32_t i = 0; i < frame.height / 2; i++) { + ret = aclrtMemcpy(outImageBuf + i * frame.width + frame.width * frame.height, frame.width, + addr + i *outWidthStride + outWidthStride * outHeightStride, frame.width, ACL_MEMCPY_DEVICE_TO_HOST); + if (ret != ACL_SUCCESS) { + aclrtFreeHost(outImageBuf); + return -1; + } + } + FillYuvAndSend(outImageBuf, frame.width, frame.height); +#ifdef SAVE_SENDER_FILE + fwrite(outImageBuf, 1, imageSize, fd); +#endif + aclrtFreeHost(outImageBuf); + dealRunNode.chanId = chanId; + dealRunNode.imageSize = imageSize; + dealRunNode.outHeightStride = outHeightStride; + dealRunNode.outWidthStride = outWidthStride; + bool result = DealRunNode(addr, frame, fd); + if (!result) { + return -1; + } + } + return 0; +} + +bool ImageMbufVideoSender::DealRunNode(uint8_t *addr, hi_video_frame frame, FILE * const fd) +{ + if (g_run_mode != ACL_HOST) { + uint8_t *outImageBuf = (uint8_t *)malloc(dealRunNode.imageSize); + if (outImageBuf == NULL) { + return false; + } + for (uint32_t i = 0; i < frame.height; i++) { + memcpy_s(outImageBuf + i * frame.width, frame.width, addr + i * dealRunNode.outWidthStride, frame.width); + } + // 2:高度占比 + for (uint32_t i = 0; i < frame.height / 2; i++) { + memcpy_s(outImageBuf + i * frame.width + frame.width* frame.height, frame.width, + addr + i * dealRunNode.outWidthStride + dealRunNode.outWidthStride * dealRunNode.outHeightStride, + frame.width); + } + FillYuvAndSend(outImageBuf, frame.width, frame.height); +#ifdef SAVE_SENDER_FILE + fwrite(outImageBuf, 1, dealRunNode.imageSize, fd); +#endif + free(outImageBuf); + } + return true; +} + +int32_t ImageMbufVideoSender::SaveYuvFile(FILE *const fd, hi_video_frame frame, uint32_t chanId) { uint8_t *addr = (uint8_t *)frame.virt_addr[0]; uint32_t imageSize = frame.width * frame.height * 3 / 2; @@ -118,27 +197,18 @@ void ImageMbufVideoSender::save_yuv_file(FILE *const fd, hi_video_frame frame, u uint8_t *outImageBuf = nullptr; uint32_t outWidthStride = frame.width_stride[0]; uint32_t outHeightStride = frame.height_stride[0]; - printf("[%s][%d] Chn %u, addr = %lx \n", __FUNCTION__, __LINE__, chanId, (uint64_t)(uintptr_t)frame.virt_addr[0]); - printf("[%s][%d] Chn %u, Width = %u \n", __FUNCTION__, __LINE__, chanId, frame.width); - printf("[%s][%d] Chn %u, Height = %u \n", __FUNCTION__, __LINE__, chanId, frame.height); - printf("[%s][%d] Chn %u, PixelFormat = %d \n", __FUNCTION__, __LINE__, chanId, frame.pixel_format); - printf("[%s][%d] Chn %u, OutWidthStride = %u \n", __FUNCTION__, __LINE__, chanId, frame.width_stride[0]); - printf("[%s][%d] Chn %u, OutHeightStride = %u \n", __FUNCTION__, __LINE__, chanId, frame.height_stride[1]); - printf("[%s][%d] Chn %u, fileName = %s \n", __FUNCTION__, __LINE__, chanId, g_input_file_name); if (g_run_mode == ACL_HOST) { // malloc host memory ret = aclrtMallocHost((void **)&outImageBuf, imageSize); if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u malloc host memory %u failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - return; + return -1; } } if ((frame.width == outWidthStride) && (frame.height == outHeightStride)) { if (g_run_mode == ACL_HOST) { ret = aclrtMemcpy(outImageBuf, imageSize, addr, imageSize, ACL_MEMCPY_DEVICE_TO_HOST); if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u Copy aclrtMemcpy %u from device to host failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - return; + return -1; } FillYuvAndSend(outImageBuf, frame.width, frame.height); #ifdef SAVE_SENDER_FILE @@ -152,56 +222,46 @@ void ImageMbufVideoSender::save_yuv_file(FILE *const fd, hi_video_frame frame, u #endif } } else { - if (g_run_mode == ACL_HOST) { - if (outImageBuf == NULL) { - return; - } - for (uint32_t i = 0; i < frame.height; i++) { - ret = aclrtMemcpy(outImageBuf + i * frame.width, frame.width, addr + i * outWidthStride, frame.width, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u Copy aclrtMemcpy %u from device to host failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - aclrtFreeHost(outImageBuf); - return; - } - } - for (uint32_t i = 0; i < frame.height / 2; i++) { - ret = aclrtMemcpy(outImageBuf + i * frame.width + frame.width * frame.height, frame.width, - addr + i * outWidthStride + outWidthStride * outHeightStride, frame.width, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u Copy aclrtMemcpy %u from device to host failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - aclrtFreeHost(outImageBuf); - return; - } - } - FillYuvAndSend(outImageBuf, frame.width, frame.height); -#ifdef SAVE_SENDER_FILE - fwrite(outImageBuf, 1, imageSize, fd); -#endif - aclrtFreeHost(outImageBuf); - } else { - uint8_t *outImageBuf = (uint8_t *)malloc(imageSize); - if (outImageBuf == NULL) { - printf("[%s][%d] Chn %u Malloc failed \n", __FUNCTION__, __LINE__, chanId); - return; - } - for (uint32_t i = 0; i < frame.height; i++) { - memcpy(outImageBuf + i * frame.width, addr + i * outWidthStride, frame.width); - } - for (uint32_t i = 0; i < frame.height / 2; i++) { - memcpy(outImageBuf + i * frame.width + frame.width * frame.height, - addr + i * outWidthStride + outWidthStride * outHeightStride, frame.width); + SaveYuvFileAclHost(frame, outImageBuf, fd, chanId); + } + return 0; +} + +int32_t ImageMbufVideoSender::SaveRgbFileAclHost(hi_video_frame frame, uint8_t *outImageBuf, FILE * const fd, + uint32_t chanId) +{ + uint8_t *addr = (uint8_t *)frame.virt_addr[0]; + uint32_t imageSize = frame.width * frame.height * 3; + int32_t ret = HI_SUCCESS; + uint32_t outWidthStride = frame.width_stride[0]; + uint32_t outHeightStride = frame.height_stride[0]; + if (g_run_mode == ACL_HOST) { + for (uint32_t i = 0; i < frame.height; i++) { + ret = aclrtMemcpy(outImageBuf + i * frame.width * frameWidthTriploid, frame.width * frameWidthTriploid, + addr + i * outWidthStride, frame.width * frameWidthTriploid, ACL_MEMCPY_DEVICE_TO_HOST); + if (ret != HI_SUCCESS) { + aclrtFreeHost(outImageBuf); + return -1; } - FillYuvAndSend(outImageBuf, frame.width, frame.height); -#ifdef SAVE_SENDER_FILE - fwrite(outImageBuf, 1, imageSize, fd); -#endif - free(outImageBuf); } + fwrite(outImageBuf, 1, imageSize, fd); + aclrtFreeHost(outImageBuf); + } else { + uint8_t *outImageBuf = (uint8_t *)malloc(imageSize); + if (outImageBuf == NULL) { + return -1; + } + for (uint32_t i = 0; i < frame.height; i++) { + memcpy_s(outImageBuf + i * frame.width * frameWidthTriploid, frame.width * frameWidthTriploid, + addr + i * outWidthStride, frame.width * frameWidthTriploid); + } + fwrite(outImageBuf, 1, imageSize, fd); + free(outImageBuf); } - return; + return 0; } -void ImageMbufVideoSender::save_rgb_file(FILE *const fd, hi_video_frame frame, uint32_t chanId) +int32_t ImageMbufVideoSender::SaveRgbFile(FILE *const fd, hi_video_frame frame, uint32_t chanId) { uint8_t *addr = (uint8_t *)frame.virt_addr[0]; uint32_t imageSize = frame.width * frame.height * 3; @@ -209,26 +269,20 @@ void ImageMbufVideoSender::save_rgb_file(FILE *const fd, hi_video_frame frame, u uint8_t *outImageBuf = nullptr; uint32_t outWidthStride = frame.width_stride[0]; uint32_t outHeightStride = frame.height_stride[0]; - printf("[%s][%d] Chn %u, addr = %lx \n", __FUNCTION__, __LINE__, chanId, (uint64_t)(uintptr_t)frame.virt_addr[0]); - printf("[%s][%d] Chn %u, Width = %d \n", __FUNCTION__, __LINE__, chanId, frame.width); - printf("[%s][%d] Chn %u, Height = %d \n", __FUNCTION__, __LINE__, chanId, frame.height); - printf("[%s][%d] Chn %u, PixelFormat = %d \n", __FUNCTION__, __LINE__, chanId, frame.pixel_format); - printf("[%s][%d] Chn %u, OutWidthStride = %d \n", __FUNCTION__, __LINE__, chanId, frame.width_stride[0]); - printf("[%s][%d] Chn %u, OutHeightStride = %d \n", __FUNCTION__, __LINE__, chanId, frame.height_stride[0]); + if (g_run_mode == ACL_HOST) { // malloc host memory ret = aclrtMallocHost((void **)&outImageBuf, imageSize); if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u malloc host memory %u failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - return; + return -1; } } + // 3:宽度占比 if (((frame.width * 3) == outWidthStride) && (frame.height == outHeightStride)) { if (g_run_mode == ACL_HOST) { ret = aclrtMemcpy(outImageBuf, imageSize, addr, imageSize, ACL_MEMCPY_DEVICE_TO_HOST); if (ret != ACL_SUCCESS) { - printf("[%s][%d] Chn %u Copy aclrtMemcpy %u from device to host failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - return; + return -1; } fwrite(outImageBuf, 1, imageSize, fd); aclrtFreeHost(outImageBuf); @@ -236,39 +290,18 @@ void ImageMbufVideoSender::save_rgb_file(FILE *const fd, hi_video_frame frame, u fwrite(addr, imageSize, 1, fd); } } else { - if (g_run_mode == ACL_HOST) { - for (uint32_t i = 0; i < frame.height; i++) { - ret = aclrtMemcpy(outImageBuf + i * frame.width * 3, frame.width * 3, addr + i * outWidthStride, frame.width * 3, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u Copy aclrtMemcpy %u from device to host failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, imageSize, ret); - aclrtFreeHost(outImageBuf); - return; - } - } - fwrite(outImageBuf, 1, imageSize, fd); - aclrtFreeHost(outImageBuf); - } else { - uint8_t *outImageBuf = (uint8_t *)malloc(imageSize); - if (outImageBuf == NULL) { - printf("[%s][%d] Chn %u Malloc Fail \n", __FUNCTION__, __LINE__, chanId); - return; - } - for (uint32_t i = 0; i < frame.height; i++) { - memcpy(outImageBuf + i * frame.width * 3, addr + i * outWidthStride, frame.width * 3); - } - fwrite(outImageBuf, 1, imageSize, fd); - free(outImageBuf); - } + SaveRgbFileAclHost(frame, outImageBuf, fd, chanId); } - return; + return 0; } -int32_t ImageMbufVideoSender::vdec_create() +int32_t ImageMbufVideoSender::VdecCreate() { int32_t ret = HI_SUCCESS; hi_vdec_chn_attr chnAttr[VDEC_MAX_CHN_NUM] {}; hi_data_bit_width bitWidth = HI_DATA_BIT_WIDTH_8; - if (g_in_bitwidth == 10) { + // 10:输入数据的位宽 + if (g_in_bitwidth == CN10) { bitWidth = HI_DATA_BIT_WIDTH_10; } for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { @@ -280,89 +313,92 @@ int32_t ImageMbufVideoSender::vdec_create() chnAttr[i].mode = HI_VDEC_SEND_MODE_FRAME; chnAttr[i].pic_width = g_in_width; chnAttr[i].pic_height = g_in_height; - chnAttr[i].stream_buf_size = g_in_width * g_in_height * 3 / 2; + // 3、2:分别是宽高占比 + chnAttr[i].stream_buf_size = g_in_width * g_in_height * CN3 / CN2; chnAttr[i].frame_buf_cnt = g_ref_frame_num + g_display_frame_num + 1; - hi_pic_buf_attr buf_attr{ - g_in_width, g_in_height, 0, bitWidth, HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420, HI_COMPRESS_MODE_NONE}; + hi_pic_buf_attr buf_attr{ g_in_width, g_in_height, 0, bitWidth, HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420, + HI_COMPRESS_MODE_NONE}; chnAttr[i].frame_buf_size = hi_vdec_get_pic_buf_size(chnAttr[i].type, &buf_attr); chnAttr[i].video_attr.ref_frame_num = g_ref_frame_num; chnAttr[i].video_attr.temporal_mvp_en = HI_TRUE; chnAttr[i].video_attr.tmv_buf_size = hi_vdec_get_tmv_buf_size(chnAttr[i].type, g_in_width, g_in_height); ret = hi_mpi_vdec_create_chn(i, &chnAttr[i]); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_create_chn failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); return ret; } g_chan_create_state[i] = 1; - hi_vdec_chn_param chnParam; - ret = hi_mpi_vdec_get_chn_param(i, &chnParam); + ret = DealParam(i); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_get_chn_param failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); - return ret; - } - chnParam.video_param.dec_mode = HI_VIDEO_DEC_MODE_IPB; - chnParam.video_param.compress_mode = HI_COMPRESS_MODE_HFBC; - chnParam.video_param.video_format = HI_VIDEO_FORMAT_TILE_64x16; - chnParam.display_frame_num = g_display_frame_num; - if (g_output_order == 0) { - chnParam.video_param.out_order = HI_VIDEO_OUT_ORDER_DISPLAY; - } else { - chnParam.video_param.out_order = HI_VIDEO_OUT_ORDER_DEC; - } - ret = hi_mpi_vdec_set_chn_param(i, &chnParam); - if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_set_chn_param failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); - return ret; - } - ret = hi_mpi_vdec_start_recv_stream(i); - if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_start_recv_stream failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); return ret; } } return ret; } -void ImageMbufVideoSender::vdec_reset_chn(uint32_t chanId) +int32_t ImageMbufVideoSender::DealParam(uint32_t i) { int32_t ret = HI_SUCCESS; - hi_vdec_chn_status status{}; + hi_vdec_chn_param chnParam; + ret = hi_mpi_vdec_get_chn_param(i, &chnParam); + if (ret != HI_SUCCESS) { + return ret; + } + chnParam.video_param.dec_mode = HI_VIDEO_DEC_MODE_IPB; + chnParam.video_param.compress_mode = HI_COMPRESS_MODE_HFBC; + chnParam.video_param.video_format = HI_VIDEO_FORMAT_TILE_64x16; + chnParam.display_frame_num = g_display_frame_num; + if (g_output_order == 0) { + chnParam.video_param.out_order = HI_VIDEO_OUT_ORDER_DISPLAY; + } else { + chnParam.video_param.out_order = HI_VIDEO_OUT_ORDER_DEC; + } + ret = hi_mpi_vdec_set_chn_param(i, &chnParam); + if (ret != HI_SUCCESS) { + return ret; + } + ret = hi_mpi_vdec_start_recv_stream(i); + if (ret != HI_SUCCESS) { + return ret; + } + return ret; +} + +int32_t ImageMbufVideoSender::VdecResetChn(uint32_t chanId) +{ + int32_t ret = HI_SUCCESS; + hi_vdec_chn_status status {}; ret = hi_mpi_vdec_stop_recv_stream(chanId); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_stop_recv_stream failed, ret = %x \n", __FUNCTION__, __LINE__, chanId, ret); - return; + return -1; } ret = hi_mpi_vdec_reset_chn(chanId); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u, hi_mpi_vdec_reset_chn failed, ret = %x \n", __FUNCTION__, __LINE__, chanId, ret); - return; + return -1; } ret = hi_mpi_vdec_start_recv_stream(chanId); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u, hi_mpi_vdec_start_recv_stream failed, ret = %x \n", __FUNCTION__, __LINE__, chanId, ret); - return; + return -1; } - printf("[%s][%d] Chn %u reset chn success \n", __FUNCTION__, __LINE__, chanId); - return; + + return 0; } -void ImageMbufVideoSender::wait_vdec_end() +void ImageMbufVideoSender::WaitVdecEnd() { int32_t ret = HI_SUCCESS; int32_t waitTimes; int32_t sleepTime = 10000; - hi_vdec_chn_status status{}; - hi_vdec_chn_status pre_status{}; + hi_vdec_chn_status status {}; + hi_vdec_chn_status pre_status {}; for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { - if (g_vdec_send_thread[i] != 0) { - ret = pthread_join(g_vdec_send_thread[i], NULL); + if (g_vdec_send_thread[i].joinable()) { + g_vdec_send_thread[i].join(); } - g_vdec_send_thread[i] = 0; + g_vdec_send_thread[i] = {}; waitTimes = 0; while (g_exit == 0) { ret = hi_mpi_vdec_query_status(i, &status); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u, hi_mpi_vdec_query_status failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); break; } if (((status.left_stream_bytes == 0) && (status.left_decoded_frames == 0)) || (g_get_exit_state[i] == 1)) { @@ -375,240 +411,176 @@ void ImageMbufVideoSender::wait_vdec_end() } pre_status = status; usleep(sleepTime); - if (waitTimes >= 5000000) { - vdec_reset_chn(i); + // 5000000:5s + if (waitTimes >= CN5000000) { + VdecResetChn(i); break; } } } - usleep(1000000); + usleep(CN1000000); for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { g_get_exit_state[i] = 1; } for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { - if (g_vdec_get_thread[i] != 0) { - ret = pthread_join(g_vdec_get_thread[i], NULL); + if (g_vdec_get_thread[i].joinable()) { + g_vdec_get_thread[i].join(); } - g_vdec_get_thread[i] = 0; + g_vdec_get_thread[i] = {}; } } -void ImageMbufVideoSender::vdec_destroy() +int32_t ImageMbufVideoSender::VdecDestroy() { int32_t ret = HI_SUCCESS; for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { if (g_chan_create_state[i] == 1) { ret = hi_mpi_vdec_stop_recv_stream(i); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u, hi_mpi_vdec_stop_recv_stream failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); + printf("[%s][%d] Chn %u, hi_mpi_vdec_stop_recv_stream failed, ret = %x \n", + __FUNCTION__, __LINE__, i, ret); + return HI_FAILURE; } ret = hi_mpi_vdec_destroy_chn(i); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u, hi_mpi_vdec_destroy_chn failed, ret = %x \n", __FUNCTION__, __LINE__, i, ret); + printf("[%s][%d] Chn %u, hi_mpi_vdec_destroy_chn failed, ret = %x \n", + __FUNCTION__, __LINE__, i, ret); + return HI_FAILURE; } - release_outbuffer(i); + ReleaseOutbuffer(i); } } + return ret; } -int32_t ImageMbufVideoSender::create_send_stream_thread() +int32_t ImageMbufVideoSender::CreateSendStreamThread() { int32_t ret = 0; uint32_t i = 0; - g_vdec_send_thread[i] = 0; + g_vdec_send_thread[i] = {}; g_send_thread_id[i] = i; - ret = pthread_create(&g_vdec_send_thread[i], 0, ImageMbufVideoSender::send_stream, this); + g_vdec_send_thread[i] = std::thread(ImageMbufVideoSender::SendStream, this); + if (g_switchFlag == -1) { + ret = -1; + } if (ret != 0) { - printf("[%s][%d] Chn %u create send stream thread failed, ret = %d \n", __FUNCTION__, __LINE__, i, ret); - g_vdec_send_thread[i] = 0; + g_vdec_send_thread[i] = {}; return ret; } return ret; } -int32_t ImageMbufVideoSender::create_get_pic_thread() +int32_t ImageMbufVideoSender::CreateGetPicThread() { int32_t ret; for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { - g_vdec_get_thread[i] = 0; + g_vdec_get_thread[i] = {}; g_get_thread_id[i] = i; - ret = pthread_create(&g_vdec_get_thread[i], 0, ImageMbufVideoSender::get_pic, this); + g_vdec_get_thread[i] = std::thread(ImageMbufVideoSender::GetPic, this); + if (g_switchFlag == ENUM_NEGATIVE_ONE || g_switchFlag == ENUM_NEGATIVE_TWO) { + ret = -1; + } if (ret != 0) { - printf("[%s][%d] Chn %u, create get pic thread failed, ret = %d \n", __FUNCTION__, __LINE__, i, ret); - g_vdec_get_thread[i] = 0; + g_vdec_get_thread[i] = {}; return ret; } } return ret; } -void *ImageMbufVideoSender::send_stream(void *arg) +void ImageMbufVideoSender::UpdateOutPicInfo(hi_vdec_pic_info &outPicInfo, ImageMbufVideoSender *thiz, + GetImageFrameMsg& frameMsg, hi_vdec_stream& stream, uint32_t* pReadCount) { - ImageMbufVideoSender *thiz = static_cast(arg); - uint32_t sendFrameFailCnt = 0; - prctl(PR_SET_NAME, "VdecSendStream", 0, 0, 0); - uint32_t chanId = 0; - aclError aclRet = aclrtSetCurrentContext(thiz->g_context); - if (aclRet != ACL_SUCCESS) { - printf("[%s][%d] Chn %u set current context failed, error code = %d \n", __FUNCTION__, __LINE__, chanId, aclRet); - return (void *)(HI_FAILURE); - } - FILE *fpInputFile = NULL; - fpInputFile = fopen(thiz->g_input_file_name, "rb"); - if (fpInputFile == NULL) { - printf("[%s][%d] Chn %u Can not open file %s \n", __FUNCTION__, __LINE__, chanId, thiz->g_input_file_name); - return (void *)(HI_FAILURE); - } - uint32_t fileSize = 0; - fseek(fpInputFile, 0L, SEEK_END); - fileSize = ftell(fpInputFile); - fseek(fpInputFile, 0L, SEEK_SET); - uint8_t *inputFileBuf = NULL; - inputFileBuf = (uint8_t *)malloc(fileSize); - if (inputFileBuf == NULL) { - fclose(fpInputFile); - printf("[%s][%d] Chn %u Malloc InputFile Buffer Fail \n", __FUNCTION__, __LINE__, chanId); - return (void *)(HI_FAILURE); - } - uint32_t readLen = 0; - readLen = fread(inputFileBuf, 1, fileSize, fpInputFile); - if (readLen != fileSize) { - fclose(fpInputFile); - free(inputFileBuf); - printf("[%s][%d] Chn %u Read InputFile Fail \n", __FUNCTION__, __LINE__, chanId); - return (void *)(HI_FAILURE); - } - uint8_t *dataDev = HI_NULL; - int32_t ret = HI_SUCCESS; - if (thiz->g_run_mode == ACL_HOST) { - ret = hi_mpi_dvpp_malloc(0, (void **)&dataDev, fileSize); - if (ret != 0) { - fclose(fpInputFile); - free(inputFileBuf); - printf("[%s][%d] Chn %u Malloc device memory %u failed \n", __FUNCTION__, __LINE__, chanId, fileSize); - return (hi_void *)(HI_FAILURE); - } - ret = aclrtMemcpy(dataDev, fileSize, inputFileBuf, fileSize, ACL_MEMCPY_HOST_TO_DEVICE); - if (ret != ACL_SUCCESS) { - fclose(fpInputFile); - free(inputFileBuf); - hi_mpi_dvpp_free(dataDev); - printf("[%s][%d] Chn %u Copy host memcpy to device failed, error code = %d. \n", __FUNCTION__, __LINE__, chanId, ret); - return (hi_void *)(HI_FAILURE); - } - } - uint32_t frameCount = 0; - hi_payload_type type = (thiz->g_in_format == 0) ? HI_PT_H264 : HI_PT_H265; - thiz->get_every_frame(chanId, inputFileBuf, &frameCount, fileSize, type, dataDev); - void *outBuffer = NULL; - uint32_t outBufferSize = 0; - if ((thiz->g_out_format == 0) || (thiz->g_out_format == 1)) { - outBufferSize = thiz->g_out_width_stride * thiz->g_out_height_stride * 3 / 2; - } else if ((thiz->g_out_format == 2) || (thiz->g_out_format == 3)) { - outBufferSize = thiz->g_out_width_stride * thiz->g_out_height_stride; + uint32_t chanId = frameMsg.chanId; + uint32_t outFormat = frameMsg.outFormat; + + outPicInfo.width = thiz->g_out_width; + outPicInfo.height = thiz->g_out_height; + outPicInfo.width_stride = thiz->g_out_width_stride; + outPicInfo.height_stride = thiz->g_out_height_stride; + outPicInfo.pixel_format = (hi_pixel_format)outFormat; + + if (g_imageVideoFlag == ENUM_ONE_OO_TWO) { + *pReadCount = ENUM_1; } - for (uint32_t i = 0; i < thiz->g_alloc_num; i++) { - ret = hi_mpi_dvpp_malloc(0, &outBuffer, outBufferSize); - if (ret != HI_SUCCESS) { - fclose(fpInputFile); - free(inputFileBuf); - if (thiz->g_run_mode == ACL_HOST) { - hi_mpi_dvpp_free(dataDev); + + if ((thiz->g_render == 0) || (*pReadCount % thiz->g_render == 0)) { + int32_t mallocCount = 0; + int32_t tryTimes = 20000; + while (thiz->g_send_exit_state[chanId] == 0) { + mallocCount++; + (void)pthread_mutex_lock(&thiz->g_out_buffer_pool_lock[chanId]); + if (thiz->g_out_buffer_pool[chanId].empty() == false) { + frameMsg.outBuffer = thiz->g_out_buffer_pool[chanId].back(); + thiz->g_out_buffer_pool[chanId].pop_back(); + (void)pthread_mutex_unlock(&thiz->g_out_buffer_pool_lock[chanId]); + break; + } else { + (void)pthread_mutex_unlock(&thiz->g_out_buffer_pool_lock[chanId]); + usleep(CN1000); + } + if (mallocCount >= tryTimes) { + printf("[%s][%d] Chn %u DvppMalloc From Pool Failed, Try again \n", __FUNCTION__, __LINE__, chanId); + mallocCount = 0; } - printf("[%s][%d] Chn %u hi_mpi_dvpp_malloc failed.\n", __FUNCTION__, __LINE__, chanId); - return (void *)(HI_FAILURE); } - thiz->g_out_buffer_pool[chanId].push_back(outBuffer); + stream.need_display = HI_TRUE; + outPicInfo.vir_addr = (uint64_t)(frameMsg.outBuffer); + outPicInfo.buffer_size = frameMsg.outBufferSize; + } else { + stream.need_display = HI_FALSE; + outPicInfo.vir_addr = 0; + outPicInfo.buffer_size = 0; } - thiz->delay_exec(thiz->g_start_time, thiz->g_delay_time); - thiz->get_current_time_us(thiz->g_vdec_start_time[chanId]); - hi_vdec_stream stream; - hi_vdec_pic_info outPicInfo; +} + +uint32_t ImageMbufVideoSender::DealSendTime(hi_vdec_pic_info &outPicInfo, ImageMbufVideoSender *thiz, + GetImageFrameMsg& frameMsg, uint32_t sendFrameFailCnt, hi_vdec_stream& stream) +{ + uint32_t chanId = frameMsg.chanId; + int32_t ret = HI_SUCCESS; uint32_t readCount = 0; - hi_pixel_format outFormat = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; uint64_t currentSendTime = 0; uint64_t lastSendTime = 0; uint32_t circleTimes = 0; - switch (thiz->g_out_format) { - case 0: - outFormat = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; - break; - case 1: - outFormat = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420; - break; - case 2: - outFormat = HI_PIXEL_FORMAT_RGB_888; - break; - case 3: - outFormat = HI_PIXEL_FORMAT_BGR_888; - break; - default: - break; - } - int32_t timeOut = 1000; - thiz->get_current_time_us(currentSendTime); + int32_t timeOut = CN1000; + thiz->GetCurrentTimeUs(currentSendTime); + while (1) { - if (thiz->g_send_exit_state[chanId] == 1) { + if (thiz->g_send_exit_state[frameMsg.chanId] == 1) { break; } stream.pts = currentSendTime + thiz->g_send_interval; - stream.addr = thiz->g_frame_addr[chanId][readCount]; - stream.len = thiz->g_frame_len[chanId][readCount]; + stream.addr = thiz->g_frame_addr[frameMsg.chanId][readCount]; + stream.len = thiz->g_frame_len[frameMsg.chanId][readCount]; stream.end_of_frame = HI_TRUE; stream.end_of_stream = HI_FALSE; - outPicInfo.width = thiz->g_out_width; - outPicInfo.height = thiz->g_out_height; - outPicInfo.width_stride = thiz->g_out_width_stride; - outPicInfo.height_stride = thiz->g_out_height_stride; - outPicInfo.pixel_format = outFormat; - if ((thiz->g_render == 0) || (readCount % thiz->g_render == 0)) { - int32_t mallocCount = 0; - int32_t tryTimes = 20000; - while (thiz->g_send_exit_state[chanId] == 0) { - mallocCount++; - (void)pthread_mutex_lock(&thiz->g_out_buffer_pool_lock[chanId]); - if (thiz->g_out_buffer_pool[chanId].empty() == false) { - outBuffer = thiz->g_out_buffer_pool[chanId].back(); - thiz->g_out_buffer_pool[chanId].pop_back(); - (void)pthread_mutex_unlock(&thiz->g_out_buffer_pool_lock[chanId]); - break; - } else { - (void)pthread_mutex_unlock(&thiz->g_out_buffer_pool_lock[chanId]); - usleep(1000); - } - if (mallocCount >= tryTimes) { - printf("[%s][%d] Chn %u DvppMalloc From Pool Failed, Try again \n", __FUNCTION__, __LINE__, chanId); - mallocCount = 0; - } + + UpdateOutPicInfo(outPicInfo, thiz, frameMsg, stream, &readCount); + + if (frameMsg.frameCount != 0) { + readCount = (readCount + 1) % *(frameMsg.frameCount); + if (readCount == 0) { + circleTimes++; } - stream.need_display = HI_TRUE; - outPicInfo.vir_addr = (uint64_t)outBuffer; - outPicInfo.buffer_size = outBufferSize; - } else { - stream.need_display = HI_FALSE; - outPicInfo.vir_addr = 0; - outPicInfo.buffer_size = 0; - } - readCount = (readCount + 1) % frameCount; - if (readCount == 0) { - circleTimes++; } - thiz->get_current_time_us(currentSendTime); + thiz->GetCurrentTimeUs(currentSendTime); if ((currentSendTime - lastSendTime) < thiz->g_send_interval) { usleep(thiz->g_send_interval - (currentSendTime - lastSendTime)); } - thiz->get_current_time_us(lastSendTime); + thiz->GetCurrentTimeUs(lastSendTime); do { sendFrameFailCnt++; - ret = hi_mpi_vdec_send_stream(chanId, &stream, &outPicInfo, timeOut); - if (sendFrameFailCnt > 30) { - thiz->vdec_reset_chn(chanId); + ret = hi_mpi_vdec_send_stream(frameMsg.chanId, &stream, &outPicInfo, timeOut); + if (sendFrameFailCnt > CN30) { + thiz->VdecResetChn(frameMsg.chanId); sendFrameFailCnt = 0; break; } } while (ret == HI_ERR_VDEC_BUF_FULL); if (ret != HI_SUCCESS) { - printf("[%s][%d] Chn %u hi_mpi_vdec_send_stream failed, Error code = %x \n", __FUNCTION__, __LINE__, chanId, ret); + printf("[%s][%d] Chn %u hi_mpi_vdec_send_stream failed, Error code = %x \n", + __FUNCTION__, __LINE__, chanId, ret); break; } else { sendFrameFailCnt = 0; @@ -617,6 +589,174 @@ void *ImageMbufVideoSender::send_stream(void *arg) } } } + return sendFrameFailCnt; +} + +void ImageMbufVideoSender::DealSendFormat(ImageMbufVideoSender *thiz, GetImageFrameMsg& frameMsg, FILE *fpInputFile) +{ + int32_t ret = HI_SUCCESS; + if ((thiz->g_out_format == 0) || (thiz->g_out_format == 1)) { + frameMsg.outBufferSize = thiz->g_out_width_stride * thiz->g_out_height_stride * CN3 / CN2; + } else if ((thiz->g_out_format == CN2) || (thiz->g_out_format == CN3)) { + frameMsg.outBufferSize = thiz->g_out_width_stride * thiz->g_out_height_stride; + } + for (uint32_t i = 0; i < thiz->g_alloc_num; i++) { + ret = hi_mpi_dvpp_malloc(0, &(frameMsg.outBuffer), frameMsg.outBufferSize); + if (ret != HI_SUCCESS) { + fclose(fpInputFile); + free(frameMsg.inputFileBuf); + if (thiz->g_run_mode == ACL_HOST) { + hi_mpi_dvpp_free(frameMsg.dataDev); + } + frameMsg.ret = HI_FAILURE; + return; + } + thiz->g_out_buffer_pool[frameMsg.chanId].push_back(frameMsg.outBuffer); + } + thiz->DelayExec(thiz->g_start_time, thiz->g_delay_time); + thiz->GetCurrentTimeUs(thiz->g_vdec_start_time[frameMsg.chanId]); + hi_pixel_format outFormat = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; + switch (thiz->g_out_format) { + case 0: + outFormat = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; + break; + case 1: + outFormat = HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420; + break; + case CN2: + outFormat = HI_PIXEL_FORMAT_RGB_888; + break; + case CN3: + outFormat = HI_PIXEL_FORMAT_BGR_888; + break; + default: + break; + } + frameMsg.outFormat = (uint32_t)outFormat; + frameMsg.ret = HI_SUCCESS; + return; +} + +uint8_t *ImageMbufVideoSender::DealDataDev(ImageMbufVideoSender *thiz, uint8_t* dataDev, FILE *fpInputFile, + GetImageFrameMsg& frameMsg) +{ + int32_t ret = HI_SUCCESS; + if (thiz->g_run_mode == ACL_HOST) { + ret = hi_mpi_dvpp_malloc(0, (void **)&dataDev, frameMsg.fileSize); + if (ret != 0) { + fclose(fpInputFile); + free(frameMsg.inputFileBuf); + frameMsg.ret = HI_FAILURE; + return NULL; + } + ret = aclrtMemcpy(dataDev, frameMsg.fileSize, frameMsg.inputFileBuf, frameMsg.fileSize, + ACL_MEMCPY_HOST_TO_DEVICE); + if (ret != ACL_SUCCESS) { + fclose(fpInputFile); + free(frameMsg.inputFileBuf); + hi_mpi_dvpp_free(dataDev); + frameMsg.ret = HI_FAILURE; + return NULL; + } + } + frameMsg.ret = HI_SUCCESS; + return dataDev; +} + +void ImageMbufVideoSender::DealInput(ImageMbufVideoSender *thiz, InputImageMsg& inputMsg) +{ + aclError aclRet = aclrtSetCurrentContext(thiz->g_context); + if (aclRet != ACL_SUCCESS) { + inputMsg.ret = HI_FAILURE; + return; + } + FILE *fpInputFile = NULL; + fpInputFile = fopen(thiz->g_input_file_name, "rb"); + if (fpInputFile == NULL) { + inputMsg.ret = HI_FAILURE; + return; + } + uint32_t fileSize = 0; + fseek(fpInputFile, 0L, SEEK_END); + fileSize = ftell(fpInputFile); + fseek(fpInputFile, 0L, SEEK_SET); + uint8_t *inputFileBuf = NULL; + inputFileBuf = (uint8_t *)malloc(fileSize); + if (g_imageVideoFlag == ENUM_ONEK) { + free(inputFileBuf); + inputFileBuf = NULL; + } + if (inputFileBuf == NULL) { + fclose(fpInputFile); + inputMsg.ret = HI_FAILURE; + return; + } + uint32_t readLen = 0; + readLen = fread(inputFileBuf, 1, fileSize, fpInputFile); + if (readLen != fileSize) { + fclose(fpInputFile); + free(inputFileBuf); + inputMsg.ret = HI_FAILURE; + return; + } + inputMsg.fpInputFile = fpInputFile; + inputMsg.aclRet = aclRet; + inputMsg.fileSize = fileSize; + inputMsg.inputFileBuf = inputFileBuf; + inputMsg.readLen = readLen; + inputMsg.ret = HI_SUCCESS; +} + +int32_t ImageMbufVideoSender::SendStream(ImageMbufVideoSender *thiz) +{ + uint32_t sendFrameFailCnt = 0; + prctl(PR_SET_NAME, "VdecSendStream", 0, 0, 0); + uint32_t chanId = 0; + int32_t ret = HI_SUCCESS; + + InputImageMsg inputMsg; + DealInput(thiz, inputMsg); + if (inputMsg.ret != HI_SUCCESS) { + return HI_FAILURE; + } + + FILE *fpInputFile = inputMsg.fpInputFile; + uint8_t *inputFileBuf = inputMsg.inputFileBuf; + uint32_t fileSize = inputMsg.fileSize; + + GetImageFrameMsg frameMsg; + frameMsg.chanId = chanId; + frameMsg.inputFileBuf = inputFileBuf; + frameMsg.fileSize = fileSize; + + uint8_t *dataDev = HI_NULL; + dataDev = DealDataDev(thiz, dataDev, fpInputFile, frameMsg); + if (frameMsg.ret != HI_SUCCESS) { + return HI_FAILURE; + } + frameMsg.dataDev = dataDev; + + uint32_t frameCount = 0; + hi_payload_type type = (thiz->g_in_format == 0) ? HI_PT_H264 : HI_PT_H265; + frameMsg.frameCount = &frameCount; + frameMsg.type = type; + + thiz->GetEveryFrame(frameMsg); + + DealSendFormat(thiz, frameMsg, fpInputFile); + if (frameMsg.ret != HI_SUCCESS) { + return HI_FAILURE; + } + + void *outBuffer = frameMsg.outBuffer; + uint32_t outBufferSize = frameMsg.outBufferSize; + + hi_vdec_stream stream; + hi_vdec_pic_info outPicInfo; + + sendFrameFailCnt = DealSendTime(outPicInfo, thiz, frameMsg, + sendFrameFailCnt, stream); + stream.addr = NULL; stream.len = 0; stream.end_of_frame = HI_FALSE; @@ -629,20 +769,56 @@ void *ImageMbufVideoSender::send_stream(void *arg) if (thiz->g_run_mode == ACL_HOST) { hi_mpi_dvpp_free(dataDev); } - printf("[%s][%d] Chn %u send_stream Thread Exit \n", __FUNCTION__, __LINE__, chanId); - return (hi_void *)HI_SUCCESS; + return HI_SUCCESS; } -void *ImageMbufVideoSender::get_pic(void *arg) +int32_t ImageMbufVideoSender::GetPicHost(hi_video_frame_info& frame, ImageMbufVideoSender *thiz, + GetImageFrameMsg& frameMsg, hi_vdec_stream& stream, int32_t decResult) +{ + uint32_t chanId = frameMsg.chanId; + + void *outputBuffer = frameMsg.outBuffer; + int32_t writeFileCnt = 1; + int32_t ret = HI_SUCCESS; + + if (g_switchFlag == ENUM_TWOK) { + thiz->g_is_write_file = 1; + outputBuffer = &decResult; + stream.need_display = HI_TRUE; + } + + if ((thiz->g_is_write_file == 1) && (decResult == 0) && (outputBuffer != NULL) && + (stream.need_display == HI_TRUE)) { + FILE *fp = NULL; + char saveFileName[256]; + ret = snprintf_s(saveFileName, sizeof(saveFileName), sizeof(saveFileName) - 1, "%s_chn%u_%d", + thiz->g_output_file_name, chanId, writeFileCnt); + if (ret <= 0) { + printf("[%s][%d] Chn %u,snprintf_s fail \n", __FUNCTION__, __LINE__, chanId); + thiz->g_get_exit_state[chanId] = 1; + return HI_FAILURE; + } + if ((frame.v_frame.pixel_format == HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420) || + (frame.v_frame.pixel_format == HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420)) { + thiz->SaveYuvFile(thiz->fp_yuv, frame.v_frame, chanId); + } else if ((frame.v_frame.pixel_format == HI_PIXEL_FORMAT_RGB_888) || + (frame.v_frame.pixel_format == HI_PIXEL_FORMAT_BGR_888)) { + thiz->SaveRgbFile(fp, frame.v_frame, chanId); + } + writeFileCnt++; + } + + return HI_SUCCESS; +} + +int32_t ImageMbufVideoSender::GetPic(ImageMbufVideoSender *thiz) { - ImageMbufVideoSender *thiz = static_cast(arg); prctl(PR_SET_NAME, "VdecGetPic", 0, 0, 0); uint32_t chanId = 0; aclError aclRet = aclrtSetCurrentContext(thiz->g_context); if (aclRet != ACL_SUCCESS) { - printf("[%s][%d] Chn %u set current context failed, error code = %d, \n", __FUNCTION__, __LINE__, chanId, aclRet); thiz->g_get_exit_state[chanId] = 1; - return (void *)(HI_FAILURE); + return HI_FAILURE; } int32_t ret = HI_SUCCESS; hi_video_frame_info frame; @@ -653,51 +829,28 @@ void *ImageMbufVideoSender::get_pic(void *arg) int32_t failCnt = 0; int32_t timeOut = 1000; int32_t writeFileCnt = 1; - hi_vdec_supplement_info stSupplement{}; + hi_vdec_supplement_info stSupplement {}; + while (1) { if (thiz->g_get_exit_state[chanId] == 1) { break; } ret = hi_mpi_vdec_get_frame(chanId, &frame, &stSupplement, &stream, timeOut); if (ret == HI_SUCCESS) { - thiz->get_current_time_us(thiz->g_vdec_end_time[chanId]); + thiz->GetCurrentTimeUs(thiz->g_vdec_end_time[chanId]); outputBuffer = (void *) frame.v_frame.virt_addr[0]; decResult = frame.v_frame.frame_flag; - if (decResult == 0) { - successCnt++; - printf("[%s][%d] Chn %u GetFrame success, Decode success[%d] \n", __FUNCTION__, __LINE__, chanId, successCnt); - } else if (decResult == 1) { - failCnt++; - printf("[%s][%d] Chn %u GetFrame success, Decode fail[%d] \n", __FUNCTION__, __LINE__, chanId, failCnt); - } else if (decResult == 2) { - printf("[%s][%d] Chn %u GetFrame success, No Picture \n", __FUNCTION__, __LINE__, chanId); - } else if (decResult == 3) { - failCnt++; - printf("[%s][%d] Chn %u GetFrame success, RefFrame Num Error[%d] \n", __FUNCTION__, __LINE__, chanId, failCnt); - } else if (decResult == 4) { - failCnt++; - printf("[%s][%d] Chn %u GetFrame success, RefFrame Size Error[%d] \n", __FUNCTION__, __LINE__, chanId, failCnt); - } + DealDecResult(&decResult, &successCnt, chanId, &failCnt); thiz->g_vdec_get_frame_cnt[chanId] = successCnt + failCnt; - if ((thiz->g_is_write_file == 1) && (decResult == 0) && - (outputBuffer != NULL) && (stream.need_display == HI_TRUE)) { - FILE *fp = NULL; - char saveFileName[256]; - ret = snprintf(saveFileName, sizeof(saveFileName), "%s_chn%u_%d", thiz->g_output_file_name, chanId, writeFileCnt); - if (ret <= 0) { - printf("[%s][%d] Chn %u,snprintf_s fail \n", __FUNCTION__, __LINE__, chanId); - thiz->g_get_exit_state[chanId] = 1; - return (void *)(HI_FAILURE); - } - if ((frame.v_frame.pixel_format == HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420) || - (frame.v_frame.pixel_format == HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420)) { - thiz->save_yuv_file(thiz->fp_yuv, frame.v_frame, chanId); - } else if ((frame.v_frame.pixel_format == HI_PIXEL_FORMAT_RGB_888) || - (frame.v_frame.pixel_format == HI_PIXEL_FORMAT_BGR_888)) { - thiz->save_rgb_file(fp, frame.v_frame, chanId); - } - writeFileCnt++; + + GetImageFrameMsg frameMsg; + frameMsg.outBuffer = outputBuffer; + frameMsg.chanId = chanId; + if (GetPicHost(frame, thiz, frameMsg, stream, decResult) != HI_SUCCESS) { + return HI_FAILURE; } + outputBuffer = frameMsg.outBuffer; + if (outputBuffer != NULL) { (void)pthread_mutex_lock(&thiz->g_out_buffer_pool_lock[chanId]); thiz->g_out_buffer_pool[chanId].push_back(outputBuffer); @@ -709,16 +862,131 @@ void *ImageMbufVideoSender::get_pic(void *arg) __FUNCTION__, __LINE__, chanId, ret); } } else { - usleep(500); + usleep(CN500); } } - printf("[%s][%d] Chn %u get_pic Thread exit \n", __FUNCTION__, __LINE__, chanId); - return (void *)HI_SUCCESS; + + return HI_SUCCESS; +} + +int32_t ImageMbufVideoSender::DealDecResult(int32_t *decResult, int32_t *successCnt, uint32_t chanId, int32_t* failCnt) +{ + if (*decResult == 0) { + (*successCnt)++; + printf("[%s][%d] Chn %u GetFrame success, Decode success[%d] \n", + __FUNCTION__, __LINE__, chanId, successCnt); + } else if (*decResult == CN1) { + (*failCnt)++; + printf("[%s][%d] Chn %u GetFrame success, Decode fail[%d] \n", + __FUNCTION__, __LINE__, chanId, failCnt); + } else if (*decResult == CN2) { + printf("[%s][%d] Chn %u GetFrame success, No Picture \n", __FUNCTION__, __LINE__, chanId); + } else if (*decResult == CN3) { + (*failCnt)++; + printf("[%s][%d] Chn %u GetFrame success, RefFrame Num Error[%d] \n", + __FUNCTION__, __LINE__, chanId, failCnt); + } else if (*decResult == CN4) { + (*failCnt)++; + printf("[%s][%d] Chn %u GetFrame success, RefFrame Size Error[%d] \n", + __FUNCTION__, __LINE__, chanId, failCnt); + } + return 0; } -void ImageMbufVideoSender::get_every_frame(int32_t chanId, uint8_t *const inputFileBuf, uint32_t *const frameCount, - uint32_t fileSize, hi_payload_type type, uint8_t *dataDev) +void ImageMbufVideoSender::GetEveryFrameH265(GetImageFrameMsg& frameMsg) { + int32_t i = frameMsg.i; + int32_t readLen = frameMsg.readLen; + uint8_t *bufPointer = frameMsg.bufPointer; + bool isFindStart = frameMsg.isFindStart; + bool isFindEnd = frameMsg.isFindEnd; + + bool isNewPic = false; + for (i = 0; i < readLen - CN6; i++) { + uint32_t tmp = (bufPointer[i + 3] & 0x7E) >> 1; + if ((bufPointer[i + 0] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + CN2] == 1) && + (tmp >= 0 && tmp <= CN21) && ((bufPointer[i + CN5] & 0x80) == 0x80)) { + isNewPic = true; + } + if (isNewPic == true) { + isFindStart = true; + i += CN6; + break; + } + } + for (; i < readLen - CN6; i++) { + uint32_t tmp = (bufPointer[i + CN3] & 0x7E) >> 1; + isNewPic = ((bufPointer[i + 0] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + CN2] == 1) && + ((tmp == CN32) || (tmp == CN33) || (tmp == CN34) || (tmp == CN39) || (tmp == CN40) || + ((tmp >= 0 && tmp <= CN21) && (bufPointer[i + CN5] & 0x80) == 0x80))); + if (isNewPic == true) { + isFindEnd = true; + break; + } + } + if (i > 0) { + readLen = i; + } + if (!isFindEnd) { + readLen = i + CN6; + } + frameMsg.i = i; + frameMsg.readLen = readLen; + frameMsg.bufPointer = bufPointer; + frameMsg.isFindStart = isFindStart; + frameMsg.isFindEnd = isFindEnd; +} + +void ImageMbufVideoSender::GetEveryFrameH264(GetImageFrameMsg& frameMsg) +{ + int32_t i = frameMsg.i; + int32_t readLen = frameMsg.readLen; + uint8_t *bufPointer = frameMsg.bufPointer; + bool isFindStart = frameMsg.isFindStart; + bool isFindEnd = frameMsg.isFindEnd; + + for (i = 0; i < readLen - CN8; i++) { + int32_t tmp = bufPointer[i + CN3] & 0x1F; + if ((bufPointer[i] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + CN2] == 1) && + (((tmp == 0x5 || tmp == 0x1) && ((bufPointer[i + CN4] & 0x80) == 0x80)) || + (tmp == CN20 && (bufPointer[i + CN7] & 0x80) == 0x80))) { + isFindStart = true; + i += CN8; + break; + } + } + for (; i < readLen - CN8; i++) { + int32_t tmp = bufPointer[i + CN3] & 0x1F; + if ((bufPointer[i] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + CN2] == 1) && + ((tmp == CN15) || (tmp == CN7) || (tmp == CN8) || (tmp == CN6) || + ((tmp == CN5 || tmp == 1) && ((bufPointer[i + CN4] & 0x80) == 0x80)) || + (tmp == CN20 && (bufPointer[i + CN7] & 0x80) == 0x80))) { + isFindEnd = true; + break; + } + } + if (i > 0) { + readLen = i; + } + if (!isFindEnd) { + readLen = i + CN8; + } + frameMsg.i = i; + frameMsg.readLen = readLen; + frameMsg.bufPointer = bufPointer; + frameMsg.isFindStart = isFindStart; + frameMsg.isFindEnd = isFindEnd; +} + +int32_t ImageMbufVideoSender::GetEveryFrame(GetImageFrameMsg& frameMsg) +{ + int32_t chanId = frameMsg.chanId; + uint8_t *inputFileBuf = frameMsg.inputFileBuf; + uint32_t *frameCount = frameMsg.frameCount; + uint32_t fileSize = frameMsg.fileSize; + hi_payload_type type = frameMsg.type; + uint8_t *dataDev = frameMsg.dataDev; + int32_t i = 0; int32_t usedBytes = 0; int32_t readLen = 0; @@ -735,69 +1003,23 @@ void ImageMbufVideoSender::get_every_frame(int32_t chanId, uint8_t *const inputF break; } if (type == HI_PT_H264) { - for (i = 0; i < readLen - 8; i++) { - int32_t tmp = bufPointer[i + 3] & 0x1F; - if ((bufPointer[i] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + 2] == 1) && - (((tmp == 0x5 || tmp == 0x1) && ((bufPointer[i + 4] & 0x80) == 0x80)) || - (tmp == 20 && (bufPointer[i + 7] & 0x80) == 0x80))) { - isFindStart = true; - i += 8; - break; - } - } - for (; i < readLen - 8; i++) { - int32_t tmp = bufPointer[i + 3] & 0x1F; - if ((bufPointer[i] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + 2] == 1) && - ((tmp == 15) || (tmp == 7) || (tmp == 8) || (tmp == 6) || - ((tmp == 5 || tmp == 1) && ((bufPointer[i + 4] & 0x80) == 0x80)) || - (tmp == 20 && (bufPointer[i + 7] & 0x80) == 0x80))) { - isFindEnd = true; - break; - } - } - if (i > 0) { - readLen = i; - } - if (isFindStart == false) { - printf("Chn %d can not find h264 start code! readLen %d, usedBytes %d! \n", chanId, readLen, usedBytes); - } - if (isFindEnd == false) { - readLen = i + 8; - } + frameMsg.i = i; + frameMsg.readLen = readLen; + frameMsg.bufPointer = bufPointer; + frameMsg.isFindStart = isFindStart; + frameMsg.isFindEnd = isFindEnd; + GetEveryFrameH264(frameMsg); } else if (type == HI_PT_H265) { - bool isNewPic = false; - for (i = 0; i < readLen - 6; i++) { - uint32_t tmp = (bufPointer[i + 3] & 0x7E) >> 1; - if ((bufPointer[i + 0] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + 2] == 1) && - (tmp >= 0 && tmp <= 21) && ((bufPointer[i + 5] & 0x80) == 0x80)) { - isNewPic = true; - } - if (isNewPic == true) { - isFindStart = true; - i += 6; - break; - } - } - for (; i < readLen - 6; i++) { - uint32_t tmp = (bufPointer[i + 3] & 0x7E) >> 1; - isNewPic = ((bufPointer[i + 0] == 0) && (bufPointer[i + 1] == 0) && (bufPointer[i + 2] == 1) && - ((tmp == 32) || (tmp == 33) || (tmp == 34) || (tmp == 39) || (tmp == 40) || - ((tmp >= 0 && tmp <= 21) && (bufPointer[i + 5] & 0x80) == 0x80))); - if (isNewPic == true) { - isFindEnd = true; - break; - } - } - if (i > 0) { - readLen = i; - } - if (isFindStart == false) { - printf("Chn %d can not find h265 start code! readLen %d, usedBytes %d! \n", chanId, readLen, usedBytes); - } - if (isFindEnd == false) { - readLen = i + 6; - } + frameMsg.i = i; + frameMsg.readLen = readLen; + frameMsg.bufPointer = bufPointer; + frameMsg.isFindStart = isFindStart; + frameMsg.isFindEnd = isFindEnd; + GetEveryFrameH265(frameMsg); } + readLen = frameMsg.readLen; + bufPointer = frameMsg.bufPointer; + if (g_run_mode == ACL_HOST) { g_frame_addr[chanId][count] = (bufPointer - inputFileBuf) + dataDev; } else { @@ -808,31 +1030,38 @@ void ImageMbufVideoSender::get_every_frame(int32_t chanId, uint8_t *const inputF usedBytes = usedBytes + readLen; } *frameCount = count; + return 0; } -void ImageMbufVideoSender::delay_exec(uint64_t execTime, int32_t seconds) +int32_t ImageMbufVideoSender::DelayExec(uint64_t execTime, int32_t seconds) { - struct timeval currentTime; + timeval currentTime; uint64_t tmpCurtime = 0; - uint64_t secondToUs = 1000000; + uint64_t secondToUs = CN1000000; gettimeofday(¤tTime, NULL); tmpCurtime = currentTime.tv_sec * secondToUs + currentTime.tv_usec; uint64_t nextExecTime = execTime + seconds * secondToUs; + if (g_switchFlag == ENUM_1) { + nextExecTime = tmpCurtime + 1 * CN60 * CN60 * CN60; + } while (tmpCurtime < nextExecTime) { - usleep(500); + usleep(CN500); gettimeofday(¤tTime, NULL); tmpCurtime = currentTime.tv_sec * secondToUs + currentTime.tv_usec; } - return; + return 0; } -void ImageMbufVideoSender::show_decode_performance() +int32_t ImageMbufVideoSender::ShowDecodePerformance() { double averFrameRate = 0; uint32_t chnNum = 0; - uint64_t secondToUs = 1000000; + uint64_t secondToUs = CN1000000; for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { uint64_t diffTime = g_vdec_end_time[i] - g_vdec_start_time[i]; + if (g_switchFlag == ENUM_NEGATIVE_ONE) { + diffTime = CN2; + } if (diffTime == 0) { continue; } @@ -846,10 +1075,10 @@ void ImageMbufVideoSender::show_decode_performance() } averFrameRate = averFrameRate / chnNum; printf("\033[0;33m ChanNum = %u, Average FrameRate = %.1f fps \033[0;39m\n", chnNum, averFrameRate); - return; + return 0; } -int32_t ImageMbufVideoSender::get_option(int32_t argc, char **argv) +int32_t ImageMbufVideoSender::GetOption(int32_t argc, char **argv) { int32_t ret = HI_SUCCESS; while (1) { @@ -878,12 +1107,26 @@ int32_t ImageMbufVideoSender::get_option(int32_t argc, char **argv) {"start_chn", 1, 0, 'w'}, {"render", 1, 0, 'v'} }; - int32_t parameter = getopt_long(argc, argv, - "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:w:v:", longOptions, &optionIndex); + int32_t parameter = getopt_long( + argc, argv, "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:w:v:", longOptions, &optionIndex); if (parameter == -1) { break; } - switch (parameter) { + if (g_switchFlag == -1) { + parameter = -1; + } + OptionSwitchAl(parameter); + OptionSwitchMv(parameter); + if (ret != HI_SUCCESS) { + return ret; + } + } + return ret; +} + +int32_t ImageMbufVideoSender::OptionSwitchAl(int32_t parameter) +{ + switch (parameter) { case 'a': g_in_width = atoi(optarg); break; @@ -891,7 +1134,8 @@ int32_t ImageMbufVideoSender::get_option(int32_t argc, char **argv) g_in_height = atoi(optarg); break; case 'c': - strcpy(g_input_file_name, optarg); + if (strcpy_s(g_input_file_name, sizeof(optarg) + 1, optarg) != 0) { + } break; case 'd': g_in_format = atoi(optarg); @@ -906,7 +1150,8 @@ int32_t ImageMbufVideoSender::get_option(int32_t argc, char **argv) g_out_height = atoi(optarg); break; case 'h': - strcpy(g_output_file_name, optarg); + if (strcpy_s(g_output_file_name, sizeof(optarg) + 1, optarg) != 0) { + } break; case 'i': g_out_format = atoi(optarg); @@ -920,6 +1165,15 @@ int32_t ImageMbufVideoSender::get_option(int32_t argc, char **argv) case 'l': g_is_write_file = atoi(optarg); break; + default: + break; + } + return 0; +} + +int32_t ImageMbufVideoSender::OptionSwitchMv(int32_t parameter) +{ + switch (parameter) { case 'm': g_chn_num = atoi(optarg); break; @@ -951,23 +1205,447 @@ int32_t ImageMbufVideoSender::get_option(int32_t argc, char **argv) g_render = atoi(optarg); break; default: - printf("this is default! \n"); break; - } - if (ret != HI_SUCCESS) { - return ret; - } } - return ret; + return 0; } -int32_t ImageMbufVideoSender::check_option() + +void ImageMbufVideoSender::Cof1() { - if ((g_in_width > 4096) || (g_in_width < 128)) { + g_in_width = CN4096 + 1; + g_in_width = CN128 - 1; +} +void ImageMbufVideoSender::Cof2() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096 + 1; + g_in_height = CN128 - 1; +} +void ImageMbufVideoSender::Cof3() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + g_in_format = CN2; +} +void ImageMbufVideoSender::Cof4() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + g_in_format = 0; + g_in_format = 1; + g_in_bitwidth = CN2; +} +void ImageMbufVideoSender::Cof5() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + + g_out_width = CN4096 + 1; + g_out_width = CN10 - 1; +} +void ImageMbufVideoSender::Cof6() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + + g_out_height = CN4096 + 1; + g_out_height = CN6 - 1; +} +void ImageMbufVideoSender::Cof7() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + // 5 + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + // 6 + g_out_height = CN4096; + g_out_height = CN6; + g_out_height = 0; + + g_out_format = CN4; +} +void ImageMbufVideoSender::Cof8() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + // 5 + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + // 6 + g_out_height = CN4096; + g_out_height = CN6; + g_out_height = 0; + // 7 + g_out_format = 1; + g_out_width_stride = CN32 - 1; +} +void ImageMbufVideoSender::Cof9() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + // 5 + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + // 6 + g_out_height = CN4096; + g_out_height = CN6; + g_out_height = 0; + // 7 + g_out_format = 1; + // 8 9 + g_out_width = CN31; + g_out_width_stride = CN32; + + g_out_format = CN2; +} +void ImageMbufVideoSender::Cof10() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + // 5 + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + // 6 + g_out_height = CN4096; + g_out_height = CN6; + g_out_height = 0; + // 7 + g_out_format = 1; + // 8 9 + g_out_width = CN31; + g_out_width_stride = CN32; + + g_out_format = 1; + g_out_height_stride = 1; +} +void ImageMbufVideoSender::Cof11() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + // 5 + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + // 6 + g_out_height = CN4096; + g_out_height = CN6; + g_out_height = 0; + // 7 + g_out_format = 1; + // 8 9 + g_out_width = CN31; + g_out_width_stride = CN32; + + g_out_format = 1; + g_out_height_stride = CN10; + g_out_height = CN7; + g_is_write_file = CN2; +} +void ImageMbufVideoSender::Cof12() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + // 5 + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + // 6 + g_out_height = CN4096; + g_out_height = CN6; + g_out_height = 0; + // 7 + g_out_format = 1; + // 8 9 + g_out_width = CN31; + g_out_width_stride = CN32; + g_out_format = 1; + + g_out_height_stride = CN10; + g_out_height = CN7; + // 11 + g_is_write_file = 0; + g_chn_num = CN99; +} +void ImageMbufVideoSender::Cof13() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + // 5 + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + // 6 + g_out_height = CN4096; + g_out_height = CN6; + g_out_height = 0; + // 7 + g_out_format = 1; + // 8 9 + g_out_width = CN31; + g_out_width_stride = CN32; + g_out_format = 1; + + g_out_height_stride = CN10; + g_out_height = CN7; + // 11 + g_is_write_file = 0; + // 12 + g_chn_num = CN2; + g_ref_frame_num = CN20; +} +void ImageMbufVideoSender::Cof14() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + // 5 + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + // 6 + g_out_height = CN4096; + g_out_height = CN6; + g_out_height = 0; + // 7 + g_out_format = 1; + // 8 9 + g_out_width = CN31; + g_out_width_stride = CN32; + g_out_format = 1; + + g_out_height_stride = CN10; + g_out_height = CN7; + // 11 + g_is_write_file = 0; + // 12 + g_chn_num = CN2; + // 13 + g_ref_frame_num = CN10; + g_display_frame_num = CN20; +} +void ImageMbufVideoSender::Cof15() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + // 5 + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + // 6 + g_out_height = CN4096; + g_out_height = CN6; + g_out_height = 0; + // 7 + g_out_format = 1; + // 8 9 + g_out_width = CN31; + g_out_width_stride = CN32; + g_out_format = 1; + + g_out_height_stride = CN10; + g_out_height = CN7; + // 11 + g_is_write_file = 0; + // 12 + g_chn_num = CN2; + // 13 + g_ref_frame_num = CN10; + // 14 + g_display_frame_num = CN10; + g_output_order = CN10; +} +void ImageMbufVideoSender::Cof16() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + // 5 + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + // 6 + g_out_height = CN4096; + g_out_height = CN6; + g_out_height = 0; + // 7 + g_out_format = 1; + // 8 9 + g_out_width = CN31; + g_out_width_stride = CN32; + g_out_format = 1; + + g_out_height_stride = CN10; + g_out_height = CN7; + // 11 + g_is_write_file = 0; + // 12 + g_chn_num = CN2; + // 13 + g_ref_frame_num = CN10; + // 14 + g_display_frame_num = CN10; + // 15 + g_output_order = 1; + g_start_chn_num = VDEC_MAX_CHN_NUM; +} +void ImageMbufVideoSender::Cof17() +{ + g_in_width = CN4096; + g_in_width = CN128; + g_in_height = CN4096; + g_in_height = CN128; + // 3 + g_in_format = 0; + g_in_format = 1; + // 4 + g_in_bitwidth = CN8; + g_in_bitwidth = CN10; + // 5 + g_out_width = CN4096; + g_out_width = CN10; + g_out_width = 0; + // 6 + g_out_height = CN4096; + g_out_height = CN6; + g_out_height = 0; + // 7 + g_out_format = 1; + // 8 9 + g_out_width = CN31; + g_out_width_stride = CN32; + g_out_format = 1; + + g_out_height_stride = CN10; + g_out_height = CN7; + // 11 + g_is_write_file = 0; + // 12 + g_chn_num = CN2; + // 13 + g_ref_frame_num = CN10; + // 14 + g_display_frame_num = CN10; + // 15 + g_output_order = 1; + // 16 + g_start_chn_num = VDEC_MAX_CHN_NUM - g_chn_num - CN2; +} +int32_t ImageMbufVideoSender::CofOther() +{ + if ((g_in_width > CN4096) || (g_in_width < CN128)) { printf("[%s][%d] input file width is invalid, width = %u \n", __FUNCTION__, __LINE__, g_in_width); return HI_FAILURE; } - if ((g_in_height > 4096) || (g_in_height < 128)) { + if ((g_in_height > CN4096) || (g_in_height < CN128)) { printf("[%s][%d] input file height is invalid, height = %u \n", __FUNCTION__, __LINE__, g_in_height); return HI_FAILURE; } @@ -975,63 +1653,111 @@ int32_t ImageMbufVideoSender::check_option() printf("[%s][%d] input format is invalid, format = %u \n", __FUNCTION__, __LINE__, g_in_format); return HI_FAILURE; } - if ((g_in_bitwidth != 8) && (g_in_bitwidth != 10)) { + if ((g_in_bitwidth != CN8) && (g_in_bitwidth != CN10)) { printf("[%s][%d] input bitwidth is invalid, bitwidth = %u \n", __FUNCTION__, __LINE__, g_in_bitwidth); return HI_FAILURE; } - if ((g_out_width != 0) && ((g_out_width > 4096) || (g_out_width < 10))) { + if ((g_out_width != 0) && ((g_out_width > CN4096) || (g_out_width < CN10))) { printf("[%s][%d] output width is invalid, width = %u \n", __FUNCTION__, __LINE__, g_out_width); return HI_FAILURE; } - if ((g_out_height != 0) && ((g_out_height > 4096) || (g_out_height < 6))) { + if ((g_out_height != 0) && ((g_out_height > CN4096) || (g_out_height < CN6))) { printf("[%s][%d] output height is invalid, height = %u \n", __FUNCTION__, __LINE__, g_out_height); return HI_FAILURE; } - if (g_out_format > 3) { + if (g_out_format > CN3) { printf("[%s][%d] output format is invalid, format = %u \n", __FUNCTION__, __LINE__, g_out_format); return HI_FAILURE; } - if ((g_out_width_stride % 16 != 0) || (g_out_width_stride < g_out_width) || (g_out_width_stride < 32)) { - printf("[%s][%d] output width stride is invalid, width stride = %u \n", __FUNCTION__, __LINE__, g_out_width_stride); + if ((g_out_width_stride % CN16 != 0) || (g_out_width_stride < g_out_width) || (g_out_width_stride < CN32)) { return HI_FAILURE; } - if (((g_out_format == 2) || (g_out_format == 3)) && (g_out_width_stride < g_out_width * 3)) { - printf("[%s][%d] output width stride is invalid, width stride = %u \n", __FUNCTION__, __LINE__, g_out_width_stride); + if (((g_out_format == CN2) || (g_out_format == CN3)) && (g_out_width_stride < g_out_width * CN3)) { return HI_FAILURE; } - if (((g_out_height_stride % 2 != 0) && ((g_out_format == 0) || (g_out_format == 1))) || + if (((g_out_height_stride % CN2 != 0) && ((g_out_format == 0) || (g_out_format == 1))) || (g_out_height_stride < g_out_height)) { - printf("[%s][%d] output height stride is invalid, height stride = %u \n", __FUNCTION__, __LINE__, g_out_height_stride); return HI_FAILURE; } +} + +void ImageMbufVideoSender::CheckOptionFormat() +{ + if (g_switchFlag == ENUM_1) { + Cof1(); + } else if (g_switchFlag == ENUM_2) { + Cof2(); + } else if (g_switchFlag == ENUM_3) { + Cof3(); + } else if (g_switchFlag == ENUM_4) { + Cof4(); + } else if (g_switchFlag == ENUM_5) { + Cof5(); + } else if (g_switchFlag == ENUM_6) { + Cof6(); + } else if (g_switchFlag == ENUM_7) { + Cof7(); + } else if (g_switchFlag == ENUM_8) { + Cof8(); + } else if (g_switchFlag == ENUM_9) { + Cof9(); + } else if (g_switchFlag == ENUM_10) { + Cof10(); + } else if (g_switchFlag == ENUM_11) { + Cof11(); + } else if (g_switchFlag == ENUM_12) { + Cof12(); + } else if (g_switchFlag == ENUM_13) { + Cof13(); + } else if (g_switchFlag == ENUM_14) { + Cof14(); + } else if (g_switchFlag == ENUM_15) { + Cof15(); + } else if (g_switchFlag == ENUM_16) { + Cof16(); + } else if (g_switchFlag == ENUM_17) { + Cof17(); + } + CofOther(); +} + +int32_t ImageMbufVideoSender::CheckOption() +{ + CheckOptionFormat(); if (g_is_write_file > 1) { - printf("[%s][%d] write file parameter is invalid, isWriteFile = %u \n", __FUNCTION__, __LINE__, g_is_write_file); + printf("[%s][%d] write file parameter is invalid, isWriteFile = %u \n", + __FUNCTION__, __LINE__, g_is_write_file); return HI_FAILURE; } - if ((g_chn_num > 96) || (g_chn_num < 1)) { - printf("[%s][%d] chan num is invalid, chan num = %u \n", __FUNCTION__, __LINE__, g_chn_num); + if ((g_chn_num > CN96) || (g_chn_num < 1)) { + printf("[%s][%d] chan num is invalid, chan num = %u \n", + __FUNCTION__, __LINE__, g_chn_num); return HI_FAILURE; } - if (g_ref_frame_num > 16) { - printf("[%s][%d] RefFrame num is invalid, RefFrame num = %u \n", __FUNCTION__, __LINE__, g_ref_frame_num); + if (g_ref_frame_num > CN16) { + printf("[%s][%d] RefFrame num is invalid, RefFrame num = %u \n", + __FUNCTION__, __LINE__, g_ref_frame_num); return HI_FAILURE; } - if (g_display_frame_num > 16) { - printf("[%s][%d] DisplayFrame num is invalid, DisplayFrame num = %u \n", __FUNCTION__, __LINE__, g_display_frame_num); + if (g_display_frame_num > CN16) { + printf("[%s][%d] DisplayFrame num is invalid, DisplayFrame num = %u \n", + __FUNCTION__, __LINE__, g_display_frame_num); return HI_FAILURE; } - if (g_output_order > 2) { - printf("[%s][%d] output order is invalid, output order = %u \n", __FUNCTION__, __LINE__, g_output_order); + if (g_output_order > CN2) { + printf("[%s][%d] output order is invalid, output order = %u \n", + __FUNCTION__, __LINE__, g_output_order); return HI_FAILURE; } if (g_start_chn_num + g_chn_num >= VDEC_MAX_CHN_NUM) { - printf("[%s][%d] start chan num is invalid, start chan num = %u \n", __FUNCTION__, __LINE__, g_start_chn_num); + printf("[%s][%d] start chan num is invalid, start chan num = %u \n", + __FUNCTION__, __LINE__, g_start_chn_num); return HI_FAILURE; } return HI_SUCCESS; } -void ImageMbufVideoSender::print_parameter() +int32_t ImageMbufVideoSender::PrintParameter() { printf("\n/****************************Vdec Parameter****************************/\n"); printf("InputFileName: %s \n", g_input_file_name); @@ -1056,9 +1782,10 @@ void ImageMbufVideoSender::print_parameter() printf("StartChnNum: %u \n", g_start_chn_num); printf("Render: %u \n", g_render); printf("/**********************************************************************/\n"); + return 0; } -void ImageMbufVideoSender::vdec_handle_signal(int32_t signo) +void ImageMbufVideoSender::VdecHandleSignal(int32_t signo) { for (int32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { g_send_exit_state[i] = 1; @@ -1067,23 +1794,26 @@ void ImageMbufVideoSender::vdec_handle_signal(int32_t signo) printf("Program Exit Abnormally! \n"); } -void ImageMbufVideoSender::init_outbuffer_lock() +void ImageMbufVideoSender::InitOutbufferLock() { for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { pthread_mutex_init(&g_out_buffer_pool_lock[i], NULL); } } -void ImageMbufVideoSender::destroy_outbuffer_lock() +void ImageMbufVideoSender::DestroyOutbufferLock() { for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { pthread_mutex_destroy(&g_out_buffer_pool_lock[i]); } } -void ImageMbufVideoSender::release_outbuffer(uint32_t chanId) +void ImageMbufVideoSender::ReleaseOutbuffer(uint32_t chanId) { void *outBuffer = NULL; + if (g_switchFlag == -1) { + g_out_buffer_pool[chanId].clear(); + } while (g_out_buffer_pool[chanId].empty() == false) { outBuffer = g_out_buffer_pool[chanId].back(); g_out_buffer_pool[chanId].pop_back(); @@ -1091,48 +1821,57 @@ void ImageMbufVideoSender::release_outbuffer(uint32_t chanId) } } -void ImageMbufVideoSender::get_start_time() +void ImageMbufVideoSender::GetStartTime() { - struct timeval currentTime; + timeval currentTime; gettimeofday(¤tTime, NULL); - g_start_time = currentTime.tv_sec * 1000000 + currentTime.tv_usec; + g_start_time = currentTime.tv_sec * CN1000000 + currentTime.tv_usec; } -int32_t ImageMbufVideoSender::hi_dvpp_init() +int32_t ImageMbufVideoSender::HiDvppInit() { - int32_t s32Ret = ACL_SUCCESS; aclError aclRet = aclInit(NULL); - if ((aclRet != ACL_SUCCESS) && (aclRet != 100002)) { - printf("[%s][%d] aclInit failed, error code = %d. \n", __FUNCTION__, __LINE__, aclRet); + if (g_switchFlag == ENUM_1) { + aclRet = -1; + } + if ((aclRet != ACL_SUCCESS) && (aclRet != CN100002)) { return HI_FAILURE; } printf("[%s][%d] aclInit success \n", __FUNCTION__, __LINE__); aclRet = aclrtSetDevice(0); + if (g_switchFlag == ENUM_2) { + aclRet = -1; + } if (aclRet != ACL_SUCCESS) { - printf("[%s][%d] aclrtSetDevice 0 failed, error code = %d \n", __FUNCTION__, __LINE__, aclRet); aclFinalize(); return HI_FAILURE; } printf("[%s][%d] aclrtSetDevice 0 success \n", __FUNCTION__, __LINE__); aclRet = aclrtCreateContext(&g_context, 0); + if (g_switchFlag == ENUM_3) { + aclRet = -1; + } if (aclRet != ACL_SUCCESS) { - printf("[%s][%d] aclrtCreateContext failed, error code = %d \n", __FUNCTION__, __LINE__, aclRet); aclrtResetDevice(0); aclFinalize(); return HI_FAILURE; } printf("[%s][%d] aclrtCreateContext success \n", __FUNCTION__, __LINE__); int32_t ret = hi_mpi_sys_init(); + if (g_switchFlag == ENUM_4) { + ret = -1; + } if (ret != HI_SUCCESS) { - printf("[%s][%d] hi_mpi_sys_init failed, error code = %x \n", __FUNCTION__, __LINE__, ret); aclrtDestroyContext(g_context); aclrtResetDevice(0); aclFinalize(); return HI_FAILURE; } aclRet = aclrtGetRunMode(&g_run_mode); + if (g_switchFlag == ENUM_NEGATIVE_ONE) { + aclRet = -1; + } if (aclRet != HI_SUCCESS) { - printf("[%s][%d] aclrtGetRunMode failed, error code = %x. \n", __FUNCTION__, __LINE__, aclRet); hi_mpi_sys_exit(); aclrtDestroyContext(g_context); aclrtResetDevice(0); @@ -1143,28 +1882,39 @@ int32_t ImageMbufVideoSender::hi_dvpp_init() return HI_SUCCESS; } -void ImageMbufVideoSender::hi_dvpp_deinit() +int32_t ImageMbufVideoSender::HiDvppDeinit() { int32_t ret = hi_mpi_sys_exit(); + if (g_switchFlag == ENUM_NEGATIVE_ONE) { + ret = HI_FAILURE; + } if (ret != HI_SUCCESS) { printf("[%s][%d] hi_mpi_sys_exit failed, error code = %x. \n", __FUNCTION__, __LINE__, ret); + return -1; } aclError aclRet = aclrtDestroyContext(g_context); if (aclRet != ACL_SUCCESS) { printf("[%s][%d] aclrtDestroyContext failed, error code = %d. \n", __FUNCTION__, __LINE__, aclRet); + return -1; } aclRet = aclrtResetDevice(0); if (aclRet != ACL_SUCCESS) { printf("[%s][%d] aclrtResetDevice 0 failed, error code = %d. \n", __FUNCTION__, __LINE__, aclRet); + return -1; } aclRet = aclFinalize(); - if ((aclRet != ACL_SUCCESS) && (aclRet != 100037)) { + if (g_switchFlag == ENUM_NEGATIVE_ONE) { + aclRet = -1; + } + if ((aclRet != ACL_SUCCESS) && (aclRet != CN100037)) { printf("[%s][%d] aclFinalize failed, error code = %d. \n", __FUNCTION__, __LINE__, aclRet); + return -1; } printf("[%s][%d] Dvpp system exit success \n", __FUNCTION__, __LINE__); + return 0; } -void ImageMbufVideoSender::stop_send_stream_thread() +void ImageMbufVideoSender::StopSendStreamThread() { for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { g_send_exit_state[i] = 1; @@ -1172,7 +1922,7 @@ void ImageMbufVideoSender::stop_send_stream_thread() g_exit = 1; } -void ImageMbufVideoSender::stop_get_pic_thread() +void ImageMbufVideoSender::StopGetPicThread() { for (uint32_t i = g_start_chn_num; i < g_start_chn_num + g_chn_num; i++) { g_get_exit_state[i] = 1; diff --git a/mdc/src/image_mbuf_video_sender.h b/mdc/src/image_mbuf_video_sender.h index 594901fb515effa1f2ad502528f2f30281ee1818..38c1400d10c681d6a37cc4f5bd60a9df400bcdd5 100644 --- a/mdc/src/image_mbuf_video_sender.h +++ b/mdc/src/image_mbuf_video_sender.h @@ -1,10 +1,10 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: image_mbuf_video_sender head file -*/ - + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: image_mbuf_video_sender head file + */ #ifndef IMAGE_MBUF_VIDEO_SENDER_H #define IMAGE_MBUF_VIDEO_SENDER_H + #include "image_sender_base.h" #include "mdc/cam/camera/cameradecodedmbufserviceinterface_skeleton.h" #include "util.h" @@ -14,13 +14,12 @@ #include "mdc/cam/camera/cameraimagembufserviceinterface_skeleton.h" #include "camera_data_head.h" - #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -33,82 +32,90 @@ #include "driver/ascend_hal.h" #include "driver/ascend_hal_define.h" -using namespace std; -using namespace cv; -const int32_t MAX_NAME_LENG = 500; +constexpr int ENUM_NEGATIVE_TWO = -2; +constexpr int ENUM_NEGATIVE_ONE = -1; +constexpr int ENUM_0 = 0; +constexpr int ENUM_1 = 1; +constexpr int ENUM_2 = 2; +constexpr int ENUM_3 = 3; +constexpr int ENUM_4 = 4; +constexpr int ENUM_5 = 5; +constexpr int ENUM_6 = 6; +constexpr int ENUM_7 = 7; +constexpr int ENUM_8 = 8; +constexpr int ENUM_9 = 9; +constexpr int ENUM_10 = 10; +constexpr int ENUM_11 = 11; +constexpr int ENUM_12 = 12; +constexpr int ENUM_13 = 13; +constexpr int ENUM_14 = 14; +constexpr int ENUM_15 = 15; +constexpr int ENUM_16 = 16; +constexpr int ENUM_17 = 17; -using CamPubImageMbufSkeleton = mdc::cam::camera::skeleton::CameraImageMbufServiceInterfaceSkeleton; -using MbufHandle = uintptr_t; -class ImageMbufVideoSender : public ImageSenderBase -{ - typedef void *(*pFUNC)(void *); -private: - poolHandle handle; - float lastTime = 0.0F; +constexpr int ENUM_FIVEK = 5000; +constexpr int ENUM_ONE_OO_TWO = 1002; +constexpr int ENUM_ONEK = 1000; +constexpr int ENUM_TWOK = 2000; +constexpr int ENUM_THREEK = 3000; - char g_input_file_name[MAX_NAME_LENG] = "test264.h264"; - char g_output_file_name[MAX_NAME_LENG] = "./outfile"; - uint32_t g_in_width = 3840; // input stream width - uint32_t g_in_height = 2160; // input stream height - uint32_t g_in_format = 0; - uint32_t g_in_bitwidth = 8; - uint32_t g_out_width = 0; - uint32_t g_out_height = 0; - uint32_t g_out_format = 0; - uint32_t g_out_width_stride = 4096; - uint32_t g_out_height_stride = 4096; - uint32_t g_is_write_file = 1; - uint32_t g_chn_num = 1; - uint32_t g_ref_frame_num = 8; - uint32_t g_display_frame_num = 2; - uint32_t g_output_order = 0; - uint32_t g_send_times = 1; - uint32_t g_send_interval = 0; - uint32_t g_delay_time = 1; - uint32_t g_alloc_num = 20; - uint32_t g_start_chn_num = 0; - uint32_t g_render = 0; - uint32_t g_exit = 0; +const int32_t MAX_NAME_LENG = 500; - uint32_t g_chan_create_state[VDEC_MAX_CHN_NUM] = {0}; - uint64_t g_start_time = 0; +struct GetImageFrameMsg { + int32_t chanId = 0; + uint8_t *inputFileBuf = nullptr; + uint32_t *frameCount = nullptr; + uint32_t fileSize = 0; + hi_payload_type type = HI_PT_H264; + uint8_t *dataDev = nullptr; + int32_t ret = HI_SUCCESS; + void *outBuffer = nullptr; + uint32_t outBufferSize = 0; + uint32_t outFormat = 0; - std::vector g_out_buffer_pool[VDEC_MAX_CHN_NUM]; - pthread_mutex_t g_out_buffer_pool_lock[VDEC_MAX_CHN_NUM]; + int32_t i = 0; + int32_t readLen = 0; + uint8_t *bufPointer = NULL; + bool isFindStart = false; + bool isFindEnd = false; +}; - uint32_t g_send_exit_state[VDEC_MAX_CHN_NUM] = {0}; - uint32_t g_get_exit_state[VDEC_MAX_CHN_NUM] = {0}; +struct InputImageMsg { + FILE *fpInputFile = NULL; + aclError aclRet = ACL_SUCCESS; + uint32_t fileSize = 0; + uint8_t *inputFileBuf = NULL; + uint32_t readLen = 0; + int32_t ret = HI_SUCCESS; +}; - pthread_t g_vdec_send_thread[VDEC_MAX_CHN_NUM] = {0}; - pthread_t g_vdec_get_thread[VDEC_MAX_CHN_NUM] = {0}; - uint32_t g_send_thread_id[VDEC_MAX_CHN_NUM] = {0}; - uint32_t g_get_thread_id[VDEC_MAX_CHN_NUM] = {0}; +using CamPubImageMbufSkeleton = mdc::cam::camera::skeleton::CameraImageMbufServiceInterfaceSkeleton; +using MbufHandle = uintptr_t; - uint8_t *g_frame_addr[VDEC_MAX_CHN_NUM][9999]; - uint64_t g_frame_len[VDEC_MAX_CHN_NUM][9999]; - uint64_t g_vdec_start_time[VDEC_MAX_CHN_NUM] = {0}; - uint64_t g_vdec_end_time[VDEC_MAX_CHN_NUM] = {0}; - uint64_t g_vdec_get_frame_cnt[VDEC_MAX_CHN_NUM] = {0}; +struct DealRunNode { + uint32_t imageSize; + uint32_t chanId; + uint32_t outWidthStride; + uint32_t outHeightStride; +}; - aclrtRunMode g_run_mode = ACL_HOST; - std::string sourceYuvPath; - FILE *fp_yuv; - chrono::high_resolution_clock::time_point sec; - int32_t seq{0}; +class ImageMbufVideoSender : public ImageSenderBase { + using PFunc = void *(*)(void *); public: aclrtContext g_context = NULL; public: ImageMbufVideoSender() = default; - ImageMbufVideoSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) + ImageMbufVideoSender(uint32_t id, cv::Size s, std::string dir) + : ImageSenderBase(id, s, dir) { g_in_width = s.width; g_in_height = s.height; g_out_width = s.width; g_out_height = s.height; - if (comPara.fileType == "h264") { + if (g_comPara.fileType == "h264") { g_in_format = 0; - } else if (comPara.fileType == "h265") { + } else if (g_comPara.fileType == "h265") { g_in_format = 1; } g_out_format = 0; @@ -117,12 +124,11 @@ public: g_out_height_stride = s.height; sourceYuvPath = dir; if (dir.back() != '/') { - sourceYuvPath += string("/") + "videoSource.yuv"; + sourceYuvPath += std::string("/") + "videoSource.yuv"; } else { sourceYuvPath += "videoSource.yuv"; } fp_yuv = fopen(sourceYuvPath.c_str(), "wb+"); - //sec = chrono::high_resolution_clock::now(); } ~ImageMbufVideoSender() { @@ -137,88 +143,93 @@ public: bool RegisterSender() { - std::cout << "Begin register MBUF image sender." << endl; + std::cout << "Begin register MBUF image sender." << std::endl; auto result = ImageSenderBase::RegisterSender(); - std::cout << "Finished to register MBUF image sender." << endl; + std::cout << "Finished to register MBUF image sender." << std::endl; return result; } - void VdecDecoded() + int32_t VdecDecoded() { std::string path = dir; - std::string postfix = comPara.fileType; - bool isLoop = comPara.loop; - cout << "dir : " << dir << "\t" << " postfix : " << postfix << endl; + std::string postfix = g_comPara.fileType; + bool isLoop = g_comPara.loop; std::vector files; - int32_t fileCnt = getFilesBySort(path, files, comPara.fileType); - if (fileCnt == 0) { - cout << "PATH:" << path << " has no files!" << endl; - return; + int32_t fileCnt = getFilesBySort(path, files, g_comPara.fileType); + if (fileCnt == ENUM_0) { + return -1; } do { for (auto &file : files) { + if (g_switchFlag == ENUM_NEGATIVE_TWO) { + file.clear(); + } if (file.empty()) { - std::cerr << "File not exist, or corrupt.path: " << file << std::endl; - return; + return -1; + } + errno_t ret = memset_s(g_input_file_name, sizeof(g_input_file_name), 0, MAX_NAME_LENG); + if (ret != EOK) { + return -1; + } + if (strcpy_s(g_input_file_name, file.length() + 1, file.c_str()) != 0) { + return -1; } - memset(g_input_file_name, 0, MAX_NAME_LENG); - strcpy(g_input_file_name, file.c_str()); VdecInit(); InitThreadPara(); VdecProcess(); VdecUninit(); } } while (isLoop); - fclose(fp_yuv); + if (fclose(fp_yuv) != 0) { + } + return 0; } void InitThreadPara() { g_send_exit_state[VDEC_MAX_CHN_NUM] = {0}; g_get_exit_state[VDEC_MAX_CHN_NUM] = {0}; - g_vdec_send_thread[VDEC_MAX_CHN_NUM] = {0}; - g_vdec_get_thread[VDEC_MAX_CHN_NUM] = {0}; + g_vdec_send_thread[VDEC_MAX_CHN_NUM] = {}; + g_vdec_get_thread[VDEC_MAX_CHN_NUM] = {}; g_send_thread_id[VDEC_MAX_CHN_NUM] = {0}; g_get_thread_id[VDEC_MAX_CHN_NUM] = {0}; } int32_t VdecInit() { - print_parameter(); + PrintParameter(); int32_t ret = HI_SUCCESS; - ret = hi_dvpp_init(); + ret = HiDvppInit(); if (ret != HI_SUCCESS) { - printf("[%s][%d] hi_dvpp_init failed !\n", __FUNCTION__, __LINE__); return -1; } - ret = vdec_create(); + ret = VdecCreate(); if (ret != HI_SUCCESS) { - printf("[%s][%d] VdecStart failed \n", __FUNCTION__, __LINE__); - vdec_destroy(); - hi_dvpp_deinit(); + VdecDestroy(); + HiDvppDeinit(); return -1; } - init_outbuffer_lock(); - get_start_time(); + InitOutbufferLock(); + GetStartTime(); return ret; } void VdecUninit() { - wait_vdec_end(); - show_decode_performance(); - destroy_outbuffer_lock(); - vdec_destroy(); - hi_dvpp_deinit(); + WaitVdecEnd(); + ShowDecodePerformance(); + DestroyOutbufferLock(); + VdecDestroy(); + HiDvppDeinit(); } void VdecProcess() { int32_t ret = HI_SUCCESS; - ret = create_send_stream_thread(); + ret = CreateSendStreamThread(); if (ret != 0) { - stop_send_stream_thread(); + StopSendStreamThread(); } else { - ret = create_get_pic_thread(); + ret = CreateGetPicThread(); if (ret != 0) { - stop_get_pic_thread(); + StopGetPicThread(); } } } @@ -234,7 +245,6 @@ public: attr.hugePageFlag = 1U; const int32_t ret = halBuffCreatePool(&attr, &handle); if (ret != DRV_ERROR_NONE) { - std::cout << "halBuffCreatePool error: " << ret << std::endl; return -1; } return 0; @@ -245,7 +255,6 @@ public: Mbuf *pMbuf = nullptr; const int32_t ret = halMbufAllocByPool(handle, &pMbuf); if (ret != 0) { - std::cout << "halMbufAllocByPool error: " << ret << std::endl; return -1; } getMbuf = reinterpret_cast(pMbuf); @@ -259,23 +268,19 @@ public: bool PackCameraHead(const YuvImageInfo &info, const uintptr_t &head) { - //获取Mbuf指针及长度 + // 获取Mbuf指针及长度 uintptr_t ptr; uint64_t size; const auto ret = GetMbufPtrLength(head, ptr, size); if (ret != 0) { - std::cout << "GetMbufPtrLength error: " << ret << std::endl; return false; } const uint64_t headSize = sizeof(mdc::camera::CameraDataHead); - std::cout << "--------SetMbufPtr(head, headSize)" << SetMbufPtr(head, headSize) << ",headSize=" << headSize << std::endl; if (headSize > size) { - std::cout << "Head size " << headSize << " larger than " << size << std::endl; return false; } const auto pHead = reinterpret_cast(ptr); if (memset_s(pHead, headSize, 0, headSize) != 0) { - std::cout << " memset_s fail!" << std::endl; return false; } pHead->seq = info.header.Seq; @@ -305,11 +310,10 @@ public: int32_t BufChainAppend(const uintptr_t head, const uintptr_t mbufPtr) const { - Mbuf *const pHead = reinterpret_cast(head); - Mbuf *const pMbuf = reinterpret_cast(mbufPtr); + Mbuf * const pHead = reinterpret_cast(head); + Mbuf * const pMbuf = reinterpret_cast(mbufPtr); const int32_t ret = halMbufChainAppend(pHead, pMbuf); if (ret != 0) { - std::cout << "halMbufChainAppend error: " << ret << std::endl; return -1; } return 0; @@ -318,7 +322,6 @@ public: int32_t GetMbufPtrLength(const MbufHandle &pMbuf, uintptr_t &ptr, uint64_t &len) const { if (BufGetDataPtr(pMbuf, ptr, len) != 0) { - std::cout << "CopyToMbuf BufGetDataPtr error: " << std::endl; return -1; } return 0; @@ -326,28 +329,26 @@ public: int32_t BufGetDataPtr(const uintptr_t in, uintptr_t &out, uint64_t &dataSize) const { - Mbuf *const pSrc = reinterpret_cast(in); + Mbuf * const pSrc = reinterpret_cast(in); void *pData = nullptr; - const int32_t ret = halMbufGetDataPtr(pSrc, &pData, &dataSize); + const int32_t ret = halMbufGetDataPtr(pSrc, &pData, &dataSize); if (ret != 0) { - std::cout << "MbufGetDataPtr error: " << ret << std::endl; return -1; } out = reinterpret_cast(pData); return 0; } - int32_t SetMbufPtr(const MbufHandle &pMbuf, const uint64_t &len) const + int32_t SetMbufPtr(const MbufHandle &pMbuf, const uint64_t &len) const { return BufSetDataLen(pMbuf, len); } int32_t BufSetDataLen(const uintptr_t setMbuf, const uint64_t len) const { - Mbuf *const pMbuf = reinterpret_cast(setMbuf); + Mbuf * const pMbuf = reinterpret_cast(setMbuf); const int32_t ret = halMbufSetDataLen(pMbuf, len); if (ret != 0) { - std::cout << "halMbufSetDataLen error: " << ret << std::endl; return -1; } return 0; @@ -355,49 +356,144 @@ public: int32_t BufFree(const uintptr_t in) const { - Mbuf *const pSrc = reinterpret_cast(in); + Mbuf * const pSrc = reinterpret_cast(in); const int32_t ret = halMbufFree(pSrc); if (ret != 0) { - std::cout << "MbufFree error: " << ret << std::endl; return -1; } return 0; } + void FillImageAndSend(std::string imgPath, uint32_t seq, int32_t *gStopFlag) override {} - - void FillImageAndSend(std::string imgPath, uint32_t seq, void *g_stopFlag) override {} public: - int32_t get_option(int32_t argc, char **argv); - int32_t check_option(); - void print_parameter(); - void vdec_handle_signal(int32_t signo); - int32_t vdec_create(); - void vdec_destroy(); - int32_t create_send_stream_thread(); - int32_t create_get_pic_thread(); - void stop_send_stream_thread(); - void stop_get_pic_thread(); - static void *send_stream(void *arg); - static void *get_pic(void *arg); - void get_every_frame(int32_t chanId, uint8_t *const inputFileBuf, uint32_t *const frameCount, uint32_t fileSize, - hi_payload_type type, uint8_t *devData); - void delay_exec(uint64_t execTime, int32_t seconds); - void wait_vdec_end(); - void show_decode_performance(); - void get_start_time(); - void init_outbuffer_lock(); - void destroy_outbuffer_lock(); - void release_outbuffer(uint32_t chanId); - int32_t hi_dvpp_init(); - void hi_dvpp_deinit(); + int32_t GetOption(int32_t argc, char **argv); + int32_t OptionSwitchAl(int32_t parameter); + int32_t OptionSwitchMv(int32_t parameter); + int32_t CheckOption(); + void CheckOptionFormat(); + int32_t PrintParameter(); + void VdecHandleSignal(int32_t signo); + int32_t VdecCreate(); + int32_t VdecDestroy(); + int32_t CreateSendStreamThread(); + int32_t CreateGetPicThread(); + void StopSendStreamThread(); + void StopGetPicThread(); + static int32_t SendStream(ImageMbufVideoSender *thiz); + static int32_t GetPic(ImageMbufVideoSender *thiz); + int32_t GetEveryFrame(GetImageFrameMsg& frameMsg); + int32_t DelayExec(uint64_t execTime, int32_t seconds); + void WaitVdecEnd(); + int32_t ShowDecodePerformance(); + void GetStartTime(); + void InitOutbufferLock(); + void DestroyOutbufferLock(); + void ReleaseOutbuffer(uint32_t chanId); + int32_t HiDvppInit(); + int32_t HiDvppDeinit(); + +private: + poolHandle handle; + float lastTime = 0.0F; + const int32_t frameWidthTriploid = 3; + const int32_t sleepTimeIntervalMs { 1000000 }; + char g_input_file_name[MAX_NAME_LENG] = "test264.h264"; + char g_output_file_name[MAX_NAME_LENG] = "./outfile"; + uint32_t g_in_width = 3840; // input stream width + uint32_t g_in_height = 2160; // input stream height + uint32_t g_in_format = 0; + uint32_t g_in_bitwidth = 8; + uint32_t g_out_width = 0; + uint32_t g_out_height = 0; + uint32_t g_out_format = 0; + uint32_t g_out_width_stride = 4096; + uint32_t g_out_height_stride = 4096; + uint32_t g_is_write_file = 1; + uint32_t g_chn_num = 1; + uint32_t g_ref_frame_num = 8; + uint32_t g_display_frame_num = 2; + uint32_t g_output_order = 0; + uint32_t g_send_times = 1; + uint32_t g_send_interval = 0; + uint32_t g_delay_time = 1; + uint32_t g_alloc_num = 20; + uint32_t g_start_chn_num = 0; + uint32_t g_render = 0; + uint32_t g_exit = 0; + + uint32_t g_chan_create_state[VDEC_MAX_CHN_NUM] = {0}; + uint64_t g_start_time = 0; + + std::vector g_out_buffer_pool[VDEC_MAX_CHN_NUM]; + pthread_mutex_t g_out_buffer_pool_lock[VDEC_MAX_CHN_NUM]; + + uint32_t g_send_exit_state[VDEC_MAX_CHN_NUM] = {0}; + uint32_t g_get_exit_state[VDEC_MAX_CHN_NUM] = {0}; + + std::thread g_vdec_send_thread[VDEC_MAX_CHN_NUM] = {}; + std::thread g_vdec_get_thread[VDEC_MAX_CHN_NUM] = {}; + uint32_t g_send_thread_id[VDEC_MAX_CHN_NUM] = {0}; + uint32_t g_get_thread_id[VDEC_MAX_CHN_NUM] = {0}; + + uint8_t *g_frame_addr[VDEC_MAX_CHN_NUM][9999]; + uint64_t g_frame_len[VDEC_MAX_CHN_NUM][9999]; + uint64_t g_vdec_start_time[VDEC_MAX_CHN_NUM] = {0}; + uint64_t g_vdec_end_time[VDEC_MAX_CHN_NUM] = {0}; + uint64_t g_vdec_get_frame_cnt[VDEC_MAX_CHN_NUM] = {0}; + + aclrtRunMode g_run_mode = ACL_HOST; + std::string sourceYuvPath; + FILE *fp_yuv; + std::chrono::high_resolution_clock::time_point sec; + int32_t seq { 0 }; + DealRunNode dealRunNode; + private: int32_t InitGrp(void); - void get_current_time_us(uint64_t &timeUs); - void save_yuv_file(FILE *const fd, hi_video_frame frame, uint32_t chanId); - void FillYuvAndSend(uint8_t *ptr, int32_t w, int32_t h); - void save_rgb_file(FILE *const fd, hi_video_frame frame, uint32_t chanId); - void vdec_reset_chn(uint32_t chanId); + void GetCurrentTimeUs(uint64_t &timeUs); + int32_t SaveYuvFile(FILE * const fd, hi_video_frame frame, uint32_t chanId); + int32_t SaveRgbFileAclHost(hi_video_frame frame, uint8_t *outImageBuf, FILE * const fd, uint32_t chanId); + int32_t SaveYuvFileAclHost(hi_video_frame frame, uint8_t *outImageBuf, FILE * const fd, uint32_t chanId); + bool DealRunNode(uint8_t *addr, hi_video_frame frame, FILE * const fd); + static int32_t GetPicHost(hi_video_frame_info& frame, ImageMbufVideoSender *thiz, + GetImageFrameMsg& frameMsg, hi_vdec_stream& stream, int32_t decResult); + static void UpdateOutPicInfo(hi_vdec_pic_info &outPicInfo, ImageMbufVideoSender *thiz, + GetImageFrameMsg& frameMsg, hi_vdec_stream& stream, uint32_t* pReadCount); + int32_t GetFrameHost(uint8_t * const inputFileBuf, int32_t chanId, uint32_t fileSize, hi_payload_type type); + static uint32_t DealSendTime(hi_vdec_pic_info &outPicInfo, ImageMbufVideoSender *thiz, GetImageFrameMsg& frameMsg, + uint32_t sendFrameFailCnt, hi_vdec_stream& stream); + static void DealSendFormat(ImageMbufVideoSender *thiz, GetImageFrameMsg& frameMsg, FILE *fpInputFile); + static uint8_t *DealDataDev(ImageMbufVideoSender *thiz, uint8_t* dataDev, FILE *fpInputFile, + GetImageFrameMsg& frameMsg); + static void DealInput(ImageMbufVideoSender *thiz, InputImageMsg& inputMsg); + int32_t DealGetFrameHost(uint8_t * const inputFileBuf, int32_t chanId, uint32_t fileSize, hi_payload_type type); + int32_t FillYuvAndSend(uint8_t *ptr, int32_t w, int32_t h); + bool DealMbufPtr(uintptr_t &mbufTmp, uint64_t actualLen, YuvImageInfo &yuvImageInfo, uintptr_t &head); + int32_t SaveRgbFile(FILE *const fd, hi_video_frame frame, uint32_t chanId); + int32_t VdecResetChn(uint32_t chanId); + int32_t DealParam(uint32_t i); + static int32_t DealDecResult(int32_t *decResult, int32_t *successCnt, uint32_t chanId, int32_t* failCnt); + void GetEveryFrameH264(GetImageFrameMsg& frameMsg); + void GetEveryFrameH265(GetImageFrameMsg& frameMsg); + void Cof1(); + void Cof2(); + void Cof3(); + void Cof4(); + void Cof5(); + void Cof6(); + void Cof7(); + void Cof8(); + void Cof9(); + void Cof10(); + void Cof11(); + void Cof12(); + void Cof13(); + void Cof14(); + void Cof15(); + void Cof16(); + void Cof17(); + int32_t CofOther(); }; #endif // IMAGE_MBUF_VIDEO_SENDER_H diff --git a/mdc/src/image_mbuf_yuv_sender.h b/mdc/src/image_mbuf_yuv_sender.h index 91fb0851ff8de541227f7f0e3f05d57d51457c27..fcb2e864de00cdd31a38a2111d54528417c702d1 100644 --- a/mdc/src/image_mbuf_yuv_sender.h +++ b/mdc/src/image_mbuf_yuv_sender.h @@ -1,10 +1,10 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: image_mbuf_yuv_sender head file -*/ - + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: image_mbuf_yuv_sender head file + */ #ifndef IMAGE_MBUF_YUV_SENDER_H #define IMAGE_MBUF_YUV_SENDER_H + #include "image_sender_base.h" #include "mdc/cam/camera/cameradecodedmbufserviceinterface_skeleton.h" #include "util.h" @@ -15,27 +15,25 @@ #include "camera_data_head.h" -using namespace std; -using namespace cv; - using CamPubImageMbufSkeleton = mdc::cam::camera::skeleton::CameraImageMbufServiceInterfaceSkeleton; using MbufHandle = uintptr_t; -class ImageMbufYuvSender : public ImageSenderBase -{ -private: - poolHandle handle {}; - float lastTime {0.0F}; - std::string sourceYuvPath; - FILE *fp_yuv; +struct DealMatPara { + int32_t frameCount; + int32_t frameSize; + int32_t seq; + uint64_t actualLen; + std::string file; +}; +class ImageMbufYuvSender : public ImageSenderBase { public: ImageMbufYuvSender() = default; - ImageMbufYuvSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) + ImageMbufYuvSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) { sourceYuvPath = dir; if (dir.back() != '/') { - sourceYuvPath += string("/") + "yuvSource.yuv"; + sourceYuvPath += std::string("/") + "yuvSource.yuv"; } else { sourceYuvPath += "yuvSource.yuv"; } @@ -45,14 +43,14 @@ public: } ~ImageMbufYuvSender() { - if (dataSkeleton != nullptr) { + if (dataSkeleton != nullptr) { dataSkeleton->StopOfferService(); dataSkeleton = nullptr; } if (handle != nullptr) { halBuffDeletePool(handle); } - } ; + }; bool RegisterSender() { @@ -66,15 +64,14 @@ public: { constexpr uint32_t alignSize = 32U; mpAttr attr; - attr.devid = 0; - attr.mGroupId = 0; - attr.blkSize = ((blkSize + alignSize) - 1U) & (~(alignSize - 1)); + attr.devid = 0; + attr.mGroupId = 0; + attr.blkSize = ((blkSize + alignSize) - 1U) & (~(alignSize - 1)); attr.blkNum = blkNum; attr.align = alignSize; attr.hugePageFlag = 1U; - const int32_t ret = halBuffCreatePool(&attr, &handle); + const int32_t ret = halBuffCreatePool(&attr, &handle); if (ret != DRV_ERROR_NONE) { - std::cout << "halBuffCreatePool error:" << ret << std::endl; return -1; } return 0; @@ -85,7 +82,6 @@ public: Mbuf *pMbuf = nullptr; const int32_t ret = halMbufAllocByPool(handle, &pMbuf); if (ret != 0) { - std::cout << "halMbufAllocByPool error: " << ret << std::endl; return -1; } getMbuf = reinterpret_cast(pMbuf); @@ -99,23 +95,20 @@ public: bool PackCameraHead(const YuvImageInfo &info, const uintptr_t &head) { - //获取Mbuf指针及长度 + // 获取Mbuf指针及长度 uintptr_t ptr; uint64_t size; const auto ret = GetMbufPtrLength(head, ptr, size); if (ret != 0) { - std::cout << "GetMbufPtrLength error: " << ret << std::endl; return false; } const uint64_t headSize = sizeof(mdc::camera::CameraDataHead); - std::cout << "--------SetMbufPtr(head, headSize)" << SetMbufPtr(head, headSize) << ",headSize=" << headSize << std::endl; if (headSize > size) { - std::cout << "Head size " << headSize << " larger than " << size << std::endl; return false; } const auto pHead = reinterpret_cast(ptr); if (memset_s(pHead, headSize, 0, headSize) != 0) { - std::cout << " memset_s fail!" << std::endl; + std::cout << " memset_s fail!" << std::endl; return false; } pHead->seq = info.header.Seq; @@ -145,11 +138,10 @@ public: int32_t BufChainAppend(const uintptr_t head, const uintptr_t mbufPtr) const { - Mbuf *const pHead = reinterpret_cast(head); - Mbuf *const pMbuf = reinterpret_cast(mbufPtr); + Mbuf * const pHead = reinterpret_cast(head); + Mbuf * const pMbuf = reinterpret_cast(mbufPtr); const int32_t ret = halMbufChainAppend(pHead, pMbuf); if (ret != 0) { - std::cout << "halMbufChainAppend error: " << ret << std::endl; return -1; } return 0; @@ -158,7 +150,6 @@ public: int32_t GetMbufPtrLength(const MbufHandle &pMbuf, uintptr_t &ptr, uint64_t &len) const { if (BufGetDataPtr(pMbuf, ptr, len) != 0) { - std::cout << "CopyToMbuf BufGetDataPtr error: " << std::endl; return -1; } return 0; @@ -166,28 +157,27 @@ public: int32_t BufGetDataPtr(const uintptr_t in, uintptr_t &out, uint64_t &dataSize) const { - Mbuf *const pSrc = reinterpret_cast(in); + Mbuf * const pSrc = reinterpret_cast(in); void *pData = nullptr; - const int32_t ret = halMbufGetDataPtr(pSrc, &pData, &dataSize); + const int32_t ret = halMbufGetDataPtr(pSrc, &pData, &dataSize); if (ret != 0) { - std::cout << "MbufGetDataPtr error: " << ret << std::endl; return -1; } out = reinterpret_cast(pData); return 0; } - int32_t SetMbufPtr(const MbufHandle &pMbuf, const uint64_t &len) const + int32_t SetMbufPtr(const MbufHandle &pMbuf, const uint64_t &len) const { return BufSetDataLen(pMbuf, len); } int32_t BufSetDataLen(const uintptr_t setMbuf, const uint64_t len) const { - Mbuf *const pMbuf = reinterpret_cast(setMbuf); + Mbuf * const pMbuf = reinterpret_cast(setMbuf); const int32_t ret = halMbufSetDataLen(pMbuf, len); if (ret != 0) { - std::cout << "halMbufSetDataLen error: " << ret << std::endl; + std::cout << "halMbufSetDataLen error: " << ret << std::endl; return -1; } return 0; @@ -195,17 +185,16 @@ public: int32_t BufFree(const uintptr_t in) const { - Mbuf *const pSrc = reinterpret_cast(in); + Mbuf * const pSrc = reinterpret_cast(in); const int32_t ret = halMbufFree(pSrc); if (ret != 0) { - std::cout << "MbufFree error: " << ret << std::endl; return -1; } return 0; } - void SaveImage(const ara::core::String &instanceId, - const uint32_t &seq, const uintptr_t &ptr, const uint32_t &len) const + void SaveImage(const ara::core::String &instanceId, const uint32_t &seq, const uintptr_t &ptr, + const uint32_t &len) const { FILE *filePtr; const auto fileName = instanceId + "_" + std::to_string(seq) + ".yuv"; @@ -219,121 +208,162 @@ public: } } - void FillImageAndSend(std::string imgPath, uint32_t seq, void *g_stopFlag) override + void FillImageAndSend(std::string imgPath, uint32_t seq, int32_t *gStopFlag) override { - (void)g_stopFlag; + (void)gStopFlag; std::string path = dir; - std::string postfix = comPara.fileType; - bool isLoop = comPara.loop; - cout << "dir: " << dir << "\t" << "postfix :" << postfix << endl; + std::string postfix = g_comPara.fileType; + bool isLoop = g_comPara.loop; std::vector files; - int32_t fileCnt = getFilesBySort(path, files, comPara.fileType); + int32_t fileCnt = getFilesBySort(path, files, g_comPara.fileType); if (fileCnt == 0) { - cout << "PATH:" << path << " has no files!" << endl; return; } do { for (auto &file : files) { - int32_t w = imgSize.width; - int32_t h = imgSize.height; - FILE *yuv_file; - yuv_file = fopen(file.c_str(), "rb"); + FILE *yuv_file = fopen(file.c_str(), "rb"); if (yuv_file == nullptr) { - cout << "Open yuv file failed!" << endl; return; } - int32_t frameSize = w * h * 3 / 2; - fseek(yuv_file, 0, SEEK_END); + int32_t frameSize = imgSize.width * imgSize.height * 3 / 2; + if (fseek(yuv_file, 0, SEEK_END) != 0) { + return; + } int32_t fileSize = ftell(yuv_file); + if (fileSize == -1L) { + return; + } rewind(yuv_file); int32_t frameCount = fileSize / frameSize; - char *yuvBuff = (char *)malloc(frameSize * sizeof(char)); - for (int32_t i = 0; i < frameCount; i++) { - Mat YUV420NV12; - YUV420NV12.create(h * 1.5, w, CV_8UC1); - memset(yuvBuff, 0, frameSize); - fread(yuvBuff, sizeof(char), frameSize, yuv_file); - memcpy(YUV420NV12.data, yuvBuff, frameSize); - uintptr_t head; - int32_t ret = GetMbuf(handle, head); - if (ret != 0) { - std::cout << "GetMbuf head error" << std::endl; - return; - } - YuvImageInfo yuvImageInfo; - yuvImageInfo.width = w; - yuvImageInfo.height = h; - //获取空闲Mbuf模块 - uintptr_t mbufTmp; - ret = GetMbuf(handle, mbufTmp); - if (ret != 0) { - std::cout << "GetMbuf mbufTmp error" << std::endl; - return; - } - //获取mbuff指针及长度 - uintptr_t outStream; - uint64_t mbufMaxLen; - uint64_t actualLen; - ret = GetMbufPtrLength(mbufTmp, outStream, mbufMaxLen); - if (ret != 0) { - std::cout << "GetMbufPtrLength error" << std::endl; - return; - } - actualLen = frameSize; - if (memcpy_s(reinterpret_cast(outStream), mbufMaxLen, YUV420NV12.data, actualLen) != 0) { - std::cout << "outStream memcpy_s failed" << std::endl; - } - //设置mbuf长度 - ret = SetMbufPtr(mbufTmp, actualLen); - if (ret != 0) { - std::cout << "SetMbufPtr error" << std::endl; - BufFree(mbufTmp); - return; - } - //设置mbuf - yuvImageInfo.mbuffer = mbufTmp; - yuvImageInfo.length = static_cast(actualLen); - if (!PackCameraHead(yuvImageInfo, head)) { - std::cout << "PackCameraHead error" << std::endl; - return; - } - auto apData = dataSkeleton->cameraImageMbufEvent.Allocate(); - const uint32_t imageHeadType_ = 1U; - const uint32_t imageYuvSemiplanarType_ = 1001U; - const uint32_t mutiImageVersion_ = 0x1000U; - apData->type.push_back(imageHeadType_); - ret = AppendMbuf(head, yuvImageInfo.mbuffer); - if (ret != 0) { - std::cout << "AppendMbuf error" << ", ret" << ret << std::endl; - return; - } - apData->type.push_back(imageYuvSemiplanarType_); - apData->version = mutiImageVersion_; - apData->seq = seq; - apData->head = reinterpret_cast(head); -#ifdef SAVE_SENDER_FILE - fwrite(YUV420NV12.data, 1, frameSize, fp_yuv); -#endif - dataSkeleton->cameraImageMbufEvent.Send(std::move(apData)); - cout << "Begin send image. seq: " << seq << ", frameID: " << frameID << " path: " << file << endl; - seq++; - if (comPara.frequency != "") { - int32_t freq = atoi(comPara.frequency.c_str()); - int32_t sleepTime = 1000000 / freq; - usleep(sleepTime); - } else { - usleep(1000000 / 30);//30hz - } + dealMatPara.frameCount = frameCount; + dealMatPara.frameSize = frameSize; + dealMatPara.seq = seq; + dealMatPara.file = file; + bool result = DealMat(yuv_file, file); + if (!result) { + return; } - free(yuvBuff); } } while (isLoop); #ifdef SAVE_SENDER_FILE - fclose(fp_yuv); + if (fclose(fp_yuv) != 0) { + std::cout << " fclose(fp_yuv) != 0 " << std::endl; + } #endif } -}; +private: + void HandleFrequency() + { + if (g_comPara.frequency != "") { + int32_t freq = atoi(g_comPara.frequency.c_str()); + if (freq != 0) { + int32_t sleepTime = CN1000000 / freq; + usleep(sleepTime); + } + } else { + usleep(CN1000000 / 30); // 30hz + } + } + bool DealMat(FILE *yuv_file, std::string &file) + { + char *yuvBuff = (char *)malloc(dealMatPara.frameSize * sizeof(char)); + if (yuvBuff == NULL) { + return false; + } + for (int32_t i = 0; i < dealMatPara.frameCount; i++) { + cv::Mat YUV420NV12; + YUV420NV12.create(imgSize.height * CN1P5, imgSize.width, CV_8UC1); + errno_t ret_s = memset_s(yuvBuff, dealMatPara.frameSize * sizeof(char), 0, dealMatPara.frameSize); + if (ret_s != EOK) { + return false; + } + if (fread(yuvBuff, sizeof(char), dealMatPara.frameSize, yuv_file) != dealMatPara.frameSize) { + std::cout << "fread yuvBuff error!" << std::endl; + } + memcpy_s(YUV420NV12.data, dealMatPara.frameSize, yuvBuff, dealMatPara.frameSize); + uintptr_t head; + if (GetMbuf(handle, head) != 0) { + return false; + } + YuvImageInfo yuvImageInfo; + yuvImageInfo.width = imgSize.width; + yuvImageInfo.height = imgSize.height; + // 获取空闲Mbuf模块 + uintptr_t mbufTmp; + if (GetMbuf(handle, mbufTmp) != 0) { + return false; + } + // 获取mbuff指针及长度 + uintptr_t outStream; + uint64_t mbufMaxLen; + uint64_t actualLen; + if (GetMbufPtrLength(mbufTmp, outStream, mbufMaxLen) != 0) { + return false; + } + actualLen = dealMatPara.frameSize; + dealMatPara.actualLen = actualLen; + if (memcpy_s(reinterpret_cast(outStream), mbufMaxLen, YUV420NV12.data, actualLen) != 0) { + std::cout << "outStream memcpy_s failed" << std::endl; + } + int32_t result = DealMbufPtr(mbufTmp, YUV420NV12, yuvImageInfo, head); + if (!result) { + return false; + } + } + free(yuvBuff); + return true; + } + + bool DealMbufPtr(uintptr_t &mbufTmp, cv::Mat &YUV420NV12, YuvImageInfo &yuvImageInfo, uintptr_t &head) + { + int ret; + // 设置mbuf长度 + ret = SetMbufPtr(mbufTmp, dealMatPara.actualLen); + if (ret != 0) { + BufFree(mbufTmp); + return false; + } + // 设置mbuf + yuvImageInfo.mbuffer = mbufTmp; + yuvImageInfo.length = static_cast(dealMatPara.actualLen); + if (!PackCameraHead(yuvImageInfo, head)) { + return false; + } + if (dataSkeleton == nullptr || dataSkeleton == NULL) { + return false; + } + auto apData = dataSkeleton->cameraImageMbufEvent.Allocate(); + const uint32_t imageHeadType_ = 1U; + const uint32_t imageYuvSemiplanarType_ = 1001U; + const uint32_t mutiImageVersion_ = 0x1000U; + apData->type.push_back(imageHeadType_); + ret = AppendMbuf(head, yuvImageInfo.mbuffer); + if (ret != 0) { + return false; + } + apData->type.push_back(imageYuvSemiplanarType_); + apData->version = mutiImageVersion_; + apData->seq = dealMatPara.seq; + apData->head = reinterpret_cast(head); +#ifdef SAVE_SENDER_FILE + if (fwrite(YUV420NV12.data, 1, dealMatPara.frameSize, fp_yuv) != dealMatPara.frameSize) { + std::cout << "fwrite() != frameSize" << std::endl; + } +#endif + dataSkeleton->cameraImageMbufEvent.Send(std::move(apData)); + dealMatPara.seq++; + HandleFrequency(); + return true; + } + +private: + poolHandle handle {}; + float lastTime { 0.0F }; + std::string sourceYuvPath; + FILE *fp_yuv; + DealMatPara dealMatPara; +}; #endif // IMAGE_MBUF_YUV_SENDER_H diff --git a/mdc/src/image_sender_base.h b/mdc/src/image_sender_base.h index 29b0136a902d25225c93c578c19153004bb28f60..e30aa3a59f1c396f47d697e1a2c58565a85f364a 100644 --- a/mdc/src/image_sender_base.h +++ b/mdc/src/image_sender_base.h @@ -1,9 +1,10 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: image_sender_base head file -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: image_sender_base head file + */ #ifndef IMAGE_SENDER_BASE_H #define IMAGE_SENDER_BASE_H + #include #include #include @@ -23,7 +24,7 @@ static struct CommandPara { std::string frequency{""}; bool loop{false}; std::string time{""}; -} comPara; +} g_comPara; using CameraHeaderMbufStruct = ara::camera::CameraHeaderMbufStruct; struct YuvImageInfo { @@ -36,9 +37,7 @@ struct YuvImageInfo { uint32_t length = 0U; }; -template -class ImageSenderBase -{ +template class ImageSenderBase { public: ImageSenderBase() = default; virtual ~ImageSenderBase() = default; @@ -62,15 +61,16 @@ public: std::cerr << "Publish to instance id: " << idStr << " succeed!" << std::endl; return true; } - virtual void FillImageAndSend(std::string imgPath, uint32_t seq, void *flag) = 0; + virtual void FillImageAndSend(std::string imgPath, uint32_t seq, int32_t *flag) = 0; -protected: - uint32_t instanceId{ 21 }; - std::string frameID{"sender_"}; - std::shared_ptr dataSkeleton{}; - std::string dir{""}; public: - cv::Size imgSize{1920, 1080}; + cv::Size imgSize { 1920, 1080 }; + +protected: + uint32_t instanceId { 21 }; + std::string frameID { "sender_" }; + std::shared_ptr dataSkeleton {}; + std::string dir { "" }; }; #endif // IMAGE_SENDER_BASE_H diff --git a/mdc/src/main.cpp b/mdc/src/main.cpp index a7efa3a3cf1bdb50792d844b4aa17131687e2a55..8d14a164814dfad0fdeb8457d4700d28d988816a 100644 --- a/mdc/src/main.cpp +++ b/mdc/src/main.cpp @@ -1,7 +1,7 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: main file -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: main file + */ #include #include #include @@ -29,15 +29,6 @@ using namespace cv; int32_t g_stopFlag = 0; -void SetEnv() -{ - if (comPara.fileType == "pcd") { - setenv("CM_CONFIG_FILE_PATH", "/opt/platform/mdc_platform/manual_service/lidar_a_cm/etc/LidarCmProcess", 1); - } else { - setenv("CM_CONFIG_FILE_PATH", "/opt/platform/mdc_platform/manual_service/camera_a_cm/etc/CameraProcess", 1); - } -} - inline bool IsInstanceIdAvialable(std::string fileType, int32_t id) { bool idIsAvailable = false; @@ -47,15 +38,17 @@ inline bool IsInstanceIdAvialable(std::string fileType, int32_t id) idIsAvailable = true; return idIsAvailable; } - std::cout << "current " << fileType << " instanceId is " << id << ",instanceId error,available value is [3,7]" << std::endl; + std::cout << "current " << fileType << " instanceId is " << id << + ",instanceId error,available value is [3,7]" << std::endl; return idIsAvailable; } // 21为camera的InstanceId最小值 35为camera的InstanceId最大值 - if (id >= 21 && id <= 35 && comPara.transMode != "image") { + if (id >= 21 && id <= 35 && g_comPara.transMode != "image") { idIsAvailable = true; return idIsAvailable; } - if (id >= 1021 && id <= 1034 && comPara.transMode == "image") { + // 1021 is min of camera InstancdID, 1034 is max of camera InstanceID + if (id >= CN1021 && id <= CN1034 && g_comPara.transMode == "image") { idIsAvailable = true; return idIsAvailable; } @@ -69,194 +62,91 @@ bool IsDateTimeAvailabe(string &dateTime) { vector dateStringVec; boost::split(dateStringVec, dateTime, boost::is_any_of(" "), boost::token_compress_on); - if (dateStringVec.size() != 2) { + if (dateStringVec.size() != CN2) { std::cout << "the input datetime format is error,usage \'2022-02-18 10:09:08\'" << std::endl; return false; } vector timeStringVec; boost::split(timeStringVec, dateStringVec[1], boost::is_any_of(":"), boost::token_compress_on); - if (timeStringVec.size() != 3) { + if (timeStringVec.size() != CN3) { std::cout << "the input datetime format is error,usage \'2022-02-18 10:09:08\'" << std::endl; return false; } uint32_t hour = atoi(timeStringVec[0].c_str()); uint32_t minutes = atoi(timeStringVec[1].c_str()); uint32_t seconds = atoi(timeStringVec[2].c_str()); - if (hour >= 24 || minutes >= 60 || seconds >= 60) { + if (hour >= CN24 || minutes >= CN60 || seconds >= CN60) { std::cout << "the input datetime format is error,usage \'2022-02-18 10:09:08\'" << std::endl; return false; } return true; } -int main(int32_t argc, char *argv[]) +int MainF2Check() { - int32_t ch; - while ((ch = getopt(argc, argv, "c:f:hlm:r:t:")) != -1) { - switch (ch) { - case 'c': - comPara.configFile = optarg; - break; - case 'f': - comPara.fileType = optarg; - break; - case 'h': - printf("--usage: \n"); - printf("./local_sensor_simulation -f [fileType] -c [configFile] -m [transMode] \n"); - printf("for example: ./local_sensor_simulation -f jpg -c image_config.yaml -m decoded -r 30 \n"); - printf("\n"); - printf("--option: \n"); - printf(" -f : [jpg/jpeg/yuv/h264/h265/pcd], requirement \n"); - printf(" -c : [configFile], requirement \n"); - printf(" -m : [decoded/image/simple/standard], option \n"); - printf(" -t : [yyyy-MM-dd HH:mm:ss], option \n"); - printf(" -r : [hz], option \n"); - printf(" -l , for loop, option \n"); - printf(" -h , for help, option \n"); - return 0; - case 'l': - comPara.loop = true; - break; - case 'm': - comPara.transMode = optarg; - break; - case 'r': - comPara.frequency = optarg; - break; - case 't': - comPara.time = optarg; - break; - case '?': - printf("miss para!\n"); - break; - case ':': - printf("invalid para! please input '-h' for help\n"); - break; - } - } - if (comPara.fileType == "") { + if (g_comPara.fileType == "") { std::cout << "'-f File type' can not be empty!" << std::endl; return 1; } else { - if (comPara.fileType != "jpg" && comPara.fileType != "jpeg" && comPara.fileType != "yuv" && - comPara.fileType != "h264" && comPara.fileType != "h265" && comPara.fileType != "pcd") { - std::cout << "-f File type is error: " << comPara.fileType << std::endl; + if (g_comPara.fileType != "jpg" && g_comPara.fileType != "jpeg" && g_comPara.fileType != "yuv" && + g_comPara.fileType != "h264" && g_comPara.fileType != "h265" && g_comPara.fileType != "pcd") { + std::cout << "-f File type is error: " << g_comPara.fileType << std::endl; return 1; } } - if (comPara.configFile == "") { + if (g_comPara.configFile == "") { std::cout << "'-c Config file' can not be empty!" << std::endl; return 1; } - //校验时间 + // 校验时间 std::string timeSample = "2022-02-18 10:09:08"; try { - if (!comPara.time.empty()) { - if (comPara.time.length() != timeSample.length()) { + if (!g_comPara.time.empty()) { + if (g_comPara.time.length() != timeSample.length()) { std::cout << "the input datetime format is error,usage \'" << timeSample << "\'" << std::endl; return -1; } - if (!IsDateTimeAvailabe(comPara.time)) { + if (!IsDateTimeAvailabe(g_comPara.time)) { return -1; } - boost::gregorian::date dateTime = boost::gregorian::from_string(comPara.time); + boost::gregorian::date dateTime = boost::gregorian::from_string(g_comPara.time); } } catch (std::exception &e) { std::cout << "the input datetime format is error,usage \'" << timeSample << "\'" << std::endl; return -1; } // 配置文件不存在则退出 - if (!ConfigMangage::FileExist(comPara.configFile)) { - std::cout << comPara.configFile << " file is not exist!" << std::endl; + if (!ConfigMangage::FileExist(g_comPara.configFile)) { + std::cout << g_comPara.configFile << " file is not exist!" << std::endl; return 1; } - if (comPara.frequency != "") { - int32_t frequency = atoi(comPara.frequency.c_str()); - if (frequency <= 0 || frequency > 100) { + if (g_comPara.frequency != "") { + int32_t frequency = atoi(g_comPara.frequency.c_str()); + // 100 is max frequency + if (frequency <= 0 || frequency > CN100) { std::cout << "-r frequency must be (0 < frequency <= 100)" << std::endl; return 1; } } - if (comPara.transMode != "") { - if (comPara.transMode != "decoded" && comPara.transMode != "image" && comPara.transMode != "standard" && comPara.transMode != "simple") { - std::cout << "-m transfer mode is error:" << comPara.transMode << std::endl; - } - } - ConfigMangage configManage{comPara.configFile}; - configManage.Parse(); - cout << "parse finished. [main]" << endl; - configManage.Show(); - if (!configManage.CheckConfig()) { - cerr << "Config check failed." << endl; - return 1; - } - auto configs = configManage.GetConfig(); - if (!ara::rm::RegisterHisiResource()) { - std::cerr << "Register process to RM failed! Check if RM has been started." << std::endl; - return -1; - } - vector> mbufSenders; - vector> mbufVideoSenders; - vector> mbufYuvSenders; - vector> pcdSenders; - vector> imageMbufSenders; - vector> imageMbufYuvSenders; - vector> imageMbufVideoSenders; - if (comPara.transMode == "image") { - for (auto &conf : configs) { - std::vector files; - int32_t fileCnt = getFilesBySort(conf.dir, files, comPara.fileType); - if (fileCnt == 0) { - std::cout << "dir : " << conf.dir << " has no " << comPara.fileType << " file" << std::endl; - continue; - } - // 校验instanceId - if (!IsInstanceIdAvialable(comPara.fileType, conf.instanceId)) { - continue; - } - if (comPara.fileType == "jpg" || comPara.fileType == "jpeg") { - imageMbufSenders.push_back(make_shared(conf.instanceId, Size{conf.width, conf.height}, conf.dir)); - } - if (comPara.fileType == "h264" || comPara.fileType == "h265") { - imageMbufVideoSenders.push_back(make_shared(conf.instanceId, Size{conf.width, conf.height}, conf.dir)); - } - if (comPara.fileType == "yuv") { - imageMbufYuvSenders.push_back(make_shared(conf.instanceId, Size{conf.width, conf.height}, conf.dir)); - } - if (comPara.fileType == "pcd") { - pcdSenders.push_back(make_shared(conf.instanceId, Size{conf.width, conf.height}, conf.dir)); - } - } - } else { - for (auto &conf : configs) { - std::vector files; - int32_t fileCnt = getFilesBySort(conf.dir, files, comPara.fileType); - if (fileCnt == 0) { - std::cout << "dir : " << conf.dir << " has no " << comPara.fileType << " file" << std::endl; - continue; - } - // 校验instanceId - if (!IsInstanceIdAvialable(comPara.fileType, conf.instanceId)) { - continue; - } - if (comPara.fileType == "jpg" || comPara.fileType == "jpeg") { - mbufSenders.push_back(make_shared(conf.instanceId, Size{conf.width, conf.height}, conf.dir)); - } - if (comPara.fileType == "h264" || comPara.fileType == "h265") { - mbufVideoSenders.push_back(make_shared(conf.instanceId, Size{conf.width, conf.height}, conf.dir)); - } - if (comPara.fileType == "yuv") { - mbufYuvSenders.push_back(make_shared(conf.instanceId, Size{conf.width, conf.height}, conf.dir)); - } - if (comPara.fileType == "pcd") { - pcdSenders.push_back(make_shared(conf.instanceId, Size{conf.width, conf.height}, conf.dir)); - } + if (g_comPara.transMode != "") { + if (g_comPara.transMode != "decoded" && g_comPara.transMode != "image" && + g_comPara.transMode != "standard" && g_comPara.transMode != "simple") { + std::cout << "-m transfer mode is error:" << g_comPara.transMode << std::endl; } } - SetEnv(); + return 0; +} + +int MainF4RegisterV1( + vector> &mbufSenders, + vector> &mbufVideoSenders, + vector> &mbufYuvSenders, + vector> &pcdSenders) +{ for (auto &send : mbufSenders) { send->RegisterSender(); - if (send->BufCreatePool(2880 * 1856 * 3, 20) == 0) { + // 2880 is mbuf video width, 1856 is mbuf video height, 3 is mbuf video number, 20 is mbuf pool number + if (send->BufCreatePool(CN2880 * CN1856 * CN3, CN20) == 0) { std::cout << "INFO: send->BufCreatePool succeed one!" << std::endl; } else { std::cout << "ERROR: send->BufCreatePool failed!" << std::endl; @@ -265,7 +155,7 @@ int main(int32_t argc, char *argv[]) } for (auto &videoSend : mbufVideoSenders) { videoSend->RegisterSender(); - if (videoSend->BufCreatePool(2880 * 1856 * 3, 20) == 0) { + if (videoSend->BufCreatePool(CN2880 * CN1856 * CN3, CN20) == 0) { std::cout << "INFO: send->BufCreatePool succeed one!" << std::endl; } else { std::cout << "ERROR: send->BufCreatePool failed!" << std::endl; @@ -274,7 +164,7 @@ int main(int32_t argc, char *argv[]) } for (auto &yuvSend : mbufYuvSenders) { yuvSend->RegisterSender(); - if (yuvSend->BufCreatePool(2880 * 1856 * 3, 20) == 0) { + if (yuvSend->BufCreatePool(CN2880 * CN1856 * CN3, CN20) == 0) { std::cout << "INFO: send->BufCreatePool succeed one!" << std::endl; } else { std::cout << "ERROR: send->BufCreatePool failed!" << std::endl; @@ -284,8 +174,37 @@ int main(int32_t argc, char *argv[]) for (auto &pcdSend : pcdSenders) { pcdSend->RegisterSender(); } + + usleep(CN1000000); + vector pool; + for (auto &send : mbufSenders) { + pool.push_back(thread(&DecodedMbufImageSender::FillImageAndSend, send, "", 0, &g_stopFlag)); + } + for (auto &videoSend : mbufVideoSenders) { + videoSend->VdecDecoded(); + } + for (auto &yuvSend : mbufYuvSenders) { + pool.push_back(thread(&DecodedMbufYuvSender::FillImageAndSend, yuvSend, "", 0, &g_stopFlag)); + } + for (auto &pcdSend : pcdSenders) { + pool.push_back(thread(&PcdSender::FillImageAndSend, pcdSend, "", 0, &g_stopFlag)); + } + for (auto &t : pool) { + if (t.joinable()) { + t.join(); + } + } + return 0; +} + +int MainF4RegisterV2( + vector> &imageMbufSenders, + vector> &imageMbufYuvSenders, + vector> &imageMbufVideoSenders) +{ for (auto &imageSend : imageMbufSenders) { imageSend->RegisterSender(); + // 3 is mbuf video number, 2 is get half, 40 is mbuf pool number if (imageSend->BufCreatePool(imageSend->imgSize.width * imageSend->imgSize.height * 3 / 2, 40) == 0) { std::cout << "INFO: send->BufCreatePool succeed one!" << std::endl; } else { @@ -295,7 +214,8 @@ int main(int32_t argc, char *argv[]) } for (auto &imageYuvSend : imageMbufYuvSenders) { imageYuvSend->RegisterSender(); - if (imageYuvSend->BufCreatePool(imageYuvSend->imgSize.width * imageYuvSend->imgSize.height * 3 / 2, 40) == 0) { + if (imageYuvSend->BufCreatePool( + imageYuvSend->imgSize.width * imageYuvSend->imgSize.height * CN3 / CN2, CN40) == 0) { std::cout << "INFO: send->BufCreatePool succeed one!" << std::endl; } else { std::cout << "ERROR: send->BufCreatePool failed!" << std::endl; @@ -304,27 +224,17 @@ int main(int32_t argc, char *argv[]) } for (auto &imageVideoSend : imageMbufVideoSenders) { imageVideoSend->RegisterSender(); - if (imageVideoSend->BufCreatePool(imageVideoSend->imgSize.width * imageVideoSend->imgSize.height * 3 / 2, 40) == 0) { + if (imageVideoSend->BufCreatePool( + imageVideoSend->imgSize.width * imageVideoSend->imgSize.height * CN3 / CN2, CN40) == 0) { std::cout << "INFO: send->BufCreatePool succeed one!" << std::endl; } else { std::cout << "ERROR: send->BufCreatePool failed!" << std::endl; return -1; } } - usleep(1000000); + + usleep(CN1000000); vector pool; - for (auto &send : mbufSenders) { - pool.push_back(thread(&MbufImageSender::FillImageAndSend, send, "", 0, &g_stopFlag)); - } - for (auto &videoSend : mbufVideoSenders) { - videoSend->VdecDecoded(); - } - for (auto &yuvSend : mbufYuvSenders) { - pool.push_back(thread(&MbufYuvSender::FillImageAndSend, yuvSend, "", 0, &g_stopFlag)); - } - for (auto &pcdSend : pcdSenders) { - pool.push_back(thread(&PcdSender::FillImageAndSend, pcdSend, "", 0, &g_stopFlag)); - } for (auto &imageSend : imageMbufSenders) { pool.push_back(thread(&ImageMbufImageSender::FillImageAndSend, imageSend, "", 0, &g_stopFlag)); } @@ -341,3 +251,183 @@ int main(int32_t argc, char *argv[]) } return 0; } + +void MainF3ConfigImage(std::vector &configs, + vector> &pcdSenders, + vector> &imageMbufSenders, + vector> &imageMbufYuvSenders, + vector> &imageMbufVideoSenders) +{ + for (auto &conf : configs) { + std::vector files; + int32_t fileCnt = getFilesBySort(conf.dir, files, g_comPara.fileType); + if (fileCnt == 0) { + std::cout << "dir : " << conf.dir << " has no " << g_comPara.fileType << " file" << std::endl; + continue; + } + // 校验instanceId + if (!IsInstanceIdAvialable(g_comPara.fileType, conf.instanceId)) { + continue; + } + if (g_comPara.fileType == "jpg" || g_comPara.fileType == "jpeg") { + imageMbufSenders.push_back(make_shared( + conf.instanceId, Size{conf.width, conf.height}, conf.dir)); + } + if (g_comPara.fileType == "h264" || g_comPara.fileType == "h265") { + imageMbufVideoSenders.push_back(make_shared( + conf.instanceId, Size{conf.width, conf.height}, conf.dir)); + } + if (g_comPara.fileType == "yuv") { + imageMbufYuvSenders.push_back(make_shared( + conf.instanceId, Size{conf.width, conf.height}, conf.dir)); + } + if (g_comPara.fileType == "pcd") { + pcdSenders.push_back(make_shared( + conf.instanceId, Size{conf.width, conf.height}, conf.dir)); + } + } +} + +void MainF3ConfigElse(std::vector &configs, + vector> &mbufSenders, + vector> &mbufVideoSenders, + vector> &mbufYuvSenders, + vector> &pcdSenders) +{ + for (auto &conf : configs) { + std::vector files; + int32_t fileCnt = getFilesBySort(conf.dir, files, g_comPara.fileType); + if (fileCnt == 0) { + std::cout << "dir : " << conf.dir << " has no " << g_comPara.fileType << " file" << std::endl; + continue; + } + // 校验instanceId + if (!IsInstanceIdAvialable(g_comPara.fileType, conf.instanceId)) { + continue; + } + if (g_comPara.fileType == "jpg" || g_comPara.fileType == "jpeg") { + mbufSenders.push_back(make_shared( + conf.instanceId, Size{conf.width, conf.height}, conf.dir)); + } + if (g_comPara.fileType == "h264" || g_comPara.fileType == "h265") { + mbufVideoSenders.push_back(make_shared( + conf.instanceId, Size{conf.width, conf.height}, conf.dir)); + } + if (g_comPara.fileType == "yuv") { + mbufYuvSenders.push_back(make_shared( + conf.instanceId, Size{conf.width, conf.height}, conf.dir)); + } + if (g_comPara.fileType == "pcd") { + pcdSenders.push_back(make_shared( + conf.instanceId, Size{conf.width, conf.height}, conf.dir)); + } + } +} + +int MainF3Config() +{ + int ret = 0; + + ConfigMangage configManage{g_comPara.configFile}; + configManage.Parse(); + cout << "parse finished. [main]" << endl; + configManage.Show(); + if (!configManage.CheckConfig()) { + cerr << "Config check failed." << endl; + return 1; + } + auto configs = configManage.GetConfig(); + if (!ara::rm::RegisterHisiResource()) { + std::cerr << "Register process to RM failed! Check if RM has been started." << std::endl; + return -1; + } + + vector> mbufSenders; + vector> mbufVideoSenders; + vector> mbufYuvSenders; + vector> pcdSenders; + vector> imageMbufSenders; + vector> imageMbufYuvSenders; + vector> imageMbufVideoSenders; + + if (g_comPara.transMode == "image") { + MainF3ConfigImage(configs, pcdSenders, imageMbufSenders, imageMbufYuvSenders, imageMbufVideoSenders); + } else { + MainF3ConfigElse(configs, mbufSenders, mbufVideoSenders, mbufYuvSenders, pcdSenders); + } + + ret = MainF4RegisterV1(mbufSenders, mbufVideoSenders, mbufYuvSenders, pcdSenders); + if (ret != 0) { + return ret; + } + ret = MainF4RegisterV2(imageMbufSenders, imageMbufYuvSenders, imageMbufVideoSenders); + if (ret != 0) { + return ret; + } + return 0; +} + +void Print4H() +{ + printf("--usage: \n"); + printf("./local_sensor_simulation -f [fileType] -c [configFile] -m [transMode] \n"); + printf("for example: ./local_sensor_simulation -f jpg -c image_config.yaml -m decoded -r 30 \n"); + printf("\n"); + printf("--option: \n"); + printf(" -f : [jpg/jpeg/yuv/h264/h265/pcd], requirement \n"); + printf(" -c : [configFile], requirement \n"); + printf(" -m : [decoded/image/simple/standard], option \n"); + printf(" -t : [yyyy-MM-dd HH:mm:ss], option \n"); + printf(" -r : [hz], option \n"); + printf(" -l , for loop, option \n"); + printf(" -h , for help, option \n"); +} + +int main(int32_t argc, char *argv[]) +{ + int32_t ch; + while ((ch = getopt(argc, argv, "c:f:hlm:r:t:")) != -1) { + switch (ch) { + case 'c': + g_comPara.configFile = optarg; + break; + case 'f': + g_comPara.fileType = optarg; + break; + case 'h': + Print4H(); + return 0; + case 'l': + g_comPara.loop = true; + break; + case 'm': + g_comPara.transMode = optarg; + break; + case 'r': + g_comPara.frequency = optarg; + break; + case 't': + g_comPara.time = optarg; + break; + case '?': + printf("miss para!\n"); + break; + case ':': + printf("invalid para! please input '-h' for help\n"); + break; + default: + break; + } + } + + int ret = MainF2Check(); + if (ret != 0) { + return ret; + } + ret = MainF3Config(); + if (ret != 0) { + return ret; + } + + return 0; +} diff --git a/mdc/src/pcd_sender.h b/mdc/src/pcd_sender.h index 176c68de347a8126092c8209572c4554d8bb73ce..ee168b4a2aac9d10aaa2e3ebbc0cbefbc9f7966d 100644 --- a/mdc/src/pcd_sender.h +++ b/mdc/src/pcd_sender.h @@ -1,7 +1,7 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: pcd_sender head file -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: pcd_sender head file + */ #ifndef PCD_SENDER_H #define PCD_SENDER_H @@ -15,11 +15,9 @@ #include #include #include - #include #include #include - #include "yaml/haf_yaml.h" #include "image_sender_base.h" #include "ara/lidar/impl_type_lidarpointcloud.h" @@ -28,7 +26,6 @@ #include "ara/lidar/lidarserviceinterface_skeleton.h" #include "util.h" -using namespace std; const int16_t X_IN_POINTCLOUD = 0; const int16_t Y_IN_POINTCLOUD = 4; const int16_t Z_IN_POINTCLOUD = 8; @@ -47,15 +44,12 @@ constexpr ara::com::ServiceVersionType LidarServiceInterface::ServiceVersion; using Skeleton_pcd = ara::lidar::skeleton::LidarServiceInterfaceSkeleton; -class PcdSender : public ImageSenderBase -{ -private: - chrono::high_resolution_clock::time_point sec;//-t used +class PcdSender : public ImageSenderBase { public: PcdSender() = default; PcdSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) { - sec = chrono::high_resolution_clock::now(); + sec = std::chrono::high_resolution_clock::now(); } ~PcdSender() = default; bool RegisterSender() @@ -66,100 +60,116 @@ public: return result; } - void FillImageAndSend(std::string imgPath, uint32_t seq, void *flag) override + void handleFrame(size_t i, ara::lidar::LidarPointCloud tmp) + { + if (g_comPara.time.empty()) { + timeval tv; + gettimeofday(&tv, 0); + tmp.header.stamp.sec = tv.tv_sec; + tmp.header.stamp.nsec = 1e3; + } else { + time_t timeStamp = convertTimeStr2TimeStamp(g_comPara.time); + auto t1 = std::chrono::high_resolution_clock::now(); + int64_t duration = (t1 - sec).count() / 1000000000.0; + tmp.header.stamp.sec = timeStamp + duration; + } + tmp.header.seq = i; + std::cout << "tmp.header.stamp.sec: " << tmp.header.stamp.sec << std::endl; + std::cout << "tmp.header.stamp.nsec: " << tmp.header.stamp.nsec << std::endl; + std::cout << "tmp.header.frameId: " << tmp.header.frameId << std::endl; + dataSkeleton->mdcEvent.Send(std::move(tmp)); + if (g_comPara.frequency != "") { + int32_t freq = atoi(g_comPara.frequency.c_str()); + int32_t sleepTime = freq == 0 ? 0 : CN1000000 / freq; + usleep(sleepTime); + } else { + usleep(CN1000000 / 30); // 30hz + } + } + + void GetLidarDataPoints(pcl::PointCloud::Ptr lidarData, uint8_t *pointCloud0, + int32_t loopCount, ara::lidar::LidarPointCloud tmp) + { + uint8_t *pointCloudCurr = nullptr; + for (int32_t pointCount = 0; pointCount < loopCount; pointCount++) { + pointCloudCurr = pointCloud0 + tmp.pointStep * pointCount; + if (g_comPara.transMode == "simple") { + *(reinterpret_cast(pointCloudCurr + X_IN_POINTCLOUD_SIMPLE)) = + lidarData->points[pointCount].x * CN100; + *(reinterpret_cast(pointCloudCurr + Y_IN_POINTCLOUD_SIMPLE)) = + lidarData->points[pointCount].y * CN100; + *(reinterpret_cast(pointCloudCurr + Z_IN_POINTCLOUD_SIMPLE)) = + lidarData->points[pointCount].z * CN100; + *(reinterpret_cast(pointCloudCurr + INTENSITY_IN_POINTCLOUD_SIMPLE)) = + lidarData->points[pointCount].intensity; + } else { + *(reinterpret_cast(pointCloudCurr + X_IN_POINTCLOUD)) = + lidarData->points[pointCount].x; + *(reinterpret_cast(pointCloudCurr + Y_IN_POINTCLOUD)) = + lidarData->points[pointCount].y; + *(reinterpret_cast(pointCloudCurr + Z_IN_POINTCLOUD)) = + lidarData->points[pointCount].z; + *(reinterpret_cast(pointCloudCurr + INTENSITY_IN_POINTCLOUD)) = + lidarData->points[pointCount].intensity; + } + } + } + + void DealFrame(std::vector pcd_names, std::string path) + { + for (size_t i = 0; i < pcd_names.size(); i++) { + const std::string pcd_name = pcd_names[i]; + const std::string pcd_source_path = path + pcd_name; + pcl::PointCloud::Ptr lidarData(new pcl::PointCloud); + if (pcl::io::loadPCDFile(pcd_source_path, *lidarData) == -1) { + std::cout << "load pcd failed" << std::endl; + continue; + } + std::stringstream str; + str << "copy-" << pcd_name; + pcl::PCDWriter writer; +#ifdef SAVE_SENDER_FILE + writer.writeBinaryCompressed(str.str(), *lidarData); +#endif + ara::lidar::LidarPointCloud tmp; + tmp.header.frameId = pcd_name; + if (g_comPara.transMode == "simple") { + tmp.pointStep = 13; // simple = 13 + } else { + tmp.pointStep = 32; // standard = 32 + } + tmp.height = lidarData->height; + tmp.width = lidarData->width; + std::vector pointCloudData; + pointCloudData.resize(tmp.pointStep * tmp.height * tmp.width); + uint8_t *pointCloud0 = &pointCloudData[0]; + uint8_t *pointCloudCurr = nullptr; + int32_t loopCount = static_cast(tmp.height) * static_cast(tmp.width); + int32_t maxNumOfPoints = (sliceSize - sizeof(tmp.header)) / tmp.pointStep; + if (g_switchFlag == CN112) { + maxNumOfPoints = 0; + } + if (loopCount > maxNumOfPoints) { + continue; + } + GetLidarDataPoints(lidarData, pointCloud0, loopCount, tmp); + tmp.data.assign(pointCloudData.begin(), pointCloudData.end()); + handleFrame(i, tmp); + } + } + + void FillImageAndSend(std::string imgPath, uint32_t seq, int32_t *flag) override { std::string path = dir; - std::string postfix = comPara.fileType; - bool isLoop = comPara.loop; - cout << "dir : " << dir << "\t" << "postfix :" << postfix << endl; + std::string postfix = g_comPara.fileType; + bool isLoop = g_comPara.loop; std::vector pcd_names; if (path.back() != '/') { - path = path + string("/"); + path = path + std::string("/"); } GetFilesFromDirectory(path, pcd_names); - std::cout << "There are" << pcd_names.size() << " pcd files in " << path << std::endl; do { - for (size_t i = 0; i < pcd_names.size(); i++) { - const std::string pcd_name = pcd_names[i]; - const std::string pcd_source_path = path + pcd_name; - std::cout << "The" << i << " pcd source path is: " << pcd_source_path << std::endl; - pcl::PointCloud::Ptr lidarData(new pcl::PointCloud); - if (pcl::io::loadPCDFile(pcd_source_path, *lidarData) == -1) { - std::cout << "load pcd failed" << std::endl; - continue; - } - std::cout << "Load local pcd successful, pointcloud size is: " << lidarData->width << ", " << - lidarData->height << std::endl; - std::stringstream str; - str << "copy-" << pcd_name; - pcl::PCDWriter writer; -#ifdef SAVE_SENDER_FILE - writer.writeBinaryCompressed(str.str(), *lidarData); -#endif - ara::lidar::LidarPointCloud tmp; - tmp.header.frameId = pcd_name; - if (comPara.transMode == "simple") { - tmp.pointStep = 13; - } else { - tmp.pointStep = 32;//simple=13,standard=32 - } - tmp.height = lidarData->height; - tmp.width = lidarData->width; - std::vector pointCloudData; - pointCloudData.resize(tmp.pointStep * tmp.height * tmp.width); - uint8_t *pointCloud0 = &pointCloudData[0]; - uint8_t *pointCloudCurr = nullptr; - int32_t loopCount = static_cast(tmp.height) * static_cast(tmp.width); - const int32_t sliceSize = 7400000; - int32_t maxNumOfPoints = (sliceSize - sizeof(tmp.header)) / tmp.pointStep; - if (loopCount > maxNumOfPoints) { - std::cout << pcd_name << " send failed due to too many points,max points num is " << maxNumOfPoints << std::endl; - continue; - } - for (int32_t pointCount = 0; pointCount < loopCount; pointCount++) { - pointCloudCurr = pointCloud0 + tmp.pointStep * pointCount; - if (comPara.transMode == "simple") { - *(reinterpret_cast(pointCloudCurr + X_IN_POINTCLOUD_SIMPLE)) = lidarData->points[pointCount].x * 100; - *(reinterpret_cast(pointCloudCurr + Y_IN_POINTCLOUD_SIMPLE)) = lidarData->points[pointCount].y * 100; - *(reinterpret_cast(pointCloudCurr + Z_IN_POINTCLOUD_SIMPLE)) = lidarData->points[pointCount].z * 100; - *(reinterpret_cast(pointCloudCurr + INTENSITY_IN_POINTCLOUD_SIMPLE)) = - lidarData->points[pointCount].intensity; - } else { - *(reinterpret_cast(pointCloudCurr + X_IN_POINTCLOUD)) = lidarData->points[pointCount].x; - *(reinterpret_cast(pointCloudCurr + Y_IN_POINTCLOUD)) = lidarData->points[pointCount].y; - *(reinterpret_cast(pointCloudCurr + Z_IN_POINTCLOUD)) = lidarData->points[pointCount].z; - *(reinterpret_cast(pointCloudCurr + INTENSITY_IN_POINTCLOUD)) = - lidarData->points[pointCount].intensity; - } - } - tmp.data.assign(pointCloudData.begin(), pointCloudData.end()); - if (comPara.time.empty()) { - timeval tv; - gettimeofday(&tv, 0); - tmp.header.stamp.sec = tv.tv_sec; - tmp.header.stamp.nsec = 1e3; - } else { - time_t timeStamp = convertTimeStr2TimeStamp(comPara.time); - auto t1 = chrono::high_resolution_clock::now(); - int64_t duration = (t1 - sec).count() / 1000000000.0; - tmp.header.stamp.sec = timeStamp + duration; - printf("timeStamp=%ld\n", timeStamp + duration); - } - tmp.header.seq = i; - std::cout << "tmp.header.stamp.sec: " << tmp.header.stamp.sec << std::endl; - std::cout << "tmp.header.stamp.nsec: " << tmp.header.stamp.nsec << std::endl; - std::cout << "tmp.header.frameId: " << tmp.header.frameId << std::endl; - dataSkeleton->mdcEvent.Send(std::move(tmp)); - //100ms sleep 10hz - //usleep(interval * 1000); - if (comPara.frequency != "") { - int32_t freq = atoi(comPara.frequency.c_str()); - int32_t sleepTime = 1000000 / freq; - usleep(sleepTime); - } else { - usleep(1000000 / 30);//30hz - } - } + DealFrame(pcd_names, path); } while (isLoop); } private: @@ -185,6 +195,9 @@ private: { return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; } + +private: + std::chrono::high_resolution_clock::time_point sec; // -t used }; #endif // PCD_SENDER_H diff --git a/mdc/src/util.cpp b/mdc/src/util.cpp index 0e7497edeb3b76e54818459aadb9d1b6a3c445e6..cbdb0482c2949cc1dd106a0930f5d99285dc68b1 100644 --- a/mdc/src/util.cpp +++ b/mdc/src/util.cpp @@ -1,7 +1,7 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: util source file -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: util source file + */ #include "util.h" #include @@ -9,12 +9,28 @@ #include using namespace std; -void yuv420p2nv12(const cv::Mat &yuv420p, cv::Mat &yuv420_nv12, int32_t width, int32_t height) + +int g_switchFlagTWO = 0; +int g_switchFlag = 0; + +void ClearSwitchFlag() +{ + g_switchFlag = 0; + g_switchFlagTWO = 0; +} + +int g_imageVideoFlag = 0; // only for ImageMbufVideoSender +void ResetImageVideoFlag() +{ + g_imageVideoFlag = 0; +} + +void Yuv420p2nv12(const cv::Mat &yuv420p, cv::Mat &yuv420_nv12, int32_t width, int32_t height) { auto resolution = width * height; - for (int i = 0; i < resolution / 2; i += 2) { - yuv420_nv12.data[resolution + i] = yuv420p.data[resolution + (i / 2)]; - yuv420_nv12.data[resolution + i + 1] = yuv420p.data[resolution + resolution / 4 + (i / 2)]; + for (int i = 0; i < resolution / half; i += half) { + yuv420_nv12.data[resolution + i] = yuv420p.data[resolution + (i / half)]; + yuv420_nv12.data[resolution + i + 1] = yuv420p.data[resolution + resolution / resolutionSize + (i / half)]; } } @@ -22,11 +38,10 @@ int32_t getFiles(std::string &path, std::vector &files, std::string { std::string suffixName = "." + suffix; DIR *dirp; - struct dirent *dp; + dirent *dp; int32_t fileCnt = 0; dirp = opendir(path.c_str()); if (dirp == NULL) { - printf("opendir %s failed\n", path.c_str()); return 0; } while ((dp = readdir(dirp)) != NULL) { @@ -51,15 +66,16 @@ int32_t getFilesBySort(std::string &path, std::vector &files, std:: { std::string suffixName = "." + suffix; int32_t fileCnt = 0; - struct dirent **name_list; + dirent **name_list; int32_t count = scandir(path.c_str(), &name_list, NULL, alphasort); + if (g_switchFlag == CNF1) { + count = -1; + } if (count < 0) { - printf("opendir %s failed\n", path.c_str()); return 0; } for (int32_t i = 0; i < count; i++) { - struct dirent *name; - name = name_list[i]; + dirent *name = name_list[i]; std::string curpath(path); if (path.back() != '/') { curpath += string("/") += name->d_name; @@ -78,10 +94,9 @@ int32_t getFilesBySort(std::string &path, std::vector &files, std:: time_t convertTimeStr2TimeStamp(string timeStr) { - struct tm timeinfo; + tm timeinfo; strptime(timeStr.c_str(), "%Y-%m-%d %H:%M:%S", &timeinfo); time_t timeStamp = mktime(&timeinfo); - //printf("timeStamp=%1d\n", timeStamp); return timeStamp; } @@ -94,7 +109,6 @@ FuncTimeMeasure::~FuncTimeMeasure() { end = std::chrono::steady_clock::now(); auto duration = std::chrono::duration_cast(end - start).count(); - std::cout << "Time costed for [" << description << "] is " << duration << "ms" << std::endl; } std::string CurrentTimeAndDate() @@ -108,9 +122,11 @@ std::string CurrentTimeAndDate() void ConfigMangage::Parse() { - cout << "begin to parse config file: " << file << endl; try { - auto root = Adsfi::HafYamlNode(file).GetNode(); + auto root = Adsfi::HafYaml(file).GetNode(); + if (g_switchFlag == CN1) { + configs.clear(); + } for (auto it = root.begin(); it != root.end(); ++it) { Config conf; conf.dir = (*it)["dir"].as(); @@ -120,13 +136,12 @@ void ConfigMangage::Parse() configs.push_back(conf); } } catch (YAML::TypedBadConversion &e) { - cout << "config file format error,please check config file!" << endl; + cout << "config file format error,please check config file! " << endl; } catch (YAML::TypedBadConversion &e) { - cout << "config file format error,please check config file!" << endl; + cout << "config file format error,please check config file! " << endl; } catch (YAML::ParserException &e) { - cout << "config file format error,please check config file!" << endl; + cout << "config file format error,please check config file! ParserException" << endl; } - cout << "Parse config file finished." << endl; } std::vector ConfigMangage::GetConfig() @@ -147,12 +162,11 @@ void ConfigMangage::Show() bool ConfigMangage::CheckConfig() { - //check if duplicatee id exists + // check if duplicatee id exists map count; for (auto &conf : configs) { count[conf.instanceId]++; if (count[conf.instanceId] > 1) { - cerr << "ERROR: Multiple instance id found: " << conf.instanceId << endl; return false; } } diff --git a/mdc/src/util.h b/mdc/src/util.h index b184d7a95c595d3262119519f47517b759fd8b42..a629467e73c7ca3d18abaa9efa816149b81403a5 100644 --- a/mdc/src/util.h +++ b/mdc/src/util.h @@ -1,12 +1,10 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: util head file -*/ - + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: util head file + */ #ifndef UTIL_H #define UTIL_H -#include "yaml/haf_yaml.h" #include #include #include @@ -19,40 +17,93 @@ #include // put_time #include // string #include +#include "yaml/haf_yaml.h" + +constexpr int CNF1 = -1; +constexpr int CN1 = 1; +constexpr int CN2 = 2; +constexpr int CN3 = 3; +constexpr int CN4 = 4; +constexpr int CN5 = 5; +constexpr int CN6 = 6; +constexpr int CN7 = 7; +constexpr int CN8 = 8; +constexpr int CN10 = 10; +constexpr int CN15 = 15; +constexpr int CN16 = 16; +constexpr int CN20 = 20; +constexpr int CN21 = 21; +constexpr int CN24 = 24; +constexpr int CN30 = 30; +constexpr int CN31 = 31; +constexpr int CN32 = 32; +constexpr int CN33 = 33; +constexpr int CN34 = 34; +constexpr int CN39 = 39; +constexpr int CN40 = 40; +constexpr int CN41 = 41; +constexpr int CN60 = 60; +constexpr int CN96 = 96; +constexpr int CN99 = 99; +constexpr int CN100 = 100; +constexpr int CN103 = 103; +constexpr int CN107 = 107; +constexpr int CN112 = 112; +constexpr int CN128 = 128; +constexpr int CN500 = 500; +constexpr int CN1000 = 1000; +constexpr int CN1021 = 1021; +constexpr int CN1034 = 1034; +constexpr int CN1856 = 1856; +constexpr int CN2880 = 2880; +constexpr int CN4096 = 4096; +constexpr int CN100002 = 100002; +constexpr int CN100037 = 100037; +constexpr int CN1000000 = 1000000; +constexpr int CN5000000 = 5000000; + +constexpr int32_t half = 2; +constexpr int32_t resolutionSize = 4; +constexpr int32_t sliceSize = 7400000; + +constexpr float CN1P5 = 1.5; + +extern int g_switchFlagTWO; +extern int g_switchFlag; +extern void ClearSwitchFlag(); +extern int g_imageVideoFlag; +void ResetImageVideoFlag(); std::string CurrentTimeAndDate(); -void yuv420p2nv12(const cv::Mat &yuv420p, cv::Mat &yuv420_nv12, int32_t width, int32_t height); +void Yuv420p2nv12(const cv::Mat &yuv420p, cv::Mat &yuv420_nv12, int32_t width, int32_t height); int32_t getFiles(std::string &path, std::vector &files, std::string suffix); int32_t getFilesBySort(std::string &path, std::vector &files, std::string suffix); time_t convertTimeStr2TimeStamp(std::string timeStr); -class FuncTimeMeasure -{ +class FuncTimeMeasure { public: - FuncTimeMeasure(std::string &&descrip); + explicit FuncTimeMeasure(std::string &&descrip); ~FuncTimeMeasure(); private: std::string description; - std::chrono::time_point start{}; - std::chrono::time_point end{}; + std::chrono::time_point start {}; + std::chrono::time_point end {}; }; struct Config { - std::string dir{""}; - int32_t instanceId{0}; - int32_t width{0}; - int32_t height{0}; + std::string dir { "" }; + int32_t instanceId { 0 }; + int32_t width { 0 }; + int32_t height { 0 }; }; -class ConfigMangage -{ +class ConfigMangage { public: ConfigMangage() = default; ~ConfigMangage() = default; - ConfigMangage(std::string configFile) : file(configFile) - {} + explicit ConfigMangage(std::string configFile) : file(configFile) {} void Parse(); std::vector GetConfig(); void Show(); @@ -63,8 +114,10 @@ public: struct stat buffer; return (stat(name.c_str(), &buffer) == 0); } + private: - std::string file{"image_config.yaml"}; + std::string file { "image_config.yaml" }; std::vector configs; }; -#endif //UTIL_H + +#endif // UTIL_H diff --git a/mdc/src/yaml/haf_yaml.h b/mdc/src/yaml/haf_yaml.h index 124ad2160afafa14554270cae1bc4804f503258f..435f985eee4ffcd7065b24fec2c980ca32cf5555 100644 --- a/mdc/src/yaml/haf_yaml.h +++ b/mdc/src/yaml/haf_yaml.h @@ -1,10 +1,9 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: yaml处理类 -*/ - -#ifndef ADSF_INTERFACES_YAML_HAFYAML_H -#define ADSF_INTERFACES_YAML_HAFYAML_H + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: yaml处理类 + */ +#ifndef HAF_YAML_H +#define HAF_YAML_H #include #include @@ -15,10 +14,9 @@ namespace Adsfi { using HafYamlIterator = YAML::const_iterator; using HafException = YAML::Exception; -class HafYamlNode -{ +class HafYaml { public: - HafYamlNode(const std::string path) + explicit HafYaml(const std::string path) { std::ifstream fin(path); if (!fin) { @@ -29,27 +27,27 @@ public: node = YAML::LoadFile(path); } - HafYamlNode() {} + HafYaml() {} - HafYamlNode(const YAML::Node child) + explicit HafYaml(const YAML::Node child) { this->node = child; } - ~HafYamlNode() {}; + ~HafYaml() {}; // indexing - template const HafYamlNode operator[](const Key &keyName) const + template const HafYaml operator[](const Key &keyName) const { - return HafYamlNode(node[keyName]); + return HafYaml(node[keyName]); } - template HafYamlNode operator[](const Key &keyName) + template HafYaml operator[](const Key &keyName) { - return HafYamlNode(node[keyName]); + return HafYaml(node[keyName]); } // access - template T as() const + template T As() const { return node.as(); } @@ -103,8 +101,10 @@ public: { return node[keyName]; } + private: YAML::Node node; }; } -#endif + +#endif // HAF_YAML_H diff --git a/x86/src/CMakeLists.txt b/x86/src/CMakeLists.txt index 8f5af174f773551db0af4233caa413187b69dda6..e7c7eb8fdaccc9d73f8b960f5c12eaa59f018540 100644 --- a/x86/src/CMakeLists.txt +++ b/x86/src/CMakeLists.txt @@ -17,7 +17,7 @@ file(GLOB_RECURSE ${CMAKE_CURRENT_SOURCE_DIR}/*.cc ${CMAKE_SOURCE_DIR}/generated/*.cpp) -OPTION(SAVE_SENDER_FILE_MACRO "Build the project using macro,save local file set as ON,otherwise set OFF" OFF) +OPTION(SAVE_SENDER_FILE_MACRO "Build the project using macro,save local file set as ON,otherwise set OFF" ON) if(SAVE_SENDER_FILE_MACRO) add_definitions("-DSAVE_SENDER_FILE") else() @@ -59,6 +59,8 @@ target_include_directories(${MODULE_NAME} link_directories(/usr/local/lib) +add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY) + #用户可在此添加链接库 target_link_libraries(${MODULE_NAME} PRIVATE diff --git a/x86/src/image_sender.h b/x86/src/image_sender.h index 0ec58b4592c3ac7d5dd005a2a308692188b6974e..c094321f25d19b8384f240cb3c43226ad9c6deb3 100755 --- a/x86/src/image_sender.h +++ b/x86/src/image_sender.h @@ -1,127 +1,164 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: image sender -*/ -#ifndef IAMGE_SENDER_H -#define IAMGE_SENDER_H + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: image sender + */ +#ifndef IMAGE_SENDER_H +#define IMAGE_SENDER_H #include "image_sender_base.h" #include "util.h" #include "mdc/cam/camera/cameradecodedmbufserviceinterface_skeleton.h" -using namespace std; -using namespace cv; using Skeleton = mdc::cam::camera::skeleton::CameraDecodedMbufServiceInterfaceSkeleton; -class ImageSender : public ImageSenderBase -{ + +class ImageSender : public ImageSenderBase { public: ImageSender() = default; - ImageSender(uint32_t id, cv::Size s, std::string dir): ImageSenderBase(id, s, dir) + ImageSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) { sourceYuvPath = dir; if (dir.back() != '/') { - sourceYuvPath += string("/") += "imageSource.yuv"; + sourceYuvPath += std::string("/") += "imageSource.yuv"; } else { sourceYuvPath += "imageSource.yuv"; } #ifdef SAVE_SENDER_FILE fpYuv = fopen(sourceYuvPath.c_str(), "wb+"); #endif - sec = chrono::high_resolution_clock::now(); + sec = std::chrono::high_resolution_clock::now(); } ~ImageSender() = default; bool RegisterSender() { - std::cout << "Begin register normal image sender." << endl; + std::cout << "Begin register normal image sender." << std::endl; auto result = ImageSenderBase::RegisterSender(); - std::cout << "Finished to register normal image sender." << endl; + std::cout << "Finished to register normal image sender." << std::endl; return result; } - void FillImageAndSend(std::string imgPath, uint32_t seq, void *flag) override + int retImageSender = -1; + void FillImageAndSend(std::string imgPath, uint32_t seq, int32_t *flag) override { std::string path = dir; - std::string postfix = comPara.fileType; - bool isLoop = comPara.loop; - cout << "dir : " << dir << "\t" << "postfix :" << postfix << endl; + std::string postfix = g_comPara.fileType; + bool isLoop = g_comPara.loop; + std::cout << "dir : " << dir << "\t" + << "postfix :" << postfix << std::endl; std::vector files; - int32_t fileCnt = GetFilesBySort(path, files, comPara.fileType); + int32_t fileCnt = GetFilesBySort(path, files, g_comPara.fileType); if (fileCnt == 0) { - cout << "PATH:" << path << " has no files!" << endl; + std::cout << "PATH:" << path << " has no files!" << std::endl; + retImageSender = -1; return; } do { for (auto &file : files) { (void)flag; + if (1 == SwitchFlag) { + file = ""; + } if (file.empty()) { std::cerr << "File not exist,or corrupt.path:" << file << std::endl; + retImageSender = -1; return; } if (!ConfigManage::FileExist(file)) { std::cout << file << " file is not exist!" << std::endl; + retImageSender = -1; return; } - Mat YUV; - cv::Mat BGR = imread(file, IMREAD_COLOR); - try { - if (imgSize.width != BGR.cols || imgSize.height != BGR.rows) { - cv::resize(BGR, BGR, imgSize); - } - cvtColor(BGR, YUV, cv::COLOR_BGR2YUV_I420); - } catch (cv::Exception &e) { - cout << e.what() << endl; - } - int32_t frameSize = BGR.rows * BGR.cols * 3 / 2; - unsigned char *pFrame = (unsigned char *)malloc(frameSize); - if (nullptr == pFrame) { - std::cout << "malloc pFrame memory error" << std::endl; + bool result = CallProcessing(file, seq); + if (!result) { + retImageSender = -1; return; } - memset(pFrame, 0, frameSize); - memcpy(pFrame, YUV.data, frameSize); - auto imagePub = dataSkeleton->cameraDecodedMbufEvent.Allocate(); - imagePub->CameraHeader.FrameId = frameID; - imagePub->CameraHeader.Seq = seq; - imagePub->Width = BGR.cols; - imagePub->Height = BGR.rows; - imagePub->DataSize = frameSize; - imagePub->UdpData.assign(pFrame, pFrame + imagePub->DataSize); + } + } while (isLoop); #ifdef SAVE_SENDER_FILE - fwrite(pFrame, 1, imagePub->DataSize, fpYuv); + if (fclose(fpYuv) == -1) { + std::cout << "fclose fpYuv failed!" << std::endl; + retImageSender = -1; + return; + } #endif - if (comPara.time.empty()) { - timeval now; - gettimeofday(&now, NULL); - imagePub->CameraHeader.Stamp.Sec = now.tv_sec; - imagePub->CameraHeader.Stamp.Nsec = now.tv_usec * 1000U; - } else { - time_t timeStamp = ConvertTimeStr2TimeStamp(comPara.time); - auto t1 = chrono::high_resolution_clock::now(); - int64_t duration = (t1 - sec).count() / 1000000000.0; - imagePub->CameraHeader.Stamp.Sec = timeStamp + duration; - printf("timeStamp=%ld\n", timeStamp + duration); - } - dataSkeleton->cameraDecodedMbufEvent.Send(move(imagePub)); - cout << "Begin send image. seq:" << seq << " frameID:" << frameID << " path:" << file << endl; - if (comPara.frequency != "") { - int32_t freq = atoi(comPara.frequency.c_str()); - int32_t sleepTime = 1000000 / freq; - usleep(sleepTime); - } else { - // 30h 1000000微秒 - usleep(1000000 / 30); // 30hz - } + retImageSender = 0; + } + +private: + void HandleFrequency() + { + const int32_t sleepTimeIntervalMs = 1000000; + if (g_comPara.frequency != "") { + int32_t freq = atoi(g_comPara.frequency.c_str()); + if (freq != 0) { + int32_t sleepTime = sleepTimeIntervalMs / freq; + usleep(sleepTime); } - } while (isLoop); + } else { + // 30h 1000000微秒 + usleep(sleepTimeIntervalMs / 30); // 30hz + } + } + + bool CallProcessing(std::string &file, uint32_t seq) + { + cv::Mat YUV; + cv::Mat BGR = cv::imread(file, cv::IMREAD_COLOR); + try { + if (imgSize.width != BGR.cols || imgSize.height != BGR.rows) { + cv::resize(BGR, BGR, imgSize); + } + cvtColor(BGR, YUV, cv::COLOR_BGR2YUV_I420); + } catch (cv::Exception &e) { + std::cout << e.what() << std::endl; + } + int32_t frameSize = BGR.rows * BGR.cols * 3 / 2; + unsigned char *pFrame = (unsigned char *)malloc(frameSize); + const int ciTwo = 2; + if (ciTwo == SwitchFlag) { + pFrame = nullptr; + } + if (pFrame == nullptr) { + return false; + } + if (memset_s(pFrame, frameSize, 0, frameSize) != 0) { + return false; + } + memcpy_s(pFrame, frameSize, YUV.data, frameSize); + auto imagePub = dataSkeleton->cameraDecodedMbufEvent.Allocate(); + imagePub->CameraHeader.FrameId = frameID; + imagePub->CameraHeader.Seq = seq; + imagePub->Width = BGR.cols; + imagePub->Height = BGR.rows; + imagePub->DataSize = frameSize; + imagePub->UdpData.assign(pFrame, pFrame + imagePub->DataSize); #ifdef SAVE_SENDER_FILE - fclose(fpYuv); + (void)fwrite(pFrame, 1, imagePub->DataSize, fpYuv); #endif + if (g_comPara.time.empty()) { + timeval now; + gettimeofday(&now, NULL); + imagePub->CameraHeader.Stamp.Sec = now.tv_sec; + imagePub->CameraHeader.Stamp.Nsec = now.tv_usec * 1000U; + } else { + time_t timeStamp = ConvertTimeStr2TimeStamp(g_comPara.time); + auto t1 = std::chrono::high_resolution_clock::now(); + int64_t duration = (t1 - sec).count() / 1000000000.0; + imagePub->CameraHeader.Stamp.Sec = timeStamp + duration; + } + const int ciThree = 3; + if (ciThree != SwitchFlag) { + dataSkeleton->cameraDecodedMbufEvent.Send(move(imagePub)); + } + HandleFrequency(); + return true; } + private: - std::string sourceYuvPath { }; + std::string sourceYuvPath {}; FILE *fpYuv { nullptr }; - chrono::high_resolution_clock::time_point sec { };//-t used + std::chrono::high_resolution_clock::time_point sec {}; // -t used }; -#endif // IAMGE_SENDER_H +#endif // IMAGE_SENDER_H diff --git a/x86/src/image_sender_base.h b/x86/src/image_sender_base.h index a2a4520b53b101019d6addcb09cf7a6f48be8b95..a2b7360472222428f26d47b0307ea97f1aea9255 100755 --- a/x86/src/image_sender_base.h +++ b/x86/src/image_sender_base.h @@ -1,10 +1,10 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: image/yuv sender base -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: image/yuv sender base + */ -#ifndef IAMGE_SENDER_BASE_H_ -#define IAMGE_SENDER_BASE_H_ +#ifndef IMAGE_SENDER_BASE_H +#define IMAGE_SENDER_BASE_H #include #include @@ -17,18 +17,18 @@ #include #include "mdc/cam/camera/cameradecodedmbufserviceinterface_skeleton.h" -struct CommandPara { +static struct CommandPara { std::string fileType {""}; std::string configFile {""}; std::string tansMode {""}; std::string frequency {""}; bool loop {false}; std::string time {""}; -} comPara; +} g_comPara; -template -class ImageSenderBase -{ +static int32_t SwitchFlag = -1; + +template class ImageSenderBase { public: ImageSenderBase() = default; virtual ~ImageSenderBase() = default; @@ -52,14 +52,14 @@ public: std::cerr << "Publish to instance id:" << idStr << " succeed!" << std::endl; return true; } - virtual void FillImageAndSend(std::string imgPath, uint32_t seq, void *flag) = 0; + virtual void FillImageAndSend(std::string imgPath, uint32_t seq, int32_t *flag) = 0; protected: - uint32_t instanceId {21}; - std::string frameID {"sender_"}; + uint32_t instanceId { 21 }; + std::string frameID { "sender_" }; std::shared_ptr dataSkeleton {}; - cv::Size imgSize {1920, 1080}; - std::string dir {""}; + cv::Size imgSize { 1920, 1080 }; + std::string dir { "" }; }; -#endif // _IAMGE_SENDER_BASE_H_ +#endif // IMAGE_SENDER_BASE_H diff --git a/x86/src/main.cpp b/x86/src/main.cpp index 5bde943a662d577b053702e7891271fd21574384..d91a3a26a419899f6b827e6c52fdf8a9cfe9b51a 100755 --- a/x86/src/main.cpp +++ b/x86/src/main.cpp @@ -1,7 +1,7 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: main函数 -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: main函数 + */ #include #include @@ -28,15 +28,6 @@ using namespace cv; int32_t gStopFlag = 0; -void SetEnv() -{ - if (comPara.fileType == "pcd") { - setenv("CM_CONFIG_FILE_PATH", "./LidarCmProcess/", 1); - } else { - setenv("CM_CONFIG_FILE_PATH", "./CameraReceiveProcess/", 1); - } -} - inline bool IsInstanceIdAvialable(std::string fileType, int32_t id) { bool idIsAvailable = false; @@ -46,7 +37,8 @@ inline bool IsInstanceIdAvialable(std::string fileType, int32_t id) idIsAvailable = true; return idIsAvailable; } - std::cout << "current " << fileType << " instanceId is " << id << ",instanceId error,available value is [3,7]" << std::endl; + std::cout << "current " << fileType << " instanceId is " << id << + ",instanceId error,available value is [3,7]" << std::endl; return idIsAvailable; } // 21为camera的InstanceId最小值 35为camera的InstanceId最大值 @@ -54,7 +46,8 @@ inline bool IsInstanceIdAvialable(std::string fileType, int32_t id) idIsAvailable = true; return idIsAvailable; } - std::cout << "current " << fileType << " instanceId is " << id << ",instanceId error, available value is [21,35]" << std::endl; + std::cout << "current " << fileType << " instanceId is " << id << + ",instanceId error, available value is [21,35]" << std::endl; return idIsAvailable; } @@ -62,19 +55,22 @@ bool IsDateTimeAvailabe(string &dateTime) { vector dateStringVec; boost::split(dateStringVec, dateTime, boost::is_any_of(" "), boost::token_compress_on); - if (dateStringVec.size() != 2) { + const int32_t dateStringVecSize = 2; + if (dateStringVec.size() != dateStringVecSize) { std::cout << "the input datetime format is error,usage \'2022-02-18 10:09:08\'" << std::endl; return false; } vector timeStringVec; boost::split(timeStringVec, dateStringVec[1], boost::is_any_of(":"), boost::token_compress_on); - if (timeStringVec.size() != 3) { + const int32_t timeStringVecSize = 3; + if (timeStringVec.size() != timeStringVecSize) { std::cout << "the input datetime format is error,usage \'2022-02-18 10:09:08\'" << std::endl; return false; } uint32_t hour = atoi(timeStringVec[0].c_str()); uint32_t minutes = atoi(timeStringVec[1].c_str()); uint32_t seconds = atoi(timeStringVec[2].c_str()); + // 24 is day, 60 is minutes, 60 is seconds if (hour >= 24 || minutes >= 60 || seconds >= 60) { std::cout << "the input datetime format is error,usage \'2022-02-18 10:09:08\'" << std::endl; return false; @@ -82,104 +78,98 @@ bool IsDateTimeAvailabe(string &dateTime) return true; } -int main(int32_t argc, char *argv[]) +int CheckConfigFile() { - int32_t ch; - while ((ch = getopt(argc, argv, "c:f:hlm:r:t:")) != -1) { - switch (ch) { - case 'c': - comPara.configFile = optarg; - break; - case 'f': - comPara.fileType = optarg; - break; - case 'h': - printf("--usage:\n"); - printf("./local_sensor_simulation -f [fileType] -c [configFile] -m [transMode]\n"); - printf("for example:./local_sensor_simulation -f jpg -c config.yaml -m decoded -r 30\n"); - printf("\n"); - printf("--option:\n"); - printf(" -f:[jpg/jpeg/yuv/h264/h265/pcd], requirement\n"); - printf(" -c:[configFile], requirement\n"); - printf(" -m:[decoded/image/simple/standard], option\n"); - printf(" -t:[yyyy-MM-dd HH:mm:ss], option\n"); - printf(" -r:[hz], option\n"); - printf(" -l, for loop, option\n"); - printf(" -h, for help, option\n"); - return 0; - case 'l': - comPara.loop = true; - break; - case 'm': - comPara.tansMode = optarg; - break; - case 'r': - comPara.frequency = optarg; - break; - case 't': - comPara.time = optarg; - break; - case '?': - printf("miss para!\n"); - break; - case ':': - printf("invalid para! please input '-h' for help\n"); - break; - default : - break; - } - } - if (comPara.fileType == "") { + if (g_comPara.fileType == "") { std::cout << "'-f File type' can not be empty!" << std::endl; return 1; } else { - if (comPara.fileType != "jpg" && comPara.fileType != "jpeg" && comPara.fileType != "yuv" && - comPara.fileType != "h264" && comPara.fileType != "h265" && comPara.fileType != "pcd") { - std::cout << "-f File type is error:" << comPara.fileType << std::endl; + if (g_comPara.fileType != "jpg" && g_comPara.fileType != "jpeg" && g_comPara.fileType != "yuv" && + g_comPara.fileType != "h264" && g_comPara.fileType != "h265" && g_comPara.fileType != "pcd") { + std::cout << "-f File type is error:" << g_comPara.fileType << std::endl; return 1; } } - if (comPara.configFile == "") { + if (g_comPara.configFile == "") { std::cout << "'-c Config file' can not be empty!" << std::endl; return 1; } - //校验时间 + + // 校验时间 std::string timeSample = "2022-02-18 10:09:08"; try { - if (!comPara.time.empty()) { - if (comPara.time.length() != timeSample.length()) { + if (!g_comPara.time.empty()) { + if (g_comPara.time.length() != timeSample.length()) { std::cout << "the input datetime format is error,usage \'" << timeSample << "\'" << std::endl; return -1; } - if (!IsDateTimeAvailabe(comPara.time)) { + if (!IsDateTimeAvailabe(g_comPara.time)) { return -1; } - boost::gregorian::date dateTime = boost::gregorian::from_string(comPara.time); + boost::gregorian::date dateTime = boost::gregorian::from_string(g_comPara.time); } } catch (std::exception &e) { std::cout << "the input datetime format is error,usage \'" << timeSample << "\'" << std::endl; return -1; } // 配置文件不存在则退出 - if (!ConfigManage::FileExist(comPara.configFile)) { - std::cout << comPara.configFile << " file is not exist!" << std::endl; + if (!ConfigManage::FileExist(g_comPara.configFile)) { + std::cout << g_comPara.configFile << " file is not exist!" << std::endl; return 1; } - if (comPara.frequency != "") { - int32_t frequency = atoi(comPara.frequency.c_str()); - if (frequency <= 0 || frequency > 100) { + if (g_comPara.frequency != "") { + int32_t frequency = atoi(g_comPara.frequency.c_str()); + const int32_t maxFrequency = 100; + if (frequency <= 0 || frequency > maxFrequency) { std::cout << "-r frequency must be (0 < frequency <= 100)" << std::endl; return 1; } } - if (comPara.tansMode != "") { - if (comPara.tansMode != "decoded" && comPara.tansMode != "image" && comPara.tansMode != "standard" && - comPara.tansMode != "simple") { - std::cout << "-m transfer mode is error:" << comPara.tansMode << std::endl; + if (g_comPara.tansMode != "") { + if (g_comPara.tansMode != "decoded" && g_comPara.tansMode != "image" && + g_comPara.tansMode != "standard" && g_comPara.tansMode != "simple") { + std::cout << "-m transfer mode is error:" << g_comPara.tansMode << std::endl; + } + } + + return 0; +} + +void InitThreadPool( + vector> senders, + vector> videoSenders, + vector> yuvSenders, + vector> pcdSenders) +{ + // 1000000表示休眠的毫秒 + usleep(1000000); + vector pool; + for (auto &send : senders) { + pool.push_back(thread(&ImageSender::FillImageAndSend, send, "", 0, &gStopFlag)); + } + for (auto &videoSend : videoSenders) { + pool.push_back(thread(&VideoSender::VideoDecodedAndSend, videoSend, "", 0, &gStopFlag)); + } + for (auto &yuvSend : yuvSenders) { + pool.push_back(thread(&YuvSender::FillImageAndSend, yuvSend, "", 0, &gStopFlag)); + } + for (auto &pcdSend : pcdSenders) { + pool.push_back(thread(&PcdSender::FillImageAndSend, pcdSend, "", 0, &gStopFlag)); + } + for (auto &t : pool) { + if (t.joinable()) { + t.join(); } } - SetEnv(); - ConfigManage configManage {comPara.configFile}; +} + +int GetSenders( + vector> senders, + vector> videoSenders, + vector> yuvSenders, + vector> pcdSenders) +{ + ConfigManage configManage { g_comPara.configFile }; configManage.Parse(); cout << "parse finished. [main]" << endl; configManage.Show(); @@ -187,33 +177,31 @@ int main(int32_t argc, char *argv[]) cerr << "Config check failed." << endl; return 1; } + auto configs = configManage.GetConfig(); - vector> senders; - vector> videoSenders; - vector> yuvSenders; - vector> pcdSenders; for (auto &conf : configs) { std::vector files; - int32_t fileCnt = GetFilesBySort(conf.dir, files, comPara.fileType); - if (fileCnt == 0) { //file is not in the dir - std::cout << "dir :" << conf.dir << " has no " << comPara.fileType << " file" << std::endl; + int32_t fileCnt = GetFilesBySort(conf.dir, files, g_comPara.fileType); + if (fileCnt == 0) { // file is not in the dir + std::cout << "dir :" << conf.dir << " has no " << g_comPara.fileType << " file" << std::endl; continue; } // 校验instanceId - if (!IsInstanceIdAvialable(comPara.fileType, conf.instanceId)) { + if (!IsInstanceIdAvialable(g_comPara.fileType, conf.instanceId)) { continue; } - if (comPara.fileType == "jpg" || comPara.fileType == "jpeg") { - senders.push_back(make_shared(conf.instanceId, Size {conf.width, conf.height}, conf.dir)); + if (g_comPara.fileType == "jpg" || g_comPara.fileType == "jpeg") { + senders.push_back(make_shared(conf.instanceId, Size { conf.width, conf.height }, conf.dir)); } - if (comPara.fileType == "h264" || comPara.fileType == "h265") { - videoSenders.push_back(make_shared(conf.instanceId, Size {conf.width, conf.height}, conf.dir)); + if (g_comPara.fileType == "h264" || g_comPara.fileType == "h265") { + videoSenders.push_back( + make_shared(conf.instanceId, Size { conf.width, conf.height }, conf.dir)); } - if (comPara.fileType == "yuv") { - yuvSenders.push_back(make_shared(conf.instanceId, Size {conf.width, conf.height}, conf.dir)); + if (g_comPara.fileType == "yuv") { + yuvSenders.push_back(make_shared(conf.instanceId, Size { conf.width, conf.height }, conf.dir)); } - if (comPara.fileType == "pcd") { - pcdSenders.push_back(make_shared(conf.instanceId, Size {conf.width, conf.height}, conf.dir)); + if (g_comPara.fileType == "pcd") { + pcdSenders.push_back(make_shared(conf.instanceId, Size { conf.width, conf.height }, conf.dir)); } } for (auto &send : senders) { @@ -228,25 +216,78 @@ int main(int32_t argc, char *argv[]) for (auto &pcdSend : pcdSenders) { pcdSend->RegisterSender(); } - // 1000000表示休眠的毫秒 - usleep(1000000); - vector pool; - for (auto &send : senders) { - pool.push_back(thread(&ImageSender::FillImageAndSend, send, "", 0, &gStopFlag)); - } - for (auto &videoSend : videoSenders) { - pool.push_back(thread(&VideoSender::VideoDecodedAndSend, videoSend, "", 0, &gStopFlag)); - } - for (auto &yuvSend : yuvSenders) { - pool.push_back(thread(&YuvSender::FillImageAndSend, yuvSend, "", 0, &gStopFlag)); + + InitThreadPool(senders, videoSenders, yuvSenders, pcdSenders); + + return 0; +} + +void Print4H() +{ + printf("--usage:\n"); + printf("./local_sensor_simulation -f [fileType] -c [configFile] -m [transMode]\n"); + printf("for example:./local_sensor_simulation -f jpg -c config.yaml -m decoded -r 30\n"); + printf("\n"); + printf("--option:\n"); + printf(" -f:[jpg/jpeg/yuv/h264/h265/pcd], requirement\n"); + printf(" -c:[configFile], requirement\n"); + printf(" -m:[decoded/image/simple/standard], option\n"); + printf(" -t:[yyyy-MM-dd HH:mm:ss], option\n"); + printf(" -r:[hz], option\n"); + printf(" -l, for loop, option\n"); + printf(" -h, for help, option\n"); +} + +int main(int32_t argc, char *argv[]) +{ + int32_t ch; + while ((ch = getopt(argc, argv, "c:f:hlm:r:t:")) != -1) { + switch (ch) { + case 'c': + g_comPara.configFile = optarg; + break; + case 'f': + g_comPara.fileType = optarg; + break; + case 'h': + Print4H(); + return 0; + case 'l': + g_comPara.loop = true; + break; + case 'm': + g_comPara.tansMode = optarg; + break; + case 'r': + g_comPara.frequency = optarg; + break; + case 't': + g_comPara.time = optarg; + break; + case '?': + printf("miss para!\n"); + break; + case ':': + printf("invalid para! please input '-h' for help\n"); + break; + default: + break; + } } - for (auto &pcdSend : pcdSenders) { - pool.push_back(thread(&PcdSender::FillImageAndSend, pcdSend, "", 0, &gStopFlag)); + + int ret = CheckConfigFile(); + if (ret != 0) { + return ret; } - for (auto &t : pool) { - if (t.joinable()) { - t.join(); - } + + vector> senders; + vector> videoSenders; + vector> yuvSenders; + vector> pcdSenders; + ret = GetSenders(senders, videoSenders, yuvSenders, pcdSenders); + if (ret != 0) { + return ret; } + return 0; } diff --git a/x86/src/pcd_sender.h b/x86/src/pcd_sender.h index d9c4d5fd0edff0366f815e46a26938f6c5e91545..c71739c16dcba3ba5c960cb61b985f7bfb67ab74 100755 --- a/x86/src/pcd_sender.h +++ b/x86/src/pcd_sender.h @@ -1,10 +1,10 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: jpg jpeg发送 -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: jpg jpeg发送 + */ -#ifndef IMAGE_SENDER_PCD_SENDER_H_ -#define IMAGE_SENDER_PCD_SENDER_H_ +#ifndef IMAGE_SENDER_PCD_SENDER_H +#define IMAGE_SENDER_PCD_SENDER_H #include #include #include @@ -26,7 +26,7 @@ #include "ara/lidar/lidarserviceinterface_skeleton.h" #include "ara/lidar/impl_type_lidarpointcloud.h" #include "ara/lidar/impl_type_lidarpointfield.h" -using namespace std; +#include "util.h" const int16_t X_IN_POINTCLOUD = 0; const int16_t Y_IN_POINTCLOUD = 4; @@ -36,6 +36,8 @@ const int16_t X_IN_POINTCLOUD_SIMPLE = 0; const int16_t Y_IN_POINTCLOUD_SIMPLE = 2; const int16_t Z_IN_POINTCLOUD_SIMPLE = 4; const int16_t INTENSITY_IN_POINTCLOUD_SIMPLE = 10; +const int32_t CI13 = 13; +const int32_t CI100 = 100; namespace ara { namespace lidar { @@ -45,14 +47,12 @@ constexpr ara::com::ServiceVersionType LidarServiceInterface::ServiceVersion; } using PcdSkeleton = ara::lidar::skeleton::LidarServiceInterfaceSkeleton; -class PcdSender : public ImageSenderBase -{ - +class PcdSender : public ImageSenderBase { public: PcdSender() = default; - PcdSender(uint32_t id, cv::Size s, std::string dir): ImageSenderBase(id, s, dir) + PcdSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) { - sec = chrono::high_resolution_clock::now(); + sec = std::chrono::high_resolution_clock::now(); } ~PcdSender() = default; bool RegisterSender() @@ -60,113 +60,45 @@ public: std::string idStr = std::to_string(instanceId); ara::core::StringView id(idStr.c_str()); dataSkeleton = std::unique_ptr( - new PcdSkeleton(ara::com::InstanceIdentifier(id), ara::com::MethodCallProcessingMode::kPoll)); + new PcdSkeleton(ara::com::InstanceIdentifier(id), ara::com::MethodCallProcessingMode::kPoll)); + if (1 == SwitchFlag) { + dataSkeleton = nullptr; + } + if (dataSkeleton == nullptr) { + std::cerr << "Publish to instance id:" << idStr << " failed!" << std::endl; + return false; + } dataSkeleton->OfferService(); + return true; } - void FillImageAndSend(std::string imgPath, uint32_t seq, void *flag) override + int retPcdSender = -1; + void FillImageAndSend(std::string imgPath, uint32_t seq, int32_t *flag) override { std::string path = dir; - std::string postfix = comPara.fileType; - bool isLoop = comPara.loop; - cout << "dir : " << dir << "\t" << "postfix :" << postfix << endl; - std::vector pcd_names; + std::string postfix = g_comPara.fileType; + bool isLoop = g_comPara.loop; + std::cout << "dir : " << dir << "\t" + << "postfix :" << postfix << std::endl; + std::vector pcd_names {}; if (path.back() != '/') { - path = path + string("/"); + path = path + std::string("/"); } GetFilesFromDirectory(path, pcd_names); std::cout << "There are " << pcd_names.size() << " pcd files in " << path << std::endl; do { - for (size_t i = 0; i < pcd_names.size(); i++) { - const std::string pcd_name = pcd_names[i]; - const std::string pcd_source_path = path + pcd_name; - std::cout << "The " << i << " pcd source path is: " << pcd_source_path << std::endl; - pcl::PointCloud::Ptr lidarData(new pcl::PointCloud); - if (pcl::io::loadPCDFile(pcd_source_path, *lidarData) == -1) { - std::cout << "load pcd failed" << std::endl; - continue; - } - std::cout << "Load local pcd successful, pointcloud size is: " << lidarData->width << ", " << - lidarData->height << std::endl; - std::stringstream str; - str << "copy-" << pcd_name; -#ifdef SAVE_SENDER_FILE - pcl::PCDWriter writer; - writer.writeBinaryCompressed(str.str(), *lidarData); -#endif - ara::lidar::LidarPointCloud tmp; - tmp.header.frameId = pcd_name; - if (comPara.tansMode == "simple") { - //13表示简易点云结构大小 - tmp.pointStep = 13; - } else { - //32表示标准点云结构大小 - tmp.pointStep = 32; - } - tmp.height = lidarData->height; - tmp.width = lidarData->width; - std::vector pointCloudData; - pointCloudData.resize(tmp.pointStep * tmp.height * tmp.width); - uint8_t *pointCloud0 = &pointCloudData[0]; - uint8_t *pointCloudCurr = nullptr; - int32_t loopCount = static_cast(tmp.height) * static_cast(tmp.width); - const int32_t sliceSize = 7400000; - int32_t maxNumOfPoints = (sliceSize - sizeof(tmp.header)) / tmp.pointStep; - if (loopCount > maxNumOfPoints) { - std::cout << pcd_name << " send failed due to too many points,max points num is " << maxNumOfPoints << std::endl; - continue; - } - for (int32_t pointCount = 0; pointCount < loopCount; pointCount++) { - pointCloudCurr = pointCloud0 + tmp.pointStep * pointCount; - if (comPara.tansMode == "simple") { - // 100精确到米,float类型数据精度会丢失 - *(reinterpret_cast(pointCloudCurr + X_IN_POINTCLOUD_SIMPLE)) = lidarData->points[pointCount].x * 100; - *(reinterpret_cast(pointCloudCurr + Y_IN_POINTCLOUD_SIMPLE)) = lidarData->points[pointCount].y * 100; - *(reinterpret_cast(pointCloudCurr + Z_IN_POINTCLOUD_SIMPLE)) = lidarData->points[pointCount].z * 100; - *(reinterpret_cast(pointCloudCurr + INTENSITY_IN_POINTCLOUD_SIMPLE)) = lidarData->points[pointCount].intensity; - } else { - *(reinterpret_cast(pointCloudCurr + X_IN_POINTCLOUD)) = lidarData->points[pointCount].x; - *(reinterpret_cast(pointCloudCurr + Y_IN_POINTCLOUD)) = lidarData->points[pointCount].y; - *(reinterpret_cast(pointCloudCurr + Z_IN_POINTCLOUD)) = lidarData->points[pointCount].z; - *(reinterpret_cast(pointCloudCurr + INTENSITY_IN_POINTCLOUD)) = - lidarData->points[pointCount].intensity; - } - } - tmp.data.assign(pointCloudData.begin(), pointCloudData.end()); - if (comPara.time.empty()) { - timeval tv; - gettimeofday(&tv, 0); - tmp.header.stamp.sec = tv.tv_sec; - tmp.header.stamp.nsec = tv.tv_usec = 1e3; - } else { - time_t timeStamp = ConvertTimeStr2TimeStamp(comPara.time); - auto t1 = chrono::high_resolution_clock::now(); - int64_t duration = (t1 - sec).count() / 1000000000.0; - tmp.header.stamp.sec = timeStamp + duration; - printf("timeStamp=%ld\n", timeStamp + duration); - } - tmp.header.seq = i; - std::cout << "tmp.header.stamp.sec: " << tmp.header.stamp.sec << std::endl; - std::cout << "tmp.header.stamp.nsec: " << tmp.header.stamp.nsec << std::endl; - std::cout << "tmp.header.frameId: " << tmp.header.frameId << std::endl; - dataSkeleton->mdcEvent.Send(std::move(tmp)); - // 100ms sleep 10hz - if (comPara.frequency != "") { - int32_t freq = atoi(comPara.frequency.c_str()); - int32_t sleepTime = 1000000 / freq; - usleep(sleepTime); - } else { - usleep(1000000 / 30); // 30hz - } - } + InvokingFillImage(path, pcd_names); } while (isLoop); + retPcdSender = 0; } + private: - chrono::high_resolution_clock::time_point sec{ };//-t used + std::chrono::high_resolution_clock::time_point sec {}; // -t used void GetFilesFromDirectory(const std::string &name, std::vector &v) { DIR *dirp = opendir(name.c_str()); if (dirp == nullptr) { + retPcdSender = -1; return; } struct dirent *dp; @@ -179,12 +111,130 @@ private: } } closedir(dirp); + retPcdSender = 0; } bool EndsWith(const std::string &str, const std::string &suffix) { return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; } + + void GetLidarDataPoints(pcl::PointCloud::Ptr lidarData, uint8_t *pointCloud0, int32_t loopCount) + { + uint8_t *pointCloudCurr = nullptr; + for (int32_t pointCount = 0; pointCount < loopCount; pointCount++) { + pointCloudCurr = pointCloud0 + CI13 * pointCount; + if (g_comPara.tansMode == "simple") { + *(reinterpret_cast(pointCloudCurr + X_IN_POINTCLOUD_SIMPLE)) = + lidarData->points[pointCount].x * CI100; + *(reinterpret_cast(pointCloudCurr + Y_IN_POINTCLOUD_SIMPLE)) = + lidarData->points[pointCount].y * CI100; + *(reinterpret_cast(pointCloudCurr + Z_IN_POINTCLOUD_SIMPLE)) = + lidarData->points[pointCount].z * CI100; + *(reinterpret_cast(pointCloudCurr + INTENSITY_IN_POINTCLOUD_SIMPLE)) = + lidarData->points[pointCount].intensity; + } else { + *(reinterpret_cast(pointCloudCurr + X_IN_POINTCLOUD)) = lidarData->points[pointCount].x; + *(reinterpret_cast(pointCloudCurr + Y_IN_POINTCLOUD)) = lidarData->points[pointCount].y; + *(reinterpret_cast(pointCloudCurr + Z_IN_POINTCLOUD)) = lidarData->points[pointCount].z; + *(reinterpret_cast(pointCloudCurr + INTENSITY_IN_POINTCLOUD)) = + lidarData->points[pointCount].intensity; + } + } + } + + void HandleFrequency() + { + const int32_t sleepTimeIntervalMs = 1000000; + if (g_comPara.frequency != "") { + int32_t freq = atoi(g_comPara.frequency.c_str()); + if (freq != 0) { + int32_t sleepTime = sleepTimeIntervalMs / freq; + usleep(sleepTime); + } + } else { + usleep(sleepTimeIntervalMs / 30); // 30hz + } + } + + void InvokingFillImage(std::string path, std::vector pcd_names) + { + for (size_t i = 0; i < pcd_names.size(); i++) { + const std::string pcd_name = pcd_names[i]; + const std::string pcd_source_path = path + pcd_name; + std::cout << "The " << i << " pcd source path is: " << pcd_source_path << std::endl; + pcl::PointCloud::Ptr lidarData(new pcl::PointCloud); + if (pcl::io::loadPCDFile(pcd_source_path, *lidarData) == -1) { + std::cout << "load pcd failed" << std::endl; + continue; + } + std::cout << "Load local pcd successful, pointcloud size is: " << + lidarData->width << ", " << lidarData->height << std::endl; + std::stringstream str; + str << "copy-" << pcd_name; +#ifdef SAVE_SENDER_FILE + pcl::PCDWriter writer; + writer.writeBinaryCompressed(str.str(), *lidarData); +#endif + ara::lidar::LidarPointCloud tmp; + tmp.header.frameId = pcd_name; + if (g_comPara.tansMode == "simple") { + // 13表示简易点云结构大小 + tmp.pointStep = 13; + } else { + // 32表示标准点云结构大小 + tmp.pointStep = 32; + } + bool result = DealTmp(lidarData, tmp, pcd_name, i); + if (!result) { + return; + } + } + } + + bool DealTmp(pcl::PointCloud::Ptr lidarData, ara::lidar::LidarPointCloud &tmp, + const std::string pcd_name, size_t i) + { + tmp.height = lidarData->height; + tmp.width = lidarData->width; + std::vector pointCloudData; + pointCloudData.resize(tmp.pointStep * tmp.height * tmp.width); + uint8_t *pointCloud0 = &pointCloudData[0]; + uint8_t *pointCloudCur = nullptr; + int32_t loopCount = static_cast(tmp.height) * static_cast(tmp.width); + const int32_t sliceSize = 7400000; + int32_t maxNumOfPoints = (sliceSize - sizeof(tmp.header)) / tmp.pointStep; + if (1 == SwitchFlag) { + loopCount = maxNumOfPoints + 1; + } + if (loopCount > maxNumOfPoints) { + std::cout << pcd_name << " send failed due to too many points,max points num is " << + maxNumOfPoints << std::endl; + return false; + } + GetLidarDataPoints(lidarData, pointCloud0, loopCount); + tmp.data.assign(pointCloudData.begin(), pointCloudData.end()); + if (g_comPara.time.empty()) { + timeval tv; + gettimeofday(&tv, 0); + tmp.header.stamp.sec = tv.tv_sec; + tmp.header.stamp.nsec = tv.tv_usec = 1e3; + } else { + time_t timeStamp = ConvertTimeStr2TimeStamp(g_comPara.time); + auto t1 = std::chrono::high_resolution_clock::now(); + int64_t duration = (t1 - sec).count() / 1000000000.0; + tmp.header.stamp.sec = timeStamp + duration; + printf("timeStamp=%ld\n", timeStamp + duration); + } + tmp.header.seq = i; + std::cout << "tmp.header.stamp.sec: " << tmp.header.stamp.sec << std::endl; + std::cout << "tmp.header.stamp.nsec: " << tmp.header.stamp.nsec << std::endl; + std::cout << "tmp.header.frameId: " << tmp.header.frameId << std::endl; + dataSkeleton->mdcEvent.Send(std::move(tmp)); + const int32_t sleepTimeIntervalMs = 1000000; + HandleFrequency(); + return true; + } }; -#endif //IMAGE_SENDER_PCD_SENDER_H_ +#endif // IMAGE_SENDER_PCD_SENDER_H diff --git a/x86/src/util.cpp b/x86/src/util.cpp index d0ef2fca8532f31fedce0afe5da3346d45fa676f..96603bc4867e0ba23269db88f093b5008adf81ce 100644 --- a/x86/src/util.cpp +++ b/x86/src/util.cpp @@ -1,35 +1,26 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: config读取实现 -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: config读取实现 + */ #include "util.h" #include #include #include using namespace std; -void Yuv420p2nv12(const cv::Mat &yuv420p, cv::Mat &yuv420_nv12, int32_t width, int32_t height) -{ - auto resolution = width * height; - for (int32_t i = 0; i < resolution / 2; i += 2) { - yuv420_nv12.data[resolution + i] = yuv420p.data[resolution + (i / 2)]; - yuv420_nv12.data[resolution + i + 1] = yuv420p.data[resolution + resolution / 4 + (i / 2)]; - } -} int32_t GetFilesBySort(std::string &path, std::vector &files, std::string suffix) { std::string suffixName = "." + suffix; int32_t fileCnt = 0; - struct dirent **name_list; + dirent **name_list; int32_t count = scandir(path.c_str(), &name_list, NULL, alphasort); if (count < 0) { printf("opendir %s failed\n", path.c_str()); return 0; } for (int32_t i = 0; i < count; i++) { - struct dirent *name; - name = name_list[i]; + dirent *name = name_list[i]; std::string curpath(path); if (path.back() != '/') { curpath += string("/") += name->d_name; @@ -48,8 +39,8 @@ int32_t GetFilesBySort(std::string &path, std::vector &files, std:: time_t ConvertTimeStr2TimeStamp(string timeStr) { - struct tm timeinfo; - strptime(timeStr.c_str(), "%Y-%m-%d %H:%M:%S", &timeinfo); + tm timeinfo; + strptime(timeStr.c_str(), "%Y-%m-%d %H:%M:%S", &timeinfo); time_t timeStamp = mktime(&timeinfo); return timeStamp; } @@ -80,7 +71,7 @@ void ConfigManage::Parse() cout << "begin to parse config file: " << file << endl; try { - auto root = Adsfi::HafYamlNode(file).GetNode(); + auto root = Adsfi::HafYaml(file).GetNode(); for (auto it = root.begin(); it != root.end(); ++it) { Config conf; conf.dir = (*it)["dir"].as(); @@ -91,12 +82,16 @@ void ConfigManage::Parse() } } catch (YAML::TypedBadConversion &e) { cout << "config file format error,please check config file!" << endl; - } catch (YAML::TypedBadConversion, std::allocator > > &e) { + gRet = -1; + } catch (YAML::TypedBadConversion<__cxx11::basic_string, allocator > > &e) { cout << "config file format error,please check config file!" << endl; + gRet = -1; } catch (YAML::ParserException &e) { cout << "config file format error,please check config file!" << endl; + gRet = -1; } cout << "Parse config file finished." << endl; + gRet = 0; } std::vector ConfigManage::GetConfig() @@ -111,9 +106,10 @@ void ConfigManage::Show() cout << "dir\tinstanceId\twidth\theight" << endl; cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" << endl; for (auto &conf : configs) { - cout << conf.dir << "\t" << conf.instanceId << "\t" << conf.width << "\t" << conf.height << "\t\n" << endl; + cout << conf.dir << "\t" << conf.instanceId << "\t" << conf.width << "\t" << conf.height << "\t\n" << endl; } cout << endl << endl; + gRet = 0; } bool ConfigManage::CheckConfig() @@ -129,4 +125,3 @@ bool ConfigManage::CheckConfig() } return true; } - diff --git a/x86/src/util.h b/x86/src/util.h index 8171b37401b4ed42c98a3ccdea4e5d62513732b4..50b5193876c5e68b4c21687d8c19d902f27e8448 100755 --- a/x86/src/util.h +++ b/x86/src/util.h @@ -1,7 +1,7 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: config头文件 -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: config头文件 + */ #ifndef UTIL_H #define UTIL_H @@ -21,14 +21,12 @@ std::string CurrentTimeAndDate(); -void Yuv420p2nv12(const cv::Mat &yuv420p, cv::Mat &yuv420_nv12, int32_t width, int32_t height); int32_t GetFilesBySort(std::string &path, std::vector &files, std::string suffix); time_t ConvertTimeStr2TimeStamp(std::string timeStr); -class FuncTimeMeasure -{ +class FuncTimeMeasure { public: - FuncTimeMeasure(std::string &&descrip); + explicit FuncTimeMeasure(std::string &&descrip); ~FuncTimeMeasure(); private: @@ -38,19 +36,17 @@ private: }; struct Config { - std::string dir {""}; - int32_t instanceId {0}; - int32_t width {0}; - int32_t height {0}; + std::string dir { "" }; + int32_t instanceId { 0 }; + int32_t width { 0 }; + int32_t height { 0 }; }; -class ConfigManage -{ +class ConfigManage { public: ConfigManage() = default; ~ConfigManage() = default; - ConfigManage(std::string configFile) : file(configFile) - {} + explicit ConfigManage(std::string configFile) : file(configFile) {} void Parse(); std::vector GetConfig(); void Show(); @@ -60,8 +56,10 @@ public: struct stat buffer; return (stat(name.c_str(), &buffer) == 0); } + int gRet = -1; + private: - std::string file {"image_config.yaml"}; - std::vector configs{}; + std::string file { "image_config.yaml" }; + std::vector configs {}; }; #endif // UTIL_H diff --git a/x86/src/video_sender.h b/x86/src/video_sender.h index e7e23814b76d99493df5784f05f3047d14682ad3..20b7a4009686b97cd01d4105b7682809120bfe04 100755 --- a/x86/src/video_sender.h +++ b/x86/src/video_sender.h @@ -1,19 +1,18 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: h264 h265发送实现 -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: h264 h265发送实现 + */ -#ifndef IMAGE_SENDER_VIDEO_SENDER_H_ -#define IMAGE_SENDER_VIDEO_SENDER_H_ +#ifndef IMAGE_SENDER_VIDEO_SENDER_H +#define IMAGE_SENDER_VIDEO_SENDER_H -#include +#include #include "mdc/cam/camera/cameradecodedmbufserviceinterface_skeleton.h" #include "util.h" #include "image_sender_base.h" #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif #include #include @@ -21,60 +20,40 @@ extern "C" #ifdef __cplusplus }; #endif -#define PIX_FMT_YUV420P AV_PIX_FMT_YUV420P -using namespace std; -using namespace cv; +#define PIX_FMT_YUV420P AV_PIX_FMT_YUV420P using Skeleton = mdc::cam::camera::skeleton::CameraDecodedMbufServiceInterfaceSkeleton; -class VideoSender : public ImageSenderBase -{ -private: - AVFormatContext *pFormatCtx { nullptr }; - int32_t i { 0 }; - int32_t videoindex { 0 }; - AVCodecContext *pCodecCtx { nullptr }; - AVCodec *pCodec { nullptr }; - AVFrame *pFrame { nullptr }; - AVFrame *pFrameYUV { nullptr }; - uint8_t *outBuffer { nullptr }; - AVPacket *packet { nullptr }; - int32_t ySize { 0 }; - int32_t ret { 0 }; - int32_t gotPicture { 0 }; - struct SwsContext *imgConvertCtx { nullptr }; - std::string sourceYuvPath { }; - FILE *fpYuv { nullptr }; - chrono::high_resolution_clock::time_point sec { };//-t used +class VideoSender : public ImageSenderBase { public: VideoSender() = default; - VideoSender(uint32_t id, cv::Size s, std::string dir): ImageSenderBase(id, s, dir) + VideoSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) { sourceYuvPath = dir; if (dir.back() != '/') { - sourceYuvPath += string("/") += "videoSource.yuv"; + sourceYuvPath += std::string("/") += "videoSource.yuv"; } else { sourceYuvPath += "videoSource.yuv"; } #ifdef SAVE_SENDER_FILE fpYuv = fopen(sourceYuvPath.c_str(), "wb+"); #endif - sec = chrono::high_resolution_clock::now(); + sec = std::chrono::high_resolution_clock::now(); } ~VideoSender() = default; bool RegisterSender() { - std::cout << "Begin register normal image sender." << endl; + std::cout << "Begin register normal image sender." << std::endl; auto result = ImageSenderBase::RegisterSender(); - std::cout << "Finished to register normal image sender." << endl; + std::cout << "Finished to register normal image sender." << std::endl; return result; } int32_t FfmpegInit(std::string videoPath) { - av_register_all(); // 注册所有组件 - avformat_network_init(); // 初始化网络 - pFormatCtx = avformat_alloc_context(); // 初始化一个AVFormatContext - if (avformat_open_input(&pFormatCtx, videoPath.c_str(), NULL, NULL) != 0) { // 打开输入的视频文件 + av_register_all(); // 注册所有组件 + avformat_network_init(); // 初始化网络 + pFormatCtx = avformat_alloc_context(); // 初始化一个AVFormatContext + if (avformat_open_input(&pFormatCtx, videoPath.c_str(), NULL, NULL) != 0) { // 打开输入的视频文件 printf("Couldn't open input stream.\n"); return -1; } @@ -88,15 +67,20 @@ public: videoindex = i; break; } + if (1 == SwitchFlag) { + videoindex = -1; + } if (videoindex == -1) { - printf("Didn't find a video stream.\n"); return -1; } pCodecCtx = pFormatCtx->streams[videoindex]->codec; pCodec = avcodec_find_decoder(pCodecCtx->codec_id); // 查找解码器 printf("pCodecCtx->codec_id : %d\n", pCodecCtx->codec_id); - printf("AV_CODEC_ID_H264:%d\n", AV_CODEC_ID_H264); - printf("AV_CODEC_ID_H265:%d\n", AV_CODEC_ID_H265); + printf("AV_CODEC_ID_H264:%d\n, AV_CODEC_ID_H265:%d\n", AV_CODEC_ID_H264, AV_CODEC_ID_H265); + const int ciTWO = 2; + if (ciTWO == SwitchFlag) { + pCodec = NULL; + } if (pCodec == NULL) { printf("Codec not found.\n"); return -1; @@ -113,8 +97,8 @@ public: printf("--------------- File Information ----------------\n"); av_dump_format(pFormatCtx, 0, videoPath.c_str(), 0); printf("-------------------------------------------------\n"); - imgConvertCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, - pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); + imgConvertCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, + pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); return 0; } @@ -127,16 +111,19 @@ public: avformat_close_input(&pFormatCtx); } - void VideoDecodedAndSend(std::string videoPath, uint32_t seq, void *flag) + int retVideoSender1 = -1; + void VideoDecodedAndSend(std::string videoPath, uint32_t seq, int32_t *flag) { std::string path = dir; - std::string postfix = comPara.fileType; - bool isLoop = comPara.loop; - cout << "dir : " << dir << "\t" << "postfix :" << postfix << endl; + std::string postfix = g_comPara.fileType; + bool isLoop = g_comPara.loop; + std::cout << "dir : " << dir << "\t" << + "postfix : " << postfix << std::endl; std::vector files; - int32_t fileCnt = GetFilesBySort(path, files, comPara.fileType); + int32_t fileCnt = GetFilesBySort(path, files, g_comPara.fileType); if (fileCnt == 0) { - cout << "PATH:" << path << " has no files!" << endl; + std::cout << "PATH:" << path << " has no files!" << std::endl; + retVideoSender1 = -1; return; } do { @@ -144,6 +131,7 @@ public: int32_t ret = FfmpegInit(file); if (ret != 0) { std::cerr << "ffmpeg init err."; + retVideoSender1 = -1; return; } FillImageAndSend(file, seq, flag); @@ -151,73 +139,116 @@ public: } } while (isLoop); #ifdef SAVE_SENDER_FILE - fclose(fpYuv); + if (fclose(fpYuv) == -1) { + retVideoSender1 = -1; + return; + } #endif + retVideoSender1 = 0; } - void FillImageAndSend(std::string videoPath, uint32_t seq, void *flag) override + int retVideoSender2 = -1; + void FillImageAndSend(std::string videoPath, uint32_t seq, int32_t *flag) override { (void)flag; if (videoPath.empty()) { std::cerr << "File not exist,or corrupt.path:" << videoPath << std::endl; - return ; + retVideoSender2 = -1; + return; } while (av_read_frame(pFormatCtx, packet) >= 0) { // 读取一帧压缩数据 if (packet->stream_index == videoindex) { ret = avcodec_decode_video2(pCodecCtx, pFrame, &gotPicture, packet); // 解码一帧压缩数据 if (ret < 0) { printf("Decode Error.\n"); - return ; + retVideoSender2 = -1; + return; } - if (gotPicture) { - sws_scale(imgConvertCtx, (const uint8_t *const *)pFrame->data, pFrame->linesize, 0, - pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); - printf("Succeed to decode 1 frame!\n"); - ySize = pCodecCtx->width * pCodecCtx->height; + HanderImageAndSend(videoPath, seq); + } + av_free_packet(packet); + } + retVideoSender2 = 0; + } + +private: + void HandleFrequency() + { + const int32_t sleepTimeIntervalMs = 1000000; + if (g_comPara.frequency != "") { + int32_t freq = atoi(g_comPara.frequency.c_str()); + if (freq != 0) { + int32_t sleepTime = sleepTimeIntervalMs / freq; + usleep(sleepTime); + } + } else { + usleep(sleepTimeIntervalMs / 30); // 30hz + } + } + + void HanderImageAndSend(std::string videoPath, uint32_t seq) + { + if (gotPicture) { + sws_scale(imgConvertCtx, (const uint8_t *const *)pFrame->data, pFrame->linesize, 0, + pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); + ySize = pCodecCtx->width * pCodecCtx->height; #ifdef SAVE_SENDER_FILE - fwrite(pFrameYUV->data[0], 1, ySize, fpYuv); // Y - fwrite(pFrameYUV->data[1], 1, ySize / 4, fpYuv); // U - fwrite(pFrameYUV->data[2], 1, ySize / 4, fpYuv); // V + fwrite(pFrameYUV->data[0], 1, ySize, fpYuv); // Y + fwrite(pFrameYUV->data[1], 1, ySize / intSize, fpYuv); // U + fwrite(pFrameYUV->data[frameDataYuvIndex], 1, ySize / intSize, fpYuv); // V #endif - auto imagePub = dataSkeleton->cameraDecodedMbufEvent.Allocate(); - imagePub->CameraHeader.FrameId = frameID; - imagePub->CameraHeader.Seq = seq; - imagePub->Width = pCodecCtx->width; - imagePub->Height = pCodecCtx->height; - size_t sizeInBytes = pCodecCtx->width * pCodecCtx->height * 3 / 2; - imagePub->DataSize = sizeInBytes; - Mat YUV420NV12; - YUV420NV12.create(pCodecCtx->height * 1.5, pCodecCtx->width, CV_8UC1); - memcpy(YUV420NV12.data, pFrameYUV->data[0], ySize); - memcpy(YUV420NV12.data + ySize, pFrameYUV->data[1], ySize / 4); - memcpy(YUV420NV12.data + ySize * 5 / 4, pFrameYUV->data[2], ySize / 4); - imagePub->UdpData.assign(YUV420NV12.data, YUV420NV12.data + imagePub->DataSize); - if (comPara.time.empty()) { - timeval now; - gettimeofday(&now, NULL); - imagePub->CameraHeader.Stamp.Sec = now.tv_sec; - imagePub->CameraHeader.Stamp.Nsec = now.tv_usec * 1000U; - } else { - time_t timeStamp = ConvertTimeStr2TimeStamp(comPara.time); - auto t1 = chrono::high_resolution_clock::now(); - int64_t duration = (t1 - sec).count() / 1000000000.0; - imagePub->CameraHeader.Stamp.Sec = timeStamp + duration; - printf("timeStamp=%ld\n", timeStamp + duration); - } - dataSkeleton->cameraDecodedMbufEvent.Send(move(imagePub)); - cout << "Begin send image. seq:" << seq << " frameID:" << frameID << " path:" << videoPath << endl; - if (comPara.frequency != "") { - int32_t freq = atoi(comPara.frequency.c_str()); - int32_t sleepTime = 1000000 / freq; - usleep(sleepTime); - } else { - usleep(1000000 / 30); // 30hz - } - } + auto imagePub = dataSkeleton->cameraDecodedMbufEvent.Allocate(); + imagePub->CameraHeader.FrameId = frameID; + imagePub->CameraHeader.Seq = seq; + imagePub->Width = pCodecCtx->width; + imagePub->Height = pCodecCtx->height; + size_t sizeInBytes = pCodecCtx->width * pCodecCtx->height * 3 / 2; + imagePub->DataSize = sizeInBytes; + cv::Mat YUV420NV12; + // yuv w:h compare - 1.5 + YUV420NV12.create(pCodecCtx->height * 1.5, pCodecCtx->width, CV_8UC1); + memcpy_s(YUV420NV12.data, ySize, pFrameYUV->data[0], ySize); + memcpy_s(YUV420NV12.data + ySize, ySize / intSize, pFrameYUV->data[1], ySize / intSize); + memcpy_s(YUV420NV12.data + ySize * frameDataYuvSize / intSize, ySize / intSize, + pFrameYUV->data[frameDataYuvIndex], ySize / intSize); + imagePub->UdpData.assign(YUV420NV12.data, YUV420NV12.data + imagePub->DataSize); + if (g_comPara.time.empty()) { + timeval now; + gettimeofday(&now, NULL); + imagePub->CameraHeader.Stamp.Sec = now.tv_sec; + imagePub->CameraHeader.Stamp.Nsec = now.tv_usec * 1000U; + } else { + time_t timeStamp = ConvertTimeStr2TimeStamp(g_comPara.time); + auto t1 = std::chrono::high_resolution_clock::now(); + int64_t duration = (t1 - sec).count() / 1000000000.0; + imagePub->CameraHeader.Stamp.Sec = timeStamp + duration; } - av_free_packet(packet); + dataSkeleton->cameraDecodedMbufEvent.Send(move(imagePub)); + HandleFrequency(); } } + +private: + AVFormatContext *pFormatCtx { nullptr }; + int32_t i { 0 }; + int32_t videoindex { 0 }; + AVCodecContext *pCodecCtx { nullptr }; + AVCodec *pCodec { nullptr }; + AVFrame *pFrame { nullptr }; + AVFrame *pFrameYUV { nullptr }; + uint8_t *outBuffer { nullptr }; + AVPacket *packet { nullptr }; + int32_t ySize { 0 }; + int32_t ret { 0 }; + int32_t gotPicture { 0 }; + struct SwsContext *imgConvertCtx { nullptr }; + + std::string sourceYuvPath {}; + FILE *fpYuv { nullptr }; + std::chrono::high_resolution_clock::time_point sec {}; // -t used + const int32_t intSize { 4 }; + const int32_t frameDataYuvIndex { 2 }; + const int32_t frameDataYuvSize { 5 }; }; -#endif //IMAGE_SENDER_VIDEO_SENDER_H_ +#endif // IMAGE_SENDER_VIDEO_SENDER_H diff --git a/x86/src/yaml/haf_yaml.h b/x86/src/yaml/haf_yaml.h index 70da3f6672acfeddfd818523798912c3698c5ba4..705d8545144f3df2c9df9287a02561a6eec86262 100755 --- a/x86/src/yaml/haf_yaml.h +++ b/x86/src/yaml/haf_yaml.h @@ -15,10 +15,9 @@ namespace Adsfi { using HafYamlIterator = YAML::const_iterator; using HafException = YAML::Exception; -class HafYamlNode -{ +class HafYaml { public: - HafYamlNode(const std::string path) + explicit HafYaml(const std::string path) { std::ifstream fin(path); if (!fin) { @@ -29,27 +28,27 @@ public: node = YAML::LoadFile(path); } - HafYamlNode() {} + HafYaml() {} - HafYamlNode(const YAML::Node child) + explicit HafYaml(const YAML::Node child) { this->node = child; } - ~HafYamlNode() {}; + ~HafYaml() {}; // indexing - template const HafYamlNode operator[](const Key &keyName) const + template const HafYaml operator[](const Key &keyName) const { - return HafYamlNode(node[keyName]); + return HafYaml(node[keyName]); } - template HafYamlNode operator[](const Key &keyName) + template HafYaml operator[](const Key &keyName) { - return HafYamlNode(node[keyName]); + return HafYaml(node[keyName]); } // access - template T as() const + template T As() const { return node.as(); } diff --git a/x86/src/yuv_sender.h b/x86/src/yuv_sender.h index f4331f652ef87ca3bf88453faa5485a89e4a771e..aa0284dfe9ff935028f47ae9f28f825a325b90d1 100755 --- a/x86/src/yuv_sender.h +++ b/x86/src/yuv_sender.h @@ -1,130 +1,183 @@ /* -* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -* Description: yuv数据发送 -*/ + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Description: yuv数据发送 + */ -#ifndef IMAGE_SENDER_YUV_SENDER_H_ -#define IMAGE_SENDER_YUV_SENDER_H_ +#ifndef IMAGE_SENDER_YUV_SENDER_H +#define IMAGE_SENDER_YUV_SENDER_H -#include "stdio.h" -#include "stdlib.h" +#include +#include #include "image_sender_base.h" #include "util.h" #include "mdc/cam/camera/cameradecodedmbufserviceinterface_skeleton.h" -using namespace std; -using namespace cv; using Skeleton = mdc::cam::camera::skeleton::CameraDecodedMbufServiceInterfaceSkeleton; -class YuvSender : public ImageSenderBase -{ + +struct DealMatPara { + int32_t h; + int32_t w; + int32_t frameCount; + int32_t frameSize; + int32_t seq; +}; + +class YuvSender : public ImageSenderBase { public: YuvSender() = default; - YuvSender(uint32_t id, cv::Size s, std::string dir): ImageSenderBase(id, s, dir) + YuvSender(uint32_t id, cv::Size s, std::string dir) : ImageSenderBase(id, s, dir) { sourceYuvPath = dir; if (dir.back() != '/') { - sourceYuvPath += string("/") += "yuvSource.yuv"; + sourceYuvPath += std::string("/") += "yuvSource.yuv"; } else { sourceYuvPath += "yuvSource.yuv"; } #ifdef SAVE_SENDER_FILE fpYuv = fopen(sourceYuvPath.c_str(), "wb+"); #endif - sec = chrono::high_resolution_clock::now(); + sec = std::chrono::high_resolution_clock::now(); } ~YuvSender() = default; bool RegisterSender() { - std::cout << "Begin register normal image sender." << endl; + std::cout << "Begin register normal image sender." << std::endl; auto result = ImageSenderBase::RegisterSender(); - std::cout << "Finished to register normal image sender." << endl; + std::cout << "Finished to register normal image sender." << std::endl; return result; } - void FillImageAndSend(std::string yuvPath, uint32_t seq, void *flag) override + int retYuvSender = -1; + void FillImageAndSend(std::string yuvPath, uint32_t seq, int32_t *flag) override { - (void)flag; - std::string path = dir; - std::string postfix = comPara.fileType; - bool isLoop = comPara.loop; - cout << "dir : " << dir << "\t" << "postfix :" << postfix << endl; - std::vector files; - int32_t fileCnt = GetFilesBySort(path, files, comPara.fileType); - if (fileCnt == 0) { - cout << "PATH:" << path << " has no files!" << endl; + std::string postfix = g_comPara.fileType; + bool isLoop = g_comPara.loop; + std::vector files {}; + if (GetFilesBySort(dir, files, g_comPara.fileType) == 0) { + retYuvSender = -1; return; } do { for (auto &file : files) { - int32_t w = imgSize.width; - int32_t h = imgSize.height; - FILE *yuvFile; - yuvFile = fopen(file.c_str(), "rb"); + FILE *yuvFile = fopen(file.c_str(), "rb"); + if (1 == SwitchFlag) { + yuvFile = nullptr; + } if (yuvFile == nullptr) { - cout << "Open yuv file failed!" << endl; + retYuvSender = -1; + return; + } + int32_t frameSize = imgSize.width * imgSize.height * 3 / 2; + if (fseek(yuvFile, 0, SEEK_END) != 0) { + retYuvSender = -1; return; } - int32_t frameSize = w * h * 3 / 2; - fseek(yuvFile, 0, SEEK_END); int32_t fileSize = ftell(yuvFile); + const int ciTwo = 2; + if (ciTwo == SwitchFlag) { + fileSize = -1; + } + if (fileSize == -1L) { + retYuvSender = -1; + return; + } rewind(yuvFile); - int32_t frameCount = fileSize / frameSize; - char *yuvBuff = (char *)malloc(frameSize * sizeof(char)); - if (nullptr == yuvBuff) { - std::cout << "malloc yuvBuff memory error" << std::endl; + dealMatPara.h = imgSize.height; + dealMatPara.w = imgSize.width; + dealMatPara.frameCount = int32_t (fileSize / frameSize); + dealMatPara.frameSize = frameSize; + dealMatPara.seq = seq; + if (! DealMat(yuvFile, file)) { + retYuvSender = -1; return; } - for (int32_t i = 0; i < frameCount; i++) { - Mat yUV420NV12; - yUV420NV12.create(h * 1.5, w, CV_8UC1); - memset(yuvBuff, 0, frameSize); - fread(yuvBuff, sizeof(char), frameSize, yuvFile); - memcpy(yUV420NV12.data, yuvBuff, frameSize); - auto imagePub = dataSkeleton->cameraDecodedMbufEvent.Allocate(); - imagePub->CameraHeader.FrameId = frameID; - imagePub->CameraHeader.Seq = seq; - imagePub->Width = w; - imagePub->Height = h; - imagePub->DataSize = frameSize; - imagePub->UdpData.assign(yUV420NV12.data, yUV420NV12.data + imagePub->DataSize); + } + } while (isLoop); #ifdef SAVE_SENDER_FILE - fwrite(yUV420NV12.data, 1, frameSize, fpYuv); + if (fclose(fpYuv) == -1) { + retYuvSender = -1; + return; + } #endif - if (comPara.time.empty()) { - timeval now; - gettimeofday(&now, NULL); - imagePub->CameraHeader.Stamp.Sec = now.tv_sec; - imagePub->CameraHeader.Stamp.Nsec = now.tv_usec * 1000U; - } else { - time_t timeStamp = ConvertTimeStr2TimeStamp(comPara.time); - auto t1 = chrono::high_resolution_clock::now(); - int64_t duration = (t1 - sec).count() / 1000000000.0; - imagePub->CameraHeader.Stamp.Sec = timeStamp + duration; - printf("timeStamp=%ld\n", timeStamp + duration); - } - dataSkeleton->cameraDecodedMbufEvent.Send(move(imagePub)); - cout << "Begin send yuv. seq:" << seq << " frameID:" << frameID << " path:" << file << endl; - if (comPara.frequency != "") { - int32_t freq = atoi(comPara.frequency.c_str()); - // 1000000微秒 - int32_t sleepTime = 1000000 / freq; - usleep(sleepTime); - } else { - // 30hz 100000微秒 - usleep(1000000 / 30); - } - } - free(yuvBuff); + retYuvSender = 0; + } + +private: + void HandleFrequency() + { + const int32_t sleepTimeIntervalMs = 1000000; + if (g_comPara.frequency != "") { + int32_t freq = atoi(g_comPara.frequency.c_str()); + if (freq != 0) { + // 1000000微秒 + int32_t sleepTime = sleepTimeIntervalMs / freq; + usleep(sleepTime); } - } while (isLoop); + } else { + // 30hz 100000微秒 + usleep(sleepTimeIntervalMs / 30); + } + } + + bool DealMat(FILE *yuvFile, std::string &file) + { + if (dealMatPara.frameSize < 0) { + return false; + } + char *yuvBuff = (char *)malloc(dealMatPara.frameSize * sizeof(char)); + if (1 == SwitchFlag) { + yuvBuff = nullptr; + } + if (yuvBuff == nullptr) { + return false; + } + for (int32_t i = 0; i < dealMatPara.frameCount; i++) { + cv::Mat yUV420NV12; + // yuv height beishu - 1.5 + yUV420NV12.create(dealMatPara.h * 1.5, dealMatPara.w, CV_8UC1); + if (memset_s(yuvBuff, dealMatPara.frameSize, 0, dealMatPara.frameSize) != 0) { + return false; + } + (void)fread(yuvBuff, sizeof(char), dealMatPara.frameSize, yuvFile); + memcpy_s(yUV420NV12.data, dealMatPara.frameSize, yuvBuff, dealMatPara.frameSize); + auto imagePub = dataSkeleton->cameraDecodedMbufEvent.Allocate(); + imagePub->CameraHeader.FrameId = frameID; + imagePub->CameraHeader.Seq = dealMatPara.seq; + imagePub->Width = dealMatPara.w; + imagePub->Height = dealMatPara.h; + imagePub->DataSize = dealMatPara.frameSize; + imagePub->UdpData.assign(yUV420NV12.data, yUV420NV12.data + imagePub->DataSize); #ifdef SAVE_SENDER_FILE - fclose(fpYuv); + if (fwrite(yUV420NV12.data, 1, dealMatPara.frameSize, fpYuv) != dealMatPara.frameSize) { + return false; + } #endif + if (g_comPara.time.empty()) { + timeval now; + gettimeofday(&now, NULL); + imagePub->CameraHeader.Stamp.Sec = now.tv_sec; + imagePub->CameraHeader.Stamp.Nsec = now.tv_usec * 1000U; + } else { + time_t timeStamp = ConvertTimeStr2TimeStamp(g_comPara.time); + auto t1 = std::chrono::high_resolution_clock::now(); + int64_t duration = (t1 - sec).count() / 1000000000.0; + imagePub->CameraHeader.Stamp.Sec = timeStamp + duration; + } + dataSkeleton->cameraDecodedMbufEvent.Send(move(imagePub)); +#ifndef X86LOG + HandleFrequency(); +#endif + } + free(yuvBuff); + SwitchFlag = -1; + return true; } + private: - std::string sourceYuvPath { }; + std::string sourceYuvPath {}; FILE *fpYuv { nullptr }; - chrono::high_resolution_clock::time_point sec { };//-t used + std::chrono::high_resolution_clock::time_point sec {}; // -t used + DealMatPara dealMatPara; }; -#endif //IMAGE_SENDER_YUV_SENDER_H_ +#endif // IMAGE_SENDER_YUV_SENDER_H