跳到主要内容

视频数据获取+VPSS视频处理功能

VENC视频编码

VENC(Video Encoder)将YUV420SP格式的图片编码成H264/H265格式的视频码流。关于VENC功能的详细介绍及约束请参见功能及约束说明

本节介绍VENC视频编码的接口调用流程,同时配合示例代码辅助理解该接口调用流程。

接口调用流程

开发应用时,如果涉及视频编码,则应用程序中必须包含视频编码的代码逻辑,关于视频编码的接口调用流程,请先参见AscendCL接口调用流程了解整体流程,再查看本节中的流程说明

图1 视频编码流程

实现视频的编码,关键接口的说明如下:

  1. 调用aclvencCreateChannel接口创建视频编码处理的通道。
    • 创建视频编码处理通道前,需先执行以下操作:
      1. 调用aclvencCreateChannelDesc接口创建通道描述信息

      2. 调用aclvencSetChannelDescParam接口设置通道描述信息的属性,包括线程、回调函数、视频编码协议、输入图片格式等,其中:

        1. 回调函数需由用户提前创建,用于在视频编码后,获取编码数据,并及时释放相关资源,回调函数的原型请参见aclvencCallback

          视频编码结束后,建议用户在回调函数内及时释放输入图片内存、以及相应的图片描述信息。视频编码的输出内存由系统管理,不由用户管理,因此无需用户释放。

        2. 线程需由用户提前创建,并自定义线程函数,在线程函数内调用aclrtProcessReport接口,等待指定时间后,触发1.b.i中的回调函数。

        :::note 说明 推荐使用aclvencSetChannelDescParam接口设置通道描述信息的属性,通过枚举值来选择通过该接口设置某一个属性的值。

        但为兼容旧版本,也可以调用aclvencSetChannelDesc系列接口设置通道描述信息的属性,每个属性的设置对应一个set接口。 :::

    • aclvencCreateChannel接口内部封装了如下接口,无需用户单独调用:
      1. aclrtCreateStream接口:显式创建Stream,VENC内部使用。
      2. aclrtSubscribeReport接口:指定处理Stream上回调函数的线程,回调函数和线程是由用户调用aclvencSetChannelDescParam接口时指定的。
  2. 调用aclvencSendFrame接口将YUV420SP格式的图片编码成H264/H265格式的视频码流。
  3. 调用aclvencDestroyChannel接口销毁视频处理的通道。
    • 系统会等待已发送帧编码完成且用户的回调函数处理完成后再销毁通道。
    • aclvencDestroyChannel接口内部封装了如下接口,无需用户单独调用:
    • 销毁通道后,需调用aclvencDestroyChannelDesc接口销毁通道描述信息。
    • 销毁通道描述信息后,用户才可以销毁1.b.ii中创建的线程。

示例代码

您可以从样例介绍中获取完整样例代码。

调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考。

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br> 10<br> 11<br> 12<br> 13<br> 14<br> 15<br> 16<br> 17<br> 18<br> 19<br> 20<br> 21<br> 22<br> 23<br> 24<br> 25<br> 26<br> 27<br> 28<br> 29<br> 30<br> 31<br> 32<br> 33<br> 34<br> 35<br> 36<br> 37<br> 38<br> 39<br> 40<br> 41<br> 42<br> 43<br> 44<br> 45<br> 46<br> 47<br> 48<br> 49<br> 50<br> 51<br> 52<br> 53<br> 54<br> 55<br> 56<br> 57<br> 58<br> 59<br> 60<br> 61<br> 62<br> 63<br> 64<br> 65<br> 66<br> 67<br> 68<br> 69<br> 70<br> 71<br> 72<br> 73<br> 74<br> 75<br> 76<br> 77<br> 78<br> 79<br> 80<br> 81<br> 82<br> 83<br> 84<br> 85<br> 86<br> 87<br> 88<br> 89<br> 90<br> 91<br> 92<br> 93<br> 94<br> 95<br> 96<br> 97<br> 98<br> 99<br>100<br>101<br>102<br>103<br>104<br>105<br>106<br>107<br>108<br>109<br>110<br>111<br>112<br>113<br>114<br>115<br>116<br>117<br>118<br>119<br>120<br>121<br>122<br>123<br>124<br>125<br><br>// 1.AscendCL初始化<br>aclRet = aclInit(nullptr);<br>// 2.运行管理资源申请(依次申请Device、Context、Stream)<br>aclrtContext context_;<br>aclrtStream stream_;<br>aclrtSetDevice(0);<br>aclrtCreateContext(&context_, 0);<br>aclrtCreateStream(&stream_);<br>// 3.创建执行回调函数的线程及线程函数<br>static bool runFlag = true;<br>void *ThreadFunc(void *arg)<br>&#123;<br> // Notice: create context for this thread<br> int deviceId = 0;<br> aclrtContext context = nullptr;<br> aclError ret = aclrtCreateContext(&context, deviceId);<br> INFO_LOG("process callback thread start ");<br> while (runFlag) &#123;<br> // Notice: timeout 1000ms<br> (void)aclrtProcessReport(1000);<br> &#125;<br> // ......<br> ret = aclrtDestroyContext(context);<br> return (void*)0;<br>&#125;<br>int createThreadErr = pthread_create(&threadId_, nullptr, ThreadFunc, nullptr);<br>// 4.创建回调函数<br>void callback(acldvppPicDesc *input, acldvppStreamDesc *outputStreamDesc, void *userdata)<br>&#123;<br> // 获取视频编码结果数据,并写入文件<br> void *outputDev = acldvppGetStreamDescData(outputStreamDesc);<br> uint32_t streamDescSize = acldvppGetStreamDescSize(outputStreamDesc);<br> if (!Utils::WriteToFile(g_outFileFp, outputDev, streamDescSize)) &#123;<br> ERROR_LOG("write file:%s failed.", g_outFile.c_str());<br> &#125;<br> INFO_LOG("success to callback, stream size:%u", streamDescSize);<br>&#125;<br>// 5.创建视频编码处理通道时的通道描述信息,设置通道描述信息的属性,其中线程、callback回调函数需要用户提前创建<br>// vencChannelDesc_是aclvdecChannelDesc类型<br>vencChannelDesc_ = aclvencCreateChannelDesc();<br>auto ret = aclvencSetChannelDescThreadId(vencChannelDesc_, threadId_);<br>ret = aclvencSetChannelDescCallback(vencChannelDesc_, callback);<br>ret = aclvencSetChannelDescEnType(vencChannelDesc_, enType_);<br>ret = aclvencSetChannelDescPicFormat(vencChannelDesc_, format_);<br>ret = aclvencSetChannelDescPicWidth(vencChannelDesc_, 128);<br>ret = aclvencSetChannelDescPicHeight(vencChannelDesc_, 128);<br>ret = aclvencSetChannelDescKeyFrameInterval(vencChannelDesc_, 16);<br>// 6.创建视频码流处理的通道、单帧编码配置数据<br>ret = aclvencCreateChannel(vencChannelDesc_);<br>// vencFrameConfig_是aclvencFrameConfig类型<br>vencFrameConfig_ = aclvencCreateFrameConfig();<br>// 7.申请Device内存dataDev,存放视频编码的输入数据<br>// 7.1 读入图片数据<br>const char *fileName = "../dvpp_venc_128x128_nv12.yuv";<br>FILE *fp = fopen(fileName, "rb+");<br>fseek(fp, 0, SEEK_END);<br>long fileLenLong = ftell(fp);<br>fseek(fp, 0, SEEK_SET);<br>auto fileLen = static_cast<uint32_t>(fileLenLong);<br>uint32_t dataSize = fileLen;<br>// 调用aclrtGetRunMode接口获取软件栈的运行模式,如果调用aclrtGetRunMode接口获取软件栈的运行模式为ACL_HOST,则需要通过aclrtMemcpy接口将输入图片数据传输到Device,数据传输完成后,需及时释放内存;否则直接申请并使用Device的内存<br>aclrtRunMode runMode;<br>ret = aclrtGetRunMode(&runMode);<br>if(runMode == ACL_HOST) &#123; <br> void *dataHost = malloc(fileLen);<br> size_t readSize = fread(dataHost, 1, fileLen, fp)<br> void *dataDev = nullptr;<br> ret = acldvppMalloc(&dataDev, dataSize);<br> ret = aclrtMemcpy(dataDev, dataSize, dataHost, fileLen, ACL_MEMCPY_HOST_TO_DEVICE);<br> // 完成数据传输后,需及时释放内存<br> free(dataHost);<br>&#125; <br>else &#123; <br> ret = acldvppMalloc(&dataDev, dataSize);<br>&#125;<br>// 8.执行视频编码<br>size_t g_vencCnt = 16;<br>// 8.1 创建输入图片描述信息,设置输入图片数据的内存地址和内存大小<br>inputPicputDesc_ = acldvppCreatePicDesc();<br>ret = acldvppSetPicDescData(inputPicputDesc_, dataDev);<br>ret = acldvppSetPicDescSize(inputPicputDesc_, dataSize);<br>// 8.2 设置单帧编码配置数据,不是结束帧<br>ret = aclvencSetFrameConfigEos(vencFrameConfig_, 0);<br>ret = aclvencSetFrameConfigForceIFrame(vencFrameConfig_, 0)<br>// 8.3 创建输出码流描述信息<br>acldvppStreamDesc *outputStreamDesc = nullptr;<br>// 8.4 执行视频编码<br>while (g_vencCnt > 0) &#123;<br> ret = aclvencSendFrame(vencChannelDesc_, inputPicputDesc_,<br> static_cast<void *>(outputStreamDesc), vencFrameConfig_, nullptr);<br> g_vencCnt--;<br> &#125;<br>// 8.5 设置单帧编码配置数据,是结束帧<br>ret = aclvencSetFrameConfigEos(vencFrameConfig_, 1);<br>ret = aclvencSetFrameConfigForceIFrame(vencFrameConfig_, 0)<br>// 8.6 执行最后一帧的视频编码<br>ret = aclvencSendFrame(vencChannelDesc_, nullptr, nullptr, vencFrameConfig_, nullptr);<br>// 9.释放资源<br>(void)aclvencDestroyChannel(vencChannelDesc_);<br>(void)aclvencDestroyChannelDesc(vencChannelDesc_);<br>(void)acldvppDestroyPicDesc(inputPicputDesc_);<br>(void)aclvencDestroyFrameConfig(vencFrameConfig_);<br>// 释放内存和销毁线程<br>(void)acldvppFree(inBufferDev_);<br>void *res = nullptr;<br>int joinThreadErr = pthread_join(threadId_, &res);<br>// 10. 释放运行管理资源(依次释放Stream、Context、Device)<br>aclrtDestroyStream(stream_);<br>aclrtDestroyContext(context_);<br>aclrtResetDevice(0);<br>// 11.AscendCL去初始化<br>aclRet = aclFinalize();<br>// ......<br>

如果调用aclvencSetChannelDescParam接口设置通道描述信息的属性,调用aclvencGetChannelDescParam接口获取通道描述信息中的属性值,示例代码如下:

// 设置回调函数
void *func = (void *)callback;
aclvencSetChannelDescParam(vencChannelDesc_, ACL_VENC_CALLBACK_PTR, 8, &func);
// 获取回调函数
void *func1 = nullptr;
aclvencGetChannelDescParam(vencChannelDesc_, ACL_VENC_CALLBACK_PTR, 8, &len, &func1);

// 设置输入图片格式
acldvppPixelFormat format = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
aclvencSetChannelDescParam(vencChannelDesc_, ACL_VENC_PIXEL_FORMAT_UINT32, 4, &format);
// 获取输入图片格式
acldvppPixelFormat format1 = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
aclvencGetChannelDescParam(vencChannelDesc_, ACL_VENC_PIXEL_FORMAT_UINT32, 4, &len, &format1);

// 设置图片宽度
uint32_t width = 128;
aclvencSetChannelDescParam(vencChannelDesc_, ACL_VENC_PIC_WIDTH_UINT32, 4, &width);
// 获取图片高度
uint32_t width1 = 0;
aclvencGetChannelDescParam(vencChannelDesc_, ACL_VENC_PIC_WIDTH_UINT32, 4, &len, &width1);

// 设置图片高度
uint32_t height = 128;
aclvencSetChannelDescParam(vencChannelDesc_, ACL_VENC_PIC_HEIGHT_UINT32, 4, &height);
// 获取图片高度
uint32_t height1 = 0;
aclvencGetChannelDescParam(vencChannelDesc_, ACL_VENC_PIC_HEIGHT_UINT32, 4, &len, &height1);

// 设置编码输出缓存地址
ret = acldvppMalloc(&buf, bufSize);
aclvencSetChannelDescParam(vencChannelDesc_, ACL_VENC_BUF_ADDR_PTR, 8, &buf);
// 获取编码输出缓存地址
void *buf1 = nullptr;
aclvencGetChannelDescParam(vencChannelDesc_, ACL_VENC_BUF_ADDR_PTR, 8, &len, &buf1);

父主题: 媒体数据处理V1

功能支持度说明

昇腾AI处理器对媒体数据处理V2版本各功能的支持度如下表所示。

昇腾AI处理器VPCJPEGDJPEGEPNGDVDECVENC视频数据获取VPSS视频处理音频功能(录音/播音/音量调节)视频数据展示区域管理
Atlas 200/500 A2推理产品

父主题: 媒体数据处理V2

视频数据获取功能

当前需通过以下功能模块的配合实现视频数据获取功能:

  • ISP系统控制

    系统控制部分用于注册3A算法、注册Sensor驱动、初始化ISP firmware、运行ISP firmware、退出ISP firmware、配置ISP属性等功能。

  • MIPI Rx ioctl命令字

    MIPI Rx是一个支持多种差分视频输入接口的采集单元,通过combo-PHY接收MIPI/LVDS/sub-LVDS/HiSPi接口的数据,通过不同的功能模式配置,MIPI Rx可以支持多种速度和分辨率的数据传输需求,支持多种外部输入设备。

  • VI(Vedio Input)

    VI模块捕获视频图像,可对其做裁剪、防抖、颜色优化、亮度优化、噪声去除等处理,并输出YUV或RAW格式的图像数据。

总体接口调用流程

接口调用流程说明如下:

  1. 调用hi_mpi_sys_init接口初始化媒体数据处理系统。
  2. 使用MIPI Rx ioctl命令字初始化MIPI/Sensor硬件对接信息,接口调用流程请参见初始化MIPI/SENSOR硬件对接信息
  3. 使用VI(Vedio Input)功能接口初始化VI模块,接口调用流程请参见初始化VI视频输入模块
  4. 使用ISP(Image Signal Processing)系统控制接口初始化并运行ISP模块,接口调用流程请参见初始化并运行ISP图像信号处理模块
  5. 使用VI功能接口获取已处理的图像数据,接口调用流程请参见获取已处理的图像数据
  6. 使用ISP功能接口释放ISP模块资源,接口调用流程请参见释放ISP图像信号处理模块资源
  7. 使用VI功能接口释放VI模块资源,接口调用流程请参见释放VI视频输入模块资源
  8. 使用MIPI Rx ioctl命令字退出MIPI/Sensor硬件,接口调用流程请参见退出MIPI/SENSOR硬件
  9. 调用hi_mpi_sys_exit接口释放媒体数据处理系统资源。

初始化MIPI/SENSOR硬件对接信息

  1. 使用HI_MIPI_SET_HS_MODE命令字设置模式。
  2. 使用HI_MIPI_ENABLE_MIPI_CLOCK命令字打开MIPI时钟。
  3. 使用HI_MIPI_RESET_MIPI命令字复位SENSOR所对接的MIPI。
  4. (可选)使用HI_MIPI_CONFIG_SENSOR_CLOCK命令字配置SENSOR时钟。
  5. (可选)使用HI_MIPI_ENABLE_SENSOR_CLOCK命令字打开SENSOR时钟。
  6. 使用HI_MIPI_RESET_SENSOR命令字复位SENSOR。
  7. 使用HI_MIPI_SET_DEV_ATTR命令字配置MIPI Rx/设备属性。
  8. 使用HI_MIPI_UNRESET_MIPI命令字撤销复位MIPI。
  9. 使用HI_MIPI_UNRESET_SENSOR命令字撤销复位SENSOR。

初始化VI视频输入模块

不同数据来源、不同数据格式、不同模式,初始化VI视频输入模块的流程不同。

处理方式接口调用流程流程说明
从Sensor传入数据,若要获取YUV格式的数据,则通过VI通道处理,线性模式1. 依次调用hi_mpi_vi_set_dev_attrhi_mpi_vi_enable_dev接口,完成VI设备的属性配置并使能。
2. 调用hi_mpi_vi_set_dev_bind_pipe接口,完成设备和PIPE的绑定关系设置。
3. 依次调用hi_mpi_vi_create_pipehi_mpi_vi_start_pipe接口,创建并启动VI PIPE。需要合理设置hi_vi_pipe_attr.depth队列深度,队列深度越大,抗抖动性越好,建议设置为3或以上值。
4. 依次调用hi_mpi_vi_set_chn_attrhi_mpi_vi_enable_chn接口,完成VI通道的属性配置并使能。需要合理设置hi_vi_chn_attr.depth队列深度,该队列深度除了要考虑VI内部处理预留内存外,还需结合用户自己的图像业务处理时长(从用户调用hi_mpi_vi_get_chn_frame接口取走图像资源,到用户调用hi_mpi_vi_release_chn_frame接口归还图像资源的时间间隔),合理设置队列深度大小。
从Sensor传入数据,若要获取YUV格式的数据,则通过VI通道处理,WDR模式相对于普通线性模式,WDR模式下,Sensor模组会通过长短曝光方式同时产生两帧图像数据,VI需要创建两个PIPE资源,并将两个PIPE绑定到同一个VI设备上,分别接收和处理对应的长短曝光帧图像,然后在主PIPE对应的通道中,输出长短曝光融合后的图像数据。所以,接口调用流程存在如下差异:
1. 需要调用hi_mpi_vi_set_dev_bind_pipe,将同一个Sensor设备的图像数据,绑定到两个Pipe上去,按示例图,将DEV0设备绑定到PIPE0和PIPE1上。
2. 需要通过接口hi_mpi_vi_create_pipehi_mpi_vi_start_pipe创建并启动两个PIPE,按示例图,创建了PIPE0和PIPE1,其中PIPE0作为主PIPE,接收并处理短曝光帧,PIPE1作为从PIPE,接收并处理长曝光帧。
(说明:WDR模式下,pipe0和pipe1为一组,pipe0为主pipe,pipe1和pipe2为一组,pipe1为主pipe。)
3. 只需启动主PIPE上的通道,从PIPE上的通道可不使能,节省资源。
若要获取RAW格式的数据,则通过VI PIPE处理1. 调用hi_mpi_vi_set_dev_attrhi_mpi_vi_enable_dev接口,完成VI设备的属性配置并使能。
2. 调用hi_mpi_vi_set_dev_bind_pipe接口,完成设备和Pipe的绑定关系设置。
3. 调用接口hi_mpi_vi_create_pipe创建PIPE。
1. 如果用户只需要获取RAW图,不需要图像经过VI处理和转换,则在hi_mpi_vi_create_pipe创建pipe时,可执行以下操作:
1. 将pipe_bypass_mode设置为HI_VI_PIPE_BYPASS_BE,不经过ISP BE处理。
2. 设置hi_vi_pipe_attr.depth大小为hi_vi_dump_attr.depth,除了dump所需图像队列外,不额外申请多余的图像资源。
3. 需要调用hi_mpi_vi_set_chn_attr,不需要调用hi_mpi_vi_enable_chn接口使能VI通道。
2. 如果用户除了获取RAW图,还需要继续将图像送给VI处理和转换,则
1. 在hi_mpi_vi_create_pipe创建pipe时,需要合理设置hi_vi_pipe_attr.depth的值,该值需要考虑在hi_vi_dump_attr.depth大小的基础上,额外预留部分VI PIPE内部处理所需队列深度,一般为hi_vi_dump_attr.depth + 3。
2. 需要继续调用hi_mpi_vi_set_chn_attrhi_mpi_vi_enable_chn接口,使能VI通道,并调用接口hi_mpi_vi_get_chn_frame获取VI处理后的图像结果数据并处理,处理完成后调用hi_mpi_vi_release_chn_frame接口释放对应图像的内存资源。
4. 要调用接口hi_mpi_vi_set_pipe_frame_dump_attr设置采图所需预留的图像队列深度。
5. 调用hi_mpi_vi_start_pipe接口启动PIPE。
由用户指定RAW图数据,VI PIPE灌入并处理,获取YUV图用户回灌图片场景,图片的数据来源不再是外部的摄像头设备,但因为当前版本还不支持虚拟pipe,只能通过物理pipe进行灌图,所以即使数据不从sensor输入,仍旧需要设置对应dev并调用hi_mpi_vi_set_dev_bind_pipe接口做dev和pipe的绑定。
1. 调用hi_mpi_vi_create_pipe接口创建PIPE。
2. 调用hi_mpi_vi_set_pipe_frame_source接口将PIPE的图像数据来源设置为VI_PIPE_FRAME_SOURCE_USER。
3. 调用hi_mpi_vi_start_pipe接口启动PIPE。
4. 调用hi_mpi_vi_set_chn_attrhi_mpi_vi_enable_chn接口,完成VI通道的属性配置并使能。
5. 开始循环发送用户指定的图片数据。
1. 调用hi_mpi_vi_pipe_get_buffer获取空闲的图像数据,所能获取的最大可用内存数量由hi_mpi_vi_create_pipe接口下发的hi_vi_pipe_attr.depth属性决定。
2. 成功获取到可用的内存资源后,将需要灌入的图像数据写入返回的内存地址中,内存地址为hi_mpi_vi_pipe_get_buffer接口返回的frame_info.v_frame.virt_addr[0],然后调用接口hi_mpi_vi_send_pipe_raw发送RAW图数据。
3. hi_mpi_vi_send_pipe_raw发送数据成功后,需要及时调用hi_mpi_vi_pipe_release_buffer接口,释放内存资源。
4. 图示为用户发送bayer格式图像的流程,如果用户需要发送YUV格式数据,则需要在调用hi_mpi_vi_create_pipe接口创建pipe时,指定像素格式pixel_format为YUV,并将isp_bypass设置为true,并将接口hi_mpi_vi_send_pipe_raw修改为hi_mpi_vi_send_pipe_yuv。当前版本支持发送的YUV图像格式为:HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422、HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420、HI_PIXEL_FORMAT_YUV_400。

初始化并运行ISP图像信号处理模块

  1. 调用hi_mpi_isp_sensor_reg_callback接口注册Sensor驱动通用算法。

  2. (可选)调用hi_mpi_ae_sensor_reg_callback接口、hi_mpi_awb_sensor_reg_callback接口注册系统内置的Sensor驱动AE、AWB算法。

    此处用户可以根据需求注册自定义的算法。

  3. (可选)调用hi_mpi_ae_register接口、hi_mpi_awb_register接口初始化系统内置的2A算法。

    此处用户可以根据需求注册自定义的算法。

  4. 调用hi_mpi_isp_mem_init接口初始化ISP内部资源。

  5. 调用hi_mpi_isp_set_pub_attr接口初始化算法模块。

  6. 调用hi_mpi_isp_init接口初始化ISP firmware。

  7. 启用单独线程,调用hi_mpi_isp_run接口运行ISP算法的调度业务主流程。

获取已处理的图像数据

  • 获取YUV数据

    VI图像处理完成后,可在对应的VI通道上获取已完成图像并进行相关处理,典型接口调用流程如下:

    1. (可选)通过系统文件句柄+select/epoll等待机制,等待图像处理完成事件,可通过hi_mpi_vi_get_chn_fd接口获取指定通道的系统文件句柄,然后获取并处理完一帧图像数据后,会唤醒系统的select/epoll读等待请求。
    2. 调用hi_mpi_vi_get_chn_frame接口,获取已处理完成的图像数据。此时图像数据对应内存资源会自动被用户占用,用户必须在处理完图像数据后,调用hi_mpi_vi_release_chn_frame接口释放对应图像的内存资源。
    3. 如果用户通过hi_mpi_vi_get_chn_frame接口获取到图像数据后,要再发布给其他进程使用,则可通过返回的hi_video_frame.user_data[0]得到acltdtBuf句柄,再结合acl的共享buf管理接口(如acltdtCopyBufRef)以及共享队列管理接口(如acltdtEnqueue)将对象发布给其他进程使用。
  • 获取RAW数据

    VI图像处理完成后,可在对应的VI PIPE上获取已完成图像并进行相关处理,典型接口调用流程如下:

    1. (可选)通过系统文件句柄+select/epoll等待机制,等待图像处理完成事件,可通过hi_mpi_vi_get_pipe_fd接口获取指定通道的系统文件句柄,当后台获取并处理完一帧图像数据后,会唤醒系统的select/epoll读等待请求。
    2. 调用hi_mpi_vi_get_pipe_frame接口,获取已处理完成的图像数据。此时图像数据对应内存资源会自动被用户占用,用户必须在处理完图像数据后,调用hi_mpi_vi_release_pipe_frame接口释放对应图像的内存资源。
    3. 如果用户通过hi_mpi_vi_get_pipe_frame接口获取到图像数据后,要再发布给其他进程使用,则可通过返回的hi_video_frame.user_data[0]得到acltdtBuf句柄,再结合acl的共享buf管理接口(如acltdtCopyBufRef)以及共享队列管理接口(如acltdtEnqueue)将对象发布给其他进程使用。

释放ISP图像信号处理模块资源

  1. 调用hi_mpi_isp_exit接口去初始化ISP firmware。
  2. 调用hi_mpi_ae_unregister接口、hi_mpi_awb_unregister接口去初始化2A算法。
  3. 调用hi_mpi_ae_sensor_unreg_callback接口、hi_mpi_awb_sensor_unreg_callback接口取消注册Sensor驱动AE、AWB算法。
  4. 调用hi_mpi_isp_sensor_unreg_callback接口取消注册Sensor驱动通用算法。

释放VI视频输入模块资源

  1. 调用hi_mpi_vi_disable_chn接口关闭VI通道。
  2. 依次调用hi_mpi_vi_stop_pipehi_mpi_vi_destroy_pipe接口停止并销毁VI PIPE。
  3. 调用hi_mpi_vi_disable_dev接口关闭VI设备。

退出MIPI/SENSOR硬件

  1. 使用HI_MIPI_RESET_SENSOR命令字复位SENSOR。
  2. 使用HI_MIPI_DISABLE_SENSOR_CLOCK命令字关闭SENSOR所连接的时钟。
  3. 使用HI_MIPI_RESET_MIPI命令字复位SENSOR所对接的MIPI。
  4. 使用HI_MIPI_DISABLE_MIPI_CLOCK关闭MIPI。

父主题: 视频数据获取和处理功能(Camera场景)

视频数据获取+VPSS视频处理功能

VPSS必须配合VI模块一起使用,接口调用流程说明如下:

图1 VPSS调用流程

接口调用流程说明如下:

  1. 初始化

    1. 调用hi_mpi_sys_init接口完成媒体系统初始化。
    2. 调用hi_mpi_rgn_create创建区域。
    3. VPSS模块只能作为被绑定方,被动接收视频流数据并处理,所以需要调用hi_mpi_sys_bind接口,将规划好的VI通道绑定到VPSS组上。
    4. 调用hi_mpi_vpss_create_grp接口创建VPSS组,作为hi_mpi_sys_bind接口的被绑定方。
    5. 按需开启VPSS上功能:
    6. 调用hi_mpi_vpss_start_grp接口启用VPSS组。
    7. 调用hi_mpi_vpss_set_chn_attr接口设置通道属性,通道输出分辨率可以与输入源分辨率不一致,当不一致时,自动开启缩放,不同通道的缩放能力不一样。
    8. 如果需要开启鱼眼畸变矫正,则还需要调用hi_mpi_vi_set_chn_fisheye接口,设置鱼眼矫正参数。
    9. 调用hi_mpi_vpss_enable_chn接口启动VPSS通道。
    10. 调用hi_mpi_rgn_attach_to_chn接口将区域叠加到VPSS通道上。
  2. 采集并处理数据

    1. 使用MIPI Rx ioctl命令字初始化MIPI/Sensor硬件对接信息,接口调用流程请参见初始化MIPI/SENSOR硬件对接信息
    2. 使用VI(Vedio Input)功能接口初始化VI模块,接口调用流程请参见初始化VI视频输入模块
    3. 使用ISP(Image Signal Processing)系统控制接口初始化并运行ISP模块,接口调用流程请参见初始化并运行ISP图像信号处理模块
    4. 根据hi_mpi_sys_bind接口设置的绑定策略,系统内部自动将VI处理后的图像自动传递给VPSS;
    5. 根据VPSS设置的参数,系统内部自动执行裁剪/3dnr/鱼眼矫正/缩放处理。
    6. 按需更新修改区域信息:
  3. 获取处理结果数据

    此时,用户可调用hi_mpi_vpss_get_chn_fd接口获取VPSS指定通道的句柄,并通过select/epoll接口等待VPSS处理结果。VPSS处理完后,会自动唤醒select/epoll等待,此时可调用hi_mpi_vpss_get_chn_frame接口获取VPSS处理后的图像数据,做后续处理,最后调用hi_mpi_vpss_release_chn_frame释放一帧通道图像。

  4. 释放VI和VPSS初始化资源

    1. 使用ISP功能接口释放ISP模块资源,接口调用流程请参见释放ISP图像信号处理模块资源
    2. 使用VI功能接口释放VI模块资源,接口调用流程请参见释放VI视频输入模块资源
    3. 使用MIPI Rx ioctl命令字退出MIPI/Sensor硬件,接口调用流程请参见退出MIPI/SENSOR硬件
    4. 调用hi_mpi_rgn_detach_from_chn接口将指定区域从通道中删除。
    5. 调用hi_mpi_vpss_disable_chn接口关闭VPSS通道。
    6. 调用hi_mpi_vpss_stop_grp接口停止VPSS组。
    7. 调用hi_mpi_vpss_destroy_grp接口销毁VPSS组。
    8. 调用hi_mpi_sys_unbind接口取消VI和VPSS的绑定。
    9. 调用hi_mpi_rgn_destroy接口销毁区域。
    10. 最后调用hi_mpi_sys_exit接口完成后媒体系统的退出。

父主题: 视频数据获取和处理功能(Camera场景)

视频解码、处理和显示功能(NVR场景)

NVR视频场景说明

NVR,全称Network Video Recorder,即网络视频录像机,是网络视频系统的存储转发部分,NVR与网络摄像机协同工作,完成音频&视频的录像、存储及转发功能,同时,NVR具备本地人机交互界面、视频解码、视频显示及语音对讲功能。

本章节描述NVR视频业务处理流程,包括下面两种:

  1. 视频解码显示流程

    视频解码显示流程涉及视频解码模块(VDEC)、视频处理模块(VPSS)、视频输出模块(VO)、HDMI接口模块, 以及增强的功能,例如Region区域管理功能TDE图形绘制功能HIFB叠加图形层管理功能

    在该流程中,通过调用hi_mpi_sys_bind接口将VDEC通道与VPSS组绑定、将VPSS组与VO设备绑定,实现数据从VDEC到VPSS、从VPSS到VO的自动传输。通过底层寄存器,实现VO自动读取HIFB的输出数据。

    若TDE、HIFB与VO不在一个应用进程中,则需要确保先启动VO所在的进程,且TDE和HIFB所在的进程中也需要调用hi_mpi_sys_init接口初始化媒体数据处理系统、并在进程退出前调用hi_mpi_sys_exit接口实现媒体数据处理系统去初始化。

  2. 视频解码智能分析流程

    视频解码智能分析流程涉及视频解码模块(VDEC)、视频处理模块(VPSS)、智能分析(模型推理), 以及增强的功能,例如REGION区域管理模块。区域管理功能的接口调用流程请参见Region区域管理功能

视频解码显示流程

视频解码显示流程涉及视频解码模块(VDEC)、视频处理模块(VPSS)、视频输出模块(VO)、HDMI接口模块, 以及增强的功能,例如Region区域管理功能TDE图形绘制功能HIFB叠加图形层管理功能

图1 业务启动、运行接口调用流程

NVR视频解码显示业务启动、运行接口调用流程说明如下:

  1. 调用hi_mpi_sys_init接口完成媒体系统初始化

  2. 创建VDEC视频****解码通道(按需创建多个通道),并通知解码器启动接收码流。

    1. 调用hi_mpi_vdec_create_chn接口创建通道。
    2. 调用hi_mpi_vdec_get_chn_param接口获取通道属性、按需设置通道属性后,调用hi_mpi_vdec_set_chn_param接口设置通道参数。
    3. 解码前,需调用hi_mpi_vdec_start_recv_stream接口通知解码器启动接收码流。
  3. 创建并启用VPSS组(按需创建多个VPSS组)。

    1. 调用hi_mpi_vpss_create_grp接口创建VPSS组
    2. 调用hi_mpi_vpss_start_grp接口启用VPSS组。
    3. 调用hi_mpi_vpss_set_chn_attr接口设置通道属性,在和VO模块配合工作时,通道属性需要设置为Auto模式。
    4. 调用hi_mpi_vpss_enable_chn接口启动VPSS通道。
  4. 调用hi_mpi_sys_bind接口绑定视频解码通道和VPSS组,经过VDEC视频解码的输出数据直接被送入对应的VPSS组继续处理。

    • 以单个显示器输出4路视频显示为例,绑定信息如下表所示:

      VDEC通道

      VPSS Group

      VO通道

      VO视频层

      VO设备号

      HDMI编号

      1

      1

      1

      视频层

      VHD0

      0

      HDMI0

      2

      2

      2

      3

      3

      3

      4

      4

      4

    • 以两个显示器输出、每个显示器输出4路视频显示为例,绑定信息如下表所示:

      VDEC通道

      VPSS Group

      VO通道

      VO视频层

      VO设备号

      HDMI编号

      1

      1

      1

      视频层

      VHD0

      0

      HDMI0

      2

      2

      2

      3

      3

      3

      4

      4

      4

      5

      5

      5

      视频层

      VHD1

      1

      HDMI1

      6

      6

      6

      7

      7

      7

      8

      8

      8

  5. 启用VO设备和VO通道(按需创建多个VO通道)。

    1. 调用hi_mpi_vo_set_pub_attr配置显示设备属性,通过hi_mpi_vo_enable使能显示设备。
    2. 调用hi_mpi_vo_set_video_layer_attr配置显示视频层属性,通过hi_mpi_vo_enable_video_layer使能显示视频层。
    3. 调用hi_mpi_vo_set_chn_attr配置显示通道属性,通过hi_mpi_vo_enable_chn使能显示通道。
  6. 初始化HDMI外设

    1. 调用hi_mpi_hdmi_init初始化HDMI设备,调用hi_mpi_hdmi_open打开HDMI。
    2. 调用hi_mpi_hdmi_set_attr配置HDMI属性。
    3. 调用hi_mpi_hdmi_start启动HDMI外设,以便显示视频。
  7. 调用hi_mpi_sys_bind接口绑定VPSS组和VO通道,经过VPSS处理后的输出数据直接被送入对应的VO通道继续处理。

    绑定信息请参见4

  8. 循环调用hi_mpi_vdec_send_stream接口,发送每一帧解码码流

    注意:

    1. 在视频解码通道和VPSS组绑定后,用户调用hi_mpi_vdec_send_stream发送码流时,接口参数中的vdec_pic_info可以设置为NULL, 此时的视频解码通道和VPSS模块绑定(参见4),解码结果数据直接被送入对应的VPSS组继续处理,不支持通过hi_mpi_vdec_get_frame接口获取解码结果数据。
    2. 视频解码支持两种模式,即回放模式和预览模式,可以通过hi_mpi_vdec_get_display_modehi_mpi_vdec_set_display_mode接口进行查询和设置,对于录像播放需要使用回放模式,此时支持播放控制。

图2 资源释放接口调用流程

NVR视频解码显示业务资源释放接口调用流程说明如下:

  1. 调用hi_mpi_sys_unbind接口取消VO通道与VPSS组的绑定
  2. 调用hi_mpi_sys_unbind接口取消VPSS组与VDEC通道的绑定
  3. 释放HDMI外设资源
    1. 首先调用hi_mpi_hdmi_stop停止HDMI。
    2. 调用hi_mpi_hdmi_close关闭HDMI。
    3. 调用hi_mpi_hdmi_deinit去初始化HDMI设备。
  4. 释放VO设备、通道资源
    1. 调用hi_mpi_vo_disable_chn禁用通道。
    2. 调用hi_mpi_vo_disable_video_layer禁用视频层。
    3. 调用hi_mpi_vo_disable禁用显示设备。
  5. 销毁VPSS组
    1. 调用hi_mpi_vpss_disable_chn接口关闭VPSS通道。
    2. 调用hi_mpi_vpss_stop_grp接口停止VPSS组。
    3. 调用hi_mpi_vpss_destroy_grp接口销毁VPSS组。
  6. 销毁VDEC视频解码通道
    1. 调用hi_mpi_vdec_stop_recv_stream接口通知解码器停止接收码流。
    2. 调用hi_mpi_vdec_destroy_chn接口销毁通道。
  7. 调用hi_mpi_sys_exit接口完成媒体数据处理系统去初始化

视频解码智能分析流程

视频解码智能分析流程涉及视频解码模块(VDEC)、视频处理模块(VPSS)、智能分析(模型推理), 以及增强的功能,例如REGION区域管理模块。区域管理功能的接口调用流程请参见Region区域管理功能

图3 业务启动、运行接口调用流程

视频解码智能分析业务启动、运行流程:

  1. 调用hi_mpi_sys_init接口完成媒体系统初始化

  2. 创建VDEC视频解码通道(按需创建多个通道),并通知解码器启动接收码流。

    1. 调用hi_mpi_vdec_create_chn接口创建通道。
    2. 调用hi_mpi_vdec_get_chn_param接口获取通道属性、按需设置通道属性后,调用hi_mpi_vdec_set_chn_param接口设置通道参数。
    3. 解码前,需调用hi_mpi_vdec_start_recv_stream接口通知解码器启动接收码流。
  3. 创建并启用VPSS组(按需创建多个VPSS组)。

    1. 调用hi_mpi_vpss_create_grp接口创建VPSS组
    2. 调用hi_mpi_vpss_start_grp接口启用VPSS组。
    3. 调用hi_mpi_vpss_set_chn_attr接口设置通道属性,通道属性需要设置为User模式。
    4. 调用hi_mpi_vpss_enable_chn接口启动VPSS通道。
  4. 调用hi_mpi_sys_bind接口绑定视频解码通道和VPSS组,经过VDEC视频解码的输出数据直接被送入对应的VPSS组继续处理。

    绑定信息请参见4

  5. 循环调用hi_mpi_vdec_send_stream接口,发送每一帧解码码流

    注意:

    在视频解码通道和VPSS组绑定后,用户调用hi_mpi_vdec_send_stream发送码流时,接口参数中的vdec_pic_info可以设置为NULL, 此时的视频解码通道和VPSS模块绑定(参见4),解码结果数据直接被送入对应的VPSS组继续处理,不支持通过hi_mpi_vdec_get_frame接口获取解码结果数据。

  6. 调用hi_mpi_vpss_get_chn_frame接口获取VPSS处理后的图像数据,可送入模型推理(参见基础推理应用),推理结束后,最后调用hi_mpi_vpss_release_chn_frame释放一帧通道图像

    注意

    在多通道时,用户可调用hi_mpi_vpss_get_chn_fd接口获取VPSS指定通道的句柄,并通过调用epoll接口(参考hi_mpi_sys_create_epoll相关接口)等待VPSS处理结果。VPSS处理完后,会自动唤醒epoll等待,此时可调用hi_mpi_vpss_get_chn_frame接口获取VPSS处理后的图像数据。

    VPSS处理后的图像,在送入模型推理前,若图片尺寸、格式等不满足要求,需要经过DVPP的VPC功能模块、AIPP功能进一步处理,请参见媒体数据处理基础知识中关于VPC、AIPP的介绍。

图4 资源释放接口调用流程

NVR视频解码智能分析业务资源释放接口调用流程说明如下:

  1. 调用hi_mpi_sys_unbind接口取消VPSS组与VDEC通道的绑定
  2. 销毁VPSS组
    1. 调用hi_mpi_vpss_disable_chn接口关闭VPSS通道。
    2. 调用hi_mpi_vpss_stop_grp接口停止VPSS组。
    3. 调用hi_mpi_vpss_destroy_grp接口销毁VPSS组。
  3. 销毁VDEC视频解码通道。
    1. 调用hi_mpi_vdec_stop_recv_stream接口通知解码器停止接收码流。
    2. 调用hi_mpi_vdec_destroy_chn接口销毁通道。
  4. 调用hi_mpi_sys_exit接口完成媒体数据处理系统去初始化

Region区域管理功能

叠加在视频上的OSD (On Screen Display)和遮挡在视频上的色块统称为区域。区域管理模块,用于统一管理这些区域资源,用于在视频上显示一些特定信息(如通道号、时间戳等)、或在视频中填充色块用于遮挡。

区域管理功能(REGION)必须配合VPSS模块一起使用,且区域管理功能需关联的VPSS组、VPSS通道已创建,接口调用流程如下所示。

  1. 初始化
    1. 调用hi_mpi_rgn_create创建区域。
    2. 调用hi_mpi_rgn_attach_to_chn接口将区域叠加到VPSS通道上。
  2. 按需修改区域信息
  3. 资源释放
    1. 调用hi_mpi_rgn_detach_from_chn接口将指定区域从VPSS通道中删除。
    2. 调用hi_mpi_rgn_destroy接口销毁区域。

TDE图形绘制功能

TDE是图形二维加速引擎,它利用硬件为 OSD(On Screen Display)和 GUI(Graphics User Interface)提供快速的图形绘制功能,主要有快速拷贝、快速色彩填充、模式填充(当前仅支持Alpha Blending操作)。

图5 TDE接口调用流程

  1. 调用hi_tde_open接口打开TDE设备

  2. 调用hi_tde_begin_job接口创建TDE任务

  3. 调用各命令执行接口,例如hi_tde_quick_copyhi_tde_quick_fillhi_tde_pattern_fill

    调用命令执行接口前,需先调用HIFB提供的**int ioctl (int fd, FBIOGET_FSCREENINFO, fb_fix_screeninfo *fix)**接口获取显存用户态地址,作为目标位图的内存地址,TDE任务执行完成后,目标位图的数据会存放在该内存地址中,作为HIFB的输入数据。

  4. 若添加命令失败,则调用hi_tde_cancel_job接口取消任务;若添加命令成功,则调用hi_tde_end_job接口提交任务。

  5. 等待TDE任务完成

    目前有等待指定TDE任务执行完成(调用hi_tde_wait_for_done接口)、等待当前TDE设备上所有任务执行完成(调用hi_tde_wait_all_done接口)两种方式。

HIFB叠加图形层管理功能

HIFB用于管理叠加图形层,它不仅提供Linux Framebuffer的基本功能,还在Linux Framebuffer的基础上增加图层显示起始位置修改、层间Alpha等扩展功能。

图6 HIFB接口调用流程

  1. 通过系统调用open打开fb设备。设备文件fb0fb4对应图层G0G4。其中,G0和G1为高清图层、G2为鼠标图层、G3和G4为标清图层。

    各图层对应的fb设备、VO设备、支持的颜色格式、分辨率等说明,请参见表1

  2. 通过系统调用ioctl,传入命令码FBIOPUT_VSCREENINFO设置屏幕基本属性

  3. 通过系统调用ioctl,传入命令码FBIOGET_FSCREENINFO获取显存用户态地址

  4. 通过系统调用mmap映射用户态虚拟地址

  5. 通过系统调用ioctl,传入功能相关的命令码设置功能属性

  6. 通过系统调用munmap解除用户态虚拟地址映射

  7. 通过系统调用close关闭fb设备

    如果HIFB与VO在同一个进程中配合使用,则需要在禁用VO设备(即调用hi_mpi_vo_disable)后关闭fb设备。

    如果HIFB与VO不在同一个进程中,则需要先停VO所在的应用进程。

父主题: 媒体数据处理V2

语音对讲功能(NVR场景)

NVR音频场景说明

NVR,全称Network Video Recorder,即网络视频录像机,是网络视频系统的存储转发部分,NVR与网络摄像机协同工作,完成音频&视频的录像、存储及转发功能,同时,NVR具备本地人机交互界面、视频解码、视频显示及语音对讲功能。

**本章节描述NVR音频业务(语音对讲功能)的接口调用流程。**在语音对讲功能中,包括媒体数据处理系统初始化&去初始化、接收IP Camera发送的语音并播放声音录制声音并向IP Camera发送语音,涉及的模块包括公共模块、音频输入模块(AI),音频编码模块(AENC),音频输出模块(AO)、音频解码模块(ADEC)。

接收IP Camera发送的语音并播放声音

图1 接收IP Camera发送的语音****并播放声音

接口调用流程说明如下:

  1. 调用hi_mpi_adec_create_chn接口创建音频解码通道

  2. 启用AO音频输出设备和通道

    1. 调用hi_mpi_ao_set_pub_attr接口设置AO设备属性。

    2. 调用hi_mpi_ao_enable接口启动AO设备。

    3. 调用hi_mpi_ao_enable_chn接口启动AO通道

    4. 调用hi_mpi_ao_enable_resample接口启用AO重采样功能。

      由于AO的采样率固定为48kHz,G.711a、G.711u协议的采样率仅支持8kHz,因此需启用重采样功能;而48kHz在AAC协议采样率支持的范围内,因此使用AAC协议时,在AO时无需重采样。

  3. 调用hi_mpi_sys_bind接口绑定ADEC与AO

    ADEC设备IDADEC通道号AO设备IDAO通道号
    0020
    0130
  4. 循环调用hi_mpi_adec_send_stream接口将每一帧待解码音频数据发送给解码器进行解码

    解码后的音频数据,根据3中的绑定关系,被自动发送到对应的AO设备,用于音频播放。

  5. 音频播放完成后,在退出流程中,先调用hi_mpi_sys_unbind接口解绑ADEC与AO,再依次调用hi_mpi_ao_disable_resample接口禁用AO重采样功能、调用hi_mpi_ao_disable_chn接口禁用AO通道、调用hi_mpi_ao_disable接口禁用AO设备,最后调用hi_mpi_adec_destroy_chn接口进行销毁ADEC通道。

录制声音并向IP Camera发送语音

图2 录制声音并向IP Camera发送语音

接口调用流程说明如下:

  1. 启用AI音频输入设备和通道

    1. 调用hi_mpi_ai_set_pub_attr接口设置AI设备属性。

    2. 调用hi_mpi_ai_enable接口启动AI设备。

    3. 调用hi_mpi_ai_set_chn_attr接口设置AI通道属性。

    4. 调用hi_mpi_ai_enable_chn接口启动AI通道。

    5. 调用hi_mpi_ai_enable_resample接口启用AI重采样功能。

      由于AI的采样率固定为48kHz,G.711a、G.711u协议的采样率仅支持8kHz,因此需启用重采样功能;而48kHz在AAC协议采样率支持的范围内,因此使用AAC协议时,在AI时无需重采样。

  2. 调用hi_mpi_aenc_create_chn接口创建音频编码通道

  3. 调用hi_mpi_sys_bind接口绑定AI与AENC

    AI设备IDAI通道号AENC设备IDAENC通道号
    2000
  4. 循环调用hi_mpi_aenc_get_stream获取编码数据,编码数据使用完成后,及时调用hi_mpi_aenc_release_stream接口释放编码数据

    经过AI设备获取到的音频数据,根据3中的绑定关系,被自动发送到对应的AENC通道进行编码,用于向IP Camera发送语音。

  5. 发送语音完成后,在退出流程中,先调用hi_mpi_sys_unbind接口解绑AI与AENC,再调用hi_mpi_aenc_destroy_chn接口进行销毁AENC通道,最后依次调用hi_mpi_ai_disable_resample接口禁用AI重采样功能、调用hi_mpi_ai_disable_chn接口禁用AI通道、调用hi_mpi_ai_disable接口禁用AI设备。

父主题: 媒体数据处理V2

音频获取&音频播放功能

音频获取功能

  1. 调用hi_mpi_sys_init接口初始化媒体公共模块。
  2. 调用hi_mpi_ai_set_pub_attr接口配置属性。
  3. 依次调用hi_mpi_ai_enable接口使能AI设备、调用hi_mpi_ai_enable_chn接口使能AI通道。
  4. 调用hi_mpi_ai_get_frame获取录音数据进行处理,之后调用hi_mpi_ai_release_frame释放音频帧,循环往复。
  5. AI采集音频结束时,先调用hi_mpi_ai_disable_chn接口禁用通道,然后调用hi_mpi_ai_disable接口禁用AI设备。
  6. 调用hi_mpi_sys_exit接口释放媒体公共模块的初始化资源。

音频播放功能

  1. 调用hi_mpi_sys_init接口初始化媒体公共模块。
  2. 调用hi_mpi_ao_set_pub_attr接口配置属性。
  3. 依次调用hi_mpi_ao_enable接口使能AO设备、调用hi_mpi_ao_enable_chn接口使能AO通道。
  4. 周期性的获取数据,并调用hi_mpi_ao_send_frame接口进行播音。
  5. AO播放音频结束时,先调用hi_mpi_ao_get_chn_delay接口获取AO通道中当前音频延时大小,延时为0后再调用hi_mpi_ao_disable_chn接口禁用通道,然后调用hi_mpi_ao_disable接口禁用AO设备。
  6. 调用hi_mpi_sys_exit接口释放媒体公共模块的初始化资源。

父主题: 媒体数据处理V2

在线提单