【海思SS528 | VO】MPP媒体处理软件V5.0 | VO模块编程总结
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍VO模块使用总结🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭
本文未经允许,不得转发!!!
目录
- 🎄一、概述
- 🎄二、VO设备
- ✨2.1 设置VO设备公共属性 hi_mpi_vo_set_pub_attr
- ✨2.2 使能VO设备 hi_mpi_vo_enable
- 🎄三、VO视频层
- ✨3.1 设置视频层属性 hi_mpi_vo_set_video_layer_attr
- ✨3.2 使能视频层 hi_mpi_vo_enable_video_layer
- 🎄四、VO通道
- ✨4.1 设置VO通道属性 hi_mpi_vo_set_chn_attr
- ✨4.2 使能VO通道 hi_mpi_vo_enable_chn
- 🎄五、VO模块工作过程
- ✨5.1 将视频图像送入VO通道显示 hi_mpi_vo_send_frame
- 🎄六、VO模块销毁
🎄一、概述
上篇文章,我们学习了海思SS528的视频输出模块的一些基础知识,本文总结一下海思视频输出(VO)的使用。
使用海思的视频输出时,我们需要做下面几个步骤:
- 1.设置VO设备公共属性、使能VO设备;
- 2.设置视频层属性,使能视频层;
- 3.设置VO通道属性,使能VO通道;
- 4.向VO通道发送视频数据;
- 5.使用后,可以销毁解码通道。
🎄二、VO设备
✨2.1 设置VO设备公共属性 hi_mpi_vo_set_pub_attr
VO设备公共属性的结构体如下:
typedef struct {
td_u32 bg_color; /* RW; background color of a device, in RGB format. */
ot_vo_intf_type intf_type; /* RW; type of a VO interface */
ot_vo_intf_sync intf_sync; /* RW; type of a VO interface timing */
ot_vo_sync_info sync_info; /* RW; information about VO interface timing */
} ot_vo_pub_attr;
结构体成员:
- bg_color:设备背景色,表示方法RGB888
- intf_type:设备接口类型
- intf_sync:接口时序
- sync_info:接口时序信息。intf_sync配置用户时序OT_VO_OUT_USER时,该结构体生效
看例子:
hi_vo_pub_attr vo_pub_attr = { 0 };
vo_pub_attr.intf_type = HI_VO_INTF_HDMI;
vo_pub_attr.intf_sync = HI_VO_OUT_3840x2160_30;
vo_pub_attr.bg_color = 0x0000FF;
ret = hi_mpi_vo_set_pub_attr(vo_dev, pub_attr);
注意:
1、可以同时使用多个接口类型示意: intf_type = OT_VO_INTF_BT1120 | OT_VO_INTF_HDMI
2、所有接口均支持用户时序
✨2.2 使能VO设备 hi_mpi_vo_enable
使能VO设备时通过调用函数 hi_mpi_vo_enable
,并指定设备号。函数原型如下:
hi_s32 hi_mpi_vo_enable(hi_vo_dev dev);
VO设备号:
#define SAMPLE_VO_DEV_DHD0 0 /* VO's device HD0 */
#define SAMPLE_VO_DEV_DHD1 1 /* VO's device HD1 */
#define SAMPLE_VO_DEV_DSD0 2 /* VO's device SD0 */
#define SAMPLE_VO_DEV_UHD SAMPLE_VO_DEV_DHD0 /* VO's ultra HD device:HD0 */
#define SAMPLE_VO_DEV_HD SAMPLE_VO_DEV_DHD1 /* VO's HD device:HD1 */
注意:
1.在调用设备使能前,必须对设备公共属性进行配置,否则返回设备未配置错误
2.如果设备已经使能,调用此接口则返回未禁用错误,不支持重复使能。
🎄三、VO视频层
✨3.1 设置视频层属性 hi_mpi_vo_set_video_layer_attr
VO视频层属性的结构体如下
typedef struct {
ot_rect display_rect; /* RW; display resolution */
ot_size img_size; /* RW; canvas size of the video layer */
td_u32 display_frame_rate; /* RW; display frame rate */
ot_pixel_format pixel_format; /* RW; pixel format of the video layer */
td_bool double_frame_en; /* RW; whether to double frames */
td_bool cluster_mode_en; /* RW; whether to take cluster way to use memory */
ot_dynamic_range dst_dynamic_range; /* RW; video layer output dynamic range type */
td_u32 display_buf_len; /* RW; Video Layer display buffer length */
ot_vo_partition_mode partition_mode; /* RW; Video Layer partition mode */
ot_compress_mode compress_mode; /* RW; Compressing mode */
} ot_vo_video_layer_attr;
结构体成员:
display_rect
:视频显示区域矩形结构体, SINGLE模式下display_rect为动态属性; MULTI模式下display_rect为静态属性。img_size
:图像分辨率结构体,即合成画面尺寸,静态属性。- display_frame_rate:视频显示帧率,静态属性
pixel_format
:视频层输入像素格式: YVU420 SEMIPLANAR, YVU422 SEMIPLANAR,YUV420 SEMIPLANAR
, YUV422 SEMIPLANAR, YUV400,静态属性- double_frame_en:视频层倍帧开关,静态属性
- cluster_mode_en:视频层内存聚集使能开关,静态属性。
- dst_dynamic_range:视频层输出动态范围类型,静态属性。
- display_buf_len:视频层显示缓存的长度,静态属性。
非省buffer方案下取值范围: [0], [3, 15]。
省buffer方案下取值范围: [0], [2,15]partition_mode
: 视频层的分割模式: OT_VO_PARTITION_MODE_SINGLE,OT_VO_PARTITION_MODE_MULTI,静态属性。- compress_mode:视频层支持压缩或解压模式:支持OT_COMPRESS_MODE_NONE,OT_COMPRESS_MODE_SEG, OT_COMPRESS_MODE_SEG_COMPACT,OT_COMPRESS_MODE_LINE,静态属性。
注意:
1.img_size和display_rect的范围都要大于或等于显示的最小分辨率32x32。
2.img_size和display_rect要求2对齐。
3.对于不支持缩放的视频层,通常保持图像分辨率和显示分辨率一致
更多注意点可以看《MPP媒体处理软件V5.0》的ot_vo_video_layer_attr
结构体。
✨3.2 使能视频层 hi_mpi_vo_enable_video_layer
使能VO视频层时通过调用函数 hi_mpi_vo_enable_video_layer
,并指定设备层号。函数原型如下:
hi_s32 hi_mpi_vo_enable_video_layer(hi_vo_layer layer);
注意:
- 1、视频层使能前必须保证该视频层所绑定的设备处于使能状态。
- 2、视频层使能前必须保证该视频层已经配置
- 3、视频输出模块有4个视频层和4个图形层,如下定义:
0: OT_VO_LAYER_V0,即视频层0;
1: OT_VO_LAYER_V1,即视频层1;
2: OT_VO_LAYER_V2,即视频层2,用作PIP层;
3: OT_VO_LAYER_V3,即视频层3。
4: OT_VO_LAYER_G0,即图形层0。
5: OT_VO_LAYER_G1,即图形层1。
6: OT_VO_LAYER_G2,即图形层2,用作鼠标层。
7: OT_VO_LAYER_G3,即图形层3 - 4、V0/V1/V3/G0/G1视频层和图形层固定绑定在相应的设备上面, PIP视频层V2可以选择绑定在设备DHD0或DHD1上,鼠标层G2可以选择绑定到设备DHD0/DHD1/DSD0上,图形层G3可以选择绑定到设备DHD0/DHD1/DSD0上。
更多注意点可以看《MPP媒体处理软件V5.0》的ot_vo_layer
结构体。
🎄四、VO通道
✨4.1 设置VO通道属性 hi_mpi_vo_set_chn_attr
VO通道属性的结构体如下
typedef struct {
td_u32 priority; /* RW; video out overlay priority sd */
ot_rect rect; /* RW; rectangle of video output channel */
td_bool deflicker_en; /* RW; deflicker or not sd */
} ot_vo_chn_attr;
结构体成员:
priority
:视频通道叠加优先级,数值越大优先级越高,优先级高的在上层。该属性只在SINGLE模式下有效。rect
:通道矩形显示区域。以屏幕的左上角为原点。其取值必须是2对齐,且该矩形区域必须在屏幕范围之内。deflicker_en
:是否使能抗闪烁。
TD_TRUE:使能;
TD_FALSE:禁用。
抗闪烁效果需要调用VGS实现,固只在SINGLE模式下有效。
注意:
1.SINGLE模式下,当多个通道有重叠的显示区域时,优先级高的通道图像将覆盖优先级低的通道。优先级相同的各通道有重叠时,默认通道号大的图像将覆盖通道号小的通道图像。
2.如果有视频层放大的情况, rect是放大前视频层上的起始位置和宽高,放大后显示的起始位置和宽高会按视频层放大的比例偏移或放大。
3.通道显示区域不能超过视频层属性中设定的画布大小(img_size大小)。
✨4.2 使能VO通道 hi_mpi_vo_enable_chn
使能指定的视频输出通道可以调用函数hi_mpi_vo_enable_chn
,并指定视频层和通道。函数原型如下:
hi_s32 hi_mpi_vo_enable_chn(hi_vo_layer layer, hi_vo_chn chn);
注意:
1.调用前必须使能相应设备上的视频层
2.通道使能前必须进行通道配置,否则返回通道未配置的错误
3.允许重复使能同一视频输出通道,不返回失败。
🎄五、VO模块工作过程
✨5.1 将视频图像送入VO通道显示 hi_mpi_vo_send_frame
如果VO模块没有绑定源模块,则可以调用函数hi_mpi_vo_send_frame
来将将视频图像送入VO通道显示。函数原型如下:
hi_s32 hi_mpi_vo_send_frame(hi_vo_layer layer, hi_vo_chn chn, const hi_video_frame_info *frame_info,
hi_s32 milli_sec);
注意:
1.调用该接口前必须保证通道已经使能
2.输入视频数据信息要符合VO数据的要求。宽和高需要与实际图像宽高相符,且均不能小于32,宽高要求以2对齐。像素格式为SPYCbCr420、 SPYCbCr422、SPYCrCb420、 SPYCrCb422或者单分量格式。视频格式支持LINEAR和TILE格式。
LINEAR视频格式的压缩模式支持非压缩,行压缩,紧凑型段压缩和非紧凑段压缩模式,通道支持的具体的确切的压缩模式与对应视频层相同。 TILE视频格式的压缩模式支持非压缩, TILE压缩
🎄六、VO模块销毁
1.先禁用VO通道
for (i = 0; i < (hi_s32)wnd_info.wnd_num; i++) {
ret = hi_mpi_vo_disable_chn(vo_layer, i);
if (ret != HI_SUCCESS) {
sample_print("failed with %#x!\n", ret);
return HI_FAILURE;
}
}
2.禁用VO视频层
hi_s32 sample_comm_vo_stop_layer(hi_vo_layer vo_layer)
{
hi_s32 ret;
ret = hi_mpi_vo_disable_video_layer(vo_layer);
if (ret != HI_SUCCESS) {
sample_print("failed with %#x!\n", ret);
return HI_FAILURE;
}
return HI_SUCCESS;
}
3.禁用VO设备
hi_s32 sample_comm_vo_stop_dev(hi_vo_dev vo_dev)
{
hi_s32 ret;
ret = hi_mpi_vo_disable(vo_dev);
if (ret != HI_SUCCESS) {
sample_print("failed with %#x!\n", ret);
return HI_FAILURE;
}
return HI_SUCCESS;
}
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁