/**********************************************************************
 * 函数名称: ShowIntervalPage
 * 功能描述: 显示"interval页面"
 * 输入参数: ptPageLayout - 内含多个图标的文件名和显示区域
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
static void ShowIntervalPage(PT_PageLayout ptPageLayout)
{
	PT_VideoMem ptVideoMem;
	int iError;
	PT_Layout atLayout = ptPageLayout->atLayout;
		
	/* 1. 获得显存 */
	ptVideoMem = GetVideoMem(ID("interval"), 1);
	if (ptVideoMem == NULL)
	{
		DBG_PRINTF("can't get video mem for interval page!\n");
		return;
	}

	/* 2. 描画数据 */
	/* 如果还没有计算过各图标的坐标 */
	if (atLayout[0].iTopLeftX == 0)
	{
		CalcIntervalPageLayout(ptPageLayout);
	}

	iError = GeneratePage(ptPageLayout, ptVideoMem);

	iError = GenerateIntervalPageSpecialIcon(g_iIntervalSecond, ptVideoMem);
	if (iError)
	{
		DBG_PRINTF("GenerateIntervalPageSpecialIcon error!\n");
	}
	
	/* 3. 刷到设备上去 */
	FlushVideoMemToDev(ptVideoMem);

	/* 4. 解放显存 */
	PutVideoMem(ptVideoMem);
}
Exemple #2
0
/**********************************************************************
 * 函数名称: ShowSavePage
 * 功能描述: 显示"Save页面"
 * 输入参数: ptPageLayout - 内含多个图标的文件名和显示区域
 * 输出参数: 无
 * 返 回 值: 无
 ***********************************************************************/
static void ShowSavePage(PT_PageLayout ptPageLayout)
{
	PT_VideoMem ptVideoMem;
	int iError;

	PT_Layout atLayout = ptPageLayout->atLayout;
		
	/* 1. 获得显存 */
	ptVideoMem = GetVideoMem(ID("save"), 1);
	if (ptVideoMem == NULL)
	{
		DBG_PRINTF("can't get video mem for Save page!\n");
		return;
	}

	/* 2. 描画数据 */

	/* 如果还没有计算过各图标的坐标 */
	if (atLayout[0].iTopLeftX == 0)
	{
		CalcSavePageLayout(ptPageLayout);
	}

	iError = GeneratePage(ptPageLayout, ptVideoMem);	

	/* 3. 刷到设备上去 */
	FlushVideoMemToDev(ptVideoMem);

	/* 4. 解放显存 */
	PutVideoMem(ptVideoMem);
}
/**********************************************************************
 * 函数名称: AutoPlayThreadFunction
 * 功能描述: "连播页面"的子线程函数:用于显示  (主线程用于读取输入数据)
 * 输入参数: pVoid - 未用
 * 输出参数: 无
 * 返 回 值: NULL   - 正常退出
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
static void *AutoPlayThreadFunction(void *pVoid)
{
    int bFirst = 1;
    int bExit;
    PT_VideoMem ptVideoMem;

    ResetAutoPlayFile();
    
    while (1)
    {
        /* 1. 先判断是否要退出 */
        pthread_mutex_lock(&g_tAutoPlayThreadMutex);
        bExit = g_bAutoPlayThreadShouldExit;
        pthread_mutex_unlock(&g_tAutoPlayThreadMutex);

        if (bExit)
        {
            return NULL;
        }

        /* 2. 准备要显示的图片 */
        ptVideoMem = PrepareNextPicture(0);

        /* 3. 时间到后就显示出来 */

        if (!bFirst)
        {
            sleep(g_tPageCfg.iIntervalSecond);       /* 先用休眠来代替 */
        }
        bFirst = 0;
        
        if (ptVideoMem == NULL)
        {
            ptVideoMem = PrepareNextPicture(1);
        }

    	/* 刷到设备上去 */
    	FlushVideoMemToDev(ptVideoMem);

    	/* 解放显存 */
    	PutVideoMem(ptVideoMem);        

    }
    return NULL;
}
Exemple #4
0
/* 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;
}