7.3.9 视频编码
概述
视频编码模块实现H.264/H.265/JPEG/MJPEG协议硬件 编码。该模块支持多通道实时编码,各通道相互独立,常见的使用场景,包括单路录像、多路录像、单路VIO视频流、多路VIO视频流、录像+VIO视频流等。
功能描述
基础规格
X3支持的编码规格如下:
H264/H265协议编码性能如下:
- H.264编解码支持最大分辨率为 8192 x 8192,最小为256 x 128,解码最小为32 x 32
- H.265编解码支持最大分辨率为 8192 x 8192,最小为256 x 128,解码最小为8 x 8
- H.264/H.265的stride是32字节对齐,width和height都是8字节对齐,如果不是对齐的建议使用VIDEO_CROP_INFO_S去对应裁剪
- H.264/H.265均具备多码流实时编码能力
- 最高能力支持 4K@60fps
- 带QP map的ROI编码(让用户选择画面中感兴趣的区域,启用ROI功能后,重要的或者移动的区域将会进行高质量无损编码,而对那些不移动,不被选择的区域降低其码率和图像质量,进行标准清晰度视频压缩,甚至是不传输这部分区域视频)
- 支持旋转和镜像
- Multi-instance处理,最多32个
JPEG协议编码能力如下:
- 编解码分辨率最大32768 x 32768,最小 16 x 16
- MJPEG、JPEG的stride是32字节对齐,width是16字节对齐,height是8字节对齐
- 对于YUV 4:2:0 格式(例如:NV12),最高能力达到 4K@30fps
- JPEG Baseline and Extended sequential ISO/IEC 10918-1
- 支持一个或三个颜色分量,每个分量可以8位或12位采样
- 支持YUV 4:0:0,4:2:0,4:2:2,4:4:0 和 4:4:4 颜色格式
- 支持编解码ROI
- 支持slice encoding
- 支持旋转和镜像
- Multi-instance,最高支持64个
编解码通道
编解码通道即一个特定类型的编解码实例,不同编解码通道的用户参数配置和资源可以相互独立,这样就可以实现多 路不同规格的视频编解码,覆盖多种业务场景。
码率控制
码率控制主要指的是对编码码率的控制。码率控制针对连续的视频编码码流而言,对于一个变化的场景,如果要达到图像质量稳定,则编码码率会抖动;如果要达到编码码率稳定,则图像质量会波动。X3针对H264、H265和MJPEG协议支持以下码率控制方式:
- H264/H265支持编码通道的CBR、VBR、AVBR、FixQp和QpMap五种码率控制方式
- MJPGE编码通道的FixQp码率控制方式。
CBR能够保证整体的编码码率稳定;
VBR则是保证编码图像的质量稳定;
AVBR会兼顾码率和图像质量,产生码率和图像质量相对稳定的码流;
FixQp是固定每一个I帧、P帧和B帧的QP值;
QPMAP是为一帧图像中的每一个块指定QP值,其中H264块大小为16x16,H265块大小为32x32。
对于CBR和AVBR来说,编码器内部会为每一帧图片找到合适的QP值,从而保证恒定码率。
编码器内部支持三种级别的码率控制,分别为帧级别、CTU/MB级别和subCTU/subMB级别。其中帧级别的控制主要会根据目标码率为每一帧图片产生一个QP值,从而保证码率恒定;CTU/MB级别的控制则根据每一个64x64的CTU或16x16的MB的目标码率为每个block产生一个QP值,能够得到更好的码率控制,但是频繁的QP值调整会造成图像质量不稳定的问题;subCTU/subMB级别的控制则为每一个32x32的subCTU或8x8的subMB产生一个QP值,其中复杂的块会得到较高的QP值,静态的块则会得到较低的QP值,因为相比于复杂的区域人眼对于静态的区域更敏感,复杂和静态区 域的检测主要依赖于内部硬件模块,这个级别控制主要是为了提高主观图像质量同时保证码率恒定,该模式控制下SSIM得分较高,但是PSNR得分会降低。
CBR、VBR、AVBR可以使能QPMAP,则每个块区域的实际值由以下公式得到:
其中MQP为ROI map中的值,RQP为编码器内部码率控制得到的值,ROIAvaQP为ROI map中QP的平均值。
GOP结构
GOP结构表可定义一组周期性的GOP结构,该GOP结构将用于整个编码过程。单个结构表中的元素如下表所示,其中可以指定该图像的参考帧,如果IDR帧后的其他帧指定的参考帧为IDR帧前的数据帧,编码器内部会自动处理这种情况使其不参考其他帧,用户无需关心这种情况。用户在自定义GOP结构时需要指明结构表的数量,最多可定义8个结构表,结构表的顺序需要按照解码顺序排列。
Element | Description |
---|---|
Type | Slice type(I,P or B) |
POC | Display order of the frame within a GOP,ranging from 1 to GOP size |
QPoffset | A quantization parameter of the picture in the custom GOP |
NUM_REF_PIC_L0 | Flag to use multi reference picture for P picture It is valid only if PIC_TYPE is P |
temporal_id | Temporal layer of the frame. A frame cannot predict from a frame with a higher temporal id(0~6). |
1st_ref_POC | The POC of the 1st reference picture of L0 |
2nd_ref_POC | The POC of 1st reference picture of L1 in case that Type is equal to B The POC of 2nd reference picture of L0 in case that Type is equal to P Note that reference_L1can have the same POC as reference in B slice. But for compression efficiency it is recommended that reference_L1 have a different POC from reference_L0 |
GOP预置结构
下表所示为预置的8种GOP结构
Index | GOP Structure | Low Delay (encoding order and display order are same) | GOP Size | Encoding Order | Minimum Source Frame Buffer | Minimum Decoded Picture Buffer | Intra Period (I Frame Interval) Requirement |
---|---|---|---|---|---|---|---|
1 | I | Yes | 1 | I0-I1-I2… | 1 | 1 | |
2 | P | Yes | 1 | P0-P1-P2… | 1 | 2 | |
3 | B | Yes | 1 | B0-B1-B2… | 1 | 3 | |
4 | BP | No | 2 | B1-P0-B3-P2… | 4 | 3 | Multiple of 2 |
5 | BBBP | No | 4 | B2-B1-B3-P0… | 7 | 4 | Multiple of 4 |
6 | PPPP | Yes | 4 | P0-P1-P2-P3… | 1 | 2 | |
7 | BBBB | Yes | 4 | B0-B1-B2-B3… | 1 | 3 | |
8 | BBBBBBBB | No | 8 | B3-B2-B4-B1-B6-B5-B7-B0… | 12 | 5 | Multiple of 8 |
其中
- GOP Preset1
- 只有I帧,没有相互参考帧
- 低延时
- GOP Preset2
- 只有I帧和P帧
- P帧参考两个前向参考帧
- 低延时
- GOP Preset3
- 只有I帧和B帧
- B帧参考两个前向参考帧
- 低延时
- GOP Preset4
- 有I帧、P帧和B帧
- P帧参考两个前向参考帧
- B帧参考一个前向参考帧和一个后向参考帧
- GOP Preset5
- 有I帧、P帧和B帧
- P帧参考两个前向参考帧
- B帧参考一个前向参考帧和一个后向参考帧,后向参考帧可为P帧或B帧
- GOP Preset 6
- 只有I帧和P帧;
- P帧参考两个前向参考帧;
- 低延时;
- GOP Preset 7
- 只有I帧和B帧;
- B帧参考两个前向参考帧;
- 低延时;
- GOP Preset 8
- 只有I帧和B帧;
- B帧参考一个前向参考帧和一个后向参考帧;
GOP和I帧周期关系
如下图所示为GOP结构和I帧周期的关系。
ROI
ROI编码的实现和QPMAP类似,需要用户按照光栅扫描的方向为每一个块设定QP值,如下图所示为H265的ROI map示例。对于H264编码来说,每一个块的大小为16x16,而H265中则为32x32。在ROI map表中,每一个QP值占用一个字节,大小为0~51。
ROI编码可以和CBR和AVBR一起工作,当不使能CBR或AVBR时,每个块区域的实际QP值就为ROI map中指定的值,当使能CBR或AVBR时,则每个块区域的实际值由以下公式得到
其中MQP为ROI map中的值,RQP为编码器内部码率控制得到的值,ROIAvaQP为ROI map中QP的平均值。
Intra Refresh
Intra Refresh模式通过在非I帧内部周期性的插入帧内编码的MB/CTU来提高容错性。它能够为解码器提供更多的修复点来避免时域错误造成的图像损坏。用户可以指定MB/CTU的连续行数、列数或者步长来强制编码器插入帧内编码单元,用户还可指定帧内编码单元的大小由编码器内部决定哪一块需要帧内编码。
长期参考帧
用户可指定长期参考帧的周期和参考长期参考帧的周期,如下图所示。
Smart background encoding
在视频监控场景中,很多时 候背景是固定的。因此希望编码器在检测到背景区域时采用忽略模式或使用更少的码流来编码该区域。实际场景中由于camera图像存在噪点导致背景区域检测不太容易,很多时候需要ISP检测到背景区域时再通知编码器,这种方案会消耗额外的带宽和系统计算资源。
H264和H265编码提供集成在codec内部的智能背景编码模式,该模式充分利用内部硬件模块和on-the-fly处理,不会消耗额外的带宽和系统资源。如下图所示为背景检测的工作模式,智能背景编码模式下内部硬件模块会将每一个块单元和参考帧的块单元对比决定该块是否为背景。
对于背景区域的判断,用户可以设置最大的像素差值(推荐值8)和平均像素差值(推荐值1)。用户还可调整Lambda参数来影响编码中的模式选择,当检测到背景区域时,编码器内部会为每个块增加对应的Lambda值,使能编码器内部偏向于采用忽略模式来编码该块单元。对于Lambda控制,用户可设置lambdaQP(推荐值32)和deltaQP(推荐值3),最终的Lambda值按以下公式计算得到。
其中QP_TO_LAMBDA_TABLE为lambda转换表,该表也会被用于非背景区域的lambda转换。
需要注意的是当ROI编码使能时,Smart background encoding不会工作。该模式实际能节省的带宽与设定的码率和I帧间隔有很大关系,当码率和I帧间隔变大时,节省的码率越多。此外该模式下可以设置图像质量较好的帧作为长期参考帧来提高背景图像的质量和节省码率。
帧skip设置
用户可调用接口设置下一次操作输入的图像的编码模式为skip模式,该模式只对非I帧编码有效;skip模式下编码器内部会忽略输入帧,而是利用上一帧的重构帧生成该次输入的的重构帧,输入帧则被编码成P帧。
API参考
HB_VENC_CreateChn:创建编码通道。
HB_VENC_DestroyChn:销毁编码通道。
HB_VENC_ResetChn:复位编码通道。
HB_VENC_StartRecvFrame:开启编码通道接收输入图像。
HB_VENC_StopRecvFrame:停止编码通道接收输入图像。
HB_VENC_SetChnAttr 设置编码通道的编码属性。
HB_VENC_GetChnAttr:获取编码通道的编码属性。
HB_VENC_GetStream:获取编码码流。
HB_VENC_ReleaseStream:释放码流缓存。
HB_VENC_SendFrame:支持用户发送原始图像进行编码。
HB_VENC_RequestIDR:请求 IDR 帧。
HB_VENC_SetRoiAttr:设置编码通道的感兴趣区域编码配置。
HB_VENC_GetRoiAttr:获取编码通道的感兴趣区域编码配置。
HB_VENC_SetH264SliceSplit:设置 H.264 编码的 slice 分割配置。
HB_VENC_GetH264SliceSplit:获取 H.264 编码的 slice 分割配置。
HB_VENC_SetH264IntraPred:设置 H.264 编码的帧内预测配置。
HB_VENC_GetH264IntraPred:获取 H.264 编码的帧内预测配置。
HB_VENC_SetH264Trans:设置 H.264 编码的变换、量化配置。
HB_VENC_GetH264Trans:获取 H.264 编码的变换、量化配置。
HB_VENC_SetH264Entropy:设置 H.264 编码的熵编码配置。
HB_VENC_GetH264Entropy:获取 H.264 编码的熵编码配置。
HB_VENC_SetH264Dblk:设置 H.264 编码的 deblocking 配置。
HB_VENC_GetH264Dblk:获取 H.264 编码的 deblocking 配置。
HB_VENC_SetH264Vui:设置 H.264 编码的 VUI 配置。
HB_VENC_GetH264Vui:获取 H.264 编码的 VUI 配置。
HB_VENC_SetH265Vui:设置 H.265 协议编码通道的 VUI 参数。
HB_VENC_GetH265Vui:获取 H.265 协议编码通道的 VUI 配置
HB_VENC_SetRcParam:设置通道码率控制高级参数。
HB_VENC_GetRcParam:获取通道码率控制高级参数。
HB_VENC_SetRefParam:设置 H.264/H.265 编码通道高级跳帧参考参数。
HB_VENC_GetRefParam:获取 H.264/H.265 编码通道高级跳帧参考参数。
HB_VENC_SetH265SliceSplit:设置 H.265 编码的 slice 分割配置。
HB_VENC_GetH265SliceSplit:获取 H.265 编码的 slice 分割配置。
HB_VENC_SetH265PredUnit:设置 H.265 编码的 PU 配置。
HB_VENC_GetH265PredUnit:获取 H.265 编码的 PU 配置。
HB_VENC_SetH265Trans:设置 H.265 编码的变换、量化配置。
HB_VENC_GetH265Trans:获取 H.265 编码的变换、量化配置。
HB_VENC_SetH265Dblk:设置 H.265 编码的 deblocking 配置。
HB_VENC_GetH265Dblk:获取 H.265 编码的 deblocking 配置。
HB_VENC_SetH265Sao:设置 H.265 编码的 SAO 配置。
HB_VENC_GetH265Sao:获取 H.265 编码的 SAO 配置。
HB_VENC_GetIntraRefresh:获取 P 帧刷 Islice 的设置参数。
HB_VENC_SetIntraRefresh:设置 P 帧刷 Islice 的参数。
HB_VENC_SetCuPrediction:设置 CU 模式的倾向性。
HB_VENC_GetCuPrediction:获取 CU 模式的倾向性配置。
HB_VENC_GetFd: 获取编码通道对应的设备文件句柄。
HB_VENC_CloseFd:关闭编码通道对应的设备文件句柄。
HB_VENC_QueryStatus:查询编码通道状态。
HB_VENC_InserUserData:插入用户数据。
HB_VENC_SendFrameEx:发送原始图像及该图的QpMap表进行编码
HB_VENC_CreateChn
【函数声明】
int32_t HB_VENC_CreateChn(VENC_CHN VeChn, const VENC_CHN_ATTR_S *pstAttr);
【功能描述】
创建编码通道。
【参数描述】
参数名称 | 描述 | 输入/输出 |
---|---|---|
VeChn | 编码通道号。 取值范围:[0, VENC_MAX_CHN_NUM)。 H264/H265最大支持32通道,JPEG/MJPEG最大支持64通道。 | 输入 |
pstAttr | 编码通道属性指针 | 输入 |
【返回值】
返回值 | 描述 |
---|---|
0 | 成功 |
非0 | 失败,参见错误码。 |
【注意事项】
无
【参考代码】
HB_VENC_GetStream参考代码
HB_VENC_DestroyChn
【函数声明】
int32_t HB_VENC_DestroyChn(VENC_CHN VeChn);
【功能描述】
销毁编码通道。
【参数描述】
参数名称 | 描述 | 输入/输出 |
---|---|---|
VeChn | 编码通道号。 取值范围:[0, VENC_MAX_CHN_NUM) | 输入 |
【返回值】
返回值 | 描述 |
---|---|
0 | 成功 |
非0 | 失败,参见错误码。 |
【注意事项】
无
【参考代码】
HB_VENC_GetStream参考代码
HB_VENC_ResetChn
【函数声明】
int32_t HB_VENC_ResetChn(VENC_CHN VeChn);
【功能描述】
复位编码通道。
【参数描述】
参数名称 | 描述 | 输入/输出 |
---|---|---|
VeChn | 编码通道号。 取值范围:[0, VENC_MAX_CHN_NUM) | 输入 |
【返回值】
返回值 | 描述 |
---|---|
0 | 成功 |
非0 | 失败,参见错误码。 |
【注意事项】
无
【参考代码】
HB_VENC_GetStream参考代码
HB_VENC_StartRecvFrame
【函数声明】
int32_t HB_VENC_StartRecvFrame(VENC_CHN VeChn, const VENC_RECV_PIC_PARAM_S *pstRecvParam);
【功能描述】
开启编码通道接收输入图像。
【参数描述】
参数名称 | 描述 | 输入/输出 |
---|---|---|
VeChn | 编码通道号。 取值范围:[0, VENC_MAX_CHN_NUM) | 输入 |
pstRecvParam | 接收图像参数结构体指针,用于指定需要接收的图像帧数。 输入 |
【返回值】
返回值 | 描述 |
---|---|
0 | 成功 |
非0 | 失败,参见错误码。 |
【注意事项】
需要在HB_VENC_SetChnAttr设置完通道属性后,才能调用。
【参考代码】
HB_VENC_GetStream参考代码
HB_VENC_StopRecvFrame
【函数声明】
int32_t HB_VENC_StopRecvFrame(VENC_CHN VeChn);
【功能描述】
停止编码通道接收输入图像。
【参数描述】
参数名称 | 描述 | 输入/输出 |
---|---|---|
VeChn | 编码通道号。 取值范围:[0, VENC_MAX_CHN_NUM) | 输入 |
【返回值】
返回值 | 描述 |
---|---|
0 | 成功 |
非0 | 失败,参见错误码。 |
【注意事项】
无
【参考代码】
HB_VENC_GetStream参考代码
HB_VENC_SetChnAttr
【函数声明】
int32_t HB_VENC_SetChnAttr(VENC_CHN VeChn, const VENC_CHN_ATTR_S *pstChnAttr);
【功能描述】
设置编码通道的编码属性。
【参数描述】
参数名称 | 描述 | 输入/输出 |
---|---|---|
VeChn | 编码通道号。 取值范围:[0, VENC_MAX_CHN_NUM) | 输入 |
pstChnAttr | 编码通道属性指针 | 输入 |
【返回值】
返回值 | 描述 |
---|---|
0 | 成功 |
非0 | 失败,参见错误码。 |
【注意事项】
需要先HB_VENC_CreateChn创建通道。
【参考代码】
HB_VENC_GetStream参考代码
HB_VENC_GetChnAttr
【函数声明】
int32_t HB_VENC_GetChnAttr(VENC_CHN VeChn, VENC_CHN_ATTR_S *pstChnAttr);
【功能描述】
获取编码通道的编码属性。
【参数描述】
参数名称 | 描述 | 输入/输出 |
---|---|---|
VeChn | 编码通道号。 取值范围:[0, VENC_MAX_CHN_NUM) | 输入 |
pstChnAttr | 编码通道属性指针 | 输入 |
【返回值】
返回值 | 描述 |
---|---|
0 | 成功 |
非0 | 失败,参见错误码。 |
【注意事项】
无
【参考代码】
HB_VENC_GetStream参考代码
HB_VENC_GetStream
【函数声明】
int32_t HB_VENC_GetStream(VENC_CHN VeChn, VIDEO_STREAM_S *pstStream, int32_t s32MilliSec);
【功能描述】
获取编码码流。
【参数描述】
参数名称 | 描述 | 输入/输出 |
---|---|---|
VeChn | 编码通道号。 取值范围:[0, VENC_MAX_CHN_NUM) | 输入 |
pstStream | 码流结构体指针 | 输入 |
s32MilliSec | 获取码流超时时间。 取值范围:[-1, + ∞ ) -1:阻塞。 0:非阻塞。 大于 0:超时时间。 | 输入 |
【返回值】
返回值 | 描述 |
---|---|
0 | 成功 |
非0 | 失败,参见错误码。 |
【注意事项】
无
【参考代码】
VENC_CHN VeChn = 0;
int32_t s32Ret = 0;
int32_t Width = 640;
int32_t Height = 480;
FILE *inFile;
char *inputFileName = "./venc/yuv/input_640x480_yuv420p.yuv";
inFile = fopen(inputFileName, "rb");
ASSERT_NE(inFile, nullptr);
char* mmz_vaddr[10];
int32_t i = 0;
for (i=0;i<10;i++) {
mmz_vaddr[i] = NULL;
}
uint64_t mmz_paddr[10];
memset(mmz_paddr, 0, sizeof(mmz_paddr));
int32_t mmz_size = Width * Height * 3 / 2;
VP_CONFIG_S struVpConf;
memset(&struVpConf, 0x00, sizeof(VP_CONFIG_S));
struVpConf.u32MaxPoolCnt = 32;
HB_VP_SetConfig(&struVpConf);
s32Ret = HB_VP_Init();
if (s32Ret != 0) {
printf("vp_init fail s32Ret = %d !\n",s32Ret);
}
for (i = 0; i < 10; i++) {
s32Ret = HB_SYS_Alloc(&mmz_paddr[i], (void **)&mmz_vaddr[i], mmz_size);
if (s32Ret == 0) {
printf("mmzAlloc paddr = 0x%x, vaddr = 0x%x i = %d \n", mmz_paddr[i], mmz_vaddr[i],i);
}
}
int32_t s32ReadLen = 0;
for (i = 0; i < 10; i++) {
s32ReadLen = fread(mmz_vaddr[i], 1, mmz_size, inFile);
printf("s32ReadLen = %d !!!!!\n", s32ReadLen);
if (s32ReadLen == 0) {
printf("read over !!!\n");
}
}
/* if (inFile) fclose(inFile); */
VENC_CHN_ATTR_S m_VencChnAttr;
memset(&m_VencChnAttr, 0, sizeof(VENC_CHN_ATTR_S));
m_VencChnAttr.stVencAttr.enType = PT_H264;
m_VencChnAttr.stVencAttr.u32PicWidth = Width;
m_VencChnAttr.stVencAttr.u32PicHeight = Height;
m_VencChnAttr.stVencAttr.enMirrorFlip = DIRECTION_NONE;
m_VencChnAttr.stVencAttr.enRotation = CODEC_ROTATION_0;
m_VencChnAttr.stVencAttr.stCropCfg.bEnable = HB_FALSE;
m_VencChnAttr.stVencAttr.stAttrH264.h264_profile = 0;
m_VencChnAttr.stVencAttr.stAttrH264.h264_level = 0;
m_VencChnAttr.stGopAttr.u32GopPresetIdx = 2;
m_VencChnAttr.stGopAttr.s32DecodingRefreshType = 2;
m_VencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
VENC_RC_ATTR_S *pstRcParam = &(m_VencChnAttr.stRcAttr);
s32Ret = HB_VENC_GetRcParam(VeChn, pstRcParam);
pstRcParam->stH264Cbr.u32BitRate = 3000;
pstRcParam->stH264Cbr.u32FrameRate = 30;
pstRcParam->stH264Cbr.u32IntraPeriod = 30;
pstRcParam->stH264Cbr.u32VbvBufferSize = 3000;
s32Ret = HB_VENC_CreateChn(VeChn, &m_VencChnAttr);
HB_VENC_SetChnAttr(VeChn, &m_VencChnAttr); // config
VENC_RECV_PIC_PARAM_S pstRecvParam;
pstRecvParam.s32RecvPicNum = 0; // unchangable
s32Ret = HB_VENC_StartRecvFrame(VeChn, &pstRecvParam);
VIDEO_FRAME_S pstFrame;
VIDEO_STREAM_S pstStream;
memset(&pstFrame, 0, sizeof(VIDEO_FRAME_S));
memset(&pstStream, 0, sizeof(VIDEO_STREAM_S));
pstFrame.stVFrame.width = Width;
pstFrame.stVFrame.height = Height;
pstFrame.stVFrame.size = mmz_size;
int32_t offset = Width * Height;
for (i=0;i<10;i++) {
pstFrame.stVFrame.phy_ptr[0] = mmz_paddr[i];
pstFrame.stVFrame.phy_ptr[1] = mmz_paddr[i] + offset;
pstFrame.stVFrame.phy_ptr[2] = mmz_paddr[i] + offset * 5 / 4;
pstFrame.stVFrame.vir_ptr[0] = mmz_vaddr[i];
pstFrame.stVFrame.vir_ptr[1] = mmz_vaddr[i] + offset;
pstFrame.stVFrame.vir_ptr[2] = mmz_vaddr[i] + offset * 5 / 4;
if (i == 9) {
pstFrame.stVFrame.frame_end = HB_TRUE;
}
s32Ret = HB_VENC_SendFrame(VeChn, &pstFrame, 3000);
usleep(300000);
s32Ret = HB_VENC_GetStream(VeChn, &pstStream, 3000);
EXPECT_EQ(s32Ret, (int32_t)0);
printf("i = %d pstStream.pstPack.size = %d !!!!!\n", i, pstStream.pstPack.size);
s32Ret = HB_VENC_ReleaseStream(VeChn, &pstStream);
}
s32Ret = HB_VENC_StopRecvFrame(VeChn);
s32Ret = HB_VENC_DestroyChn(VeChn);
for (i = 0; i < 10; i++) {
s32Ret = HB_SYS_Free(mmz_paddr[i], mmz_vaddr[i]);
if (s32Ret == 0) {
printf("mmzFree paddr = 0x%x, vaddr = 0x%x i = %d \n", mmz_paddr[i],
mmz_vaddr[i], i);
}
}
s32Ret = HB_VP_Exit();
if (s32Ret == 0) printf("vp exit ok!\n");
printf("GetStream_Test\n");
if (inFile) fclose(inFile);