/****************************************************************************** Some simple Hisilicon Hi3531 video output functions. Copyright (C), 2010-2011, Hisilicon Tech. Co., Ltd. ****************************************************************************** Modification: 2011-2 Created ******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sample_comm.h" static HI_S32 gs_s32SnapCnt = 0; HI_S32 SAMPLE_COMM_VO_GetWH(VO_INTF_SYNC_E enIntfSync, HI_U32 *pu32W,HI_U32 *pu32H, HI_U32 *pu32Frm) { switch (enIntfSync) { case VO_OUTPUT_PAL : *pu32W = 720; *pu32H = 576; *pu32Frm = 25; break; case VO_OUTPUT_NTSC : *pu32W = 720; *pu32H = 480; *pu32Frm = 30; break; case VO_OUTPUT_576P50 : *pu32W = 720; *pu32H = 576; *pu32Frm = 50; break; case VO_OUTPUT_480P60 : *pu32W = 720; *pu32H = 480; *pu32Frm = 60; break; case VO_OUTPUT_800x600_60: *pu32W = 800; *pu32H = 600; *pu32Frm = 60; break; case VO_OUTPUT_720P50 : *pu32W = 1280; *pu32H = 720; *pu32Frm = 50; break; case VO_OUTPUT_720P60 : *pu32W = 1280; *pu32H = 720; *pu32Frm = 60; break; case VO_OUTPUT_1080I50 : *pu32W = 1920; *pu32H = 1080; *pu32Frm = 50; break; case VO_OUTPUT_1080I60 : *pu32W = 1920; *pu32H = 1080; *pu32Frm = 60; break; case VO_OUTPUT_1080P24 : *pu32W = 1920; *pu32H = 1080; *pu32Frm = 24; break; case VO_OUTPUT_1080P25 : *pu32W = 1920; *pu32H = 1080; *pu32Frm = 25; break; case VO_OUTPUT_1080P30 : *pu32W = 1920; *pu32H = 1080; *pu32Frm = 30; break; case VO_OUTPUT_1080P50 : *pu32W = 1920; *pu32H = 1080; *pu32Frm = 50; break; case VO_OUTPUT_1080P60 : *pu32W = 1920; *pu32H = 1080; *pu32Frm = 60; break; case VO_OUTPUT_1024x768_60: *pu32W = 1024; *pu32H = 768; *pu32Frm = 60; break; case VO_OUTPUT_1280x1024_60: *pu32W = 1280; *pu32H = 1024; *pu32Frm = 60; break; case VO_OUTPUT_1366x768_60: *pu32W = 1366; *pu32H = 768; *pu32Frm = 60; break; case VO_OUTPUT_1440x900_60: *pu32W = 1440; *pu32H = 900; *pu32Frm = 60; break; case VO_OUTPUT_1280x800_60: *pu32W = 1280; *pu32H = 800; *pu32Frm = 60; break; case VO_OUTPUT_1600x1200_60: *pu32W = 1600; *pu32H = 1200; *pu32Frm = 60; break; case VO_OUTPUT_1680x1050_60: *pu32W = 1680; *pu32H = 1050; *pu32Frm = 60; break; case VO_OUTPUT_1920x1200_60: *pu32W = 1920; *pu32H = 1200; *pu32Frm = 60; break; case VO_OUTPUT_3840x2160_30: *pu32W = 3840; *pu32H = 2160; *pu32Frm = 30; break; case VO_OUTPUT_3840x2160_60: *pu32W = 3840; *pu32H = 2160; *pu32Frm = 60; break; case VO_OUTPUT_USER : *pu32W = 720; *pu32H = 576; *pu32Frm = 25; break; default: SAMPLE_PRT("vo enIntfSync not support!\n"); return HI_FAILURE; } return HI_SUCCESS; } /****************************************************************************** * function : Set system memory location ******************************************************************************/ HI_S32 SAMPLE_COMM_VO_MemConfig(VO_DEV VoDev, HI_CHAR *pcMmzName) { HI_S32 s32Ret = HI_SUCCESS; MPP_CHN_S stMppChnVO; /* config vo dev */ stMppChnVO.enModId = HI_ID_VOU; stMppChnVO.s32DevId = VoDev; stMppChnVO.s32ChnId = 0; s32Ret = HI_MPI_SYS_SetMemConf(&stMppChnVO, pcMmzName); if (s32Ret) { SAMPLE_PRT("HI_MPI_SYS_SetMemConf ERR !\n"); return HI_FAILURE; } return HI_SUCCESS; } HI_S32 SAMPLE_COMM_VO_StartDev(VO_DEV VoDev, VO_PUB_ATTR_S *pstPubAttr) { HI_S32 s32Ret = HI_SUCCESS; s32Ret = HI_MPI_VO_SetPubAttr(VoDev, pstPubAttr); if (s32Ret != HI_SUCCESS) { SAMPLE_PRT("failed with %#x!\n", s32Ret); return HI_FAILURE; } s32Ret = HI_MPI_VO_Enable(VoDev); if (s32Ret != HI_SUCCESS) { SAMPLE_PRT("failed with %#x!\n", s32Ret); return HI_FAILURE; } return s32Ret; } HI_S32 SAMPLE_COMM_VO_StopDev(VO_DEV VoDev) { HI_S32 s32Ret = HI_SUCCESS; s32Ret = HI_MPI_VO_Disable(VoDev); if (s32Ret != HI_SUCCESS) { SAMPLE_PRT("failed with %#x!\n", s32Ret); return HI_FAILURE; } return s32Ret; } HI_S32 SAMPLE_COMM_VO_StartLayer(VO_LAYER VoLayer,const VO_VIDEO_LAYER_ATTR_S *pstLayerAttr) { HI_S32 s32Ret = HI_SUCCESS; s32Ret = HI_MPI_VO_SetVideoLayerAttr(VoLayer, pstLayerAttr); if (s32Ret != HI_SUCCESS) { SAMPLE_PRT("failed with %#x!\n", s32Ret); return HI_FAILURE; } s32Ret = HI_MPI_VO_EnableVideoLayer(VoLayer); if (s32Ret != HI_SUCCESS) { SAMPLE_PRT("failed with %#x!\n", s32Ret); return HI_FAILURE; } return s32Ret; } HI_S32 SAMPLE_COMM_VO_StopLayer(VO_LAYER VoLayer) { HI_S32 s32Ret = HI_SUCCESS; s32Ret = HI_MPI_VO_DisableVideoLayer(VoLayer); if (s32Ret != HI_SUCCESS) { SAMPLE_PRT("failed with %#x!\n", s32Ret); return HI_FAILURE; } return s32Ret; } HI_S32 SAMPLE_COMM_VO_StartChn(VO_LAYER VoLayer, SAMPLE_VO_MODE_E enMode) { HI_S32 i; HI_S32 s32Ret = HI_SUCCESS; HI_U32 u32WndNum = 0; HI_U32 u32Square = 0; HI_U32 u32Width = 0; HI_U32 u32Height = 0; VO_CHN_ATTR_S stChnAttr; VO_VIDEO_LAYER_ATTR_S stLayerAttr; HI_S32 s32ChnFrmRate; switch (enMode) { case VO_MODE_1MUX: u32WndNum = 1; u32Square = 1; break; case VO_MODE_4MUX: u32WndNum = 4; u32Square = 2; break; case VO_MODE_9MUX: u32WndNum = 9; u32Square = 3; break; case VO_MODE_16MUX: u32WndNum = 16; u32Square = 4; break; default: SAMPLE_PRT("failed with %#x!\n", s32Ret); return HI_FAILURE; } s32Ret = HI_MPI_VO_GetVideoLayerAttr(VoLayer, &stLayerAttr); if (s32Ret != HI_SUCCESS) { SAMPLE_PRT("failed with %#x!\n", s32Ret); return HI_FAILURE; } u32Width = stLayerAttr.stImageSize.u32Width; u32Height = stLayerAttr.stImageSize.u32Height; printf("u32Width:%d, u32Square:%d\n", u32Width, u32Square); if (stLayerAttr.u32DispFrmRt <= 0) { s32ChnFrmRate = 30; } else if (stLayerAttr.u32DispFrmRt > 30) { s32ChnFrmRate = stLayerAttr.u32DispFrmRt / 2; } else { s32ChnFrmRate = stLayerAttr.u32DispFrmRt; } for (i=0; ienHdmi; HI_HDMI_ATTR_S stHdmiAttr; HI_HDMI_SINK_CAPABILITY_S stSinkCap; HI_HDMI_INFOFRAME_S stHdmiInfoFrame; printf("\n --- hotplug event handling ---\n"); s32Ret = HI_MPI_HDMI_GetAttr(hHdmi, &stHdmiAttr); if(HI_SUCCESS != s32Ret) { printf("HI_MPI_HDMI_GetAttr ERROR \n"); return HI_FAILURE; } s32Ret = HI_MPI_HDMI_GetSinkCapability(hHdmi, &stSinkCap); if(HI_SUCCESS != s32Ret) { printf("HI_MPI_HDMI_GetSinkCapability ERROR \n"); return HI_FAILURE; } if (HI_FALSE == stSinkCap.bConnected ) { printf("stSinkCap.bConnected is HI_FALSE!\n"); return HI_FAILURE; } stHdmiAttr.enVidOutMode = HI_HDMI_VIDEO_MODE_YCBCR444; if(HI_TRUE == stSinkCap.bSupportHdmi) { stHdmiAttr.bEnableHdmi = HI_TRUE; if(HI_TRUE != stSinkCap.bSupportYCbCr) { stHdmiAttr.enVidOutMode = HI_HDMI_VIDEO_MODE_RGB444; } } else { stHdmiAttr.enVidOutMode = HI_HDMI_VIDEO_MODE_RGB444; //read real edid ok && sink not support hdmi,then we run in dvi mode stHdmiAttr.bEnableHdmi = HI_FALSE; } if(HI_TRUE == stHdmiAttr.bEnableHdmi) { stHdmiAttr.bEnableVideo = HI_TRUE; stHdmiAttr.enDeepColorMode = HI_HDMI_DEEP_COLOR_OFF; stHdmiAttr.bxvYCCMode = HI_FALSE; stHdmiAttr.bEnableAudio = HI_FALSE; stHdmiAttr.enSoundIntf = HI_HDMI_SND_INTERFACE_I2S; stHdmiAttr.bIsMultiChannel = HI_FALSE; stHdmiAttr.enBitDepth = HI_HDMI_BIT_DEPTH_16; stHdmiAttr.bEnableAviInfoFrame = HI_TRUE; stHdmiAttr.bEnableAudInfoFrame = HI_TRUE; stHdmiAttr.bEnableSpdInfoFrame = HI_FALSE; stHdmiAttr.bEnableMpegInfoFrame = HI_FALSE; stHdmiAttr.bDebugFlag = HI_FALSE; stHdmiAttr.bHDCPEnable = HI_FALSE; stHdmiAttr.b3DEnable = HI_FALSE; HI_MPI_HDMI_GetInfoFrame(hHdmi, HI_INFOFRAME_TYPE_AVI, &stHdmiInfoFrame); stHdmiInfoFrame.unInforUnit.stAVIInfoFrame.enOutputType = stHdmiAttr.enVidOutMode; HI_MPI_HDMI_SetInfoFrame(hHdmi, &stHdmiInfoFrame); } else { stHdmiAttr.bEnableVideo = HI_TRUE; stHdmiAttr.enVidOutMode = HI_HDMI_VIDEO_MODE_RGB444; stHdmiAttr.enDeepColorMode = HI_HDMI_DEEP_COLOR_OFF; stHdmiAttr.bEnableAudio = HI_FALSE; stHdmiAttr.bEnableAviInfoFrame = HI_FALSE; stHdmiAttr.bEnableAudInfoFrame = HI_FALSE; } if ( pArgs->eForceFmt >= HI_HDMI_VIDEO_FMT_1080P_60 && pArgs->eForceFmt < HI_HDMI_VIDEO_FMT_BUTT && stSinkCap.bVideoFmtSupported[pArgs->eForceFmt] ) { printf("set force format=%d\n",pArgs->eForceFmt); stHdmiAttr.enVideoFmt = pArgs->eForceFmt; } else { printf("not support expected format=%d, we set native format=%d\n",pArgs->eForceFmt,stSinkCap.enNativeVideoFormat); stHdmiAttr.enVideoFmt = stSinkCap.enNativeVideoFormat; } s32Ret = HI_MPI_HDMI_SetAttr(hHdmi, &stHdmiAttr); if(HI_SUCCESS != s32Ret) { printf("HI_MPI_HDMI_SetAttr ERROR \n"); return HI_FAILURE; } /* HI_MPI_HDMI_SetAttr must before HI_MPI_HDMI_Start! */ s32Ret = HI_MPI_HDMI_Start(hHdmi); if(HI_SUCCESS != s32Ret) { printf("HI_MPI_HDMI_Start ERROR \n"); return HI_FAILURE; } return s32Ret; } static HI_S32 SAMPLE_COMM_HdmiUnPlugEvent(HI_VOID *pPrivateData) { HI_S32 s32Ret = HI_SUCCESS; HDMI_CALLBACK_ARGS_S *pArgs = (HDMI_CALLBACK_ARGS_S*)pPrivateData; HI_HDMI_ID_E hHdmi = pArgs->enHdmi; printf("\n --- UnPlug event handling. --- \n"); s32Ret = HI_MPI_HDMI_Stop(hHdmi); if(HI_SUCCESS != s32Ret) { printf("HI_MPI_HDMI_Stop ERROR \n"); return HI_FAILURE; } return s32Ret; } HI_VOID SAMPLE_COMM_HdmiCallbackEvent(HI_HDMI_EVENT_TYPE_E event, HI_VOID *pPrivateData) { printf("\ncallback fun HDMI_EventProc handling event:%d(0x%02x)\n",event,event); switch ( event ) { case HI_HDMI_EVENT_HOTPLUG: printf("[HDMI EVENT]==>HI_HDMI_EVENT_HOTPLUG \n"); SAMPLE_COMM_HdmiHotPlugEvent(pPrivateData); break; case HI_HDMI_EVENT_NO_PLUG: printf("[HDMI EVENT]==>HI_HDMI_EVENT_NO_PLUG \n"); SAMPLE_COMM_HdmiUnPlugEvent(pPrivateData); break; case HI_HDMI_EVENT_EDID_FAIL: printf("[HDMI EVENT]==>HI_HDMI_EVENT_EDID_FAIL \n"); break; case HI_HDMI_EVENT_HDCP_FAIL: printf("[HDMI EVENT]==>HI_HDMI_EVENT_HDCP_FAIL \n"); break; case HI_HDMI_EVENT_HDCP_SUCCESS: printf("[HDMI EVENT]==>HI_HDMI_EVENT_HDCP_SUCCESS \n"); break; case HI_HDMI_EVENT_HDCP_USERSETTING: printf("[HDMI EVENT]==>HI_HDMI_EVENT_HDCP_USERSETTING \n"); break; default: printf("[HDMI EVENT]==>un-known event:%d\n",event); return; } return; } HI_S32 SAMPLE_COMM_VO_HdmiCallbackStart(VO_INTF_SYNC_E enIntfSync, HDMI_CALLBACK_ARGS_S *pstCallbackArgs) { HI_HDMI_VIDEO_FMT_E enVideoFmt; HI_HDMI_INIT_PARA_S stHdmiPara; SAMPLE_COMM_VO_HdmiConvertSync(enIntfSync, &enVideoFmt); pstCallbackArgs->eForceFmt = enVideoFmt; pstCallbackArgs->enHdmi = HI_HDMI_ID_0; stHdmiPara.enForceMode = HI_HDMI_FORCE_HDMI; stHdmiPara.pCallBackArgs = (void *)pstCallbackArgs; stHdmiPara.pfnHdmiEventCallback = SAMPLE_COMM_HdmiCallbackEvent; HI_MPI_HDMI_Init(&stHdmiPara); HI_MPI_HDMI_Open(HI_HDMI_ID_0); printf("HDMI start success.\n"); return HI_SUCCESS; } HI_S32 SAMPLE_COMM_VO_HdmiStart(VO_INTF_SYNC_E enIntfSync) { HI_HDMI_ATTR_S stAttr; HI_HDMI_VIDEO_FMT_E enVideoFmt; HI_HDMI_INIT_PARA_S stHdmiPara; SAMPLE_COMM_VO_HdmiConvertSync(enIntfSync, &enVideoFmt); stHdmiPara.pfnHdmiEventCallback = NULL; stHdmiPara.pCallBackArgs = NULL; stHdmiPara.enForceMode = HI_HDMI_FORCE_HDMI; HI_MPI_HDMI_Init(&stHdmiPara); HI_MPI_HDMI_Open(HI_HDMI_ID_0); HI_MPI_HDMI_GetAttr(HI_HDMI_ID_0, &stAttr); stAttr.bEnableHdmi = HI_TRUE; stAttr.bEnableVideo = HI_TRUE; stAttr.enVideoFmt = enVideoFmt; stAttr.enVidOutMode = HI_HDMI_VIDEO_MODE_YCBCR444; stAttr.enDeepColorMode = HI_HDMI_DEEP_COLOR_OFF; stAttr.bxvYCCMode = HI_FALSE; stAttr.bEnableAudio = HI_FALSE; stAttr.enSoundIntf = HI_HDMI_SND_INTERFACE_I2S; stAttr.bIsMultiChannel = HI_FALSE; stAttr.enBitDepth = HI_HDMI_BIT_DEPTH_16; stAttr.bEnableAviInfoFrame = HI_TRUE; stAttr.bEnableAudInfoFrame = HI_TRUE; stAttr.bEnableSpdInfoFrame = HI_FALSE; stAttr.bEnableMpegInfoFrame = HI_FALSE; stAttr.bDebugFlag = HI_FALSE; stAttr.bHDCPEnable = HI_FALSE; stAttr.b3DEnable = HI_FALSE; HI_MPI_HDMI_SetAttr(HI_HDMI_ID_0, &stAttr); HI_MPI_HDMI_Start(HI_HDMI_ID_0); printf("HDMI start success.\n"); return HI_SUCCESS; } HI_S32 SAMPLE_COMM_VO_HdmiStop(HI_VOID) { HI_MPI_HDMI_Stop(HI_HDMI_ID_0); HI_MPI_HDMI_Close(HI_HDMI_ID_0); HI_MPI_HDMI_DeInit(); return HI_SUCCESS; } HI_S32 SAMPLE_COMM_VO_SnapStart(VENC_CHN VencChn, SIZE_S *pstSize) { HI_S32 s32Ret; VENC_CHN_ATTR_S stVencChnAttr; VENC_ATTR_JPEG_S stJpegAttr; /****************************************** step 1: Create Venc Channel ******************************************/ stVencChnAttr.stVeAttr.enType = PT_JPEG; stJpegAttr.u32MaxPicWidth = pstSize->u32Width; stJpegAttr.u32MaxPicHeight = pstSize->u32Height; stJpegAttr.u32PicWidth = pstSize->u32Width; stJpegAttr.u32PicHeight = pstSize->u32Height; stJpegAttr.u32BufSize = pstSize->u32Width * pstSize->u32Height * 2; stJpegAttr.bByFrame = HI_TRUE;/*get stream mode is field mode or frame mode*/ stJpegAttr.bSupportDCF = HI_FALSE; memcpy(&stVencChnAttr.stVeAttr.stAttrJpeg, &stJpegAttr, sizeof(VENC_ATTR_JPEG_S)); s32Ret = HI_MPI_VENC_CreateChn(VencChn, &stVencChnAttr); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("HI_MPI_VENC_CreateChn [%d] faild with %#x!\n",\ VencChn, s32Ret); return s32Ret; } return HI_SUCCESS; } /****************************************************************************** * funciton : Stop snap ******************************************************************************/ HI_S32 SAMPLE_COMM_VO_SnapStop(VENC_CHN VencChn) { HI_S32 s32Ret; s32Ret = HI_MPI_VENC_StopRecvPic(VencChn); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("HI_MPI_VENC_StopRecvPic vechn[%d] failed with %#x!\n", VencChn, s32Ret); return HI_FAILURE; } s32Ret = HI_MPI_VENC_DestroyChn(VencChn); if (HI_SUCCESS != s32Ret) { SAMPLE_PRT("HI_MPI_VENC_DestroyChn vechn[%d] failed with %#x!\n", VencChn, s32Ret); return HI_FAILURE; } return HI_SUCCESS; }