DM8168 解码显示模块代码阅读分析

解码/显示概述:从共享文件夹获取H264流,对264流进行解析,生成hdr文件,hdr文件中包含每一帧的信息,将视频帧信息存放在A8核分配的共享内存空间,供其他核或其他的link调用,M3 Video核调用Display函数通过HDMI输出显示。

/**
	解码显示函数流程图
*/
Demo_run()
{
	Demo_startStop(demoId, TRUE)
	{
		VcapVdis_start()
	    {
			VdecVdis_bitsRdInit()
			{
				/*重置文件处理句柄*/
				VdecVdis_bitsRdResetFileHandles();
				
				/*从.ini文件中获取源H264流,并调用iniparser()解析得到hdr文件,hdr文件中有每一帧的数据信息。
				  如果已经解析过在运行程序时可以选择否。
				  gVdecVdis_config中保存.ini文件的属性
				  gVdecVdis_obj.fdRdData 保存H264流
			          gVdecVdis_obj.fpRdHdr  保存hdr解析流
				*/
				VdecVdis_bitsRdGetFileInfoFromIniFile();

				/*创建发送和接收数据流的线程*/
				VdecVdis_bitsRdInitThrObj()
				{
					 OSA_semCreate(&gVdecVdis_obj.thrStartSem,1,0);//创建信号量
					 status = OSA_thrCreate(&gVdecVdis_obj.thrHandle,		     //线程句柄,用于指向各种系统资源,比如信号量,线程,和文件等
           								VdecVdis_bitsRdSendFxn,              //线程函数
            								MCFW_IPCBITS_SENDFXN_TSK_PRI,
            								MCFW_IPCBITS_SENDFXN_TSK_STACK_SIZE, //线程其实地址
            								&gVdecVdis_obj);		     //线程运行的参数
				
					 VdecVdis_bitsRdSendFxn(Void * prm)
					 {
					 	OSA_semWait(&gVdecVdis_obj.thrStartSem,OSA_TIMEOUT_FOREVER);//等待系统消息
					 	while (FALSE == gVdecVdis_obj.thrExit)
					 	{

					 		OSA_waitMsecs(MCFW_IPCBITS_SENDFXN_PERIOD_MS);//每8秒是一个时钟周期
					 		/**/
					 		VdecVdis_bitsRdGetEmptyBitBufs(&emptyBufList, i)
					 		{
					 			VDEC_BUF_REQUEST_S reqInfo.bufSize = gVdecVdis_config.chBufSize[chId];//得到每一个channel的buf
					 			Vdec_requestBitstreamBuffer(&reqInfo, emptyBufList, 0)//reqInfo指示通道i和bufSize大小
					 			{
					 				IpcBitsOutLinkHLOS_BitstreamBufReqInfo ipcReqInfo=reqInfo;
					 				IpcBitsOutLink_getEmptyVideoBitStreamBufs(gVdecModuleContext.ipcBitsOutHLOSId, &ipcBufList,&ipcReqInfo);
									{
										linkId=gVdecModuleContext.ipcBitsOutHLOSId;
										OSA_TskHndl * pTsk=System_getLinkTskHndl(linkId);//得到OutLink的线程Id
										IpcBitsOutLink_Obj * pObj= pTsk->appData;;//pObj包含OutLink的基本信息

										if (pObj->startProcessing)
										{
											IpcBitsOutLink_releaseBitBufs(pObj);//清空pObj->listElemQue
											reqInfo=ipcReqInfo;bufList=ipcBufList;//参数变化
											IpcBitsOutLink_getEmptyBufs(pObj,bufList,reqInfo);//
											{
												//&pListElem=&pObj->listElemQue[chNum]
												OSA_queGet(&pObj->listElemQue[chNum],(Int32 *) (&pListElem), OSA_TIMEOUT_NONE);
												bufList=&pListElem;//最后共享空间的数据放在bufList中
											}
									    }

									}//以上函数功能:将共享区域的数据流放在临时空间&ipcBufList
									/*最后将从共享空间获取的数据流放入空队列emptyBufList中*/
									Vdec_copyBitBufInfoLink2McFw(emptyBufList,&ipcBufList);
					 			}


					 		}//VdecVdis_bitsRdGetEmptyBitBufs(&emptyBufList, i)

					 		if (emptyBufList.numBufs)
							{
							    VdecVdis_bitsRdReadData(&emptyBufList);//读取gVdecVdis_obj.fdRdData的帧数据,并填充emptyBufList
							    VdecVdis_bitsRdSendFullBitBufs(&emptyBufList)
							    {
							    	 Vdec_putBitstreamBuffer(fullBufList)
							    	 {
							    	 	Vdec_copyBitBufInfoMcFw2Link(ipcBufList,fullBufList);
							    	 	IpcBitsOutLink_putFullVideoBitStreamBufs(gVdecModuleContext.ipcBitsOutHLOSId,&ipcBufList)
							    	 	{
							    	 		linkId=gVdecModuleContext.ipcBitsOutHLOSId;
							    	 		OSA_TskHndl * pTsk=System_getLinkTskHndl(linkId);
							    	 		IpcBitsOutLink_Obj * pObj=pTsk->appData;
							    	 		bufList=ipcBufList;
							    	 		IpcBitsOutLink_putFullBufs(pObj,bufList)//将读取的数据帧放入pObj即共享空间
							    	 		{
							    	 			Bitstream_Buf *pBitBuf=pBufList->bufs[bufId];
							    	 			SharedRegion_getPtr(pListElem->srBufPtr)=pBitBuf->addr);//得到共享空间地址
													freeBitBufList.bufs[freeBitBufList.numBufs] = pBitBuf;
													IpcBitsOutLink_listMPPut(pObj, pListElem);//???
													IpcBitsOutLink_putEmptyBufs(pObj, &freeBitBufList)
													{
														pBufList=freeBitBufList;
														pListElem = (SystemIpcBits_ListElem *) pBufList->bufs[bufId];
														SharedRegion_getPtr(pListElem->srBufPtr) =pBufList->bufs[bufId]->addr;
														OSA_quePut(&(pObj->listElemQue),pListElem, OSA_TIMEOUT_NONE);//pObj得到freeBitBufList的数据流
													}
	 												
												
							    	 		}
							    	 	}
							    	 }
							    } //VdecVdis_bitsRdSendFullBitBufs(&emptyBufList)将新的数据帧放入共享空间

							}if (emptyBufList.numBufs)

					 	}//while()


					 }
				}//创建发送和接收数据流的线程
			
			}//VdecVdis_bitsRdInit()

			/*初始化系统变量vsysParams*/
			Vsys_params_init(&vsysParams);
			/*系统初始化*/
			Vsys_init(&vsysParams)
			{
				Vcap_init(NULL);//init gVcapModuleContext
   				Vdis_init(NULL);//init gVdisModuleContext  Vdis_hdmiCtrl_init();
   				Vdec_init(NULL);//init gVdecModuleContext
    				Venc_init(NULL);//init gVencModuleContext

    			 System_init();//mcfw/src_linux/links/system/system_common.c
    			 {
    			 	//创建信号量,用于控制线程
    			 	OSA_mutexCreate(&gSystem_objCommon.linkControlMutex);
    			 	System_ipcInit();
    			 	{
    			 		SysLink_setup ();
    			 		system_ipc_reset_srheaps();//gSystem_ipcObj.srHeaps=0
    			 		System_ipcMsgQInit();
    			 		{
    			 			System_ipcMsgQHeapCreate();//创建共享堆区gSystem_ipcObj
						    System_ipcMsgQCreate();    //创建消息队列并初始化msgQParams
						    System_ipcMsgQTskCreate(); //创建线程
						    {
						    	 OSA_thrCreate( &gSystem_ipcObj.msgQTask,
								                System_ipcMsgQTaskMain,
								                SYSTEM_MSGQ_TSK_PRI,
								                SYSTEM_MSGQ_TSK_STACK_SIZE,
								                NULL
								            );
						    	 System_ipcMsgQTaskMain()//管理消息队列的线程,线程调度
						    }
    			 		}
    			 		System_ipcNotifyInit();

    			 	}

				IpcBitsInLink_init();
				{
				    	status = OSA_tskCreate(&pObj->tsk,             //线程句柄
							       IpcBitsInLink_tskMain,  //线程主函数
							       IPC_LINK_TSK_PRI,
							       IPC_LINK_TSK_STACK_SIZE, 0, pObj);
							       
			                IpcBitsInLink_tskMain()
			                {
			                    while (!done)
			                    {
			                         cmd = OSA_msgGetCmd(pMsg);//get系统消息
					       	 switch (cmd)
						 {
						      case SYSTEM_CMD_NEW_DATA:
						         OSA_tskAckOrFreeMsg(pMsg, status);//释放消息
						         IpcBitsInLink_processBitBufs(pObj);//缓冲流处理
						         {
						              while (1)
						              {
						                   pListElem = ListMP_getHead(pObj->listMPOutHndl);   //得到共享区头部
						                   IpcBitsInLink_getBitBuf(pObj, pListElem, &pBitBuf);//pBitBuf指向共享内存区
						                   //outBitBufQue得到共享内存区数据用于其他link调用
						                   OSA_quePut(&pObj->outBitBufQue, (Int32) pBitBuf, OSA_TIMEOUT_NONE);
						                   				                   
						              }
						         }
                				      break;
						 }
			                    }
    
			                
			                }
				 }
				 IpcBitsOutLink_init();
				 {
				       System_registerLink(pObj->tskId, &linkObj);//注册link
				       IpcBitsOutLink_initListMP(pObj);  //创建多通道句柄 &pObj->listMPOutHndl, &pObj->listMPInHndl
				       status = OSA_tskCreate(&pObj->tsk, //创建线程
							       IpcBitsOutLink_tskMain, //线程
							       IPC_LINK_TSK_PRI,
							       IPC_LINK_TSK_STACK_SIZE, 0, pObj);
			               
			               IpcBitsOutLink_tskMain()//线程主函数
			               {
			                    IpcBitsOutLink_create(pObj, OSA_msgGetPrm(pMsg));//创建link
			                    {
			                         IpcBitsOutLink_createOutObj(pObj);
			                         {
			                             IpcBitsOutLink_createFreeListElemQue(pObj);//
			                             {
			                                 //&pObj->listElemFreeQue= (Int32)pObj->listElem[i]
			                             	 IpcBitsOutLink_createFreeListElemQue(pObj);
			                             }
			                             //创建队列
			                             OSA_queCreate(&pObj->listElemQue[chId],SYSTEM_IPC_BITS_MAX_LIST_ELEM);
			                             //&listElem->&pObj->listElemFreeQue
			                             status = OSA_queGet(&pObj->listElemFreeQue,(Int32 *)&listElem,OSA_TIMEOUT_NONE);
			                             //set listElem
			                             //&pObj->listElemQue[chId]=listElem
			                             status =OSA_quePut(&pObj->listElemQue[chId], (Int32) listElem,OSA_TIMEOUT_NONE);

			                             
			                         }
			                         IpcBitsOutLink_createPrdObj(pObj);
			                         {
			                         	OSA_thrCreate(&pObj->prd.thrHandle,
								     IpcBitsOutLink_periodicTaskFxn,
								     IPC_LINK_TSK_PRI, IPC_LINK_TSK_STACK_SIZE, pObj);
						        //线程管理,用于向arm发送任务消息
						        IpcBitsOutLink_periodicTaskFxn()
						        
			                         }
			                    }//create done
			                    
			                     while (!done)
    					     {
    					     	    cmd = OSA_msgGetCmd(pMsg);
    					     	    switch (cmd)
       						    {
       						         //case......
       						         case SYSTEM_CMD_START:
       						              IpcBitsOutLink_start(pObj);
							      OSA_tskAckOrFreeMsg(pMsg, status);
							      break;
							 case IPCBITSOUT_LINK_CMD_CREATE_CH_BUFFER:
							    {
								status = IpcBitsOutLink_CreateChBuffer(pObj,//创建buf
												      OSA_msgGetPrm(pMsg));
								{
								    //创建缓冲池
								    ipcbitsoutlink_validate_createbuf_params(pObj,bufCreatePrms);
								    status = IpcBitsOutLink_doChBufCreate(pObj,bufCreatePrms);
								        {
								           //读取内存中的数据
								           RingBufferInit(&pObj->ringBufHdnl[chId], pObj->bitBufBasePtr[chId], totBufSize);
									   //listElem->&pObj->listElemFreeQue(listElem是临时变量)
									   OSA_queGet(&pObj->listElemFreeQue,(Int32 *)&listElem,OSA_TIMEOUT_NONE);
								           //&pObj->listElemQue[chId]=listElem
								           OSA_quePut(&pObj->listElemQue[chId], (Int32) listElem,OSA_TIMEOUT_NONE);
									}
								}
								
								OSA_tskAckOrFreeMsg(pMsg, status);
								break;
							    }
       						    }
    					     }
			               
			               }
						
				 }
				 IpcFramesInLink_init();
				 IpcFramesOutLink_init();

				 AvsyncLink_init();

				 SystemLink_init();
    			 }

			}

		
		}//VcapVdis_start()
	 
	 
	}

	 while(!done)
     {
	ch = Demo_getChar();//设置
        switch(ch)
	    case '1':
			    Demo_captureSettings(demoId);
                break;
            case '2':
                Demo_encodeSettings(demoId);
                break;
            case '3':
                Demo_decodeSettings(demoId);
                break;
            case '4':
                Demo_displaySettings(demoId);
                break;
		       //...
	   case 'e':
                done = TRUE;
                break;
	 }
   /*结束demo,正常退出并释放内存资源
     如果在程序运行期间采取ctrl+c的方式中断程序会因为内存没用正常释放从而导致
     在下一次重新启动demo是出错。这种错误需要reboot开发板并重新init load	
  */
   Demo_startStop(demoId, FALSE)
   {
		 VdecVdis_stop()
	    	 {
			 VdecVdis_bitsRdStop();
			 
			 /* Stop components */
			 Vdec_stop();
			 Vdis_stop();

			 grpx_exit();
				
			 Vsys_delete();

			 /* De-configure display */
			 Vsys_deConfigureDisplay();

  
    	                /* De-initialize components */
			Vdec_exit();
			Vdis_exit();
			Vsys_exit();	
			 
			VdecVdis_bitsRdExit();
		 }
   }

   return 0;

}





posted @ 2014-04-27 15:20  懒人部落  阅读(456)  评论(0编辑  收藏  举报