zoukankan      html  css  js  c++  java
  • 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;
    
    }
    
    
    
    


  • 相关阅读:
    通过SSH隧道的本地转发实现Django连接远程数据库
    Mysql多数据库备份
    apollo 项目配置中心开源框架部署
    nginx 配置多个 https 域名访问
    beetl 模板语法
    异常:由 spring-session pom 引发
    异常:NoSuchFieldError: BEST_MATCHING_HANDLER_ATTRIBUTE
    【Redis__验证】手机验证和限制登录功能
    【Linux__环境】配置
    【Layui__上传】多图上传
  • 原文地址:https://www.cnblogs.com/wennian/p/5036929.html
Copyright © 2011-2022 走看看