diff --git a/mxVision/Ascendffmpeg/README.md b/mxVision/Ascendffmpeg/README.md index e66d16730cfc4c2ae2e1f132d94f9f61c33ddc65..68204236c8f16361e47666094976c3e96f2ea4e2 100644 --- a/mxVision/Ascendffmpeg/README.md +++ b/mxVision/Ascendffmpeg/README.md @@ -1,28 +1,14 @@ -# FFmpeg-Ascend +# 基于Ascend的Ffmpeg流媒体框架 -## 介绍 +## 1 介绍 -MxVison ascend 硬件平台内置了视频相关的硬件加速解码器, -为了用户的易用性,MxVision 提供了 FFmepg-Ascend 解决方案。 +### 1.1 简介 -该样例的处理流程为: +mxVison ascend 硬件平台内置了视频相关的硬件加速解码器, +为了提升用户的易用性,mxVision提供了 FFmepg-Ascend 解决方案。 -``` -准备芯片及环境 > 安装 CANN 版本包 > 拉取 FFmpeg-Ascend 代码 > 编译 > 执行 -``` - -## 支持的产品 -Atlas 300I Pro, Atlas 300V Pro和Atlas A500 A2 - -### 支持的版本 -本样例配套的MxVision版本、CANN版本、Driver/Firmware版本如下所示: +支持的功能: -| MxVision版本 | CANN版本 | Driver/Firmware版本 | -| --------- | ------------------ | -------------- | -| 5.0.0 | 7.0.0 | 23.0.0 | -| 6.0.RC2 | 8.0.RC2 | 24.1.RC2 | - -## 支持的功能 |功能|mpeg4|h264/h265|多路| |:----:|:----:|:----:|:----:| |硬件解码|√|√|√| @@ -30,79 +16,82 @@ Atlas 300I Pro, Atlas 300V Pro和Atlas A500 A2 |硬件转码|√|√|√| |硬件缩放|√|√|√| -## 安装 CANN 版本包 -[详情请参考CANN用户指南](https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/80RC3alpha001/softwareinst/instg/instg_0001.html) +### 1.2 支持的产品 + +本项目支持昇腾Atlas 300I pro、 Atlas 300V pro, 和Atlas A500 A2。 + +### 1.3 支持的版本 +本样例配套的CANN版本、Driver/Firmware版本如下所示: + +| CANN版本 | Driver/Firmware版本 | +| ------------------ | -------------- | +| 8.0.RC3 | 24.1.RC3 | -## FFmpeg-Ascend目录结构 +### 1.4 三方依赖 +无 -FFmpeg-Ascend 目录主要文件: -. -|-- configure (FFmpeg 编译入口) -| -|-- README.md (FFmpeg-Ascend 使用手册) -| -|-- ffbuild (编译相关文件) -| -|-- fftools (FFmpeg 相关命令行工具) -| -|-- libavcodec (FFmpeg 编解码器) -| -|-- libavutil (FFmpeg 相关工具,包含硬件加速相关流程) -## 依赖条件 -设置环境变量: +## 2 设置环境变量 * `ASCEND_HOME` Ascend 安装的路径,一般为 `/usr/local/Ascend` -* `FFMPEG_LIB_PATH` FFmpeg 编译安装的 lib 文件路径(一般为 FFmpeg 安装目录下的 lib 目录, 由安装时的 --prefix 编译选项来指定)。 -* `LD_LIBRARY_PATH` 指定 ffmpeg 程序运行时依赖的动态库查找路径。 +* 执行命令 + ```bash + export ASCEND_HOME=/usr/local/Ascend + . /usr/local/Ascend/ascend-toolkit/set_env.sh #toolkit默认安装路径,根据实际安装路径修改 + ``` -```bash -export ASCEND_HOME=/usr/local/Ascend -export LD_LIBRARY_PATH=${FFMPEG_LIB_PATH}:${ASCEND_HOME}/ascend-toolkit/latest/acllib/lib64:$LD_LIBRARY_PATH -``` -## 编译 +## 3 编译与运行 -编写编译脚本 +**步骤1:** 在项目目录`Ascendffmpeg/`下添加可执行权限 ```bash -vi run.sh +chmod +x ./configure +chmod +x ./ffbuild/*.sh ``` -`run.sh` 内编译选项: -* `prefix` : FFmpeg 及相关组件安装目录 -* `enable-shared` : FFmpeg 允许生成 so 文件 -* `extra-cflags` : 添加第三方头文件 -* `extra-libs` : 添加第三方 so 文件 -* `enable-ascend` : 允许使用 ascend 进行硬件加速 -```bash -./configure \ - --prefix=./ascend \ - --enable-shared \ - --extra-cflags="-I${ASCEND_HOME}/ascend-toolkit/latest/acllib/include" \ - --extra-libs="-lacl_dvpp_mpi -lascendcl" \ - --enable-ascend \ - && make -j && make install -``` -脚本添加可执行权限 -```bash -chmod +x run.sh -``` -运行脚本 -```bash -./run.sh -``` -注意:若是运行失败,则可能是 `./configure` 没有可执行权限 +**步骤2:** 在项目目录`Ascendffmpeg/`下执行编译 +* 编译选项说明 + ```text + prefix : FFmpeg 及相关组件安装目录 + enable-shared : FFmpeg 允许生成 so 文件 + extra-cflags : 添加第三方头文件 + extra-ldflags : 指定第三方库位置 + extra-libs : 添加第三方 so 文件 + enable-ascend : 允许使用 ascend 进行硬件加速 + ``` +执行编译命令: + ```bash + ./configure \ + --prefix=./ascend \ + --enable-shared \ + --extra-cflags="-I${ASCEND_HOME}/ascend-toolkit/latest/acllib/include" \ + --extra-ldflags="-L${ASCEND_HOME}/ascend-toolkit/latest/acllib/lib64" \ + --extra-libs="-lacl_dvpp_mpi -lascendcl" \ + --enable-ascend \ + && make -j && make install + ``` + +**步骤3:** 添加环境变量 + +通过指令 +`find / -name libavdevice.so` +查找到文件所在路径, + +形如`/PATH/TO/mindxsdk-referenceapps/mxVision/Ascendffmpeg/ascend/lib/libavdevice.so`, + +则执行: ```bash -chmod +x ./configure -chmod +x ./ffbuild/*.sh +export LD_LIBRARY_PATH=/PATH/TO/mindxsdk-referenceapps/mxVision/Ascendffmpeg/ascend/lib:$LD_LIBRARY_PATH ``` -## 运行 -当前目录或者 FFmpeg 安装目录下均会生成 `ffmpeg` 可执行文件,均可以使用。 +**步骤4:** 运行 + +在项目目录`Ascendffmpeg/`下会生成 `ffmpeg` 可执行文件,可以参考下面的说明使用。 + 相关指令参数: * `-hwaccel` - 指定采用 ascend 来进行硬件加速, 用来做硬件相关初始化工作。 @@ -110,14 +99,14 @@ chmod +x ./ffbuild/*.sh 解码相关参数(注意:解码相关参数需要在 `-i` 参数前设置): * `-c:v` - 指定解码器为 h264_ascend (解码 h265 格式可以使用 h265_ascend)。 * `-device_id` - 指定硬件设备 id 为 0。取值范围取决于芯片个数,默认为 0。 `npu-smi info` 命令可以查看芯片个数 -* `-channel_id` - 指定解码通道 id ,默认为0,取值范围取决于芯片实际情况,超出时会报错(Atlas 推理系列产品(Ascend 310P处理器),该参数的取值范围:[0, 256),JPEGD功能和VDEC功能共用通道,且通道总数最多256。Atlas 500 A2推理产品,该参数的取值范围:[0, 128),JPEGD功能和VDEC功能共用通道,且通道总数最多128)。 若是指定的通道已被占用, 则自动寻找并申请新的通道。 -* `-resize` - 指定缩放大小, 输入格式为: {width}x{height}。宽高:[128x128-4096x4096], 宽高相乘不能超过 4096*2304(此为h264的约束)。宽要与 16 对齐,高要与 2 对齐。 +* `-channel_id` - 指定解码通道 id ,默认为0,取值范围取决于芯片实际情况,超出时会报错(对于昇腾Atlas 300I pro、 Atlas 300V pro,该参数的取值范围:[0, 256),JPEGD功能和VDEC功能共用通道,且通道总数最多256。对于Atlas 500 A2推理产品,该参数的取值范围:[0, 128),JPEGD功能和VDEC功能共用通道,且通道总数最多128)。 若是指定的通道已被占用, 则自动寻找并申请新的通道。 +* `-resize` - 指定缩放大小, 输入格式为: {width}x{height}。宽高:[128x128-4096x4096], 宽高相乘不能超过 4096*2304(此为h264的约束)。宽要与 16 对齐,高要与 2 对齐。 * `-i` - 指定输入文件(支持h264和h265及rtsp视频流, 其他视频格式不做保证)。 编码相关参数(注意:编码相关参数需要在 `-i` 参数后设置): * `-c:v` - 指定编码器为 h264_ascend (编码成 h265 格式可以使用 h265_ascend)。 * `-device_id` - 指定硬件设备 id 为 0。取值范围取决于芯片个数,默认为 0。 `npu-smi info` 命令可以查看芯片个数。 -* `-channel_id` - 指定解码通道 id ,默认为0,取值范围取决于芯片实际情况,超出时会报错(Atlas 推理系列产品(Ascend 310P处理器),该参数的取值范围:[0, 256),JPEGD功能和VDEC功能共用通道,且通道总数最多256。Atlas 500 A2推理产品,该参数的取值范围:[0, 128),JPEGD功能和VDEC功能共用通道,且通道总数最多128)。 若是指定的通道已被占用, 则自动寻找并申请新的通道。 +* `-channel_id` - 指定解码通道 id ,默认为0,取值范围取决于芯片实际情况,超出时会报错(对于昇腾Atlas 300I pro、 Atlas 300V pro,该参数的取值范围:[0, 256),JPEGD功能和VDEC功能共用通道,且通道总数最多256。Atlas 500 A2推理产品,该参数的取值范围:[0, 128),JPEGD功能和VDEC功能共用通道,且通道总数最多128)。 若是指定的通道已被占用, 则自动寻找并申请新的通道。 * `-profile` - 指定视频编码的画质级别(0: baseline, 1: main, 2: high, 默认为 1。 H265 编码器只支持 main)。 * `-rc_mode` - 指定视频编码器的速率控制模式(0: CBR, 1: VBR, 默认为 0)。 * `-gop` - 指定关键帧间隔, [1, 65536], 默认为 30。 @@ -125,15 +114,29 @@ chmod +x ./ffbuild/*.sh * `-max_bit_rate` - 限制码流的最大比特率, [2, 614400], 默认为 20000。 * `-movement_scene` - 指定视频场景(0:静态场景(监控视频等), 1:动态场景(直播,游戏等)), 默认为 1。 +**可参考的指令样例(test.264为h264视频):** ```bash +# 将输入文件 test.264 通过 Ascend 硬件解码与编码,最终输出为 out.264 ./ffmpeg -hwaccel ascend -c:v h264_ascend -i test.264 -c:v h264_ascend out.264 ``` ```bash +# 将输入文件 test.264 根据指定参数重新编码为H.264格式,输出文件为 out.264 ./ffmpeg -hwaccel ascend -c:v h264_ascend -device_id 0 -channel_id 0 -resize 1024x1000 -i test.264 -c:v h264_ascend -device_id 0 -channel_id 0 -profile 2 -rc_mode 0 -gop 30 -frame_rate 25 -max_bit_rate 20000 out.264 ``` ```bash +# 将输入文件 test.264 解码,并将解码后的原始视频帧输出为YUV格式的 out.yuv 文件 ./ffmpeg -hwaccel ascend -c:v h264_ascend -i test.264 out.yuv +# 将输入文件 out.yuv 编码为H.264格式,输出文件为 out.264 ./ffmpeg -hwaccel ascend -s 1920x1080 -pix_fmt nv12 -i out.yuv -c:v h264_ascend out.264 -``` \ No newline at end of file +``` + +## 4 常见问题 +### 4.1 文件编译问题 + +问题描述: 文件编译不通过 + +解决方案: 可能是文件格式被改变或者破坏,建议通过以下两种方式直接获取代码,而非文件传输: +1. 在环境上通过git clone直接下载该代码仓。 +2. 直接从代码仓网页gitee下载zip包,并在环境上通过`unzip`解压。 diff --git a/mxVision/Ascendffmpeg/fftools/ffmpeg.c b/mxVision/Ascendffmpeg/fftools/ffmpeg.c index 3396761c12b93b97c5801d7528fa1e496a691494..fe6ca19328b21ba5d1fc9dd8fd9227260b9368fa 100644 --- a/mxVision/Ascendffmpeg/fftools/ffmpeg.c +++ b/mxVision/Ascendffmpeg/fftools/ffmpeg.c @@ -32,7 +32,6 @@ #include #include #include -#include #if HAVE_IO_H #include @@ -652,6 +651,7 @@ static void ffmpeg_cleanup(int ret) av_log(NULL, AV_LOG_ERROR, "Error closing vstats file, loss of information possible: %s\n", av_err2str(AVERROR(errno))); + vstats_file = NULL; } av_freep(&vstats_filename); diff --git a/mxVision/Ascendffmpeg/fftools/ffmpeg_opt.c b/mxVision/Ascendffmpeg/fftools/ffmpeg_opt.c index c2386e4a38477c36f741f417ea410078b421d3a3..807e783422f8ff97ba33740ca61f5b4a9b8b3f8f 100644 --- a/mxVision/Ascendffmpeg/fftools/ffmpeg_opt.c +++ b/mxVision/Ascendffmpeg/fftools/ffmpeg_opt.c @@ -20,7 +20,6 @@ */ #include -#include #include "ffmpeg.h" #include "cmdutils.h" diff --git a/mxVision/Ascendffmpeg/libavutil/hwcontext_ascend.c b/mxVision/Ascendffmpeg/libavutil/hwcontext_ascend.c index bcd6b05980f1fd2858ff3c28a46e3cd83b55e503..fcde625e26ac31840e97a4524de16f51747fab20 100644 --- a/mxVision/Ascendffmpeg/libavutil/hwcontext_ascend.c +++ b/mxVision/Ascendffmpeg/libavutil/hwcontext_ascend.c @@ -285,10 +285,6 @@ static int ascend_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, const A static int ascend_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src) { - AVHWDeviceContext *device_ctx = ctx->device_ctx; - AVASCENDDeviceContext *hwctx = ctx->hwctx; - AscendContext *ascend_ctx = hwctx->ascend_ctx; - int i; size_t dstBytes; size_t srcBytes;