Hi3536的SDK定义了一些常见的分辨率,诸如3840X2160@30/1920X1080@60/3840X2160@60等:
typedef enum hiVO_INTF_SYNC_E
{
VO_OUTPUT_PAL = 0,
VO_OUTPUT_NTSC,
VO_OUTPUT_960H_PAL, /* ITU-R BT.1302 960 x 576 at 50 Hz (interlaced)*/
VO_OUTPUT_960H_NTSC, /* ITU-R BT.1302 960 x 480 at 60 Hz (interlaced)*/
VO_OUTPUT_1080P24,
VO_OUTPUT_1080P25,
VO_OUTPUT_1080P30,
VO_OUTPUT_720P50,
VO_OUTPUT_720P60,
VO_OUTPUT_1080I50,
VO_OUTPUT_1080I60,
VO_OUTPUT_1080P50,
VO_OUTPUT_1080P60,
VO_OUTPUT_576P50,
VO_OUTPUT_480P60,
VO_OUTPUT_640x480_60, /* VESA 640 x 480 at 60 Hz (non-interlaced) CVT */
VO_OUTPUT_800x600_60, /* VESA 800 x 600 at 60 Hz (non-interlaced) */
VO_OUTPUT_1024x768_60, /* VESA 1024 x 768 at 60 Hz (non-interlaced) */
VO_OUTPUT_1280x1024_60, /* VESA 1280 x 1024 at 60 Hz (non-interlaced) */
VO_OUTPUT_1366x768_60, /* VESA 1366 x 768 at 60 Hz (non-interlaced) */
VO_OUTPUT_1440x900_60, /* VESA 1440 x 900 at 60 Hz (non-interlaced) CVT Compliant */
VO_OUTPUT_1280x800_60, /* 1280*800@60Hz VGA@60Hz*/
VO_OUTPUT_1680x1050_60, /* VESA 1680 x 1050 at 60 Hz (non-interlaced) */
VO_OUTPUT_1920x2160_30, /* 1920x2160_30 */
VO_OUTPUT_1600x1200_60, /* VESA 1600 x 1200 at 60 Hz (non-interlaced) */
VO_OUTPUT_1920x1200_60, /* VESA 1920 x 1600 at 60 Hz (non-interlaced) CVT (Reduced Blanking)*/
VO_OUTPUT_2560x1440_30, /* 2560x1440_30 */
VO_OUTPUT_2560x1440_60, /* 2560x1440_60 */
VO_OUTPUT_2560x1600_60, /* 2560x1600_60 */
VO_OUTPUT_3840x2160_25, /* 3840x2160_25 */
VO_OUTPUT_3840x2160_30, /* 3840x2160_30 */
VO_OUTPUT_3840x2160_50, /* 3840x2160_50 */
VO_OUTPUT_3840x2160_60, /* 3840x2160_60 */
VO_OUTPUT_USER,
VO_OUTPUT_BUTT
} VO_INTF_SYNC_E;
但是它不一定都满足我们的需求,譬如,给LED屏幕显示,分辨率可能是奇怪的,那么怎么办呢?
不用担心,海思提供了接口供我们解决这类问题,就是VO_OUTPUT_USER,即自定义输出时序。下面给出一个例子:
static HI_S32 SAMPLE_COMM_VO_StartDev2(VO_DEV VoDev, VO_PUB_ATTR_S *pstPubAttr, HI_S32 u32Fps)
{
HI_S32 s32Ret = HI_SUCCESS;
s32Ret = HI_MPI_VO_SetPubAttr(VoDev, pstPubAttr);
...
//设置用户时序下的设备输出帧率(文档要求)
s32Ret = HI_MPI_VO_SetDevFrameRate(VoDev, u32Fps); //该接口只能配置为25、30、50、60
...
s32Ret = HI_MPI_VO_Enable(VoDev);
...
return s32Ret;
}
HI_S32 HiUsrDisplayTimingConfig(USR_DISPLAY_TIMING_S *pstTiming)
{
HI_S32 s32Ret = -1;
VO_DEV voDev = SAMPLE_VO_DEV_DHD0;
VO_LAYER voLayer = SAMPLE_VO_LAYER_VHD0;
VO_PUB_ATTR_S stVoPubAttr;
VO_VIDEO_LAYER_ATTR_S stVoLayerAttr;
memset(&stVoPubAttr,0,sizeof(VO_PUB_ATTR_S));
memset(&stVoLayerAttr,0,sizeof(VO_VIDEO_LAYER_ATTR_S));
stVoPubAttr.enIntfSync = VO_OUTPUT_USER; //接口时序类型
stVoPubAttr.enIntfType = VO_INTF_HDMI; //接口类型
stVoPubAttr.u32BgColor = 0x000000ff; //设备背景色
stVoPubAttr.stSyncInfo.bSynm = HI_FALSE; //保留字段
stVoPubAttr.stSyncInfo.u8Intfb = 8; //保留字段
stVoPubAttr.stSyncInfo.bIdv = HI_FALSE; //保留字段
stVoPubAttr.stSyncInfo.bIop = pstTiming->bIop; //逐行或隔行扫描
stVoPubAttr.stSyncInfo.u16Vact = pstTiming->u16Vact; //垂直有效区域
stVoPubAttr.stSyncInfo.u16Vbb = pstTiming->u16Vbb; //垂直消隐后肩
stVoPubAttr.stSyncInfo.u16Vfb = pstTiming->u16Vfb; //垂直消隐前肩
stVoPubAttr.stSyncInfo.u16Hact = pstTiming->u16Hact; //水平有效区域
stVoPubAttr.stSyncInfo.u16Hbb = pstTiming->u16Hbb; //水平消隐后肩
stVoPubAttr.stSyncInfo.u16Hfb = pstTiming->u16Hfb; //水平消隐前肩
stVoPubAttr.stSyncInfo.u16Hpw = pstTiming->u16Hpw; //水平同步宽度
stVoPubAttr.stSyncInfo.u16Vpw = pstTiming->u16Vpw; //垂直同步宽度
stVoPubAttr.stSyncInfo.bIhs = pstTiming->bIhs; //hs极性
stVoPubAttr.stSyncInfo.bIvs = pstTiming->bIvs; //vs极性
//隔行扫描相关参数
stVoPubAttr.stSyncInfo.u16Hmid = pstTiming->u16Hmid;
stVoPubAttr.stSyncInfo.u16Bvact = pstTiming->u16Bvact;
stVoPubAttr.stSyncInfo.u16Bvbb = pstTiming->u16Bvbb;
stVoPubAttr.stSyncInfo.u16Bvfb = pstTiming->u16Bvfb;
s32Ret = SAMPLE_COMM_VO_StartDev2(voDev, &stVoPubAttr, pstTiming->u32Fps);
//根据像素时钟,设置vpll0寄存器的参数
SetVpll0(pstTiming->u32PixelClock);
s32Ret = SAMPLE_COMM_VO_HdmiStart(VO_OUTPUT_3840x2160_30); //使用VO_OUTPUT_3840x2160_30做个样子即可
...
stVoLayerAttr.bClusterMode = HI_FALSE;
stVoLayerAttr.bDoubleFrame = HI_FALSE;
stVoLayerAttr.enPixFormat = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
stVoLayerAttr.stDispRect.u32Width = pstTiming->u16Hact;
stVoLayerAttr.stDispRect.u32Height = pstTiming->u16Vact;
stVoLayerAttr.u32DispFrmRt = pstTiming->u32Fps;
stVoLayerAttr.stImageSize.u32Width = stVoLayerAttr.stDispRect.u32Width ;
stVoLayerAttr.stImageSize.u32Height = stVoLayerAttr.stDispRect.u32Height ;
s32Ret = SAMPLE_COMM_VO_StartLayer(voLayer, &stVoLayerAttr);
...
s32Ret = SAMPLE_COMM_VO_StartChn(voLayer, VO_MODE_1MUX);
return s32Ret;
}
//使用参考:
USR_DISPLAY_TIMING_S stTiming[] =
{
[0] = {
.u32Fps = 60 , //帧率,只能配置为25、30、50、60
.u32PixelClock = 101000 , //像素时钟101MHz(REDUCED BLANKING)
.bIop = 1 , //逐行扫描
.u16Vact = 1050 , //垂直有效区域
.u16Vbb = 23 , //垂直消隐后肩
.u16Vfb = 3 , //垂直消隐前肩
.u16Hact = 1400 , //水平有效区域
.u16Hbb = 80 , //水平消隐后肩
.u16Hfb = 48 , //水平消隐前肩
.u16Hpw = 32 , //水平同步宽度
.u16Vpw = 4 , //垂直同步宽度
.bIhs = 0 , //hs极性 0为高有效,1为低有效
.bIvs = 1 , //vs极性 0为高有效,1为低有效
},
[1] = {
.u32Fps = 60 , //帧率,只能配置为25、30、50、60
.u32PixelClock = 148500 , //像素时钟148.5MHz
.bIop = 1 , //逐行扫描
.u16Vact = 1080 , //垂直有效区域
.u16Vbb = 36 , //垂直消隐后肩
.u16Vfb = 4 , //垂直消隐前肩
.u16Hact = 1920 , //水平有效区域
.u16Hbb = 148 , //水平消隐后肩
.u16Hfb = 88 , //水平消隐前肩
.u16Hpw = 44 , //水平同步宽度
.u16Vpw = 5 , //垂直同步宽度
.bIhs = 0 , //hs极性 0为高有效,1为低有效
.bIvs = 0 , //vs极性 0为高有效,1为低有效
},
// ...
//...
};
USR_DISPLAY_TIMING_S *pstTiming = &stTiming[1];
HiUsrDisplayTimingConfig(pstTiming);
上面的代码完全就是按照海思SDK里01.software/board/document_cn/《HiMPP V3.0 媒体处理软件 FAQ.pdf》文档的”3.6 如何设置VO的用户时序“章节的描述写出来的,包括各参数意义说明、vpll0配置方法以及VO帧率设置,我并没有创新之处!
Vpll0的配置参考文章《https://blog.csdn.net/litao31415/article/details/107326413》,
以及SDK提及的: