/* video2lcd </dev/video0,1,,,>*/ int main(int argc, char **argv) { int iError; T_VideoDevice tVideoDevice; PT_VideoConvert ptVideoConvert; int iPixFormatOfVideo; int iPixFormatOfDisp; PT_VideoBuf ptVideoBufCur; T_VideoBuf tVideoBuf; T_VideoBuf tConvertBuf; T_VideoBuf tZoomBuf; T_VideoBuf tFrameBuf; int iLcdWidth,iLcdHeight,iLcdBpp; int iTopLeftX,iTopLeftY ; float k; if (argc != 2) { DBG_PRINTF("Usage:\n"); DBG_PRINTF("%s video2lcd </dev/video0,1,,,>\n", argv[0]); return 0; } /*一系列的初始化*/ /* 注册显示设备 */ DisplayInit(); /* 可能可支持多个显示设备: 选择和初始化指定的显示设备 */ SelectAndInitDefaultDispDev("fb"); GetDispResolution(&iLcdWidth, &iLcdHeight, &iLcdBpp); GetVideoBufForDisplay(&tFrameBuf); iPixFormatOfDisp = tFrameBuf.iPixelFormat; VideoInit(); iError = VideoDeviceInit(argv[1], &tVideoDevice); if(iError) { DBG_PRINTF("VideoInit for %s error\n",argv[1]); return -1; } iPixFormatOfVideo = tVideoDevice.ptopr->GetFormat(&tVideoDevice); VideoConvertInit(); ptVideoConvert = GetVideoConvertForFormat(iPixFormatOfVideo, iPixFormatOfDisp); if(ptVideoConvert == NULL) { DBG_PRINTF("Can not support this format convert !\n"); return -1; } /*启动摄像头*/ iError = tVideoDevice.ptopr->StartDevice(&tVideoDevice); if(iError) { DBG_PRINTF("Start device for %s error\n",argv[1]); return -1; } memset(&tVideoBuf, 0, sizeof(tVideoBuf)); memset(&tConvertBuf, 0, sizeof(tConvertBuf)); tConvertBuf.tPixelDatas->iBpp = iLcdBpp; memset(&tZoomBuf, 0, sizeof(tZoomBuf)); while(1) { /*读入摄像头数据*/ iError = tVideoDevice.ptopr->GetFrame(&tVideoDevice, &tVideoBuf); if(iError) { DBG_PRINTF("GetFrame for %s error\n",argv[1]); return -1; } ptVideoBufCur = &tVideoBuf; /*转换为RGB数据*/ if(iPixFormatOfVideo != iPixFormatOfDisp) { /*转换为RGB数据*/ iError = ptVideoConvert->Covert(&tVideoBuf, &tConvertBuf); if(iError) { DBG_PRINTF("Covert for %s error\n",argv[1]); return -1; } ptVideoBufCur = &tConvertBuf; } /*如果图像分辨率,大于LCD,缩放*/ if (ptVideoBufCur->tPixelDatas.iWidth > iLcdWidth || ptVideoBufCur->tPixelDatas.iHeight> iLcdHeight) { /*确定缩放后的分辨率*/ /* 把图片按比例缩放到VideoMem上, 居中显示 * 1. 先算出缩放后的大小 */ k = (float)ptVideoBufCur->tPixelDatas.iHeight / ptVideoBufCur->tPixelDatas.iWidth; tZoomBuf.tPixelDatas.iWidth = iLcdWidth; tZoomBuf.tPixelDatas.iHeight = iLcdWidth* k; if (tZoomBuf.tPixelDatas.iHeight > iLcdHeight) { tZoomBuf.tPixelDatas.iWidth = iLcdHeight / k; tZoomBuf.tPixelDatas.iHeight = iLcdHeight; } tZoomBuf.tPixelDatas.iBpp = iLcdBpp; tZoomBuf.tPixelDatas.iLineBytes = tZoomBuf->tPixelDatas.iWidth * tZoomBuf.tPixelDatas.iBpp / 8; tZoomBuf.tPixelDatas.iTotalBytes = tZoomBuf->tPixelDatas.iLineBytes * tZoomBuf.tPixelDatas.iHeight; if(!tZoomBuf.tPixelDatas.aucPixelDatas) { tZoomBuf.tPixelDatas.aucPixelDatas = malloc(tZoomBuf.tPixelDatas.iTotalBytes); } if (tZoomBuf.tPixelDatas.aucPixelDatas == NULL) { PutVideoMem(ptVideoMem); return NULL; } PicZoom(&ptVideoBufCur.tPixelDatas, &tZoomBuf.tPixelDatas); ptVideoBufCur = &tZoomBuf; } /*合并进入frmaebuffer*/ /* 接着算出居中显示时左上角坐标 */ iTopLeftX = (iLcdWidth- ptVideoBufCur->tPixelDatas.iWidth) / 2; iTopLeftY = (iLcdHeight- ptVideoBufCur->tPixelDatas.iHeight) / 2; PicMerge(iTopLeftX,iTopLeftY,&ptVideoBufCur->tPixelDatas,&tFrameBuf.tPixelDatas); FlushPixelDataToDev(&tFrameBuf.tPixelDatas); iError = tVideoDevice.ptopr->PutFrame(&tVideoDevice, &tVideoBuf); if (iError) { DBG_PRINTF("PutFrame for %s error\n",argv[1]); return -1; } /*把framebuffer的数据刷到LCD上*/ } /* 初始化调试模块: 可以通过"标准输出"也可以通过"网络"打印调试信息 * 因为下面马上就要用到DBG_PRINTF函数, 所以先初始化调试模块 */ return 0; }
/********************************************************************** * 函数名称: PrepareNextPicture * 功能描述: 准备显示下一图片: 取出下图片的数据,存入VideoMem中 * 输入参数: bCur : 0 - 表示这是做准备用的, 有可能无法获得videomem * 1 - 表示必须获得videomem, 因为这是马上就要在LCD上显示出来的 * 输出参数: 无 * 返 回 值: NULL - 无法获得VideoMem,所以下一个图片没有预先备好 * 非NULL - 存有下一个图片数据的VideoMem的指针 * 修改日期 版本号 修改人 修改内容 * ----------------------------------------------- * 2013/02/08 V1.0 韦东山 创建 ***********************************************************************/ static PT_VideoMem PrepareNextPicture(int bCur) { T_PixelDatas tOriginIconPixelDatas; T_PixelDatas tPicPixelDatas; PT_VideoMem ptVideoMem; int iError; int iXres, iYres, iBpp; int iTopLeftX, iTopLeftY; float k; char strFileName[256]; GetDispResolution(&iXres, &iYres, &iBpp); /* 获得显存 */ ptVideoMem = GetVideoMem(-1, bCur); if (ptVideoMem == NULL) { DBG_PRINTF("can't get video mem for browse page!\n"); return NULL; } /* 把VidoeMem清为背景色 */ ClearVideoMem(ptVideoMem, COLOR_BACKGROUND); while (1) { /* 获得下一个要播放的图片的名字 */ iError = GetNextAutoPlayFile(strFileName); if (iError) { DBG_PRINTF("GetNextAutoPlayFile error\n"); PutVideoMem(ptVideoMem); return NULL; } /* 从图片文件中取出象素数据 */ iError = GetPixelDatasFrmFile(strFileName, &tOriginIconPixelDatas); if (0 == iError) { break; } } /* 把图片按比例缩放到VideoMem上, 居中显示 * 1. 先算出缩放后的大小 */ k = (float)tOriginIconPixelDatas.iHeight / tOriginIconPixelDatas.iWidth; tPicPixelDatas.iWidth = iXres; tPicPixelDatas.iHeight = iXres * k; if (tPicPixelDatas.iHeight > iYres) { tPicPixelDatas.iWidth = iYres / k; tPicPixelDatas.iHeight = iYres; } tPicPixelDatas.iBpp = iBpp; tPicPixelDatas.iLineBytes = tPicPixelDatas.iWidth * tPicPixelDatas.iBpp / 8; tPicPixelDatas.iTotalBytes = tPicPixelDatas.iLineBytes * tPicPixelDatas.iHeight; tPicPixelDatas.aucPixelDatas = malloc(tPicPixelDatas.iTotalBytes); if (tPicPixelDatas.aucPixelDatas == NULL) { PutVideoMem(ptVideoMem); return NULL; } /* 2. 再进行缩放 */ PicZoom(&tOriginIconPixelDatas, &tPicPixelDatas); /* 3. 接着算出居中显示时左上角坐标 */ iTopLeftX = (iXres - tPicPixelDatas.iWidth) / 2; iTopLeftY = (iYres - tPicPixelDatas.iHeight) / 2; /* 4. 最后把得到的图片合并入VideoMem */ PicMerge(iTopLeftX, iTopLeftY, &tPicPixelDatas, &ptVideoMem->tPixelDatas); /* 5. 释放图片原始数据 */ FreePixelDatasFrmFile(&tOriginIconPixelDatas); /* 6. 释放缩放后的数据 */ free(tPicPixelDatas.aucPixelDatas); return ptVideoMem; }