一、前言
客户需要 Hisilicon DVR 项目上实现 快进/快退 ,暂停播放 ,感兴趣区域的放大缩小功能 ,并要求对这些功能封装函数 ,用命令行的形式对这些功能继续测试 ,接下来我将与大家分享实现这些功能的过程
二、程序运行环境
使用的硬件平台为 :HI3559V200DMEB VER.A
图1 HI3559V200DMEB Board
使用的软件版本为 :Hi3559V200_MobileCam_SDK_V1.0.1.5 , Project Type 为 SampleCam
图2 SampleCam Menuconfig
三、搭建视频回放播放器的环境
3.1 编译 player_sample
Hisilicon 自带视频播放软件 player_sample ,这个软件的路径为 :middleware\sample\liteplayer\player_sample ,
编译结束后会在目录下生成 sample_play 的应用程序
3.2 拷贝库文件
需要将 liteos 测的镜像烧写为 sample/liteos/media_app.bin (对应的压缩镜像为media_app_zip.bin)
把 middleware/sample/liteplayer/player_sample/AAC/libhiaacdec.so拷贝到单板的 /app/sharefs/ 下
将 middleware/component/liteplayer/lib/目录下的 libffmpeg_demuxer.so 拷贝至单板的 /usr/lib/ 下面
3.3 运行 sample_play
把 test.mp4 文件拷贝到 SD 卡
sh /app/komod/mmc_load.sh // 挂载 SD 卡
mount /dev/mmcblk0p1 /mnt // 挂载 SD 卡
./app/sharefs/sharefs &
./sample_play test.mp4
通过以上步骤可以看到 视频可以正常播放,快进/快退 ,暂停/播放 功能都是正常的 ,但抓取感兴趣图像功能没有
四、加入缩放功能
4.1 视频回放的数据流程
图3 视频回放的处理流程图
从上面的流程图可以了解到视频的处理流程 :
MP4 --> VDEC --> VPSS --> VO --> Display
视频文件解码后会通过 VPSS 通道把数据送到 VO ,然后进行显示
4.2 缩放的工作原理
数据在 VPSS 通道经过 CROP 进行扣图 ,通过 VGS 进行缩放 ,然后送到 VO 进行显示
VPSS 的裁剪是通过调用下面的函数完成 :
HI_S32 HI_MPI_VPSS_SetChnCrop(VPSS_GRP VpssGrp, VPSS_CHN VpssChn, const
VPSS_CROP_INFO_S *pstCropInfo);
参数说明 :
VpssGrp : VPSS GROUP 号 [0, VPSS_MAX_GRP_NUM)
VpssChn : VPSS 通道号 取值范围:[0, VPSS_MAX_CHN_NUM)
pstCropInfo : CROP 功能参数
4.3 Linux 和 Liteos 通过 HiSysLink 进行双核间的跨核通信
图4 HiSysLink 双核通信架构图
我们接下来会在 Middleware 的 Client 端封装一个函数
HI_S32 HI_MW_VPSS_Crop_Video(HI_HANDLE hVpssGrpHdl, HI_HANDLE hVpssChnHdl,
HI_HANDLE hDispHdl, HI_HANDLE hWndHdl, HI_U32 u32Width, HI_U32 u32Height,
HI_U32 u32Startx, HI_U32 u32Starty)
通过 HiSysLink 的方式把数据送到 Middleware 的 Server 端 ,Server 收到数据后调用 HI_MPI_VPSS_SetChnCrop()来抓取图像
HI_MW_VPSS_Crop_Video()调用函数 COMMON_Client_VPSS_Crop_Video();
客户需要 Hisilicon DVR 项目上实现 快进/快退 ,暂停播放 ,感兴趣区域的放大缩小功能 ,并要求对这些功能封装函数 ,用命令行的形式对这些功能继续测试 ,接下来我将与大家分享实现这些功能的过程
二、程序运行环境
使用的硬件平台为 :HI3559V200DMEB VER.A
图1 HI3559V200DMEB Board
使用的软件版本为 :Hi3559V200_MobileCam_SDK_V1.0.1.5 , Project Type 为 SampleCam
图2 SampleCam Menuconfig
三、搭建视频回放播放器的环境
3.1 编译 player_sample
Hisilicon 自带视频播放软件 player_sample ,这个软件的路径为 :middleware\sample\liteplayer\player_sample ,
编译结束后会在目录下生成 sample_play 的应用程序
3.2 拷贝库文件
需要将 liteos 测的镜像烧写为 sample/liteos/media_app.bin (对应的压缩镜像为media_app_zip.bin)
把 middleware/sample/liteplayer/player_sample/AAC/libhiaacdec.so拷贝到单板的 /app/sharefs/ 下
将 middleware/component/liteplayer/lib/目录下的 libffmpeg_demuxer.so 拷贝至单板的 /usr/lib/ 下面
3.3 运行 sample_play
把 test.mp4 文件拷贝到 SD 卡
sh /app/komod/mmc_load.sh // 挂载 SD 卡
mount /dev/mmcblk0p1 /mnt // 挂载 SD 卡
./app/sharefs/sharefs &
./sample_play test.mp4
通过以上步骤可以看到 视频可以正常播放,快进/快退 ,暂停/播放 功能都是正常的 ,但抓取感兴趣图像功能没有
四、加入缩放功能
4.1 视频回放的数据流程
图3 视频回放的处理流程图
从上面的流程图可以了解到视频的处理流程 :
MP4 --> VDEC --> VPSS --> VO --> Display
视频文件解码后会通过 VPSS 通道把数据送到 VO ,然后进行显示
4.2 缩放的工作原理
数据在 VPSS 通道经过 CROP 进行扣图 ,通过 VGS 进行缩放 ,然后送到 VO 进行显示
VPSS 的裁剪是通过调用下面的函数完成 :
HI_S32 HI_MPI_VPSS_SetChnCrop(VPSS_GRP VpssGrp, VPSS_CHN VpssChn, const
VPSS_CROP_INFO_S *pstCropInfo);
参数说明 :
VpssGrp : VPSS GROUP 号 [0, VPSS_MAX_GRP_NUM)
VpssChn : VPSS 通道号 取值范围:[0, VPSS_MAX_CHN_NUM)
pstCropInfo : CROP 功能参数
4.3 Linux 和 Liteos 通过 HiSysLink 进行双核间的跨核通信
图4 HiSysLink 双核通信架构图
我们接下来会在 Middleware 的 Client 端封装一个函数
HI_S32 HI_MW_VPSS_Crop_Video(HI_HANDLE hVpssGrpHdl, HI_HANDLE hVpssChnHdl,
HI_HANDLE hDispHdl, HI_HANDLE hWndHdl, HI_U32 u32Width, HI_U32 u32Height,
HI_U32 u32Startx, HI_U32 u32Starty)
通过 HiSysLink 的方式把数据送到 Middleware 的 Server 端 ,Server 收到数据后调用 HI_MPI_VPSS_SetChnCrop()来抓取图像
--- a/media_adpt/hi3559v200/media_init.c +++ b/media_adpt/hi3559v200/media_init.c +HI_S32 HI_MW_VPSS_Crop_Video(HI_HANDLE hVpssGrpHdl, HI_HANDLE hVpssChnHdl, + HI_HANDLE hDispHdl, HI_HANDLE hWndHdl, HI_U32 u32Width, HI_U32 u32Height, + HI_U32 u32Startx, HI_U32 u32Starty) +{ + printf("====== HI_MW_VPSS_Crop_Video ======= \n"); + return COMMON_Client_VPSS_Crop_Video(hVpssGrpHdl, hVpssChnHdl, hDispHdl, hWndHdl, + u32Width, u32Height, u32Startx, u32Starty); +} |
HI_MW_VPSS_Crop_Video()调用函数 COMMON_Client_VPSS_Crop_Video();
--- a/media_adpt/hi3559v200/common_ipcmsg_client.c +++ b/media_adpt/hi3559v200/common_ipcmsg_client.c +HI_S32 COMMON_Client_VPSS_Crop_Video(HI_HANDLE hVpssGrpHdl, HI_HANDLE hVpssChnHdl, + HI_HANDLE hDispHdl, HI_HANDLE hWndHdl, HI_U32 u32Width, HI_U32 u32Height, HI_U32 u32Startx, HI_U32 u32Starty) +{ + HI_S32 s32Ret = HI_SUCCESS; + COMMON_VO_OPEN_REQ_MSG_S stOpenReq; + stOpenReq.hDispHdl = hDispHdl; + stOpenReq.hWndHdl = hWndHdl; + stOpenReq.hVpssGrpHdl = hVpssGrpHdl; + stOpenReq.hVpssChnHdl = hVpssChnHdl; + stOpenReq.u32Width = u32Width; + stOpenReq.u32Height = u32Height; + stOpenReq.u32Startx = u32Startx; + stOpenReq.u32Starty = u32Starty; + + s32Ret = COMMON_IPCMSG_CLIENT_SendSync(COMMON_MSG_CLIENT_VPSS_CROP, + &stOpenReq, sizeof(COMMON_VO_OPEN_REQ_MSG_S), NULL, 0, AVPLAY_MSG_LONG_TIMEOUT); |
+
+ printf("====== COMMON_MSG_CLIENT_VPSS_CROP ======= \n");
+
+ if (s32Ret != HI_SUCCESS)
+ {
+ printf("common vo open send ipcmsg exec error ret:%d \n", s32Ret);
+ return HI_FAILURE;
+ }
+ return HI_SUCCESS;
COMMON_Client_VPSS_Crop_Video()函数通过命令 COMMON_IPCMSG_CLIENT_SendSync(COMMON_MSG_CLIENT_VPSS_CROP 与 Server 端通信
--- a/media_adpt/hi3559v200/liteos/common_ipcmsg_server.c +++ b/media_adpt/hi3559v200/liteos/common_ipcmsg_server.c @@ -68,6 +68,51 @@ static HI_VOID COMMON_IPCMSG_SVR_HandleVoOpen(HI_IPCMSG_MESSAGE_S* pReq) } } +static HI_VOID COMMON_IPCMSG_SVR_HandleVPSSCropVideo(HI_IPCMSG_MESSAGE_S* pReq) +{ + HI_S32 s32Ret = HI_SUCCESS; + + if(pReq->u32BodyLen != sizeof(COMMON_VO_OPEN_REQ_MSG_S)) + { + COMMON_IPCMSG_SendResp(pReq, HI_FAILURE, NULL, 0); + } + else + { + COMMON_VO_OPEN_REQ_MSG_S* pstOpen = (COMMON_VO_OPEN_REQ_MSG_S*)pReq->pBody; + + printf("====== COMMON_IPCMSG_SVR_HandleVPSSCropVideo ======= \n"); + + s32Ret = PLAYER_VPSS_Crop_Video(pstOpen->hVpssGrpHdl, pstOpen->hVpssChnHdl, + pstOpen->hDispHdl, pstOpen->hWndHdl,pstOpen->u32Width, + pstOpen->u32Height,pstOpen->u32Startx,pstOpen->u32Starty); + + COMMON_IPCMSG_SendResp(pReq, s32Ret, NULL, 0); + } +} + |
COMMON_IPCMSG_SVR_HandleVPSSCropVideo()函数调用 PLAYER_VPSS_Crop_Video()来抓取感兴趣局域
--- a/media_adpt/hi3559v200/liteos/media_init_liteos.c +++ b/media_adpt/hi3559v200/liteos/media_init_liteos.c +HI_S32 PLAYER_VPSS_Crop_Video(HI_HANDLE hVpssGrpHdl, HI_HANDLE hVpssChnHdl, HI_HANDLE hDispHdl, HI_HANDLE hWndHdl, + HI_U32 u32Width, HI_U32 u32Height, HI_U32 u32Startx, HI_U32 u32Starty) +{ + + HI_S32 s32Ret = HI_SUCCESS; + + VPSS_CROP_INFO_S stCropInfo; + + printf("==== PLAYER_VPSS_Crop_Video u32Startx = %d , u32Starty = %d====== \n" ,u32Startx ,u32Starty); + + stCropInfo.bEnable = HI_TRUE; + stCropInfo.enCropCoordinate = VPSS_CROP_ABS_COOR; + stCropInfo.stCropRect.s32X = u32Startx; + stCropInfo.stCropRect.s32Y = u32Starty; + stCropInfo.stCropRect.u32Width = u32Width;//640; + stCropInfo.stCropRect.u32Height = u32Height;//360; + s32Ret = HI_MPI_VPSS_SetGrpCrop(hVpssGrpHdl, &stCropInfo); + + if (s32Ret != HI_SUCCESS) + { + return s32Ret; + } + + s32Ret = HI_MPI_VPSS_GetGrpCrop(hVpssGrpHdl, &stCropInfo); + if(s32Ret != HI_SUCCESS) + { + return s32Ret; + } + + return HI_SUCCESS; + } + |
五、通过命令行进行测试
添加命令行输入函数 :
--- a/sample/liteplayer/player_sample/player_sample.c +++ b/sample/liteplayer/player_sample/player_sample.c printf("Input CMD: quit, pause(pu), replay(re), play(pl), seek(sk), ff [speed] , bw [speed]\n"); - while (fgets(cmd, 10, stdin)) + while (fgets(cmd, 63, stdin)) { - cmd[10] = '\0'; + cmd[63] = '\0'; if (strncmp(cmd, "quit", 4) == 0 ) { @@ -562,10 +565,52 @@ int main(int argc , char** argv) s32Ret = HI_LITEPLAYER_TPlay(g_pPlayer, &stTPlayAttr); printf("HI_LITEPLAYER_TPlay() ret=0x%x\n", s32Ret); } - else - { - printf("Input CMD: quit, pause(pu), replay(re), play(pl), seek(sk), ff [speed] , bw [speed]\n"); - } + else + { + int startx = 0, starty = 0, width =0, hight = 0; + + printf("cmd strings len : %d \n",strlen(cmd)); + + if (strncmp(cmd, "display540", 10) == 0) + { + if (2 != sscanf(cmd, "display540 startx: %d starty: %d", &startx,&starty)) + { + printf("display540 startx input err \n" ); + } + + printf("display540 startx = %d starty = %d \n" ,startx,starty); + + HI_MW_VO_Res_Chg(g_hVpssGrpHandle, g_hVpssGrpChnHandle, g_hDispHandle,+ HI_MW_VO_Res_Chg(g_hVpssGrpHandle, g_hVpssGrpChnHandle, g_hDispHandle, + g_hDispWndHandle, 960, 540,startx ,starty); + } + + if (strncmp(cmd, "display720", 10) == 0) + { + HI_MW_VO_Res_Chg(g_hVpssGrpHandle, g_hVpssGrpChnHandle, g_hDispHandle,+ g_hDispWndHandle, 1280, 720,0 ,0); + } + + if (strncmp(cmd, "cropvideo", 9) == 0) + { + if (4 != sscanf(cmd, "cropvideo width: %d hight: %d startx: %d starty: %d",&width, &hight,&startx,&starty)) + { + printf("cropvideo data input err \n" ); + } + + printf("cropvideo width: %d hight %d startx = %d starty = %d \n" ,width,hight,startx,starty); + + HI_MW_VPSS_Crop_Video(g_hVpssGrpHandle, g_hVpssGrpChnHandle, g_hDispHandle,+ g_hDispWndHandle, width, hight,startx ,starty); + + } + if (strncmp(cmd, "cropnormal", 10) == 0) + { + HI_MW_VPSS_Crop_Video(g_hVpssGrpHandle, g_hVpssGrpChnHandle, g_hDispHandle,+ g_hDispWndHandle, 1920, 1080,0 ,0); + } + + } |
输入命令后查看效果
# cropvideo width: 896 hight: 504 startx: 76 starty: 88 |
左边为放大后的照片 ,右边为放大前的照片
图5 测试结果
六、参考文档
HiMPP媒体处理软件 V4.0 开发参考.pdf , 文档版本 16 ,发布时间 :2020-01-20
评论