320 lines
8.5 KiB
C
320 lines
8.5 KiB
C
#include <sys/mman.h>
|
||
#include <fcntl.h>
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <unistd.h>
|
||
#include <sys/ioctl.h>
|
||
|
||
#include "hi_common.h"
|
||
#include "hi_comm_video.h"
|
||
#include "hi_comm_sys.h"
|
||
#include "mpi_sys.h"
|
||
#include "hi_comm_vb.h"
|
||
#include "mpi_vb.h"
|
||
#include "hi_comm_vpss.h"
|
||
#include "mpi_vpss.h"
|
||
|
||
#define VALUE_BETWEEN(x,min,max) (((x)>=(min)) && ((x) <= (max)))
|
||
|
||
#if 1
|
||
static HI_S32 s_s32MemDev = -1;
|
||
|
||
#define MEM_DEV_OPEN() \
|
||
do {\
|
||
if (s_s32MemDev <= 0)\
|
||
{\
|
||
s_s32MemDev = open("/dev/mem", O_CREAT|O_RDWR|O_SYNC);\
|
||
if (s_s32MemDev < 0)\
|
||
{\
|
||
perror("Open dev/mem error");\
|
||
return -1;\
|
||
}\
|
||
}\
|
||
}while(0)
|
||
|
||
#define MEM_DEV_CLOSE() \
|
||
do {\
|
||
HI_S32 s32Ret;\
|
||
if (s_s32MemDev > 0)\
|
||
{\
|
||
s32Ret = close(s_s32MemDev);\
|
||
if(HI_SUCCESS != s32Ret)\
|
||
{\
|
||
perror("Close mem/dev Fail");\
|
||
return s32Ret;\
|
||
}\
|
||
s_s32MemDev = -1;\
|
||
}\
|
||
}while(0)
|
||
|
||
HI_VOID* COMM_SYS_Mmap(HI_U32 u32PhyAddr, HI_U32 u32Size)
|
||
{
|
||
HI_U32 u32Diff;
|
||
HI_U32 u32PagePhy;
|
||
HI_U32 u32PageSize;
|
||
HI_U8* pPageAddr;
|
||
|
||
/* The mmap address should align with page */
|
||
u32PagePhy = u32PhyAddr & 0xfffff000;
|
||
u32Diff = u32PhyAddr - u32PagePhy;
|
||
|
||
/* The mmap size shuld be mutliples of 1024 */
|
||
u32PageSize = ((u32Size + u32Diff - 1) & 0xfffff000) + 0x1000;
|
||
pPageAddr = mmap ((void*)0, u32PageSize, PROT_READ | PROT_WRITE,
|
||
MAP_SHARED, s_s32MemDev, u32PagePhy);
|
||
if (MAP_FAILED == pPageAddr )
|
||
{
|
||
perror("mmap error");
|
||
return NULL;
|
||
}
|
||
return (HI_VOID*) (pPageAddr + u32Diff);
|
||
}
|
||
|
||
HI_S32 COMM_SYS_Munmap(HI_VOID* pVirAddr, HI_U32 u32Size)
|
||
{
|
||
HI_U32 u32PageAddr;
|
||
HI_U32 u32PageSize;
|
||
HI_U32 u32Diff;
|
||
|
||
u32PageAddr = (((HI_U32)pVirAddr) & 0xfffff000);
|
||
u32Diff = (HI_U32)pVirAddr - u32PageAddr;
|
||
u32PageSize = ((u32Size + u32Diff - 1) & 0xfffff000) + 0x1000;
|
||
|
||
return munmap((HI_VOID*)u32PageAddr, u32PageSize);
|
||
}
|
||
#endif
|
||
|
||
/* sp420 ת<><D7AA>Ϊ p420 ; sp422 ת<><D7AA>Ϊ p422 */
|
||
void sample_yuv_dump(VIDEO_FRAME_S* pVBuf, FILE* pfd)
|
||
{
|
||
unsigned int w, h;
|
||
char* pVBufVirt_Y;
|
||
char* pVBufVirt_C;
|
||
char* pMemContent;
|
||
unsigned char TmpBuff[2000]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ̫С<CCAB><D0A1>ͼ<EFBFBD><CDBC><EFBFBD>ܴ<EFBFBD><DCB4>Ļ<EFBFBD><C4BB>治<EFBFBD><E6B2BB>
|
||
HI_U32 phy_addr, size;
|
||
HI_CHAR* pUserPageAddr[2];
|
||
PIXEL_FORMAT_E enPixelFormat = pVBuf->enPixelFormat;
|
||
HI_U32 u32UvHeight;/* <20><>Ϊplanar <20><>ʽʱ<CABD><CAB1>UV<55><56><EFBFBD><EFBFBD><EFBFBD>ĸ߶<C4B8> */
|
||
|
||
if (PIXEL_FORMAT_YUV_SEMIPLANAR_420 == enPixelFormat)
|
||
{
|
||
size = (pVBuf->u32Stride[0]) * (pVBuf->u32Height) * 3 / 2;
|
||
u32UvHeight = pVBuf->u32Height / 2;
|
||
}
|
||
else
|
||
{
|
||
size = (pVBuf->u32Stride[0]) * (pVBuf->u32Height) * 2;
|
||
u32UvHeight = pVBuf->u32Height;
|
||
}
|
||
|
||
phy_addr = pVBuf->u32PhyAddr[0];
|
||
|
||
//printf("phy_addr:%x, size:%d\n", phy_addr, size);
|
||
pUserPageAddr[0] = (HI_CHAR*) HI_MPI_SYS_Mmap(phy_addr, size);
|
||
if (NULL == pUserPageAddr[0])
|
||
{
|
||
return;
|
||
}
|
||
//printf("stride: %d,%d\n",pVBuf->u32Stride[0],pVBuf->u32Stride[1] );
|
||
|
||
pVBufVirt_Y = pUserPageAddr[0];
|
||
pVBufVirt_C = pVBufVirt_Y + (pVBuf->u32Stride[0]) * (pVBuf->u32Height);
|
||
|
||
/* save Y ----------------------------------------------------------------*/
|
||
fprintf(stderr, "saving......Y......");
|
||
fflush(stderr);
|
||
for (h = 0; h < pVBuf->u32Height; h++)
|
||
{
|
||
pMemContent = pVBufVirt_Y + h * pVBuf->u32Stride[0];
|
||
fwrite(pMemContent, pVBuf->u32Width, 1, pfd);
|
||
}
|
||
fflush(pfd);
|
||
|
||
|
||
/* save U ----------------------------------------------------------------*/
|
||
fprintf(stderr, "U......");
|
||
fflush(stderr);
|
||
for (h = 0; h < u32UvHeight; h++)
|
||
{
|
||
pMemContent = pVBufVirt_C + h * pVBuf->u32Stride[1];
|
||
|
||
pMemContent += 1;
|
||
|
||
for (w = 0; w < pVBuf->u32Width / 2; w++)
|
||
{
|
||
TmpBuff[w] = *pMemContent;
|
||
pMemContent += 2;
|
||
}
|
||
fwrite(TmpBuff, pVBuf->u32Width / 2, 1, pfd);
|
||
}
|
||
fflush(pfd);
|
||
|
||
/* save V ----------------------------------------------------------------*/
|
||
fprintf(stderr, "V......");
|
||
fflush(stderr);
|
||
for (h = 0; h < u32UvHeight; h++)
|
||
{
|
||
pMemContent = pVBufVirt_C + h * pVBuf->u32Stride[1];
|
||
|
||
for (w = 0; w < pVBuf->u32Width / 2; w++)
|
||
{
|
||
TmpBuff[w] = *pMemContent;
|
||
pMemContent += 2;
|
||
}
|
||
fwrite(TmpBuff, pVBuf->u32Width / 2, 1, pfd);
|
||
}
|
||
fflush(pfd);
|
||
|
||
fprintf(stderr, "done %d!\n", pVBuf->u32TimeRef);
|
||
fflush(stderr);
|
||
|
||
HI_MPI_SYS_Munmap(pUserPageAddr[0], size);
|
||
}
|
||
|
||
|
||
HI_VOID* SAMPLE_MISC_VpssDump(VPSS_GRP Grp, VPSS_CHN Chn, HI_U32 u32FrameCnt)
|
||
{
|
||
VIDEO_FRAME_INFO_S stFrame;
|
||
HI_CHAR szYuvName[128];
|
||
HI_CHAR szPixFrm[10];
|
||
FILE* pfd;
|
||
VPSS_GRP VpssGrp = Grp;
|
||
VPSS_CHN VpssChn = Chn;
|
||
HI_U32 u32Cnt = u32FrameCnt;
|
||
HI_U32 u32Depth = 2;
|
||
HI_U32 u32OrigDepth = 0;
|
||
VPSS_CHN_MODE_S stOrigVpssMode, stVpssMode;
|
||
HI_S32 s32MilliSec = 200;
|
||
|
||
if (HI_MPI_VPSS_GetChnMode(VpssGrp, VpssChn, &stOrigVpssMode) != HI_SUCCESS)
|
||
{
|
||
printf("get mode error!!!\n");
|
||
return (HI_VOID*) - 1;
|
||
}
|
||
|
||
if (HI_MPI_VPSS_GetDepth(VpssGrp, VpssChn, &u32OrigDepth) != HI_SUCCESS)
|
||
{
|
||
printf("get depth error!!!\n");
|
||
return (HI_VOID*) - 1;
|
||
}
|
||
|
||
stVpssMode.enChnMode = stOrigVpssMode.enChnMode;
|
||
stVpssMode.enPixelFormat = stOrigVpssMode.enPixelFormat;
|
||
|
||
stVpssMode.u32Width = stOrigVpssMode.u32Width;
|
||
stVpssMode.u32Height = stOrigVpssMode.u32Height;
|
||
stVpssMode.enCompressMode = COMPRESS_MODE_NONE;
|
||
stVpssMode.bDouble = HI_FALSE;
|
||
if (HI_MPI_VPSS_SetChnMode(VpssGrp, VpssChn, &stVpssMode) != HI_SUCCESS)
|
||
{
|
||
printf("set mode error!!!\n");
|
||
return (HI_VOID*) - 1;
|
||
}
|
||
if (HI_MPI_VPSS_SetDepth(VpssGrp, VpssChn, u32Depth) != HI_SUCCESS)
|
||
{
|
||
printf("set depth error!!!\n");
|
||
return (HI_VOID*) - 1;
|
||
}
|
||
|
||
memset(&stFrame, 0, sizeof(stFrame));
|
||
while (HI_MPI_VPSS_GetChnFrame(VpssGrp, VpssChn, &stFrame, s32MilliSec) != HI_SUCCESS)
|
||
{
|
||
printf("get frame error!!!\n");
|
||
usleep(40000);
|
||
}
|
||
|
||
|
||
switch (stFrame.stVFrame.enPixelFormat)
|
||
{
|
||
case PIXEL_FORMAT_YUV_SEMIPLANAR_420:
|
||
snprintf(szPixFrm, 10, "P420");
|
||
break;
|
||
case PIXEL_FORMAT_YUV_SEMIPLANAR_422:
|
||
snprintf(szPixFrm, 10, "P422");
|
||
break;
|
||
case PIXEL_FORMAT_SINGLE:
|
||
snprintf(szPixFrm, 10, "Single");
|
||
break;
|
||
default:
|
||
snprintf(szPixFrm, 10, "--");
|
||
break;
|
||
}
|
||
|
||
/* make file name */
|
||
sprintf(szYuvName, "./vpss_grp%d_chn%d_w%d_h%d_%s_%d.yuv", VpssGrp, VpssChn,
|
||
stFrame.stVFrame.u32Width, stFrame.stVFrame.u32Height, szPixFrm, u32Cnt);
|
||
printf("Dump YUV frame of vpss chn %d to file: \"%s\"\n", VpssChn, szYuvName);
|
||
fflush(stdout);
|
||
|
||
HI_MPI_VPSS_ReleaseChnFrame(VpssGrp, VpssChn, &stFrame);
|
||
/* open file */
|
||
pfd = fopen(szYuvName, "wb");
|
||
|
||
if (NULL == pfd)
|
||
{
|
||
return (HI_VOID*) - 1;
|
||
}
|
||
|
||
/* get frame */
|
||
while (u32Cnt--)
|
||
{
|
||
if (HI_MPI_VPSS_GetChnFrame(VpssGrp, VpssChn, &stFrame, s32MilliSec) != HI_SUCCESS)
|
||
{
|
||
printf("Get frame fail \n");
|
||
usleep(1000);
|
||
continue;
|
||
}
|
||
sample_yuv_dump(&stFrame.stVFrame, pfd);
|
||
|
||
printf("Get VpssGrp %d frame %d!!\n", VpssGrp, u32Cnt);
|
||
/* release frame after using */
|
||
HI_MPI_VPSS_ReleaseChnFrame(VpssGrp, VpssChn, &stFrame);
|
||
}
|
||
fclose(pfd);
|
||
|
||
HI_MPI_VPSS_SetDepth(VpssGrp, VpssChn, u32OrigDepth);
|
||
HI_MPI_VPSS_SetChnMode(VpssGrp, VpssChn, &stOrigVpssMode);
|
||
|
||
return (HI_VOID*)0;
|
||
}
|
||
|
||
HI_S32 main(int argc, char* argv[])
|
||
{
|
||
VPSS_GRP VpssGrp = 0;
|
||
VPSS_CHN VpssChn = 0;
|
||
HI_U32 u32FrmCnt = 1;
|
||
|
||
printf("Usage: ./vpss_dump [Grp] [Chn] [Count] \n");
|
||
printf("Grp: vpss Grp id.\n");
|
||
printf("Chn: vpss Chn id.\n");
|
||
printf("Count: frame count.\n");
|
||
if (argc < 4)
|
||
{
|
||
printf("wrong arg!!!!\n\n");
|
||
return -1;
|
||
}
|
||
|
||
VpssGrp = atoi(argv[1]);
|
||
if (!VALUE_BETWEEN(VpssGrp, 0, VPSS_MAX_GRP_NUM - 1))
|
||
{
|
||
printf("grp id must be [0,%d]!!!!\n\n",VPSS_MAX_GRP_NUM - 1);
|
||
return -1;
|
||
}
|
||
|
||
VpssChn = atoi(argv[2]);/* chn id*/
|
||
if (!VALUE_BETWEEN(VpssChn, 0, VPSS_MAX_PHY_CHN_NUM - 1))
|
||
{
|
||
printf("chn id must be [0,%d]!!!!\n\n",VPSS_MAX_PHY_CHN_NUM - 1);
|
||
return -1;
|
||
}
|
||
u32FrmCnt = atoi(argv[3]);/* frame count*/
|
||
|
||
MEM_DEV_OPEN();
|
||
SAMPLE_MISC_VpssDump(VpssGrp, VpssChn, u32FrmCnt);
|
||
MEM_DEV_CLOSE();
|
||
|
||
return HI_SUCCESS;
|
||
}
|