From 90e02376ff92e4e63e054aa441c2deab6dc2f7cf Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 19 Dec 2024 11:12:02 +0000 Subject: [PATCH 01/30] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20VideoEncoder&VideoDe?= =?UTF-8?q?coder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorials/VideoEncoder&VideoDecoder/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tutorials/VideoEncoder&VideoDecoder/.keep diff --git a/tutorials/VideoEncoder&VideoDecoder/.keep b/tutorials/VideoEncoder&VideoDecoder/.keep new file mode 100644 index 000000000..e69de29bb -- Gitee From 95f91cfa3b0a7a294aaa77d087a0c143b94fd4d3 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 19 Dec 2024 11:13:05 +0000 Subject: [PATCH 02/30] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20C++?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorials/VideoEncoder&VideoDecoder/C++/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tutorials/VideoEncoder&VideoDecoder/C++/.keep diff --git a/tutorials/VideoEncoder&VideoDecoder/C++/.keep b/tutorials/VideoEncoder&VideoDecoder/C++/.keep new file mode 100644 index 000000000..e69de29bb -- Gitee From 1d08564fb132dcfd29d86282d809240a3f019481 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 19 Dec 2024 11:13:42 +0000 Subject: [PATCH 03/30] =?UTF-8?q?=E6=B7=BB=E5=8A=A0main.cpp=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- .../VideoEncoder&VideoDecoder/C++/main.cpp | 389 ++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 tutorials/VideoEncoder&VideoDecoder/C++/main.cpp diff --git a/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp b/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp new file mode 100644 index 000000000..804ae681e --- /dev/null +++ b/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp @@ -0,0 +1,389 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: VideoDecoder and videoEncoder tutorials. + * Author: MindX SDK + * Create: 2024 + * History: NA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "unistd.h" +#include "acl/acl.h" +#include "acl/acl_rt.h" +#include "MxBase/Log/Log.h" +#include "MxBase/DeviceManager/DeviceManager.h" +#include "MxBase/E2eInfer/Image/Image.h" +#include "MxBase/E2eInfer/VideoDecoder/VideoDecoder.h" +#include "MxBase/E2eInfer/VideoEncoder/VideoEncoder.h" +#include "MxBase/MxBase.h" +#include "BlockingQueue.h" +extern "C" { +#include +} + +using namespace std; +using namespace MxBase; + +const int TIME_OUT = 3000; +const int QUEUE_SIZE = 1000; +const int FRAME_WAIT_TIME = 15; +const int DEFAULT_DEVICE_ID = 0; +const int DEFAULT_CHANNEL_ID = 0; +const std::string DEFAULT_SAVED_FILE_PATH = "./output"; +static bool g_sendSignial = false; +static bool g_readVideoEnded = false; +static bool g_vdecEnded = false; +static bool g_vencEnded = false; + +static void SigHandler(int signal) +{ + if (signal == SIGINT) { + g_sendSignial = true; + } +} + +struct DecodedFrame { + MxBase::Image image; + uint32_t frameId = 0; + uint32_t channelId = 0; +}; + +struct EncodedFrame { + std::shared_ptr data; + uint32_t dataSize = 0; + uint32_t frameId = 0; + uint32_t channelId = 0; +}; + +// 创建用于拉流线程、解码线程、编码线程、视频文件保存线程之间通信的全局队列 +BlockingQueue g_pullerToVdecQueue(QUEUE_SIZE); +BlockingQueue g_vdecToVencQueue(QUEUE_SIZE); +BlockingQueue g_vencToFileSaveQueue(QUEUE_SIZE); + +AVFormatContext* CreateFormatContext(const std::string &filePath) +{ + AVFormatContext *formatContext = nullptr; + AVDictionary *options = nullptr; + int ret = avformat_open_input(&formatContext, filePath.c_str(), nullptr, nullptr); + if (options != nullptr) { + av_dict_free(&options); + } + if (ret != 0) { + LogError << "Couldn't open input stream " << filePath.c_str() << " ret=" << ret; + return nullptr; + } + ret = avformat_find_stream_info(formatContext, nullptr); + if (ret != 0) { + LogError << "Couldn't find stream information"; + return nullptr; + } + return formatContext; +} + +void GetFrame(AVPacket& pkt, EncodedFrame& encodedFrame, AVFormatContext* pFormatCtx) +{ + av_init_packet(&pkt); + int avRet = av_read_frame(pFormatCtx, &pkt); + if (avRet != 0) { + LogWarn << "[StreamPuller] Channel read frame failed, continue!"; + if (avRet == AVERROR_EOF) { + g_readVideoEnded = true; + LogWarn << "[StreamPuller] Channel streamPuller is EOF, over!"; + } + return; + } else { + if (pkt.size <= 0) { + LogError << "Invalid pkt.size: " << pkt.size; + return; + } + auto hostDeleter = [](void *dataPtr) -> void {aclrtFreeHost(dataPtr);}; + MemoryData data(pkt.size, MemoryData::MEMORY_HOST); + MemoryData src((void *)(pkt.data), pkt.size, MemoryData::MEMORY_HOST_MALLOC); + APP_ERROR ret = MemoryHelper::MxbsMallocAndCopy(data, src); + if (ret != APP_ERR_OK) { + LogError << "MxbsMallocAndCopy failed!" << std::endl; + } + std::shared_ptr imageData((uint8_t*)data.ptrData, hostDeleter); + encodedFrame.data = imageData; + encodedFrame.dataSize = pkt.size; + av_packet_unref(&pkt); + } +} + +// 线程1:用于拉流 +void StreamPullerThread(const std::string filePath, const uint32_t width, const uint32_t height) +{ + uint32_t streamHeight = 0; + uint32_t streamWidth = 0; + AVPacket pkt; + uint32_t frameId = 0; + uint32_t channelId = 0; + AVFormatContext* pFormatCtx = avformat_alloc_context(); + pFormatCtx = CreateFormatContext(filePath); // create context + if (pFormatCtx == nullptr) { + return; + } + av_dump_format(pFormatCtx, 0, filePath.c_str(), 0); + DeviceContext context = {}; + context.devId = 0; + DeviceManager::GetInstance()->SetDevice(context); + // get the real width and height of the stream + for (unsigned int i = 0; i < pFormatCtx->nb_streams; ++i) { + AVStream *inStream = pFormatCtx->streams[i]; + if (inStream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + streamHeight = inStream->codecpar->height; + streamWidth = inStream->codecpar->width; + if (streamHeight != height) { + LogError << "Video height " << streamHeight << " is not equal to the configuration height " << height << "."; + g_readVideoEnded = true; + return; + } + if (streamWidth != width) { + LogError << "Video width " << streamWidth << " is not equal to the configuration width " << width << "."; + g_readVideoEnded = true; + return; + } + } + } + while (g_sendSignial == false && g_readVideoEnded == false) { + EncodedFrame encodedFrame; + encodedFrame.channelId = channelId; + encodedFrame.frameId = frameId; + GetFrame(pkt, encodedFrame, pFormatCtx); + g_pullerToVdecQueue.Push(encodedFrame, true); + frameId += 1; + std::this_thread::sleep_for(std::chrono::milliseconds(FRAME_WAIT_TIME)); + } + std::cout << "*********************StreamPullThread end*********************" << std::endl; +} + +// |拉流| +// | +// | +// V +// |下发解码指令| +// 线程2:用于下发解码指令 +void VdecThread(VideoDecoder& videoDecoder) +{ + while (true) { + if (g_sendSignial || (g_readVideoEnded && g_pullerToVdecQueue.GetSize() ==0)) { + break; + } + // 获取待解码的视频帧数据 + EncodedFrame encodedFrame; + APP_ERROR ret = g_pullerToVdecQueue.Pop(encodedFrame, TIME_OUT); + if (ret != APP_ERR_OK || encodedFrame.data == nullptr) { + continue; + } + // 下发解码指令 + ret = videoDecoder.Decode(encodedFrame.data, encodedFrame.dataSize, encodedFrame.frameId, + static_cast(&g_vdecToVencQueue)); + if (ret != APP_ERR_OK) { + LogError << "Decode failed."; + } + // 控制调用Decode接口的频率 + std::this_thread::sleep_for(std::chrono::milliseconds(FRAME_WAIT_TIME)); + } + g_vdecEnded = true; + std::cout << "*********************VdecThread end*********************" << std::endl; +} + +// |下发解码指令| +// | +// | +// V +// |获取解码结果| +// 线程3:用于获取解码结果(获取解码结果的线程由mxVision内部创建,用户仅需自定义回调函数、用于由该线程调用、获取解码结果) +APP_ERROR VdecCallBack(MxBase::Image &decodedImage, uint32_t channelId, uint32_t frameId, + void *userData) +{ + DecodedFrame decodedFrame{decodedImage, channelId, frameId}; + BlockingQueue* vdecToVencQueuePtr = static_cast*>(userData); + if (vdecToVencQueuePtr == nullptr) { + LogError << "VideoDecoderCallback: g_vdecToVencQueue has been released."; + return APP_ERR_DVPP_INVALID_FORMAT; + } + vdecToVencQueuePtr->Push(decodedFrame, true); + return APP_ERR_OK; +} + +// |获取解码结果| +// | +// | +// V +// |下发编码指令| +// 线程4:用于下发编码指令 +void VencThread(VideoEncoder& videoEncoder) +{ + while(true) { + if (g_sendSignial || (g_vdecEnded && g_vdecToVencQueue.GetSize() ==0)) { + break; + } + // 获取解码后的视频帧 + DecodedFrame decodedFrame; + APP_ERROR ret = g_vdecToVencQueue.Pop(decodedFrame, TIME_OUT); + if (ret != APP_ERR_OK) { + continue; + } + // 下发编码指令 + ret = videoEncoder.Encode(decodedFrame.image, decodedFrame.frameId, static_cast(&g_vencToFileSaveQueue)); + if (ret != APP_ERR_OK) { + LogError << "Encode failed."; + } + // 控制调用Encode接口的频率 + std::this_thread::sleep_for(std::chrono::milliseconds(FRAME_WAIT_TIME)); + } + g_vencEnded = true; + std::cout << "*********************VencThread end*********************" << std::endl; +} + +// |下发编码指令| +// | +// | +// V +// |获取编码结果| +// 线程5:用于获取编码结果(用于获取编码结果的线程由mxVision内部创建,用户仅需自定义回调函数、用于由该线程调用、获取编码结果) +APP_ERROR VencCallBack(std::shared_ptr& outDataPtr, uint32_t& outDataSize, + uint32_t& channelId, uint32_t& frameId, void* userData) +{ + EncodedFrame encodedFrame {outDataPtr, outDataSize, channelId, frameId}; + auto vencToFileSaveQueuePtr = static_cast*>(userData); + if (vencToFileSaveQueuePtr == nullptr) { + LogError << "g_vencToFileSaveQueue has been released." << std::endl; + return APP_ERR_DVPP_INVALID_FORMAT; + } + vencToFileSaveQueuePtr->Push(encodedFrame, true); + return APP_ERR_OK; +} + +// |获取编码结果| +// | +// | +// V +// |保存编码结果| +// 线程6:用于保存编码结果 +void SaveFrameThread(StreamFormat streamFormat) +{ + string savePath = DEFAULT_SAVED_FILE_PATH; + if (streamFormat == StreamFormat::H265_MAIN_LEVEL) { + savePath = savePath + ".h265"; + } else { + savePath = savePath + ".h264"; + } + + FILE *fp = fopen(savePath.c_str(), "wb"); + if (fp == nullptr) { + LogError << "Failed to open file."; + return; + } + + bool mbFoundFirstIDR = false; + bool bIsIDR = false; + while (true) { + if (g_sendSignial || (g_vencEnded && g_vencToFileSaveQueue.GetSize() == 0)) { + break; + } + // 获取编码后的视频帧 + EncodedFrame encodedFrame; + APP_ERROR ret = g_vencToFileSaveQueue.Pop(encodedFrame, TIME_OUT); + if (ret != APP_ERR_OK) { + continue; + } + // 保存编码后的视频帧 + bIsIDR = (encodedFrame.dataSize > 1); + if (!mbFoundFirstIDR) { + if (!bIsIDR) { + LogWarn << "Not bIsIDR!!!"; + continue; + } else { + mbFoundFirstIDR = true; + } + } + if (fwrite(encodedFrame.data.get(), encodedFrame.dataSize, 1, fp) != 1) { + LogError << "write frame to file fail"; + } + } + if (fclose(fp) != 0) { + LogError << "Failed to close file."; + } + std::cout << "*********************Save frame thread end*********************" << std::endl; +} + + +int main(int argc, char *argv[]) +{ + // 初始化全局资源 + avformat_network_init(); + if (MxInit() != APP_ERR_OK) { + LogError << "Fail to conduct MxInit."; + return APP_ERR_COMM_FAILURE; + } + if (signal(SIGINT, SigHandler) == SIG_ERR) { + LogError << "Fail to register SigHandler."; + return APP_ERR_COMM_FAILURE; + } + { + // 设置输入视频路径和该视频宽、高 + std::string filePath = "./xx.264"; + int width = 1920; + int height = 1080; + // 设置解码器主要配置项,根据配置项初始化解码器 + VideoDecodeConfig vDecodeConfig; + vDecodeConfig.width = width; // 指定视频宽 + vDecodeConfig.height = height; // 指定视频高 + vDecodeConfig.inputVideoFormat = StreamFormat::H264_MAIN_LEVEL; // 指定待解码的输入视频格式 + vDecodeConfig.outputImageFormat = ImageFormat::YUV_SP_420; // 指定解码后的输出图片格式 + vDecodeConfig.callbackFunc = VdecCallBack; // 指定解码后、用于取解码结果的回调函数 + VideoDecoder videoDecoder = VideoDecoder(vDecodeConfig, DEFAULT_DEVICE_ID, DEFAULT_CHANNEL_ID); // 初始化解码器 + + // 设置编码器主要配置项,根据配置项初始化编码器 + VideoEncodeConfig vEncodeConfig; + vEncodeConfig.width = width; // 指定视频宽 + vEncodeConfig.height = height; // 指定视频高 + vEncodeConfig.inputImageFormat = ImageFormat::YUV_SP_420; // 指定待编码的输入图片格式 + vEncodeConfig.srcRate = 10; // 指定待编码的输入图片帧率 + vEncodeConfig.outputVideoFormat = StreamFormat::H264_MAIN_LEVEL; // 指定编码后的输出视频格式 + vEncodeConfig.displayRate = 25; // 指定编码后的输出视频帧率 + vEncodeConfig.callbackFunc = VencCallBack; // 指定编码后,用于取编码结果的回调函数 + VideoEncoder videoEncoder = VideoEncoder(vEncodeConfig, DEFAULT_DEVICE_ID, DEFAULT_CHANNEL_ID); // 初始化编码器 + + // 启动拉流线程 + std::cout << "*********************StreamPullerThread start*********************" << std::endl; + std::thread streamPullerThread = std::thread(StreamPullerThread, filePath, width, height); + // 启动解码线程 + std::cout << "*********************VdecThread start*********************" << std::endl; + std::thread vdecThread = std::thread(VdecThread, std::ref(videoDecoder)); + // 启动视频编码线程 + std::cout << "*********************VencThread start*********************" << std::endl; + std::thread vencThread = std::thread(VencThread, std::ref(videoEncoder)); + // 启动视频文件保存线程 + std::cout << "*********************SaveFrameThread start*********************" << std::endl; + std::thread saveFrameThread = std::thread(SaveFrameThread, vEncodeConfig.outputVideoFormat); + + // 销毁线程 + streamPullerThread.join(); + vdecThread.join(); + vencThread.join(); + saveFrameThread.join(); + + // 销毁全局资源 + g_pullerToVdecQueue.Clear(); + g_vdecToVencQueue.Clear(); + g_vencToFileSaveQueue.Clear(); + } + // 去初始化 + MxDeInit(); + return 0; +} \ No newline at end of file -- Gitee From 5191c8c23ac8c989ca6196a217574f1685bcd964 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 19 Dec 2024 11:14:59 +0000 Subject: [PATCH 04/30] =?UTF-8?q?=E6=B7=BB=E5=8A=A0CMakeLists.txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- .../C++/CMakeLists.txt | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 tutorials/VideoEncoder&VideoDecoder/C++/CMakeLists.txt diff --git a/tutorials/VideoEncoder&VideoDecoder/C++/CMakeLists.txt b/tutorials/VideoEncoder&VideoDecoder/C++/CMakeLists.txt new file mode 100644 index 000000000..36eb9b9bf --- /dev/null +++ b/tutorials/VideoEncoder&VideoDecoder/C++/CMakeLists.txt @@ -0,0 +1,43 @@ +# +# Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved. +# Description: CMakeLists for this project. +# Author: MindX SDK +# Create: 2024 +# History: NA +# + +cmake_minimum_required(VERSION 3.5.2) +project(VideoDecoderAndEncoder) + +set(MX_SDK_HOME $ENV{MX_SDK_HOME}) +set(FFMPEG_PATH $ENV{FFMPEG_PATH}) +set(ASCEND_HOME_PATH $ENV{ASCEND_TOOLKIT_HOME}) +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--copy-dt-needed-entries") + +# Add compile options +add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) +add_definitions(-Dgoogle=mindxsdk_private) +add_compile_options(-std=c++14 -fPIC -fstack-protector-all -Wall -g -O0) +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro,-z,now,-z,noexecstack -pie") + +# Add header path +include_directories( + ${MX_SDK_HOME}/include + ${MX_SDK_HOME}/opensource/include + ${MX_SDK_HOME}/opensource/include/opencv4 + ${FFMPEG_PATH}/include + ${ASCEND_HOME_PATH}/include +) + +# Add lib path +link_directories( + ${MX_SDK_HOME}/lib + ${MX_SDK_HOME}/opensource/lib + ${MX_SDK_HOME}/opensource/lib64 + ${FFMPEG_PATH}/lib + ${ASCEND_HOME_PATH}/lib64 +) + +add_executable(main main.cpp) + +target_link_libraries(main mxbase -lpthread -lm avformat avcodec avdevice avutil swresample) \ No newline at end of file -- Gitee From 18d607eb7442284d8c8e5d17db39b8cf9ba26231 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 19 Dec 2024 11:17:10 +0000 Subject: [PATCH 05/30] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20tu?= =?UTF-8?q?torials/VideoEncoder&VideoDecoder/C++/.keep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorials/VideoEncoder&VideoDecoder/C++/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tutorials/VideoEncoder&VideoDecoder/C++/.keep diff --git a/tutorials/VideoEncoder&VideoDecoder/C++/.keep b/tutorials/VideoEncoder&VideoDecoder/C++/.keep deleted file mode 100644 index e69de29bb..000000000 -- Gitee From c8d2a8c7d179004435a119a5c113ecec138c08e9 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 19 Dec 2024 11:17:22 +0000 Subject: [PATCH 06/30] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20tu?= =?UTF-8?q?torials/VideoEncoder&VideoDecoder/.keep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorials/VideoEncoder&VideoDecoder/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tutorials/VideoEncoder&VideoDecoder/.keep diff --git a/tutorials/VideoEncoder&VideoDecoder/.keep b/tutorials/VideoEncoder&VideoDecoder/.keep deleted file mode 100644 index e69de29bb..000000000 -- Gitee From 57fceecad1b0f679fef7175884c9dbc4046ea2e4 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 19 Dec 2024 11:17:37 +0000 Subject: [PATCH 07/30] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20Python?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorials/VideoEncoder&VideoDecoder/Python/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tutorials/VideoEncoder&VideoDecoder/Python/.keep diff --git a/tutorials/VideoEncoder&VideoDecoder/Python/.keep b/tutorials/VideoEncoder&VideoDecoder/Python/.keep new file mode 100644 index 000000000..e69de29bb -- Gitee From 90c5b2620ed8a674196ab997bdc1854c0932430e Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Thu, 19 Dec 2024 12:00:05 +0000 Subject: [PATCH 08/30] =?UTF-8?q?=E5=A2=9E=E5=8A=A0README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 tutorials/VideoEncoder&VideoDecoder/README.md diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md new file mode 100644 index 000000000..69d042f6e --- /dev/null +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -0,0 +1,111 @@ +# MxVision快速入门——mxBaseV2视频编解码接口使用 + +## 1 介绍 + +### 1.1 简介 +本样例属于mxVision快速入门样例,用于向用户介绍mxBaseV2系列视频编解码接口的基本使用。本系统以昇腾Atlas 300V,Atlas 300I pro和 Atlas300V pro为主要的硬件平台。 + +本样例以本地视频拉流、解码、编码、编码结果保存为例子,着重介绍解码接口VideoDecoder和编码接口VideoEncoder的实例化和功能接口(Decode接口、Encode接口)使用。 + +建议用户按照README跑通示例代码后,通过阅读示例源码的方式,更深入的理解mxBaseV2系列视频编解码接口基本使用。 + +### 1.2 支持的产品 +本项目以昇腾Atlas 300V,Atlas 300I pro和 Atlas300V pro为主要的硬件平台。 + +### 1.3 支持的版本 + +| MxVision版本 | CANN版本 | Driver/Firmware版本 | + | --------- | ------------------ | -------------- | +| 6.0.RC3 | 8.0.RC3 | 24.1.RC3 | + +### 1.4 三方依赖 + +本项目除了依赖昇腾Driver、Firmware、CANN和MxVision及其要求的配套软件外,还需额外依赖以下软件: + +| 软件名称 | 版本 | +|--------| ------ | +| ffmpeg | 3.4.11 | + +注意:ffmpeg需要用户自行到相关网站下载源码进行编译安装。 + +## 2 设置环境变量 + +在执行后续步骤前,需要设置环境变量: + +```bash +# 执行环境变量脚本使环境变量生效 +. ${ascend-toolkit-path}/set_env.sh +. ${mxVision-path}/set_env.sh +export FFMPEG_PATH=${ffmpeg-path} +export LD_LIBRARY_PATH=${ffmpeg-lib-path}:$LD_LIBRARY_PATH +# mxVision-path: mxVision安装路径 +# ascend-toolkit-path: CANN安装路径 +# ffmpeg-path: ffmpeg安装路径,通常为/usr/local/ffmpeg +# ffmpeg-lib-path: ffmpeg的lib库安装路径,通常为/usr/local/ffmpeg/lib +``` + +## 3 编译与运行 +### 3.1 C++样例运行 +**步骤1:下载BlockingQueue.h文件** + +根据[链接](https://gitee.com/ascend/mindxsdk-referenceapps/blob/master/contrib/FireDetection/c++/BlockingQueue/BlockingQueue.h)下载Blockingqueue.h文件,将BlockingQueue.h文件放在本项目根目录的C++目录下。 + + +**步骤2:准备视频** + +准备一个H264格式的视频文件,并放至在本项目路径下。 + +**步骤3:修改main.cpp文件,指定VideoDecoder和VideoEncoder的基本初始化参数** + + +第**339**行到第**359**行展示了VideoDecoder和VideoEncoder的主要配置项,用户可以结合mxVision官方文档根据需要调整。本样例中仅修改必要配置项,如下所示: + +第**339**行 `"std::string filePath = ${filePath}"`中的${filePath}替换为步骤2中视频文件实际的路径。 + +第**343**行 `"vDecodeConfig.width = ${width}"`中的${width}替换为步骤2中视频帧实际的宽。 + +第**344**行 `"vDecodeConfig.height = ${height}"`中的${height}替换为步骤2中视频帧实际的高。 + + +**步骤4:编译** + +进入项目根目录的C++目录下,执行以下命令: +``` +bash build.sh +``` + +**步骤5:运行** +进入项目根目录的C++目录下,执行以下命令: +``` +./main +``` + +**步骤6:查看结果** + +保存后的视频文件(命令为output.h264)会在同级目录下,打开该文件即可查看编码结果。 + + + +### 3.2 Python样例运行 + + +**步骤1:准备视频** + +准备一个H264格式的视频文件,并放至在本项目路径下。 + +**步骤2:修改main.py文件,指定VideoDecoder和VideoEncoder的基本初始化参数** + + + +**步骤3:运行** +进入项目根目录的Python目录下,执行以下命令: +``` +python3 main.py +``` + +**步骤4:查看结果** + +保存后的视频文件(命令为output.h264)会在同级目录下,打开该文件即可查看编码结果。 + + + -- Gitee From bdcb8e5666965d86767404058a5019febdf67056 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 07:05:53 +0000 Subject: [PATCH 09/30] =?UTF-8?q?=E6=96=B0=E5=A2=9Emain.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- .../VideoEncoder&VideoDecoder/Python/main.py | 210 ++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 tutorials/VideoEncoder&VideoDecoder/Python/main.py diff --git a/tutorials/VideoEncoder&VideoDecoder/Python/main.py b/tutorials/VideoEncoder&VideoDecoder/Python/main.py new file mode 100644 index 000000000..d47b82cfd --- /dev/null +++ b/tutorials/VideoEncoder&VideoDecoder/Python/main.py @@ -0,0 +1,210 @@ +import threading +import signal +import time +import av +import logging +from mindx.sdk import base +from mindx.sdk.base import VideoDecoder, VideoDecodeConfig, \ + VdecCallBacker, VideoEncoder, VideoEncodeConfig, VencCallBacker + +logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') +DEFAULT_DEVICE_ID = 0 +DEFAULT_CHANNEL_ID = 0 +DEFAULT_SAVED_FILE_PATH = "./output" +PULLER_TO_VDEC_QUEUE = [] +VDEC_TO_VENC_QUEUE = [] +VENC_TO_FILE_SAVE_QUEUE = [] +SEND_SIGNAL = False +READ_VIDEO_ENDED = False +VDEC_ENDED = False +VENC_ENDED = False + +class DecodedFrame: + def __init__(self, image, frame_id, channel_id): + self.image = image + self.frame_id = frame_id + self.channel_id = channel_id + +class EncodedFrame: + def __init__(self, data, frame_id, channel_id): + self.data = data + self.frame_id = frame_id + self.channel_id = channel_id + + +def stop_handler(signum, frame): + global SEND_SIGNAL + SEND_SIGNAL = True + +# 线程1:用于拉流 +def stream_puller_thread(file_path, width, height): + global SEND_SIGNAL + with av.open(file_path) as container: + frame_id = 0 + # 校验视频宽高是否符合编码器要求 + video_stream = next(s for s in container.streams if s.type == 'video') + if video_stream.height != height: + logging.error("Video height is not equal to configured height.") + SEND_SIGNAL = True + return + if video_stream.width != width: + logging.error("Video width is not equal to configured width.") + SEND_SIGNAL = True + return + # 循环取帧解码 + for packet in container.demux(): + if SEND_SIGNAL: + break + if packet.size == 0: + logging.info("Finish to pull rtsp stream.") + READ_VIDEO_ENDED = True + break + PULLER_TO_VDEC_QUEUE.append(EncodedFrame(packet, frame_id, DEFAULT_CHANNEL_ID)) + frame_id += 1 + logging.info("*********************StreamPullThread end*********************") + +# |拉流| +# | +# | +# V +# |下发解码指令| +# 线程2:用于下发解码指令 +def vdec_thread(video_decoder): + global VDEC_ENDED + while True: + if SEND_SIGNAL or (READ_VIDEO_ENDED and len(PULLER_TO_VDEC_QUEUE) == 0): + break + #获取待解码的视频帧数据 + if not PULLER_TO_VDEC_QUEUE: + continue + encoded_frame = PULLER_TO_VDEC_QUEUE.pop(0) + logging.debug("send packet:{} ".format(encoded_frame.frame_id)) + video_decoder.decode(encoded_frame.data, encoded_frame.frame_id) + VDEC_ENDED = True + logging.info("*********************VdecThread end*********************") + +# |下发解码指令| +# | +# | +# V +# |获取解码结果| +# 线程3:用于获取解码结果(获取解码结果的线程由mxVision内部创建,用户仅需自定义回调函数、用于由该线程调用、获取解码结果) +def vdec_callback_func(decoded_image, channel_id, frame_id): + VDEC_TO_VENC_QUEUE.append(DecodedFrame(decoded_image, frame_id, channel_id)) + + # |获取解码结果| + # | + # | + # V + # |下发编码指令| + # 线程4:用于下发编码指令 +def venc_thread(video_encoder): + global VENC_ENDED + while True: + if SEND_SIGNAL or (VDEC_ENDED and len(VDEC_TO_VENC_QUEUE) == 0): + break + #获取待编码的视频帧数据 + if not VDEC_TO_VENC_QUEUE: + continue + decoded_frame = VDEC_TO_VENC_QUEUE.pop(0) + video_encoder.encode(decoded_frame.image, decoded_frame.frame_id) + VENC_ENDED = True + logging.info("*********************VencThread end*********************") + + +# |下发编码指令| +# | +# | +# V +# |获取编码结果| +# 线程5:用于获取编码结果(用于获取编码结果的线程由mxVision内部创建,用户仅需自定义回调函数、用于由该线程调用、获取编码结果) +def venc_callback_func(output, output_datasize, channel_id, frame_id): + VENC_TO_FILE_SAVE_QUEUE.append(EncodedFrame(output, frame_id, channel_id)) + +# |获取编码结果| +# | +# | +# V +# |保存编码结果| +# 线程6:用于保存编码结果 +def save_frame_thread(stream_format): + save_path = DEFAULT_SAVED_FILE_PATH + if stream_format == base.h265_main_level: + save_path = save_path + ".265" + else: + save_path = save_path + ".264" + + while True: + if SEND_SIGNAL or (VENC_ENDED and len(VENC_TO_FILE_SAVE_QUEUE) == 0): + break + if not VENC_TO_FILE_SAVE_QUEUE: + continue + encoded_frame = VENC_TO_FILE_SAVE_QUEUE.pop(0) + with open(save_path, 'ab') as file: + file.write(encoded_frame.data) + logging.info("*********************Save frame thread end*********************") + +def start_service(): + # 设置输入视频路径和该视频宽、高 + file_path = "./fireDetection.264" + width = 1920 + height = 1080 + + # 设置解码器主要配置项,根据配置项初始化解码器 + vdec_conf = VideoDecodeConfig() + vdec_conf.width = width # 指定视频宽 + vdec_conf.height = height # 指定视频高 + vdec_conf.inputVideoFormat = base.h264_main_level # 指定待解码的输入视频格式 + vdec_conf.outputImageFormat = base.nv12 # 指定解码后的输出图片格式 + vdec_callbacker = VdecCallBacker() + vdec_callbacker.registerVdecCallBack(vdec_callback_func) # 指定解码后、用于取解码结果的回调函数 + video_decoder = VideoDecoder(vdec_conf, vdec_callbacker, DEFAULT_DEVICE_ID, DEFAULT_CHANNEL_ID) # 初始化解码器 + + + # 设置编码器主要配置项,根据配置项初始化编码器 + venc_conf = VideoEncodeConfig() + venc_conf.width = width # 指定视频宽 + venc_conf.height = height # 指定视频高 + venc_conf.inputImageFormat = base.nv12 # 指定待编码的输入图片格式 + venc_conf.srcRate = 30 # 指定待编码的输入图片帧率 + venc_conf.outputVideoFormat = base.h264_main_level # 指定编码后的输出视频格式 + venc_conf.displayRate = 25 # 指定编码后的输出视频帧率 + venc_callbacker = VencCallBacker() + venc_callbacker.registerVencCallBack(venc_callback_func) # 指定编码后,用于取编码结果的回调函数 + video_encoder = VideoEncoder(venc_conf, venc_callbacker, DEFAULT_DEVICE_ID) # 初始化编码器 + + # 启动拉流线程 + stream_puller = threading.Thread(target=stream_puller_thread, kwargs={"file_path": file_path, "width": width, + "height": height}) + stream_puller.start() + logging.info("*********************stream_puller_thread start*********************" ) + # 启动解码线程 + vdec = threading.Thread(target=vdec_thread, kwargs={"video_decoder": video_decoder}) + vdec.start() + logging.info("*********************vdec_thread start*********************") + # 启动视频编码线程 + venc = threading.Thread(target=venc_thread, kwargs={"video_encoder": video_encoder}) + venc.start() + logging.info("*********************venc_thread start*********************") + # 启动视频文件保存线程 + save_frame = threading.Thread(target=save_frame_thread, kwargs={"stream_format": venc_conf.outputVideoFormat}) + save_frame.start() + logging.info("*********************save_frame_thread start*********************") + + # 等待执行完毕 + stream_puller.join() + vdec.join() + venc.join() + save_frame.join() + + # 销毁全局资源 + PULLER_TO_VDEC_QUEUE.clear() + VDEC_TO_VENC_QUEUE.clear() + VENC_TO_FILE_SAVE_QUEUE.clear() + +if __name__ == '__main__': + base.mx_init() + signal.signal(signal.SIGINT, stop_handler) + start_service() + base.mx_deinit() + -- Gitee From 08c4bef1996011645e637acb562f6e3380ad4d38 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 07:06:14 +0000 Subject: [PATCH 10/30] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20tu?= =?UTF-8?q?torials/VideoEncoder&VideoDecoder/Python/.keep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorials/VideoEncoder&VideoDecoder/Python/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tutorials/VideoEncoder&VideoDecoder/Python/.keep diff --git a/tutorials/VideoEncoder&VideoDecoder/Python/.keep b/tutorials/VideoEncoder&VideoDecoder/Python/.keep deleted file mode 100644 index e69de29bb..000000000 -- Gitee From c3c0252e119b5498bbd42d3a6c9fe8ed4a22a119 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 07:32:08 +0000 Subject: [PATCH 11/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/Python/main.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/Python/main.py b/tutorials/VideoEncoder&VideoDecoder/Python/main.py index d47b82cfd..0c88a3dbf 100644 --- a/tutorials/VideoEncoder&VideoDecoder/Python/main.py +++ b/tutorials/VideoEncoder&VideoDecoder/Python/main.py @@ -39,6 +39,7 @@ def stop_handler(signum, frame): # 线程1:用于拉流 def stream_puller_thread(file_path, width, height): global SEND_SIGNAL + global READ_VIDEO_ENDED with av.open(file_path) as container: frame_id = 0 # 校验视频宽高是否符合编码器要求 @@ -92,12 +93,12 @@ def vdec_thread(video_decoder): def vdec_callback_func(decoded_image, channel_id, frame_id): VDEC_TO_VENC_QUEUE.append(DecodedFrame(decoded_image, frame_id, channel_id)) - # |获取解码结果| - # | - # | - # V - # |下发编码指令| - # 线程4:用于下发编码指令 +# |获取解码结果| +# | +# | +# V +# |下发编码指令| +# 线程4:用于下发编码指令 def venc_thread(video_encoder): global VENC_ENDED while True: @@ -207,4 +208,3 @@ if __name__ == '__main__': signal.signal(signal.SIGINT, stop_handler) start_service() base.mx_deinit() - -- Gitee From 8a25725d93a37f50218745238f68605f7db2d9ac Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 07:46:49 +0000 Subject: [PATCH 12/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md index 69d042f6e..5f951bb49 100644 --- a/tutorials/VideoEncoder&VideoDecoder/README.md +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -24,6 +24,7 @@ | 软件名称 | 版本 | |--------| ------ | +| av | 10.0.0 | | ffmpeg | 3.4.11 | 注意:ffmpeg需要用户自行到相关网站下载源码进行编译安装。 @@ -58,13 +59,17 @@ export LD_LIBRARY_PATH=${ffmpeg-lib-path}:$LD_LIBRARY_PATH **步骤3:修改main.cpp文件,指定VideoDecoder和VideoEncoder的基本初始化参数** -第**339**行到第**359**行展示了VideoDecoder和VideoEncoder的主要配置项,用户可以结合mxVision官方文档根据需要调整。本样例中仅修改必要配置项,如下所示: +第**338**行到第**360**行展示了VideoDecoder和VideoEncoder的主要配置项,用户可以结合mxVision官方文档根据需要调整。本样例中仅指定必要配置项,如下所示: 第**339**行 `"std::string filePath = ${filePath}"`中的${filePath}替换为步骤2中视频文件实际的路径。 -第**343**行 `"vDecodeConfig.width = ${width}"`中的${width}替换为步骤2中视频帧实际的宽。 +第**340**行 `"int width = ${width}"`中的${width}替换为步骤2中视频帧实际的宽。 -第**344**行 `"vDecodeConfig.height = ${height}"`中的${height}替换为步骤2中视频帧实际的高。 +第**341**行 `"int height = ${height}"`中的${height}替换为步骤2中视频帧实际的高。 + +第**356**行 `"vEncodeConfig.srcRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 + +第**358**行 `"vEncodeConfig.displayRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 **步骤4:编译** @@ -95,6 +100,18 @@ bash build.sh **步骤2:修改main.py文件,指定VideoDecoder和VideoEncoder的基本初始化参数** +第**149**行到第**175**行展示了VideoDecoder和VideoEncoder的主要配置项,用户可以结合mxVision官方文档根据需要调整。本样例中仅指定必要配置项,如下所示: + +第**150**行 `"file_path = ${file_path}"`中的${file_path}替换为步骤2中视频文件实际的路径。 + +第**151**行 `"width = ${width}"`中的${width}替换为步骤2中视频帧实际的宽。 + +第**152**行 `"height = ${height}"`中的${height}替换为步骤2中视频帧实际的高。 + +第**170**行 `"venc_conf.srcRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 + +第**172**行 `"venc_conf.srcRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 + **步骤3:运行** -- Gitee From d34a2f1fe08c2f0c77c5263fb7f1856a21be611c Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 07:47:26 +0000 Subject: [PATCH 13/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md index 5f951bb49..116b33cdc 100644 --- a/tutorials/VideoEncoder&VideoDecoder/README.md +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -87,7 +87,7 @@ bash build.sh **步骤6:查看结果** -保存后的视频文件(命令为output.h264)会在同级目录下,打开该文件即可查看编码结果。 +保存后的视频文件(命令为output.264)会在同级目录下,打开该文件即可查看编码结果。 @@ -122,7 +122,7 @@ python3 main.py **步骤4:查看结果** -保存后的视频文件(命令为output.h264)会在同级目录下,打开该文件即可查看编码结果。 +保存后的视频文件(命令为output.264)会在同级目录下,打开该文件即可查看编码结果。 -- Gitee From b20a3ecbff419cd9df132acf24efb21a3750b4db Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 07:48:38 +0000 Subject: [PATCH 14/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md index 116b33cdc..280b22d4d 100644 --- a/tutorials/VideoEncoder&VideoDecoder/README.md +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -80,6 +80,7 @@ bash build.sh ``` **步骤5:运行** + 进入项目根目录的C++目录下,执行以下命令: ``` ./main @@ -98,6 +99,7 @@ bash build.sh 准备一个H264格式的视频文件,并放至在本项目路径下。 + **步骤2:修改main.py文件,指定VideoDecoder和VideoEncoder的基本初始化参数** 第**149**行到第**175**行展示了VideoDecoder和VideoEncoder的主要配置项,用户可以结合mxVision官方文档根据需要调整。本样例中仅指定必要配置项,如下所示: @@ -115,6 +117,7 @@ bash build.sh **步骤3:运行** + 进入项目根目录的Python目录下,执行以下命令: ``` python3 main.py -- Gitee From 3947d52a273c877743dc90718614eab6c0ebebb6 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 07:49:29 +0000 Subject: [PATCH 15/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md index 280b22d4d..51a7d85e5 100644 --- a/tutorials/VideoEncoder&VideoDecoder/README.md +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -104,15 +104,15 @@ bash build.sh 第**149**行到第**175**行展示了VideoDecoder和VideoEncoder的主要配置项,用户可以结合mxVision官方文档根据需要调整。本样例中仅指定必要配置项,如下所示: -第**150**行 `"file_path = ${file_path}"`中的${file_path}替换为步骤2中视频文件实际的路径。 +第**150**行 `"file_path = ${file_path}"`中的${file_path}替换为步骤1中视频文件实际的路径。 -第**151**行 `"width = ${width}"`中的${width}替换为步骤2中视频帧实际的宽。 +第**151**行 `"width = ${width}"`中的${width}替换为步骤1中视频帧实际的宽。 -第**152**行 `"height = ${height}"`中的${height}替换为步骤2中视频帧实际的高。 +第**152**行 `"height = ${height}"`中的${height}替换为步骤1中视频帧实际的高。 -第**170**行 `"venc_conf.srcRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 +第**170**行 `"venc_conf.srcRate = ${fps}"`中的${fps}替换为步骤1中视频帧实际的帧率。 -第**172**行 `"venc_conf.srcRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 +第**172**行 `"venc_conf.srcRate = ${fps}"`中的${fps}替换为步骤1中视频帧实际的帧率。 -- Gitee From 89b3db6b78e01e4cd7a69202eb97e3a4675ab5ff Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 07:50:52 +0000 Subject: [PATCH 16/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9main.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- .../VideoEncoder&VideoDecoder/C++/main.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp b/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp index 804ae681e..d2f6b5c0b 100644 --- a/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp +++ b/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp @@ -336,13 +336,13 @@ int main(int argc, char *argv[]) } { // 设置输入视频路径和该视频宽、高 - std::string filePath = "./xx.264"; - int width = 1920; - int height = 1080; + std::string filePath = ${filePath}; + int width = ${width} + int height = ${height} // 设置解码器主要配置项,根据配置项初始化解码器 VideoDecodeConfig vDecodeConfig; - vDecodeConfig.width = width; // 指定视频宽 - vDecodeConfig.height = height; // 指定视频高 + vDecodeConfig.width = ${width}; // 指定视频宽 + vDecodeConfig.height = ${height}; // 指定视频高 vDecodeConfig.inputVideoFormat = StreamFormat::H264_MAIN_LEVEL; // 指定待解码的输入视频格式 vDecodeConfig.outputImageFormat = ImageFormat::YUV_SP_420; // 指定解码后的输出图片格式 vDecodeConfig.callbackFunc = VdecCallBack; // 指定解码后、用于取解码结果的回调函数 @@ -353,26 +353,26 @@ int main(int argc, char *argv[]) vEncodeConfig.width = width; // 指定视频宽 vEncodeConfig.height = height; // 指定视频高 vEncodeConfig.inputImageFormat = ImageFormat::YUV_SP_420; // 指定待编码的输入图片格式 - vEncodeConfig.srcRate = 10; // 指定待编码的输入图片帧率 + vEncodeConfig.srcRate = ${fps}; // 指定待编码的输入图片帧率 vEncodeConfig.outputVideoFormat = StreamFormat::H264_MAIN_LEVEL; // 指定编码后的输出视频格式 - vEncodeConfig.displayRate = 25; // 指定编码后的输出视频帧率 + vEncodeConfig.displayRate = ${fps}; // 指定编码后的输出视频帧率 vEncodeConfig.callbackFunc = VencCallBack; // 指定编码后,用于取编码结果的回调函数 VideoEncoder videoEncoder = VideoEncoder(vEncodeConfig, DEFAULT_DEVICE_ID, DEFAULT_CHANNEL_ID); // 初始化编码器 // 启动拉流线程 - std::cout << "*********************StreamPullerThread start*********************" << std::endl; std::thread streamPullerThread = std::thread(StreamPullerThread, filePath, width, height); - // 启动解码线程 - std::cout << "*********************VdecThread start*********************" << std::endl; + std::cout << "*********************StreamPullerThread start*********************" << std::endl; + // 启动视频解码线程 std::thread vdecThread = std::thread(VdecThread, std::ref(videoDecoder)); + std::cout << "*********************VdecThread start*********************" << std::endl; // 启动视频编码线程 - std::cout << "*********************VencThread start*********************" << std::endl; std::thread vencThread = std::thread(VencThread, std::ref(videoEncoder)); + std::cout << "*********************VencThread start*********************" << std::endl; // 启动视频文件保存线程 - std::cout << "*********************SaveFrameThread start*********************" << std::endl; std::thread saveFrameThread = std::thread(SaveFrameThread, vEncodeConfig.outputVideoFormat); + std::cout << "*********************SaveFrameThread start*********************" << std::endl; - // 销毁线程 + // 等待执行完毕 streamPullerThread.join(); vdecThread.join(); vencThread.join(); -- Gitee From b7308089d9d6f5b4ffde66467afd1dee7dc85f75 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 07:51:31 +0000 Subject: [PATCH 17/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9main.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/Python/main.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/Python/main.py b/tutorials/VideoEncoder&VideoDecoder/Python/main.py index 0c88a3dbf..03c0b3372 100644 --- a/tutorials/VideoEncoder&VideoDecoder/Python/main.py +++ b/tutorials/VideoEncoder&VideoDecoder/Python/main.py @@ -147,9 +147,9 @@ def save_frame_thread(stream_format): def start_service(): # 设置输入视频路径和该视频宽、高 - file_path = "./fireDetection.264" - width = 1920 - height = 1080 + file_path = ${file_path} + width = ${width} + height = ${height} # 设置解码器主要配置项,根据配置项初始化解码器 vdec_conf = VideoDecodeConfig() @@ -167,9 +167,9 @@ def start_service(): venc_conf.width = width # 指定视频宽 venc_conf.height = height # 指定视频高 venc_conf.inputImageFormat = base.nv12 # 指定待编码的输入图片格式 - venc_conf.srcRate = 30 # 指定待编码的输入图片帧率 + venc_conf.srcRate = ${fps} # 指定待编码的输入图片帧率 venc_conf.outputVideoFormat = base.h264_main_level # 指定编码后的输出视频格式 - venc_conf.displayRate = 25 # 指定编码后的输出视频帧率 + venc_conf.displayRate = ${fps} # 指定编码后的输出视频帧率 venc_callbacker = VencCallBacker() venc_callbacker.registerVencCallBack(venc_callback_func) # 指定编码后,用于取编码结果的回调函数 video_encoder = VideoEncoder(venc_conf, venc_callbacker, DEFAULT_DEVICE_ID) # 初始化编码器 -- Gitee From 4396d5ee17ecd5ecf31e603cc63f891ef26069cc Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:11:59 +0000 Subject: [PATCH 18/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9main.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- .../VideoEncoder&VideoDecoder/C++/main.cpp | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp b/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp index d2f6b5c0b..f0f63438e 100644 --- a/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp +++ b/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp @@ -6,20 +6,12 @@ * History: NA */ -#include #include #include -#include -#include -#include -#include #include #include #include -#include #include -#include -#include "unistd.h" #include "acl/acl.h" #include "acl/acl_rt.h" #include "MxBase/Log/Log.h" @@ -146,18 +138,20 @@ void StreamPullerThread(const std::string filePath, const uint32_t width, const streamHeight = inStream->codecpar->height; streamWidth = inStream->codecpar->width; if (streamHeight != height) { - LogError << "Video height " << streamHeight << " is not equal to the configuration height " << height << "."; + LogError << "Video height " << streamHeight << " is not equal to the configuration height " + << height << "."; g_readVideoEnded = true; return; } if (streamWidth != width) { - LogError << "Video width " << streamWidth << " is not equal to the configuration width " << width << "."; + LogError << "Video width " << streamWidth << " is not equal to the configuration width " + << width << "."; g_readVideoEnded = true; return; } } } - while (g_sendSignial == false && g_readVideoEnded == false) { + while (!g_sendSignial && !g_readVideoEnded) { EncodedFrame encodedFrame; encodedFrame.channelId = channelId; encodedFrame.frameId = frameId; @@ -177,8 +171,8 @@ void StreamPullerThread(const std::string filePath, const uint32_t width, const // 线程2:用于下发解码指令 void VdecThread(VideoDecoder& videoDecoder) { - while (true) { - if (g_sendSignial || (g_readVideoEnded && g_pullerToVdecQueue.GetSize() ==0)) { + while (!g_sendSignial) { + if (g_readVideoEnded && g_pullerToVdecQueue.GetSize() ==0) { break; } // 获取待解码的视频帧数据 @@ -227,8 +221,8 @@ APP_ERROR VdecCallBack(MxBase::Image &decodedImage, uint32_t channelId, uint32_t // 线程4:用于下发编码指令 void VencThread(VideoEncoder& videoEncoder) { - while(true) { - if (g_sendSignial || (g_vdecEnded && g_vdecToVencQueue.GetSize() ==0)) { + while (!g_sendSignial) { + if (g_vdecEnded && g_vdecToVencQueue.GetSize() ==0) { break; } // 获取解码后的视频帧 @@ -291,8 +285,8 @@ void SaveFrameThread(StreamFormat streamFormat) bool mbFoundFirstIDR = false; bool bIsIDR = false; - while (true) { - if (g_sendSignial || (g_vencEnded && g_vencToFileSaveQueue.GetSize() == 0)) { + while (!g_sendSignial) { + if (g_vencEnded && g_vencToFileSaveQueue.GetSize() == 0) { break; } // 获取编码后的视频帧 @@ -337,12 +331,12 @@ int main(int argc, char *argv[]) { // 设置输入视频路径和该视频宽、高 std::string filePath = ${filePath}; - int width = ${width} - int height = ${height} + int width = ${width}; + int height = ${height}; // 设置解码器主要配置项,根据配置项初始化解码器 VideoDecodeConfig vDecodeConfig; - vDecodeConfig.width = ${width}; // 指定视频宽 - vDecodeConfig.height = ${height}; // 指定视频高 + vDecodeConfig.width = width; // 指定视频宽 + vDecodeConfig.height = height; // 指定视频高 vDecodeConfig.inputVideoFormat = StreamFormat::H264_MAIN_LEVEL; // 指定待解码的输入视频格式 vDecodeConfig.outputImageFormat = ImageFormat::YUV_SP_420; // 指定解码后的输出图片格式 vDecodeConfig.callbackFunc = VdecCallBack; // 指定解码后、用于取解码结果的回调函数 -- Gitee From 5e75070930a5c73c8b487840c6fb5da810ed6a4d Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:14:30 +0000 Subject: [PATCH 19/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md index 51a7d85e5..0bec64ba4 100644 --- a/tutorials/VideoEncoder&VideoDecoder/README.md +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -59,17 +59,17 @@ export LD_LIBRARY_PATH=${ffmpeg-lib-path}:$LD_LIBRARY_PATH **步骤3:修改main.cpp文件,指定VideoDecoder和VideoEncoder的基本初始化参数** -第**338**行到第**360**行展示了VideoDecoder和VideoEncoder的主要配置项,用户可以结合mxVision官方文档根据需要调整。本样例中仅指定必要配置项,如下所示: +第**332**行到第**354**行展示了VideoDecoder和VideoEncoder的主要配置项,用户可以结合mxVision官方文档根据需要调整。本样例中仅指定必要配置项,如下所示: -第**339**行 `"std::string filePath = ${filePath}"`中的${filePath}替换为步骤2中视频文件实际的路径。 +第**333**行 `"std::string filePath = ${filePath}"`中的${filePath}替换为步骤2中视频文件实际的路径。 -第**340**行 `"int width = ${width}"`中的${width}替换为步骤2中视频帧实际的宽。 +第**334**行 `"int width = ${width}"`中的${width}替换为步骤2中视频帧实际的宽。 -第**341**行 `"int height = ${height}"`中的${height}替换为步骤2中视频帧实际的高。 +第**335**行 `"int height = ${height}"`中的${height}替换为步骤2中视频帧实际的高。 -第**356**行 `"vEncodeConfig.srcRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 +第**350**行 `"vEncodeConfig.srcRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 -第**358**行 `"vEncodeConfig.displayRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 +第**352**行 `"vEncodeConfig.displayRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 **步骤4:编译** @@ -127,5 +127,3 @@ python3 main.py 保存后的视频文件(命令为output.264)会在同级目录下,打开该文件即可查看编码结果。 - - -- Gitee From 3017eacfe80931e1cbb3e3ca31ce1f2372905998 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:17:55 +0000 Subject: [PATCH 20/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md index 0bec64ba4..9c76711a8 100644 --- a/tutorials/VideoEncoder&VideoDecoder/README.md +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -67,9 +67,9 @@ export LD_LIBRARY_PATH=${ffmpeg-lib-path}:$LD_LIBRARY_PATH 第**335**行 `"int height = ${height}"`中的${height}替换为步骤2中视频帧实际的高。 -第**350**行 `"vEncodeConfig.srcRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 +第**350**行 `"vEncodeConfig.srcRate = ${fps}"`中的${fps}替换为步骤2中视频实际的帧率。 -第**352**行 `"vEncodeConfig.displayRate = ${fps}"`中的${fps}替换为步骤2中视频帧实际的帧率。 +第**352**行 `"vEncodeConfig.displayRate = ${fps}"`中的${fps}替换为步骤2中视频实际的帧率。 **步骤4:编译** @@ -110,9 +110,9 @@ bash build.sh 第**152**行 `"height = ${height}"`中的${height}替换为步骤1中视频帧实际的高。 -第**170**行 `"venc_conf.srcRate = ${fps}"`中的${fps}替换为步骤1中视频帧实际的帧率。 +第**170**行 `"venc_conf.srcRate = ${fps}"`中的${fps}替换为步骤1中视频实际的帧率。 -第**172**行 `"venc_conf.srcRate = ${fps}"`中的${fps}替换为步骤1中视频帧实际的帧率。 +第**172**行 `"venc_conf.srcRate = ${fps}"`中的${fps}替换为步骤1中视频实际的帧率。 @@ -126,4 +126,3 @@ python3 main.py **步骤4:查看结果** 保存后的视频文件(命令为output.264)会在同级目录下,打开该文件即可查看编码结果。 - -- Gitee From 2bd89a632012e04c31fea9dff2c77d6f2d72bc62 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:25:21 +0000 Subject: [PATCH 21/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md index 9c76711a8..9ac71e8f3 100644 --- a/tutorials/VideoEncoder&VideoDecoder/README.md +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -115,7 +115,6 @@ bash build.sh 第**172**行 `"venc_conf.srcRate = ${fps}"`中的${fps}替换为步骤1中视频实际的帧率。 - **步骤3:运行** 进入项目根目录的Python目录下,执行以下命令: @@ -126,3 +125,6 @@ python3 main.py **步骤4:查看结果** 保存后的视频文件(命令为output.264)会在同级目录下,打开该文件即可查看编码结果。 + +_注意:为提高Python示例代码易读性,main.py线程模型与C++代码保持一致。实际业务中,为提高性能,Python的线程模型可以适度精简。_ + -- Gitee From f221bbbba5ac190149bab69f8d66e641ada3b2bc Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:26:18 +0000 Subject: [PATCH 22/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md index 9ac71e8f3..054982ac2 100644 --- a/tutorials/VideoEncoder&VideoDecoder/README.md +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -126,5 +126,4 @@ python3 main.py 保存后的视频文件(命令为output.264)会在同级目录下,打开该文件即可查看编码结果。 -_注意:为提高Python示例代码易读性,main.py线程模型与C++代码保持一致。实际业务中,为提高性能,Python的线程模型可以适度精简。_ - +_注意:为提高Python示例代码易读性,Python示例代码的线程模型与C++示例代码保持一致。实际业务中,为提高性能,Python代码的线程模型可以适度精简。_ -- Gitee From e31ec9d07c37b34fd47e8846a9c293d301c5f34f Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:27:19 +0000 Subject: [PATCH 23/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md index 054982ac2..2847540ea 100644 --- a/tutorials/VideoEncoder&VideoDecoder/README.md +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -126,4 +126,5 @@ python3 main.py 保存后的视频文件(命令为output.264)会在同级目录下,打开该文件即可查看编码结果。 -_注意:为提高Python示例代码易读性,Python示例代码的线程模型与C++示例代码保持一致。实际业务中,为提高性能,Python代码的线程模型可以适度精简。_ +_注意:为提高Python示例代码易读性,Python示例代码的线程模型与C++示例代码保持一致。在实际业务中,为提高性能,Python代码的线程模型可以适度精简。_ + -- Gitee From be1a5546830ab1ee1784410ca5e004337a49d435 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:27:58 +0000 Subject: [PATCH 24/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md index 2847540ea..aaa132b6f 100644 --- a/tutorials/VideoEncoder&VideoDecoder/README.md +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -126,5 +126,5 @@ python3 main.py 保存后的视频文件(命令为output.264)会在同级目录下,打开该文件即可查看编码结果。 -_注意:为提高Python示例代码易读性,Python示例代码的线程模型与C++示例代码保持一致。在实际业务中,为提高性能,Python代码的线程模型可以适度精简。_ +_注意:为提高Python示例代码易读性,Python示例代码的线程模型与C++示例代码保持一致。在实际业务中,为提高性能,Python代码的线程模型应适度精简。_ -- Gitee From 939f488f7c72b7bdba3717e856dc9d403f634d23 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:36:38 +0000 Subject: [PATCH 25/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9main.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/Python/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/Python/main.py b/tutorials/VideoEncoder&VideoDecoder/Python/main.py index 03c0b3372..b88bf0753 100644 --- a/tutorials/VideoEncoder&VideoDecoder/Python/main.py +++ b/tutorials/VideoEncoder&VideoDecoder/Python/main.py @@ -147,7 +147,7 @@ def save_frame_thread(stream_format): def start_service(): # 设置输入视频路径和该视频宽、高 - file_path = ${file_path} + file_path = "${file_path}" width = ${width} height = ${height} -- Gitee From 63cb405ca2500bc1609f5b0e329b42f7567ea866 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:40:52 +0000 Subject: [PATCH 26/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9main.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/C++/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp b/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp index f0f63438e..c6a5d947c 100644 --- a/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp +++ b/tutorials/VideoEncoder&VideoDecoder/C++/main.cpp @@ -330,7 +330,7 @@ int main(int argc, char *argv[]) } { // 设置输入视频路径和该视频宽、高 - std::string filePath = ${filePath}; + std::string filePath = "${filePath}"; int width = ${width}; int height = ${height}; // 设置解码器主要配置项,根据配置项初始化解码器 -- Gitee From effa42587b127f1bc0e6e1d385531416a6f8eafd Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:41:47 +0000 Subject: [PATCH 27/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/README.md b/tutorials/VideoEncoder&VideoDecoder/README.md index aaa132b6f..099673e41 100644 --- a/tutorials/VideoEncoder&VideoDecoder/README.md +++ b/tutorials/VideoEncoder&VideoDecoder/README.md @@ -61,7 +61,7 @@ export LD_LIBRARY_PATH=${ffmpeg-lib-path}:$LD_LIBRARY_PATH 第**332**行到第**354**行展示了VideoDecoder和VideoEncoder的主要配置项,用户可以结合mxVision官方文档根据需要调整。本样例中仅指定必要配置项,如下所示: -第**333**行 `"std::string filePath = ${filePath}"`中的${filePath}替换为步骤2中视频文件实际的路径。 +第**333**行 `"std::string filePath = "${filePath}"`中的${filePath}替换为步骤2中视频文件实际的路径。 第**334**行 `"int width = ${width}"`中的${width}替换为步骤2中视频帧实际的宽。 @@ -104,7 +104,7 @@ bash build.sh 第**149**行到第**175**行展示了VideoDecoder和VideoEncoder的主要配置项,用户可以结合mxVision官方文档根据需要调整。本样例中仅指定必要配置项,如下所示: -第**150**行 `"file_path = ${file_path}"`中的${file_path}替换为步骤1中视频文件实际的路径。 +第**150**行 `"file_path = "${file_path}”"`中的${file_path}替换为步骤1中视频文件实际的路径。 第**151**行 `"width = ${width}"`中的${width}替换为步骤1中视频帧实际的宽。 -- Gitee From 5c78f71bff753dc9cf1a16a364161cb9d05dde2e Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:43:29 +0000 Subject: [PATCH 28/30] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/C++/build.sh | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tutorials/VideoEncoder&VideoDecoder/C++/build.sh diff --git a/tutorials/VideoEncoder&VideoDecoder/C++/build.sh b/tutorials/VideoEncoder&VideoDecoder/C++/build.sh new file mode 100644 index 000000000..12772b39b --- /dev/null +++ b/tutorials/VideoEncoder&VideoDecoder/C++/build.sh @@ -0,0 +1,8 @@ +# 删除build文件夹如果存在 +rm -rf build +# 创建build文件夹并进入 +mkdir build +cd build +# 执行编译 +cmake .. +make \ No newline at end of file -- Gitee From 08e9cbb047a303f6864b3f235fc7aabb5610ed57 Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 08:46:58 +0000 Subject: [PATCH 29/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9CmakeLists?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/C++/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tutorials/VideoEncoder&VideoDecoder/C++/CMakeLists.txt b/tutorials/VideoEncoder&VideoDecoder/C++/CMakeLists.txt index 36eb9b9bf..cc678669c 100644 --- a/tutorials/VideoEncoder&VideoDecoder/C++/CMakeLists.txt +++ b/tutorials/VideoEncoder&VideoDecoder/C++/CMakeLists.txt @@ -13,6 +13,7 @@ set(MX_SDK_HOME $ENV{MX_SDK_HOME}) set(FFMPEG_PATH $ENV{FFMPEG_PATH}) set(ASCEND_HOME_PATH $ENV{ASCEND_TOOLKIT_HOME}) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--copy-dt-needed-entries") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/") # Add compile options add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) -- Gitee From e5a50cc8041afbb2fff9e0b1d489681546bb6eda Mon Sep 17 00:00:00 2001 From: hid54630209 Date: Fri, 20 Dec 2024 09:01:28 +0000 Subject: [PATCH 30/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hid54630209 --- tutorials/VideoEncoder&VideoDecoder/C++/build.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tutorials/VideoEncoder&VideoDecoder/C++/build.sh b/tutorials/VideoEncoder&VideoDecoder/C++/build.sh index 12772b39b..5a1e1947c 100644 --- a/tutorials/VideoEncoder&VideoDecoder/C++/build.sh +++ b/tutorials/VideoEncoder&VideoDecoder/C++/build.sh @@ -1,8 +1,15 @@ -# 删除build文件夹如果存在 -rm -rf build -# 创建build文件夹并进入 +#!/bin/bash +# 定义要检查的目录名 +dir_name="build" + +# 检查目录是否存在 +if [ -d "$dir_name" ]; then + # 删除目录及其内容 + rm -rf "$dir_name" +fi + mkdir build cd build # 执行编译 cmake .. -make \ No newline at end of file +make -- Gitee