VENC视频编码【免费下载链接】docs该仓库用于维护cann公共文档项目地址: https://gitcode.com/cann/docs本节介绍VENC视频编码的接口调用流程同时配合示例代码辅助理解该接口调用流程。VENCVideo Encoder将YUV420SP格式的图片编码成H264/H265格式的视频码流。关于VENC功能的详细介绍及使用约束请参见《DVPP媒体加速库》。在实现VENC视频编码功能时可在创建通道时设置基本参数、或调用对应的set接口设置高级参数优化视频编码质量请参见优化视频编码质量。接口调用流程图 1VENC视频编码功能调用流程![](https://raw.gitcode.com/cann/docs/raw/a173bdbfa81bbfd36d1c4da672d78301fb678d36/docs/app-dev/zh/figures/VENC视频编码功能调用流程.png VENC视频编码功能调用流程?utm_sourcegitcode_repo_files)当前系统支持H264/H265格式的视频码流关键接口的说明如下资源初始化调用aclInit接口初始化系统。调用aclrtSetDevice接口指定计算设备。用hi_mpi_sys_init接口进行媒体数据处理系统初始化。调用hi_mpi_venc_create_chn函数创建通道。成功创建通道之后您可以根据实际需求设置编码的高级参数例如场景模式、码流控制器的高级参数等请参见hi_mpi_venc_set_jpeg_param~hi_mpi_venc_compact_jpeg_tables章节中的接口说明。调用hi_mpi_venc_get_fd将通道ID转换为一个文件句柄。**说明**Control CPU开放形态下为了兼容旧版本用户在等待编码完成时旧版本的应用程序中调用Linux操作系统的select或者poll函数的方式仍然可用。建议使用上图中的接口调用流程保证后续版本的演进。调用hi_mpi_sys_create_epoll函数创建DVPP epoll实例再调用hi_mpi_sys_ctl_epoll函数将编码通道的文件句柄添加到epoll实例中由epoll实例处理。select或者poll方式不需要执行该步骤。视频编码调用hi_mpi_venc_start_chn函数通知通道准备开始编码。调用hi_mpi_dvpp_malloc接口申请存放Device上输入数据的内存。启动一个用户态线程调用hi_mpi_sys_wait_epoll函数等待编码完成。之后用户就可以调用hi_mpi_venc_send_frame函数发送待编码的码流。一旦编码完成hi_mpi_sys_wait_epoll函数或select函数或poll函数就会返回用户就可以调用hi_mpi_venc_query_status接口查询编码状态再调用hi_mpi_venc_get_stream函数获取编码结果。用户需要注意的是编码结果数据使用完成之后需要及时调用hi_mpi_venc_release_stream函数释放buffer。否则会因编码buffer用完导致后续编码无法进行。调用hi_mpi_dvpp_free接口释放输入内存。当用户不需发送图像到目的通道继续编码时需要调用hi_mpi_venc_stop_chn函数通知该通道不再接收新的输入图片。资源释放调用hi_mpi_sys_ctl_epoll函数从epoll实例中删除编码通道的文件句柄。当用户完成所有编码之后需要调用hi_mpi_venc_destroy_chn释放编码通道以及内部内存资源。调用hi_mpi_sys_close_epoll函数销毁DVPP epoll实例。调用hi_mpi_sys_exit接口进行媒体数据处理系统去初始化。调用aclrtResetDevice接口复位设备释放Device上的资源。调用aclFinalize接口实现系统去初始化用于释放进程内acl接口使用的相关资源。优化视频编码质量在实现VENC视频编码功能时可在创建通道时设置基本参数、或调用对应的set接口设置高级参数优化视频编码质量以下调整手段可以叠加使用效果是叠加的例如H264视频数据获取场景分辨率720Pgop 60帧率30fps码率1M需要提升编码质量可以使用如下优化手段组合CBR模式、HI_VENC_SCENE_0、stats_time等于2、profile等于2、关闭宏块级码控。H265电影场景分辨率1080Pgop30帧率25fps码率2M需要提升编码质量可以使用如下优化手段组合CBR模式、HI_VENC_SCENE_1、stats_time等于1、关闭宏块级码控。当前支持以下方式优化视频编码质量设置基本参数优化视频编码质量不同分辨率的视频其编码质量与视频的帧率、GOPGroup of pictures、码率有关在调用hi_mpi_venc_create_chn接口创建通道时可设置编码的等级、设置H.264/H.265协议编码场景下CBR/VBR/AVBR/CVBR/QVBR模式的帧率、GOP、码率等参数来调整视频编码质量编码等级通过hi_venc_chn_attr.venc_attr结构内的profile参数来设置帧率通过hi_venc_chn_attr.rc_attr结构体内的src_frame_rate输入帧率参数、dst_frame_rate输出帧率参数来设置GOP通过hi_venc_chn_attr.rc_attr结构体内的gop参数来设置码率通过hi_venc_chn_attr.rc_attr结构体内的bit_rate或max_bit_rate或target_bit_rate参数来设置。表 1典型场景下帧率、GOP、码率的取值画质/分辨率帧率GOP码率Mbps4K38402160/4096216025或30建议GOP为帧率的整数倍例如帧率为25时GOP建议25或50。- 视频数据获取场景H264/H265码流码率取值8~12。- 秀场/主播/短视频场景H265码流码率取值6~12。H264码流不涉及。- 游戏视频场景H264/H265码流码率取值10~16。2K2560*144025或30建议GOP为帧率的整数倍例如帧率为25时GOP建议25或50。- 视频数据获取场景H264/H265码流码率取值6~10。- 秀场/主播/短视频场景H265码流码率取值4.8~8。H264码流不涉及。- 游戏视频场景H264/H265码流码率取值6~10。1080P蓝光1920*108025或30建议GOP为帧率的整数倍例如帧率为25时GOP建议25或50。- 视频数据获取场景H265码流码率取值1~4。H264码流码率取值2~6。- 秀场/主播/短视频场景H265码流码率取值1.4~3.6。H264码流码率取值2~4.8。- 游戏视频场景H264/H265码流码率取值3~6。720P高清1280*72025或30建议GOP为帧率的整数倍例如帧率为25时GOP建议25或50。- 视频数据获取场景H265码流码率取值0.8~2。H264码流码率取值1~3。- 秀场/主播/短视频场景H265码流码率取值1~2。H264码流码率取值1~3。- 游戏视频场景H264/H265码流码率取值2~4。480P/D1_N标清854480/72048025或30建议GOP为帧率的整数倍例如帧率为25时GOP建议25或50。- 视频数据获取场景H265码流码率取值0.3~0.7。H264码流码率取值0.6~1.4。- 秀场/主播/短视频场景H265码流码率取值0.25~0.6。H264码流码率取值0.3~0.7。- 游戏视频场景不涉及。576P/D1标清720*57625或30建议GOP为帧率的整数倍例如帧率为25时GOP建议25或50。- 视频数据获取场景H265码流码率取值0.3~0.7。H264码流码率取值0.6~1.4。- 秀场/主播/短视频场景H265码流码率取值0.25~0.6。H264码流码率取值0.3~0.7。- 游戏视频场景不涉及。270P流畅480*27025或30建议GOP为帧率的整数倍例如帧率为25时GOP建议25或50。- 视频数据获取场景不涉及。- 秀场/主播/短视频场景H265码流码率取值0.2。H264码流码率取值0.3。- 游戏视频场景不涉及。CIF P/N352288/32024025或30建议GOP为帧率的整数倍例如帧率为25时GOP建议25或50。- 视频数据获取场景H264/H265码流码率取值0.25。- 秀场/主播/短视频场景不涉及。- 游戏视频场景不涉及。设置高级参数调整视频编码细节您可以调用接口设置码控模式、宏块级码率控制参数、编码场景模式等来调整视频编码的细节进一步改善编码质量。表 2高级配置项列表配置项接口参数名说明码控模式hi_mpi_venc_create_chnhi_venc_chn_attr.rc_attr结构体内的rc_mode参数追求码率平稳或追求PSNR大且码率符合目标值配置为CBR追求节省码率对主观编码质量有一定要求配置为VBR追求节省码率对主观编码质量有一定要求且场景中有较多静止画面配置为AVBR追求PSNR且对码率上浮没有严格要求配置为QVBR追求节省码率对主观编码质量有一定要求且可以根据带宽、存储空间要求进行更多调整配置为CVBR码率控制模型统计时间hi_mpi_venc_create_chnhi_venc_chn_attr.rc_attr内各模式属性值结构体内的stats_time参数关注长期码率稳定短期波动不在意的可以设置大一些例DVR存盘。设大可以提高重编码判决的门槛重编码次数会减少但是码率波动会加大。宏块级码率控制参数hi_mpi_venc_set_rc_paramhi_venc_rc_param结构内的threshold_i、threshold_p、threshold_b、direction、row_qp_delta参数如果图像内容复杂、细节较多或用户关注PSNR等客观指标时需关闭宏块级码率控制。第一帧的起始Qp值hi_mpi_venc_create_chnhi_venc_rc_param结构内的first_frame_start_qp参数典型场景下用户配置的码率小于表1中给的参考值且编码后的视频第一帧明显模糊则建议配置first_frame_start_qp参数参数值取[min_i_qp, max_i_qp]的中间值例如,[min_i_qp, max_i_qp]为[30, 40]则first_frame_start_qp参数配置为35同时将max_reencode_times参数配置为0会获得较好的编码质量。编码场景模式hi_mpi_venc_set_scene_modehi_venc_scene_mode安防场景配置为HI_VENC_SCENE_0辅助驾驶、直播、游戏、动画、电影配置为HI_VENC_SCENE_1。示例代码以下是VENC视频编码功能关键步骤的代码示例不能直接拷贝编译运行仅供参考。调用接口后需增加异常处理的分支并记录报错日志、提示日志此处不一一列举。您可以单击venc_sample获取样例。// 1.初始化媒体数据处理系统 int32_t ret hi_mpi_sys_init(); // 2.创建通道 hi_venc_chn chn 0; hi_venc_chn_attr attr{}; attr.venc_attr.type HI_PT_H265; attr.venc_attr.profile 0; attr.venc_attr.max_pic_width 128; attr.venc_attr.max_pic_height 128; attr.venc_attr.pic_width 128; attr.venc_attr.pic_height 128; attr.venc_attr.buf_size 2 * 1024 * 1024; attr.venc_attr.is_by_frame HI_TRUE; attr.rc_attr.rc_mode HI_VENC_RC_MODE_H265_VBR; attr.rc_attr.h265_vbr.gop 30; attr.rc_attr.h265_vbr.stats_time 1; attr.rc_attr.h265_vbr.src_frame_rate 30; attr.rc_attr.h265_vbr.dst_frame_rate 30; attr.rc_attr.h265_vbr.max_bit_rate 4000; attr.gop_attr.gop_mode HI_VENC_GOP_MODE_NORMAL_P; attr.gop_attr.normal_p.ip_qp_delta 3; ret hi_mpi_venc_create_chn(chn, attr); // 3.通知编码器启动接收输入数据 hi_venc_start_param recv_param{}; recv_param.recv_pic_num -1; ret hi_mpi_venc_start_chn(chn, recv_param); // 4.发送输入数据 // 4.1 申请输入内存 uint8_t* inputAddr nullptr; int32_t inputSize 128 * 128 * 3 / 2; ret hi_mpi_dvpp_malloc(0, inputAddr, inputSize); // 将输入数据读入Device内存中该自定义函数VencReadYuvFile由用户实现 VencReadYuvFile(streamName, inputAddr, inputSize); // 4.2 发送输入数据开始编码 hi_video_frame_info frame{}; frame.mod_id HI_ID_VENC; frame.v_frame.width 128; frame.v_frame.height 128; frame.v_frame.field HI_VIDEO_FIELD_FRAME; frame.v_frame.pixel_format HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; frame.v_frame.video_format HI_VIDEO_FORMAT_LINEAR; frame.v_frame.compress_mode HI_COMPRESS_MODE_NONE; frame.v_frame.dynamic_range HI_DYNAMIC_RANGE_SDR8; frame.v_frame.color_gamut HI_COLOR_GAMUT_BT709; frame.v_frame.width_stride[0] 128; frame.v_frame.width_stride[1] 128; frame.v_frame.width_stride[2] 128; frame.v_frame.virt_addr[0] inputAddr; frame.v_frame.virt_addr[1] (hi_void *)((uintptr_t)frame.v_frame.virt_addr[0] 128 * 128); frame.v_frame.frame_flag 0; frame.v_frame.time_ref 0; frame.v_frame.pts 0; ret hi_mpi_venc_send_frame(chn, frame, 0); // 5.获取编码结果 // 5.1 创建EPOLL实例 int32_t epollFd 0; int32_t fd hi_mpi_venc_get_fd(chn); ret hi_mpi_sys_create_epoll(10, epollFd); hi_dvpp_epoll_event event; event.events HI_DVPP_EPOLL_IN; event.data (void*)(unsigned long)(fd); ret hi_mpi_sys_ctl_epoll(epollFd, HI_DVPP_EPOLL_CTL_ADD, fd, event); int32_t eventCount 0; // 编码完成前会超时阻塞在这里一旦完成才会往下执行 ret hi_mpi_sys_wait_epoll(epollFd, events, 3, 1000, eventCount); // 5.2 获取编码结果 hi_venc_chn_status stat; ret hi_mpi_venc_query_status(chn, stat); hi_venc_stream stream; stream.pack_cnt stat.cur_packs; stream.pack new hi_venc_pack[stream.pack_cnt]; ret hi_mpi_venc_get_stream(chn, stream, 1000); // 5.3 获取编码输出码流数据 // 可以直接使用编码输出码流数据在stream.pack[0].addr指向的内存中 // TODO: 推理相关的代码逻辑 // 6.释放输入内存和输出码流 ret hi_mpi_dvpp_free(inputAddr); ret hi_mpi_venc_release_stream(chn, stream); delete[] stream.pack; // 7.通知编码器停止接收输入数据 ret hi_mpi_venc_stop_chn(chn); ret hi_mpi_sys_ctl_epoll(epollFd, HI_DVPP_EPOLL_CTL_DEL, fd, NULL); ret hi_mpi_sys_close_epoll(epollFd); // 8.销毁通道 ret hi_mpi_venc_destroy_chn(chn); // 9.媒体数据处理系统去初始化 ret hi_mpi_sys_exit(); // ....【免费下载链接】docs该仓库用于维护cann公共文档项目地址: https://gitcode.com/cann/docs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考