/***************************************************************************** *_Copyright (c) 2004 DST Technologies Inc. All Rights Reserved. * * file name: dstddPsiProcess.c * * Description: Platform-Specific PID/Section Filter Management * *****************************************************************************/ #include #include #include #include #include #include "dsthalcommon.h" #include "dsthalPsiAtscPsip.h" #include "dsthalPsiMpegSi.h" #include "dstdddmx.h" /* * Driver Includes. */ #include "pd_dmx.h" #ifdef DMALLOC #include #endif int gddPsiDbgLvl = 2; #if 0 ___Definitions_______________() #endif #if 1 #define PRINT_PREF_FILTER(pref) do { int i; printf("Filter/Mask\n"); \ for (i=0; i<((pref)->numEntries); i++) { \ if ( i==(((pref)->numEntries)-1) ) \ printf("%02X\n", (pref)->entries[i].value);\ else \ printf("%02X-", (pref)->entries[i].value);\ } \ for (i=0; i<((pref)->numEntries); i++) { \ if ( i==(((pref)->numEntries)-1) ) \ printf("%02X\n", (pref)->entries[i].matchMask);\ else \ printf( "%02X-", (pref)->entries[i].matchMask);\ } \ } while(0) #define PRINT_FILTER(byte,size) do { int i; DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "Filter-%d(%d): ", pSectCtl->iSelfIndex, __LINE__); \ for (i=0; i<(size); i++) { \ if ( i==((size)-1) ) \ printf("%02X\n", (byte)[i]);\ else \ printf("%02X-", (byte)[i]); \ } \ } while(0) #define PRINT_MASK(byte,size) do { int i; DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "Mask (%d): ", __LINE__); \ for (i=0; i<(size); i++) { \ if ( i==((size)-1) ) \ printf("%02X\n", (byte)[i]);\ else \ printf( "%02X-", (byte)[i]); \ } \ } while(0) #else #define PRINT_FILTER(byte,size) #define PRINT_MASK(byte,size) #endif //========================================================================================= // Configuration Definitions //========================================================================================= #if (BOG_SW_VERSION>=0x0031A000) #define NEW_API // Demux API º¯°æ °ü·Ã. #endif //========================================================================================= // PID/Section Filter Size //========================================================================================= #define SECTION_FILTER_SIZE 16 // ½ÇÁ¦·Î´Â Á¦ÇÑÀÌ ÀÖÀ¸³ª 16À¸·Î »ç¿ë. #define MAX_PID_FILTER_CNT 64 // ÃÖ´ë 64°³. #define MAX_SECTION_FILTER_CNT 64 // ÃÖ´ë 256°³À̳ª, PID Filter Cnt¿¡ Á¾¼ÓÀûÀ̱⿡ 64°³. //========================================================================================= // Local Definitions //========================================================================================= #define USE_ONESHOT 0 #define MAX_PSI_EVENT 4 // PSI Callback Events typedef enum tag_PSI_EVENT_t { PSI_EVENT__RCVD_NO_ERROR=0x01, PSI_EVENT__RCVD_OVERFLOW=0x02, } PSI_EVENT_t; #define MSG_STOP (0xDEADBEEF) // PSI Monitor Stop Message int g_FilterCount_4Kb = 0; int g_FilterCount_1Kb = 0; int g_Demux_Debug = 0; int g_Temp_Debug = 0; int g_TotalLeakSize = 0; int g_TotalLeakCnt = 0; // // Filter State // typedef enum{ PCS_RAW = 0x00, PCS_INIT = 0x01, PCS_RUNNING = 0x03 } PSI_CTL_State_e; // // Structure for managing PID Filter // typedef struct PSI_PID_CTL_t { int nRefCount; int nRefCountRunning; PSI_CTL_State_e eState; /* two state : PCS_INIT , PCS_RAW. */ unsigned int uiPid; } PSI_PID_CTL_t; // // Structure for managing Section Filter // typedef void (*PSI_CB_FUNC_t)( PSI_EVENT_t Event, DS_U32 Arg, DS_U8 *pBuf, DS_U32 Len ); typedef struct PSI_SECTION_CTL_t { unsigned char iSelfIndex; struct PSI_INFRA_CTL_t *pParent; int iPidCtlIndex; DS_U32 Pid; OS_SEMAPHORE_ID hSectionSema4; PSI_CTL_State_e eState; /*three state : PCS_RAW , PCS_INIT , PCS_RUNNING. */ PSIContext_t *pContext; /*user request°¡ ÀÖÀ» ¶§¸¸ µ¿ÀûÀ¸·Î »ý¼º,Á¦°Å.*/ DS_U8 filterBytes[SECTION_FILTER_SIZE]; DS_U8 filterMasks[SECTION_FILTER_SIZE]; DS_U8 filterInvert[SECTION_FILTER_SIZE]; DS_U32 filtCount; DS_U8 nLockCount; DS_U32 iCurLockedTask; OS_TASK_ID taskId; DS_U8 isMonitorStarted; DS_U8 isMonitorError; PD_SECFILTER *pDrvSecFilter; DS_U8 Matched; } PSI_SECTION_CTL_t; typedef struct PSI_LIST_ELEM_t { struct PSI_LIST_ELEM_t *pPrev; struct PSI_LIST_ELEM_t *pNext; }PSI_LIST_ELEM_t; typedef struct PSI_LIST_HEADER_t { int nCount; PSI_LIST_ELEM_t *pElem; OS_SEMAPHORE_ID hAccessSema4; }PSI_LIST_HEADER_t; /*the base structure for PSI resources*/ typedef struct PSI_INFRA_CTL_t { PSI_PID_CTL_t aPidCtl[MAX_PID_FILTER_CNT]; OS_SEMAPHORE_ID hPidCtlAccessSema4; PSI_LIST_HEADER_t lhSectCtl; /*section ctl list¸¦ À§ÇÑ header.*/ DS_BOOL aSectCtlUsedList[MAX_SECTION_FILTER_CNT]; PSI_SECTION_CTL_t aSectCtl[MAX_SECTION_FILTER_CNT]; OS_SEMAPHORE_ID hSectCtlAccessSema4; }PSI_INFRA_CTL_t; #if 0 ___Local_Variables_______________() #endif static void DD_PSI_DeleteAllSectCtls( PSI_INFRA_CTL_t *pPsiInfra ); static void DD_PSI_ReleaseAllPidCtls( PSI_INFRA_CTL_t *pPsiInfra ); static void cbReceiveSection(PD_SECFILTER *psec, DS_U8 *pSecData, int Size); DHL_RESULT DD_PSI_StartPidCtl ( PSI_INFRA_CTL_t *pPsiInfra, int iPidCtlIndex ); DHL_RESULT DD_PSI_StopPidCtl ( PSI_INFRA_CTL_t *pPsiInfra , int iPidCtlIndex ); DHL_RESULT DD_PSI_GetPidCtl( PSI_INFRA_CTL_t *pPsiInfra , unsigned int pid, int *iPidCtlIndex ); DHL_RESULT DD_PSI_LockPidCtlArray ( PSI_INFRA_CTL_t *pPsiInfra , int timeOut ); DHL_RESULT DD_PSI_UnlockPidCtlArray ( PSI_INFRA_CTL_t *pPsiInfra ); DHL_RESULT DD_PSI_ReleasePidCtl ( PSI_INFRA_CTL_t *pPsiInfra , int iPidCtlIndex ); PSI_SECTION_CTL_t* DD_PSI_GetSectCtlFromArray( PSI_INFRA_CTL_t *pPsiInfra ); void DD_PSI_ReleaseSectCtlFromArray( PSI_INFRA_CTL_t *pPsiInfra, int iSectIndex ); void DD_PSI_ReleaseSectionCtl ( PSI_SECTION_CTL_t *pSectCtl ); DS_BOOL DD_PSI_ExistSectionFilter( void *pPsiInfo, DS_U16 pid, PSI_SECTION_CTL_t *pCtrlToFind, PSI_SECTION_CTL_t **returnSectCtl ); void DD_PSI_ResetSectionCtl( PSI_SECTION_CTL_t *pSectCtl , int iSelfIndex ); #if 0 ___Common_APIs___________________() #endif static PSI_INFRA_CTL_t *g_pPsiInfra; DHL_RESULT DD_PSI_Init( void **arg4 /*returned psi handle*/ ) { int i = 0; PSI_INFRA_CTL_t *pPsiInfra = (PSI_INFRA_CTL_t *)PSI_Malloc( sizeof(PSI_INFRA_CTL_t) ); if( pPsiInfra == NULL ) return DHL_FAIL_OUT_OF_RESOURCE; memset( pPsiInfra , 0 , sizeof(PSI_INFRA_CTL_t) ); pPsiInfra->hPidCtlAccessSema4 = OS_CreateCountingSemaphore( "pidSema4", 0, 1 ); pPsiInfra->hSectCtlAccessSema4 = OS_CreateCountingSemaphore( "sectSema4", 0, 1 ); for ( i = 0 ; i < MAX_SECTION_FILTER_CNT ; i++ ) { DD_PSI_ResetSectionCtl(&(pPsiInfra->aSectCtl[i]) , i ); } PD_DMX_SetSectionFilterCallback( cbReceiveSection, 0 ); g_pPsiInfra = pPsiInfra; *arg4 = (void *)pPsiInfra; return DHL_OK; } DHL_RESULT DD_PSI_Close( void *pPsiHandle ) { PSI_INFRA_CTL_t *pPsiInfra = (PSI_INFRA_CTL_t *)pPsiHandle; if( !pPsiInfra ) return DHL_FAIL_NULL_POINTER; DD_PSI_DeleteAllSectCtls( pPsiHandle); /*for exception cases.*/ DD_PSI_ReleaseAllPidCtls( pPsiInfra ); if(pPsiInfra->hPidCtlAccessSema4) OS_DeleteSemaphore( pPsiInfra->hPidCtlAccessSema4 ); pPsiInfra->hPidCtlAccessSema4 = 0; if(pPsiInfra->hSectCtlAccessSema4) OS_DeleteSemaphore( pPsiInfra->hSectCtlAccessSema4); pPsiInfra->hSectCtlAccessSema4 = 0; PSI_Free(pPsiInfra); return DHL_OK; } #if 0 ___Section_Filter_API____________() #endif DHL_RESULT DD_PSI_CreateAndSetFilter( PSI_SECTION_CTL_t *pSectCtl, DS_U32 Pid, DS_U8 *pFilterBytes, DS_U8 *pFilterMask, DS_U8 *pFilterInvert, DS_U32 filtSize ) { DHL_RESULT dhlResult = DHL_OK; PSIContext_t *pPsiContext = pSectCtl->pContext; // // Set Filter Settings. // pSectCtl->Pid = Pid; pSectCtl->Matched = 0; //DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "|%d-0x%x| [%d]\n", __LINE__, (unsigned int)pSectCtl, (int)OS_GetTickCount() ); // // Init PSI Monitor Thread. // pSectCtl->isMonitorStarted = 0; pSectCtl->isMonitorError = 0; if ( pSectCtl->isMonitorError ) dhlResult = DHL_FAIL; if ( g_Demux_Debug ) { DHL_DbgPrintf(0,DDDBG_AV, "++ [4k:%d, 1k:%d] PID = 0x%x [%s]\n", g_FilterCount_4Kb, g_FilterCount_1Kb, (unsigned int)pSectCtl->Pid, pPsiContext->oneShot ? "OneShot" : "Conti" ); PRINT_FILTER( pSectCtl->filterBytes, pSectCtl->filtCount); PRINT_MASK( pSectCtl->filterMasks, pSectCtl->filtCount); } pSectCtl->pDrvSecFilter = PD_DMX_CreateSectionFilter( Pid, pFilterBytes, pFilterMask, (int)filtSize, 1024, 0 ); if ( pSectCtl->pDrvSecFilter == (PD_SECFILTER *)NULL ) printf("|%s:%d| ERROR.\n", __FUNCTION__, __LINE__); /* * Just to avoid WARNING message. */ pPsiContext = pPsiContext; return dhlResult; } DHL_RESULT DD_PSI_StopAndDeleteFilter( PSI_SECTION_CTL_t *pSectCtl ) { DHL_RESULT dhlResult = DHL_OK; PSIContext_t *pPsiContext = pSectCtl->pContext; int retVal = PD_DMX_SUCCESS; if ( g_Demux_Debug ) { DHL_DbgPrintf(0,DDDBG_AV, "-- [4k:%d, 1k:%d] PID = 0x%x [%s]\n", g_FilterCount_4Kb, g_FilterCount_1Kb, (unsigned int)pSectCtl->Pid, pPsiContext->oneShot ? "OneShot" : "Conti" ); PRINT_FILTER( pSectCtl->filterBytes, pSectCtl->filtCount); PRINT_MASK( pSectCtl->filterMasks, pSectCtl->filtCount); } retVal = PD_DMX_DeleteSectionFilter( pSectCtl->pDrvSecFilter ); SysASSERT( PD_DMX_OK(retVal) ); return dhlResult; } #if 0 ___Section_Control_API__________() #endif DHL_RESULT DD_PSI_InitSectionCtl( PSI_SECTION_CTL_t *pSectionCtl ) { DHL_RESULT dhlResult = DHL_OK; if( !pSectionCtl ) return DHL_FAIL_NULL_POINTER; if( !pSectionCtl->hSectionSema4 ) { pSectionCtl->hSectionSema4 = OS_CreateCountingSemaphore( "PSISema4", 0, 1 ); } if( !pSectionCtl->hSectionSema4) DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_InitSectionCtl : OS_CreateCountingSemaphore fail.\n"); //pSectionCtl->taskId = (gmtCL_ThreadID)-1; return dhlResult; } DHL_RESULT DD_PSI_InitSectionCtlBig( PSI_SECTION_CTL_t *pSectionCtl ) { DHL_RESULT dhlResult = DHL_OK; if( !pSectionCtl ) return DHL_FAIL_NULL_POINTER; if( !pSectionCtl->hSectionSema4 ) pSectionCtl->hSectionSema4 = OS_CreateCountingSemaphore( "psiSecSema4", 0, 1 ); if( !pSectionCtl->hSectionSema4) DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_InitSectionCtlBig : OS_CreateCountingSemaphore fail.\n"); return dhlResult; } DHL_RESULT DD_PSI_OpenSectionCtl( PSI_INFRA_CTL_t *pPsiInfra, PSI_SECTION_CTL_t *pSectionCtl , DS_U32 uPidCtlIndex, DS_U32 uSectionFilterName, DS_U32 uSIName) { DHL_RESULT dhlResult = DHL_OK; if(!pPsiInfra) return DHL_FAIL_NULL_POINTER; if(!pSectionCtl) return DHL_FAIL_NULL_POINTER; /*1.set a PID-Ctl Index==============================*/ pSectionCtl->iPidCtlIndex = uPidCtlIndex; /*2.Open a Section Filter===============================*/ /*3.Open a Streaming Interface ========================*/ return(dhlResult); } DHL_RESULT DD_PSI_StartSectionCtl( PSI_SECTION_CTL_t * pSectionCtl , PSIMask_t *prefList ) { int i , j; int maxCnt = 0; DHL_RESULT dhlResult; PSI_INFRA_CTL_t *pPsiInfra = NULL; PSI_PID_CTL_t *pPidCtl = NULL; if( !pSectionCtl ) return DHL_FAIL_INVALID_PARAM; pPsiInfra = (PSI_INFRA_CTL_t *)pSectionCtl->pParent; pPidCtl = &(pPsiInfra->aPidCtl[pSectionCtl->iPidCtlIndex]); /*first, check the current state.*/ if( !(pSectionCtl->eState == PCS_INIT) ) { dhlResult = DHL_FAIL_INVALID_PARAM; goto GOOUT; } /*third, set the hardware pid , section filtering parameters & start si.*/ /* notification setting */ if( prefList->numEntries > SECTION_FILTER_SIZE ) maxCnt = SECTION_FILTER_SIZE; else maxCnt = prefList->numEntries; for ( i = 0 , j = 0 ; i < maxCnt ; ++i ) { #if USE_FILTER1 if ( i == 2 || i == 7 ) /*index°¡ 2,7ÀÎ byte´Â ¹«½Ã.*/ continue; #endif // #if USE_FILTER1 pSectionCtl->filterBytes [j] = prefList->entries[i].value; pSectionCtl->filterMasks [j] = prefList->entries[i].matchMask; pSectionCtl->filterInvert[j] = prefList->entries[i].noMatchMask; ++j; } maxCnt = j; pSectionCtl->filtCount = maxCnt; #if DEBUG { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "\r\nFILTER_BYTE :"); for( i = 0 ; i < maxCnt ; i++ ) DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, " 0x%x" , pSectionCtl->filterBytes [i]); DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "\r\nFILTER_MASK :"); for( i = 0 ; i < maxCnt ; i++ ) DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, " 0x%x" , pSectionCtl->filterMasks [i]); DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "\r\nFILTER_INVERT :"); for( i = 0 ; i < maxCnt ; i++ ) DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, " 0x%x" , pSectionCtl->filterInvert[i]); DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "\r\nFILTER_COUNT : %ld\r\n", pSectionCtl->filtCount); } #endif dhlResult = DD_PSI_CreateAndSetFilter( pSectionCtl, pPidCtl->uiPid, pSectionCtl->filterBytes, pSectionCtl->filterMasks, pSectionCtl->filterInvert, pSectionCtl->filtCount ); if (DHL_ERROR(dhlResult)) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "ERROR, LINE=%d\n", __LINE__); goto GOOUT; } pSectionCtl->eState = PCS_RUNNING; dhlResult = DD_PSI_StartPidCtl ( pPsiInfra , pSectionCtl->iPidCtlIndex ); if ( dhlResult != DHL_OK ) { pSectionCtl->eState = PCS_INIT; DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "ERROR, LINE=%d\n", __LINE__); } GOOUT: return dhlResult; } DHL_RESULT DD_PSI_StopSectionCtl( PSI_SECTION_CTL_t *pSectionCtl ) { DHL_RESULT dhlResult; PSI_INFRA_CTL_t *pPsiInfra = NULL; if (!pSectionCtl) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "NULL SectionCtl.\r\n"); return DHL_FAIL_NULL_POINTER; } pPsiInfra = (PSI_INFRA_CTL_t *)pSectionCtl->pParent; if (pSectionCtl->eState != PCS_RUNNING) { #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "It is not started. skipped.\r\n"); #endif return DHL_OK; } /*3.stop pid filter.**********************************************/ dhlResult = DD_PSI_StopPidCtl ( pPsiInfra , pSectionCtl->iPidCtlIndex ); if ( dhlResult != DHL_OK ) DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "ERROR, LINE=%d\n", __LINE__); /******************************************************************/ /*4.Stop SI component**********************************************/ /******************************************************************/ if ( PD_DMX_SUCCESS != PD_DMX_EnableSectionFilter( pSectionCtl->pDrvSecFilter, 0 ) ) DHL_DbgPrintf(0, DDDBG_PSI, "ERROR, LINE=%d\n", __LINE__); /*5. back to the init state.*/ pSectionCtl->eState = PCS_INIT; return dhlResult; } DHL_RESULT DD_PSI_GetSectionCtl( PSI_INFRA_CTL_t *pPsiInfra , DS_U16 pid , PSIMask_t *prefList, PSI_SECTION_CTL_t **retSectCtlPtr ) { DHL_RESULT dhlResult = DHL_OK; PSI_SECTION_CTL_t *pSectionCtl = NULL; int iPidCtlIndex = 0; DS_BOOL bExist = _FALSE_; DS_U16 tableId = 0; *retSectCtlPtr = NULL; if( !pPsiInfra || !prefList || !retSectCtlPtr ) return DHL_FAIL_INVALID_PARAM; tableId = prefList->entries[0].value; /*tableId*/ bExist = DD_PSI_ExistSectionCtl( pPsiInfra, pid, prefList ); if( bExist == _TRUE_ ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_MonitorPSIPid : it's already exist filter. so, reject your request. \r\n"); PRINT_PREF_FILTER( prefList ); return DHL_FAIL_NOT_AVAILABLE; } dhlResult = DD_PSI_GetPidCtl( pPsiInfra ,pid, &iPidCtlIndex ); if( dhlResult != DHL_OK ) return dhlResult; pSectionCtl = DD_PSI_GetSectCtlFromArray( pPsiInfra ); if( !pSectionCtl ) { DD_PSI_ReleasePidCtl ( pPsiInfra , iPidCtlIndex ); return dhlResult; } dhlResult = DD_PSI_OpenSectionCtl( pPsiInfra, pSectionCtl , iPidCtlIndex, 0, 0); if( dhlResult != DHL_OK ) { DD_PSI_ReleaseSectCtlFromArray( pPsiInfra , pSectionCtl->iSelfIndex ); return dhlResult; } dhlResult = DD_PSI_InitSectionCtl( pSectionCtl ); if( dhlResult != DHL_OK ) { DD_PSI_ReleaseSectionCtl(pSectionCtl); //DD_PSI_FreeSectoinCtl( pSectionCtl ); *retSectCtlPtr = NULL; pSectionCtl = NULL; } pSectionCtl->eState = PCS_INIT; *retSectCtlPtr = pSectionCtl; return dhlResult; } DHL_RESULT DD_PSI_GetSectionCtlBig( PSI_INFRA_CTL_t *pPsiInfra , DS_U16 pid , PSIMask_t *prefList, PSI_SECTION_CTL_t **retSectCtlPtr ) { DHL_RESULT dhlResult = DHL_OK; PSI_SECTION_CTL_t *pSectionCtl = NULL; int iPidCtlIndex = 0; DS_BOOL bExist = _FALSE_; DS_U16 tableId = 0; *retSectCtlPtr = NULL; if( !pPsiInfra || !prefList || !retSectCtlPtr ) return DHL_FAIL_INVALID_PARAM; tableId = prefList->entries[0].value; /*tableId*/ bExist = DD_PSI_ExistSectionCtl( pPsiInfra, pid, prefList ); if( bExist == _TRUE_ ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_GetSectionCtlBig : it's already exist filter. so, reject your request. \r\n"); return DHL_FAIL_NOT_AVAILABLE; } dhlResult = DD_PSI_GetPidCtl( pPsiInfra ,pid, &iPidCtlIndex ); if( dhlResult != DHL_OK ) return dhlResult; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_GetSectionCtlBig : iPidCtlIndex = %d , state = %d \r\n" , iPidCtlIndex , pPsiInfra->aPidCtl[iPidCtlIndex].eState ); #endif pSectionCtl = DD_PSI_GetSectCtlFromArray( pPsiInfra ); if( !pSectionCtl ) { DD_PSI_ReleasePidCtl ( pPsiInfra , iPidCtlIndex ); return dhlResult; } dhlResult = DD_PSI_OpenSectionCtl( pPsiInfra, pSectionCtl , iPidCtlIndex, 0, 0); if( dhlResult != DHL_OK ) { DD_PSI_ReleaseSectCtlFromArray( pPsiInfra , pSectionCtl->iSelfIndex ); return dhlResult; } dhlResult = DD_PSI_InitSectionCtlBig( pSectionCtl ); if( dhlResult != DHL_OK ) { DD_PSI_ReleaseSectionCtl(pSectionCtl); //DD_PSI_FreeSectoinCtl( pSectionCtl ); *retSectCtlPtr = NULL; pSectionCtl = NULL; } pSectionCtl->eState = PCS_INIT; *retSectCtlPtr = pSectionCtl; return dhlResult; } void DD_PSI_FreeSectionCtl ( PSI_SECTION_CTL_t *pSectCtl ) { if( !pSectCtl ) return; /*If exists, delete sema4.*/ if ( pSectCtl->hSectionSema4 != 0 ) { #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "delete psectCtl->sema4. \n"); #endif OS_DeleteSemaphore( pSectCtl->hSectionSema4 ); pSectCtl->hSectionSema4 = 0; } } void DD_PSI_ResetSectionCtl( PSI_SECTION_CTL_t *pSectCtl , int iSelfIndex ) { if( !pSectCtl ) return; pSectCtl->iSelfIndex = iSelfIndex; pSectCtl->pParent = NULL; pSectCtl->iPidCtlIndex = 0; pSectCtl->eState = PCS_RAW; pSectCtl->pContext = NULL; if( !(pSectCtl->hSectionSema4) ) pSectCtl->hSectionSema4 = OS_CreateCountingSemaphore( "psiSectSema4", 0, 1 ); if( !(pSectCtl->hSectionSema4) ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ResetSectionCtl : fail create sema4.\r\n"); } else { #ifdef PIS_DBG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ResetSectionCtl : create section sema4 ok.\r\n"); #endif } } void DD_PSI_ReleaseSectionCtl ( PSI_SECTION_CTL_t *pSectCtl ) { DHL_RESULT dhlResult = DHL_OK; if( !pSectCtl ) return; if( pSectCtl->eState == PCS_RAW ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "|%d| WARING: Try to release section control not allocated.\n", __LINE__); return; } if( pSectCtl->eState == PCS_RUNNING) DD_PSI_StopSectionCtl( pSectCtl ); dhlResult = DD_PSI_StopAndDeleteFilter( pSectCtl ); if ( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "ERROR, LINE=%d\n", __LINE__); return; } DD_PSI_ReleasePidCtl( (PSI_INFRA_CTL_t *)(pSectCtl->pParent) , pSectCtl->iPidCtlIndex ); if( pSectCtl->pContext ) { DD_PSI_ReleasePSICtx( pSectCtl->pContext ); pSectCtl->pContext = NULL; } //pSectCtl->filterId = -1; pSectCtl->eState = PCS_INIT; DD_PSI_ReleaseSectCtlFromArray(pSectCtl->pParent ,pSectCtl->iSelfIndex); } DS_BOOL DD_PSI_ExistSectionCtl( void *pPsiInfo, DS_U16 pid, PSIMask_t *prefList ) { PSI_INFRA_CTL_t *pPsiInfra = (PSI_INFRA_CTL_t *)pPsiInfo; PSI_SECTION_CTL_t * pSectionCtl = NULL; DS_BOOL bFound = _FALSE_; int i=0 ,j =0; if(!pPsiInfra || !prefList ) return _FALSE_; for( i = 0 ; i < MAX_SECTION_FILTER_CNT ; i++ ) { if( pPsiInfra->aSectCtlUsedList[i] == _FALSE_ ) continue; pSectionCtl = &(pPsiInfra->aSectCtl[i]); #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ExistSectionCtl : index = %d. filtCount = %d\r\n" , pSectionCtl->iPidCtlIndex , pSectionCtl->filtCount); #endif if ( pPsiInfra->aPidCtl[pSectionCtl->iPidCtlIndex].uiPid == pid ) { int iFilterIndex = 0; for ( iFilterIndex = 0 , j = 0 ; iFilterIndex < pSectionCtl->filtCount; iFilterIndex++, j++ ) { #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ExistSectionCtl :filterBytes[%d] = 0x%x ,entries[%d] = 0x%x. \r\n" , j , pSectionCtl->filterBytes[j], iFilterIndex , prefList->entries[iFilterIndex].value ); #endif if( iFilterIndex == 2 || iFilterIndex == 7 ) /*2, 7 index °¡Áö´Â byte¹«½Ã.*/ continue; if( pSectionCtl->filterBytes[j] != prefList->entries[iFilterIndex].value ) break; /*for loop break*/ if ( pSectionCtl->filterMasks[j] != prefList->entries[iFilterIndex].matchMask ) break; /*for loop break*/ //++j; } if ( pSectionCtl->filtCount && iFilterIndex == pSectionCtl->filtCount ) /*filterCount ¸ðµÎ ºñ±³Çصµ ´Ù¸¥°Ô ¾ø´Ù¸é*/ { bFound = _TRUE_; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ExistSectionCtl : already registered filter. so rejecjt it.\r\n"); #endif break; /*while loop break*/ } } /*if ( pPsiInfra->aPidCtl[iPidCtlIndex] == pid )*/ } /*for*/ return bFound; } DS_BOOL DD_PSI_ExistSectionFilter( void *pPsiInfo, DS_U16 pid, PSI_SECTION_CTL_t *pCtrlToFind, PSI_SECTION_CTL_t **returnSectCtl ) { PSI_INFRA_CTL_t *pPsiInfra = (PSI_INFRA_CTL_t *)pPsiInfo; PSI_SECTION_CTL_t * pSectionCtl = NULL; DS_BOOL bFound = _FALSE_; int i=0 ,j =0; if(!pPsiInfra || !pCtrlToFind ) return _FALSE_; for( i = 0 ; i < MAX_SECTION_FILTER_CNT ; i++ ) { if( pPsiInfra->aSectCtlUsedList[i] == _FALSE_ ) continue; pSectionCtl = &(pPsiInfra->aSectCtl[i]); #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "index = %d. filtCount = %d\r\n" , pSectionCtl->iPidCtlIndex , pSectionCtl->filtCount); #endif if ( pPsiInfra->aPidCtl[pSectionCtl->iPidCtlIndex].uiPid == pid ) { int iFilterIndex = 0; for ( iFilterIndex = 0 , j = 0 ; iFilterIndex < pSectionCtl->filtCount; iFilterIndex++ ) { #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ExistSectionCtl :filterBytes[%d] = 0x%x ,entries[%d] = 0x%x. \r\n" , j , pSectionCtl->filterBytes[j], iFilterIndex, pCtrlToFind->filterBytes[iFilterIndex] ); #endif if( iFilterIndex == 2 || iFilterIndex == 7 || iFilterIndex >= 9) /*2, 7 index °¡Áö´Â byte¹«½Ã.*/ continue; if( pSectionCtl->filterBytes[j] != pCtrlToFind->filterBytes[j] ) break; /*for loop break*/ if ( pSectionCtl->filterMasks[j] != pCtrlToFind->filterMasks[j] ) break; /*for loop break*/ ++j; } if ( pSectionCtl->filtCount && iFilterIndex == pSectionCtl->filtCount ) /*filterCount ¸ðµÎ ºñ±³Çصµ ´Ù¸¥°Ô ¾ø´Ù¸é*/ { if ( pSectionCtl != pCtrlToFind ) { bFound = _TRUE_; *returnSectCtl = pSectionCtl; break; /*while loop break*/ } } } /*if ( pPsiInfra->aPidCtl[iPidCtlIndex] == pid )*/ } /*for*/ return bFound; } DS_BOOL DD_PSI_IsRunningSectionCtl( PSI_SECTION_CTL_t * pSectionCtl ) { if( pSectionCtl->eState == PCS_RUNNING ) return _TRUE_; else return _FALSE_; } static void DD_PSI_DeleteAllSectCtls( PSI_INFRA_CTL_t *pPsiInfra ) { int i = 0; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_DeleteAllSectCtls.\n"); #endif if(!pPsiInfra) return; for ( i = 0 ; i < MAX_SECTION_FILTER_CNT ; i++ ) { if( pPsiInfra->aSectCtlUsedList[i] == _TRUE_ ) { #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "%d th sectCtl is deleted.\n"); #endif DD_PSI_CancelPSIPid( pPsiInfra ,(void *)(&( pPsiInfra->aSectCtl[i])) ); } DD_PSI_FreeSectionCtl( &(pPsiInfra->aSectCtl[i]) ); pPsiInfra->aSectCtlUsedList[i] = _TRUE_; } } DHL_RESULT DD_PSI_LockSectCtlArray( PSI_INFRA_CTL_t *pPsiInfra , int timeOut ) { int res = 0; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_LockSectCtlArray.\r\n"); #endif if( !pPsiInfra) return DHL_FAIL_NULL_POINTER; if( !(pPsiInfra->hSectCtlAccessSema4) ) return DHL_FAIL_INVALID_PARAM; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockSectCtlArray. before sema lock\r\n"); #endif res = OS_TakeSemaphore_Wait(pPsiInfra->hSectCtlAccessSema4 , timeOut); if( res != 0 ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockSectCtlArray : OS_TakeSemaphore_Wait timeout.\n"); /*return */ return DHL_FAIL_TIMEOUT; } #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockSectCtlArray. after sema lock\r\n"); #endif return DHL_OK; } DHL_RESULT DD_PSI_UnlockSectCtlArray( PSI_INFRA_CTL_t *pPsiInfra ) { DS_U32 res; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_UnlockSectCtlArra.\r\n"); #endif if( !pPsiInfra ) return DHL_FAIL_NULL_POINTER; if( !pPsiInfra->hSectCtlAccessSema4 ) return DHL_FAIL_INVALID_PARAM; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_UnlockSectCtlArray. before sema unlock\r\n"); #endif res = OS_GiveSemaphore(pPsiInfra->hSectCtlAccessSema4); if ( res ) DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "ERROR, LINE=%d\n", __LINE__); #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_UnlockSectCtlArray. after sema unlock\r\n"); #endif return DHL_OK; } PSI_SECTION_CTL_t* DD_PSI_GetSectCtlFromArray( PSI_INFRA_CTL_t *pPsiInfra ) { #if !DONOT_USE_LOCK_SECTCTRLARRAY DHL_RESULT dhlResult = DHL_OK; #endif PSI_SECTION_CTL_t *pSectCtl = NULL; int i = 0; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_GetSectCtlFromArray...\r\n"); #endif if( !pPsiInfra ) return NULL; #if !DONOT_USE_LOCK_SECTCTRLARRAY dhlResult = DD_PSI_LockSectCtlArray( pPsiInfra , OS_WAIT_FOREVER /*infinite*/ ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockSectCtlArray... : timeout.\r\n"); return NULL; } #endif for( i = 0 ; i < MAX_SECTION_FILTER_CNT ; i++ ) { if( pPsiInfra->aSectCtlUsedList[i] == _FALSE_ ) { pSectCtl = &(pPsiInfra->aSectCtl[i]); pPsiInfra->aSectCtlUsedList[i] = _TRUE_; break; } }/*for*/ if( pSectCtl ) pSectCtl->pParent = pPsiInfra; #if !DONOT_USE_LOCK_SECTCTRLARRAY DD_PSI_UnlockSectCtlArray( pPsiInfra ); #endif return pSectCtl; } void DD_PSI_ReleaseSectCtlFromArray( PSI_INFRA_CTL_t *pPsiInfra, int iSectIndex ) { #if !DONOT_USE_LOCK_SECTCTRLARRAY DHL_RESULT dhlResult = DHL_OK; #endif #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_ReleaseSectCtlFromArray...\r\n"); #endif if( !pPsiInfra || iSectIndex > MAX_SECTION_FILTER_CNT ) return; #if !DONOT_USE_LOCK_SECTCTRLARRAY dhlResult = DD_PSI_LockSectCtlArray( pPsiInfra , OS_WAIT_FOREVER /*infinite*/ ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ReleaseSectCtlFromArray... : timeout.\r\n"); return; } #endif if ( pPsiInfra->aSectCtlUsedList[iSectIndex] == _TRUE_ ) { pPsiInfra->aSectCtlUsedList[iSectIndex] = _FALSE_; DD_PSI_ResetSectionCtl( &(pPsiInfra->aSectCtl[iSectIndex]) ,iSectIndex ); } #if !DONOT_USE_LOCK_SECTCTRLARRAY DD_PSI_UnlockSectCtlArray( pPsiInfra ); #endif return; } DHL_RESULT DD_PSI_LockSectionCtl( PSI_SECTION_CTL_t *pSectionCtl , int timeOut ) { DS_U32 res; DS_U32 currTaskId = 0; currTaskId = OS_GetSelfTaskId(); if( !pSectionCtl ) return DHL_FAIL_NULL_POINTER; if( !pSectionCtl->hSectionSema4 ) return DHL_FAIL_INVALID_PARAM; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_LockSectionCtl. lockCount = %d\r\n" , pSectionCtl->nLockCount); DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "lockedTask = 0x%x , curTaskId = 0x%x\r\n", pSectionCtl->iCurLockedTask, currTaskId); #endif if( pSectionCtl->iCurLockedTask != 0 ) { if( pSectionCtl->iCurLockedTask == currTaskId ) { pSectionCtl->nLockCount++; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "Same task sema4 lock. so no try lock.\r\n"); #endif return DHL_OK; } } #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockSectionCtl[0x%lX]. before sema lock.\r\n", (DS_U32)pSectionCtl); #endif res = OS_TakeSemaphore_Wait(pSectionCtl->hSectionSema4 , timeOut ); if( res != 0 ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_LockSectionCtl : OS_TakeSemaphore_Wait timeout.\n"); /*return */ return DHL_FAIL_TIMEOUT; } #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockSectionCtl[0x%lX]. after sema lock.\r\n", (DS_U32)pSectionCtl); #endif pSectionCtl->iCurLockedTask = currTaskId; pSectionCtl->nLockCount++; return DHL_OK; } DHL_RESULT DD_PSI_UnlockSectionCtl ( PSI_SECTION_CTL_t *pSectionCtl ) { DS_U32 currTaskId = 0; currTaskId = OS_GetSelfTaskId(); #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_UnlockSectionCtl.\r\n"); #endif if( !pSectionCtl ) return DHL_FAIL_NULL_POINTER; if( !pSectionCtl->hSectionSema4 ) return DHL_FAIL_INVALID_PARAM; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_UnlockSectionCtl. before sema unlock. lockCount =%d. \r\n" , pSectionCtl->nLockCount); #endif pSectionCtl->nLockCount--; if(pSectionCtl->nLockCount == 0 ) { pSectionCtl->iCurLockedTask = 0; OS_GiveSemaphore(pSectionCtl->hSectionSema4); } else if( pSectionCtl->nLockCount <= 0 ) pSectionCtl->nLockCount = 0; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_UnlockSectionCtl. after sema unlock.\r\n"); #endif return DHL_OK; } /*ÁÖ¾îÁø setion¿¡ °üÇÑ pid,section,si component stop. pidFilter´Â option.*/ DHL_RESULT DD_PSI_ResetSectMask ( void *pParent ,PSIMask_t *prefList ) { int i , j; int maxCnt = 0; PSI_SECTION_CTL_t * pSectionCtl = NULL; PSI_PID_CTL_t *pPidCtl = NULL; DS_U8 filterBytes[SECTION_FILTER_SIZE]; DS_U8 filterMasks[SECTION_FILTER_SIZE]; DS_U8 filterInvert[SECTION_FILTER_SIZE]; pSectionCtl = (PSI_SECTION_CTL_t * )pParent; pPidCtl = &(pSectionCtl->pParent->aPidCtl[pSectionCtl->iPidCtlIndex]); /*1.remove pipe notification for section ************************/ /*****************************************************************/ /*2.stop section filter.******************************************/ /*****************************************************************/ /*4.Stop SI component**********************************************/ /******************************************************************/ /* notification setting */ memset( filterBytes, 0, SECTION_FILTER_SIZE ); memset( filterMasks, 0, SECTION_FILTER_SIZE ); memset( filterInvert, 0, SECTION_FILTER_SIZE ); if( prefList->numEntries > SECTION_FILTER_SIZE ) maxCnt = SECTION_FILTER_SIZE; else maxCnt = prefList->numEntries; for ( i = 0 , j = 0 ; i < maxCnt ; ++i ) { if ( i == 2 || i == 7 ) /*index°¡ 2,7ÀÎ byte´Â ¹«½Ã.*/ continue; pSectionCtl->filterBytes [j] = prefList->entries[i].value; pSectionCtl->filterMasks [j] = prefList->entries[i].matchMask; pSectionCtl->filterInvert[j] = prefList->entries[i].noMatchMask; ++j; } pSectionCtl->filtCount = j; #if 0 dhlResult = DD_PSI_CreateAndSetFilter( pSectionCtl, pPidCtl->uiPid, pSectionCtl->filterBytes, pSectionCtl->filterMasks, pSectionCtl->filterInvert, pSectionCtl->filtCount ); if(DHL_ERROR(dhlResult)) DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "ERROR, LINE=%d\n", __LINE__); #endif return DHL_OK; } void DD_PSI_SetSegmentNumber( void *p_section_ctl, int segment_number ) { PSI_SECTION_CTL_t *pSectCtl = (PSI_SECTION_CTL_t *)p_section_ctl; pSectCtl->pContext->segment_number = segment_number; } static int cbFilterNotification( PSI_EVENT_t Event, DS_U32 Arg, DS_U8 *pBuf, DS_U32 Len, DS_BOOL bNeedSWFilter ) { PSI_SECTION_CTL_t *pSectCtl = (PSI_SECTION_CTL_t *)Arg; int i; int bMatch = 0; if ( g_Demux_Debug >= 2 ) { printf( "Received Section: Len=%d\n", (int)Len); if ( g_Demux_Debug == 2 ) { for (i=0; i<16; i++) { if ( !(i%16) ) printf( "\n"); printf( "%02X ", pBuf[i] ); } } else { for (i=0; ieState == PCS_RUNNING) { DD_PSI_LockSectionCtl( pSectCtl, OS_WAIT_FOREVER ); DD_PSI_DataReceived( pSectCtl->pContext, (DS_U8 *)pBuf, Len ); DD_PSI_UnlockSectionCtl( pSectCtl ); } else { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "Invalid section state: %s (%d)\n", pSectCtl->eState == PCS_RUNNING ? "Running" : pSectCtl->eState == PCS_RAW ? "RAW" : pSectCtl->eState == PCS_INIT ? "INIT" : "Unknown", (int)pSectCtl->eState); } } return bMatch; } /****************************************************************************** * cbReceiveSection * Callback Function called by lower demux device driver. ******************************************************************************/ static void cbReceiveSection(PD_SECFILTER *p_sec, DS_U8 *pSecData, int Size) { PSI_INFRA_CTL_t *pPsiInfra = (PSI_INFRA_CTL_t *)g_pPsiInfra; PSI_SECTION_CTL_t * pSectionCtl = NULL; DS_U8 *pSectionBuffer = (DS_U8 *)NULL; int i; SysREQUIRE(Size<=4096); for( i = 0 ; i < MAX_SECTION_FILTER_CNT ; i++ ) { if( pPsiInfra->aSectCtlUsedList[i] == DS_FALSE ) continue; pSectionCtl = &(pPsiInfra->aSectCtl[i]); if ( pSectionCtl->pDrvSecFilter == p_sec /*&& pSectionCtl->eState == PCS_RUNNING*/ ) break; } if ( pSectionCtl->eState != PCS_RUNNING ) return; if ( i == MAX_SECTION_FILTER_CNT ) { printf("|%s| cannot find any matched section filter; pid: %d, filterid=0x%08lX\n", __FUNCTION__, p_sec->i_pid, (DS_U32)p_sec); return; } pSectionBuffer = (DS_U8 *)malloc(Size); SysASSERT( pSectionBuffer ); memcpy( pSectionBuffer, pSecData, Size ); cbFilterNotification( PSI_EVENT__RCVD_NO_ERROR, (DS_U32)pSectionCtl, pSectionBuffer, Size, 0 ); free( pSectionBuffer ); } static void cbStopSectionCtl( DS_U32 arg1 , DS_U32 arg2 ) { DHL_RESULT dhlResult = DHL_OK; PSI_SECTION_CTL_t *pSectionCtl = (void *)arg1; PSI_INFRA_CTL_t *pPsiInfra = (void *)arg2; if(!pSectionCtl || !pPsiInfra) return; dhlResult = DD_PSI_LockSectionCtl(pSectionCtl , OS_WAIT_FOREVER /*infinite*/ ); if ( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_cbStopSectonCtl : timeout.\r\n"); return; } dhlResult = DD_PSI_StopSectionCtl( pSectionCtl ); if( dhlResult != DHL_OK ) DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "cbStopSectionCtl :DD_PSI_StopSectionCtl has returned error(0x%x)\r\n" , dhlResult ); DD_PSI_UnlockSectionCtl(pSectionCtl); } #if 0 ___PID_Control__API__________() #endif DHL_RESULT DD_PSI_StartPidCtl ( PSI_INFRA_CTL_t *pPsiInfra, int iPidCtlIndex ) { PSI_PID_CTL_t *pPidCtl = NULL; DHL_RESULT dhlResult = DHL_OK; if( iPidCtlIndex > MAX_PID_FILTER_CNT ) return DHL_FAIL_INVALID_PARAM; dhlResult = DD_PSI_LockPidCtlArray( pPsiInfra, OS_WAIT_FOREVER ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_GetPidCtl : timeout.\r\n"); return dhlResult; } pPidCtl = &(pPsiInfra->aPidCtl[iPidCtlIndex]); /*its refCount should be more than one.*/ if(pPidCtl->nRefCount <= 0 || pPidCtl->eState != PCS_INIT) { dhlResult = DHL_FAIL_INVALID_STATE; goto GOOUT; } if( pPidCtl->nRefCountRunning == 0 ) ++(pPidCtl->nRefCountRunning); else if ( pPidCtl->nRefCountRunning > 0 ) ++(pPidCtl->nRefCountRunning); else dhlResult = DHL_FAIL_INVALID_STATE; GOOUT: DD_PSI_UnlockPidCtlArray( pPsiInfra ); return dhlResult; } /*nRefCountRunning Decrease.*/ DHL_RESULT DD_PSI_StopPidCtl ( PSI_INFRA_CTL_t *pPsiInfra , int iPidCtlIndex ) { DHL_RESULT dhlResult = DHL_OK; PSI_PID_CTL_t *pPidCtl = NULL; if( iPidCtlIndex > MAX_PID_FILTER_CNT ) return DHL_FAIL_INVALID_PARAM; dhlResult = DD_PSI_LockPidCtlArray( pPsiInfra , OS_WAIT_FOREVER ); if ( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_GetPidCtl : timeout.\r\n"); return dhlResult; } pPidCtl = &(pPsiInfra->aPidCtl[iPidCtlIndex]); if( pPidCtl->nRefCountRunning <= 0 ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_StopPidCtl : not running state.\r\n"); pPidCtl->nRefCountRunning = 0; dhlResult = DHL_FAIL_INVALID_STATE; goto GOOUT; } --(pPidCtl->nRefCountRunning); GOOUT: DD_PSI_UnlockPidCtlArray( pPsiInfra ); return dhlResult; } /* state change to PCS_RAW. : pidCtl LockÀ» ¹Ì¸® °É°í È£Ãâ*/ DHL_RESULT DD_PSI_ClosePidCtl ( PSI_INFRA_CTL_t *pPsiInfra , int iPidCtlIndex ) { PSI_PID_CTL_t *pPidCtl = NULL; if( !pPsiInfra ) return DHL_FAIL_NULL_POINTER; if( iPidCtlIndex > MAX_PID_FILTER_CNT ) return DHL_FAIL_INVALID_PARAM; pPidCtl = &(pPsiInfra->aPidCtl[iPidCtlIndex]); #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ClosePidCtl : iPidCtlIndex = %i, refCount = %d , state = %d\r\n" ,iPidCtlIndex , pPidCtl->nRefCount , pPidCtl->eState); #endif if ( pPidCtl->nRefCount == 0 && pPidCtl->eState == PCS_INIT ) { pPidCtl->eState = PCS_RAW; } return DHL_OK; } /*state change to PCS_INIT : pidCtl LockÀ» ¹Ì¸® °É°í È£Ãâ.*/ DHL_RESULT DD_PSI_OpenPidCtl( PSI_INFRA_CTL_t *pPsiInfra , int iPidCtlIndex ) { DHL_RESULT dhlResult = DHL_OK; PSI_PID_CTL_t *pPidCtl = NULL; if( !pPsiInfra ) return DHL_FAIL_NULL_POINTER; if( iPidCtlIndex > MAX_PID_FILTER_CNT ) return DHL_FAIL_INVALID_PARAM; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_OpenPidCtl : iPidCtlIndex = %i\r\n" ,iPidCtlIndex ); #endif pPidCtl = &(pPsiInfra->aPidCtl[iPidCtlIndex]); if ( pPidCtl->nRefCount == 0 ) { pPidCtl->eState = PCS_INIT; } return (DHL_RESULT)dhlResult; } /*refCount decrease.*/ DHL_RESULT DD_PSI_ReleasePidCtl ( PSI_INFRA_CTL_t *pPsiInfra , int iPidCtlIndex ) { int i=0; DHL_RESULT dhlResult = DHL_OK; if(!pPsiInfra) return DHL_FAIL_NULL_POINTER; if( iPidCtlIndex > MAX_PID_FILTER_CNT) return DHL_FAIL_INVALID_PARAM; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_ReleasePidCtl\r\n"); #endif dhlResult = DD_PSI_LockPidCtlArray( pPsiInfra , OS_WAIT_FOREVER ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ReleasePidCtl : timeout.\r\n"); return dhlResult; } if( pPsiInfra->aPidCtl[iPidCtlIndex].nRefCount <= 0) { #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "eState = PCS_RAW set.\r\n"); #endif pPsiInfra->aPidCtl[iPidCtlIndex].nRefCount = 0; pPsiInfra->aPidCtl[i].eState = PCS_RAW; dhlResult = DHL_FAIL_INVALID_PARAM; goto GOOUT; } --(pPsiInfra->aPidCtl[iPidCtlIndex].nRefCount); #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ReleasePidCtl, pid = 0x%x, -nRefCount = %d , nRunn = %d , state = %d\r\n" , pPsiInfra->aPidCtl[iPidCtlIndex].uiPid , pPsiInfra->aPidCtl[iPidCtlIndex].nRefCount, pPsiInfra->aPidCtl[iPidCtlIndex].nRefCountRunning, pPsiInfra->aPidCtl[iPidCtlIndex].eState ); #endif if(pPsiInfra->aPidCtl[iPidCtlIndex].nRefCount == 0 ) { int i = 0; /*exception case : why this happend?*/ for( i = 0 ; i < pPsiInfra->aPidCtl[iPidCtlIndex].nRefCountRunning ; i++ ) { DD_PSI_StopPidCtl( pPsiInfra , iPidCtlIndex ); } DD_PSI_ClosePidCtl( pPsiInfra , iPidCtlIndex ); } GOOUT : DD_PSI_UnlockPidCtlArray( pPsiInfra ); return dhlResult; } /*refCount increase.*/ DHL_RESULT DD_PSI_GetPidCtl( PSI_INFRA_CTL_t *pPsiInfra , unsigned int pid, int *iPidCtlIndex ) { int i = 0; unsigned int iFirstRawPidCtlIndex = 0xffffffff; DHL_RESULT dhlResult = DHL_FAIL_NOT_FOUND; DS_BOOL bFound = _FALSE_; if(!pPsiInfra) return DHL_FAIL_NULL_POINTER; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_GetPidCtl\r\n"); #endif dhlResult = DD_PSI_LockPidCtlArray( pPsiInfra , OS_WAIT_FOREVER ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_GetPidCtl : timeout.\r\n"); return dhlResult; } for( i = 0 ; i < MAX_PID_FILTER_CNT ; i++ ) { /*try to find the same pid among already allcoated pid-Ctls*/ if( pPsiInfra->aPidCtl[i].eState != PCS_RAW ) { if( pPsiInfra->aPidCtl[i].uiPid == pid ) { ++(pPsiInfra->aPidCtl[i].nRefCount); dhlResult = DHL_OK; *iPidCtlIndex = i; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_GetPidCtl : already exist pid-ctl. refn = %d , state = %d , index =%d \r\n", \ pPsiInfra->aPidCtl[i].nRefCount , pPsiInfra->aPidCtl[i].eState , i ); #endif bFound = _TRUE_; break; } } else { if( iFirstRawPidCtlIndex == 0xffffffff ) iFirstRawPidCtlIndex = i; } } /*if not found it among already allocated pid-Ctls.*/ if( bFound == _FALSE_) { if( iFirstRawPidCtlIndex == 0xffffffff ) { #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_GetPidCtl : no more pidFilter\r\n"); #endif dhlResult = DHL_FAIL_OUT_OF_RESOURCE; goto GOOUT; } *iPidCtlIndex = iFirstRawPidCtlIndex; dhlResult = DD_PSI_OpenPidCtl( pPsiInfra , iFirstRawPidCtlIndex ); if( dhlResult == DHL_OK ) { ++(pPsiInfra->aPidCtl[iFirstRawPidCtlIndex].nRefCount); pPsiInfra->aPidCtl[iFirstRawPidCtlIndex].uiPid = pid; } else { pPsiInfra->aPidCtl[iFirstRawPidCtlIndex].eState = PCS_RAW; DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_GetPidCtl : DD_PSI_OpenPidCtl returned error(0x%x)\r\n", dhlResult ); } } GOOUT: DD_PSI_UnlockPidCtlArray( pPsiInfra ); return dhlResult; } static void DD_PSI_ReleaseAllPidCtls( PSI_INFRA_CTL_t *pPsiInfra ) { int i; int j; int count; DHL_RESULT dhlResult = DHL_OK; if( !pPsiInfra ) return; DD_PSI_LockPidCtlArray( pPsiInfra , OS_WAIT_FOREVER ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_GetPidCtl : timeout.\r\n"); } for( i = 0 ; i < MAX_PID_FILTER_CNT ; i++ ) { DHL_RESULT dhlResult = DHL_OK; /*exception case 1:*/ count = pPsiInfra->aPidCtl[i].nRefCountRunning ; for( j = 0 ; j < count ; j++) { dhlResult = DD_PSI_StopPidCtl(pPsiInfra , i ); DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ReleaseAllPidCtls: DD_PSI_StopPidCtl call(%d).\r\n" , i); } /*exception case 2:*/ count = pPsiInfra->aPidCtl[i].nRefCount; for( j = 0 ; j < count ; j++) { dhlResult = DD_PSI_ReleasePidCtl(pPsiInfra , i ); DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ReleaseAllPidCtls: DD_PSI_ClosePidCtl call(%d).\r\n" , i); } } DD_PSI_UnlockPidCtlArray( pPsiInfra ); } DHL_RESULT DD_PSI_LockPidCtlArray ( PSI_INFRA_CTL_t *pPsiInfra , int timeOut ) { DS_U32 res; if( !pPsiInfra) return DHL_FAIL_NULL_POINTER; if( !(pPsiInfra->hPidCtlAccessSema4) ) return DHL_FAIL_INVALID_PARAM; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockPidCtlArray. before sema lock\r\n"); #endif res = OS_TakeSemaphore_Wait(pPsiInfra->hPidCtlAccessSema4 , timeOut ); if ( res ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockPidCtlArray : OS_TakeSemaphore_Wait timeout.\n"); return DHL_FAIL_TIMEOUT; } #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockPidCtlArray. after sema lock\r\n"); #endif return DHL_OK; } DHL_RESULT DD_PSI_UnlockPidCtlArray ( PSI_INFRA_CTL_t *pPsiInfra ) { DS_U32 res; if( !pPsiInfra ) return DHL_FAIL_NULL_POINTER; if( !pPsiInfra->hPidCtlAccessSema4 ) return DHL_FAIL_INVALID_PARAM; res = OS_GiveSemaphore(pPsiInfra->hPidCtlAccessSema4); if ( res ) DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "ERROR, LINE=%d\n", __LINE__); return DHL_OK; } void DD_PSI_PrintListElem( PSI_LIST_HEADER_t *pListHeader ) { int i = 0; PSI_LIST_ELEM_t *pElem = NULL; DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_PrintListElem : nCount = %d \r\n", pListHeader->nCount ); pElem = pListHeader->pElem; while(pElem) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, " %d elem : next = 0x%lx , 0x%lx , prev = 0x%lx\r\n", i, (DS_U32)pElem->pNext, (DS_U32)pElem, (DS_U32)pElem->pPrev ); pElem = pElem->pPrev; i++; } } /*header ÀÇ pElemÀÌ ³ªÁß¿¡ addµÈ element°¡ µÇµµ·Ï ÇÏÀÚ.*/ DHL_RESULT DD_PSI_AddElemIntoList(PSI_LIST_HEADER_t *pListHeader , void * pElemToInsert ) { PSI_LIST_ELEM_t *pAddElem = pElemToInsert; if(!pAddElem || !pListHeader) return DHL_FAIL_NULL_POINTER; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_AddElemIntoList. new elem = 0x%x \r\n" , pAddElem ); #endif pAddElem->pPrev = NULL; pAddElem->pNext = NULL; if(pListHeader->pElem) { pListHeader->pElem->pNext = pAddElem; pAddElem->pPrev = pListHeader->pElem; } pListHeader->pElem = pAddElem; ++(pListHeader->nCount); #if DEBUG DD_PSI_PrintListElem(pListHeader); #endif return DHL_OK; } /*header ÀÇ pElemÀÌ °¡Àå ÃÖ±Ù¿¡ addµÈ element°¡ µÇµµ·Ï ÇÏÀÚ.*/ DHL_RESULT DD_PSI_DelElemFromList(PSI_LIST_HEADER_t *pListHeader , void * pElemToDelete ) { PSI_LIST_ELEM_t *pDelElem = NULL; DHL_RESULT dhlResult = DHL_FAIL_NOT_FOUND; if(!pElemToDelete || !pListHeader) return DHL_FAIL_NULL_POINTER; pDelElem = pListHeader->pElem; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_DelElemFromList. count = %d , old elem = 0x%x \r\n" , pListHeader->nCount ,pElemToDelete ); #endif while(pDelElem) { if( pDelElem == (PSI_LIST_ELEM_t *)pElemToDelete ) { if( pDelElem->pNext ) { pDelElem->pNext->pPrev = pDelElem->pPrev; } else /*header¶ó´Â ¼Ò¸®³×.*/ { if( pDelElem->pPrev ) { pDelElem->pPrev->pNext = NULL; } pListHeader->pElem = pDelElem->pPrev; } if( pDelElem->pPrev ) { pDelElem->pPrev->pNext = pDelElem->pNext; } else /*tailÀ̶õ ¼Ò¸®.*/ { if( pDelElem->pNext ) { pDelElem->pNext->pPrev = NULL; } } --(pListHeader->nCount); if(pListHeader->nCount == 0) pListHeader->pElem = NULL; #if DEBUG DD_PSI_PrintListElem(pListHeader); #endif dhlResult = DHL_OK; break; } pDelElem = pDelElem->pPrev; } return dhlResult; } DHL_RESULT DD_PSI_MonitorPSIPid( void *pPsiInfo, DS_U16 pid, PSIMode psiMode, PSIUpdateMode updateMode, PSIMask_t *prefList, DS_U16 maxData, DS_U16 maxSections, PSIEventProc_f eventProc, DS_U32 userParam, void **returnPSIControl ) { DHL_RESULT dhlResult = DHL_OK; PSI_INFRA_CTL_t *pPsiInfra = NULL; PSI_SECTION_CTL_t * pSectionCtl = NULL; PSIContext_t *pPsiContext = NULL; // DS_BOOL bExist = _FALSE_; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the MonitorPSIPid.\r\n"); #endif *returnPSIControl = NULL; pPsiInfra = (PSI_INFRA_CTL_t *)pPsiInfo; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "pPsiInfra = 0x%x. pid = %d , entries.value = 0x%x \r\n" , pPsiInfra ,pid , prefList->entries[0].value); #endif #if DONOT_USE_LOCK_SECTCTRLARRAY dhlResult = DD_PSI_LockSectCtlArray( pPsiInfra , OS_WAIT_FOREVER /*infinite*/ ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockSectCtlArray... : timeout.\r\n"); return DHL_FAIL_CORE_DRIVER; } #endif /*ATI section control unitÀ» ÇÒ´ç ¹Þ´Â´Ù.*/ dhlResult = DD_PSI_GetSectionCtl( pPsiInfra , pid , prefList , &pSectionCtl ); if( dhlResult != DHL_OK || pSectionCtl == NULL ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_MonitorPSIPid : PSI_GetSectionCtl has returned NULL.\r\n"); goto GOOUT2; } dhlResult = DD_PSI_LockSectionCtl( pSectionCtl , OS_WAIT_FOREVER ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_MonitorPSIPid : error. DD_PSI_LockSectionCtl timeout.\r\n"); goto GOOUT2; } /*second, allocate current psi context for gathering mpeg sections.*/ /*±âÁ¸¿¡ registerÇϰí releaseÇÏÁö ¾ÊÀº context°¡ ÀÖÀ¸¸é ¸ÕÀú releaseÇÑ´Ù.*/ if( pSectionCtl->pContext ) { DD_PSI_ReleasePSICtx( pSectionCtl->pContext); pSectionCtl->pContext = NULL; } /*»õ·Î ¹Þ±â¸¦ ½Ãµµ ÇÑ´Ù.*/ dhlResult = DD_PSI_RegisterPSICtx( (void *)pSectionCtl, pid, psiMode, updateMode, prefList, maxData, maxSections, eventProc, userParam , cbStopSectionCtl, (DS_U32)(void *)(pSectionCtl->pParent), _FALSE_, (void **)&pPsiContext ); if( dhlResult != DHL_OK || pPsiContext == NULL ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_MonitorPSIPid : DD_PSI_RegisterPSICtx return erorr(0x%x)\r\n" , dhlResult ); dhlResult = DHL_FAIL_OUT_OF_RESOURCE; //DD_PSI_ReleaseSectionCtl(pSectionCtl); goto GOOUT1; } pSectionCtl->pContext = pPsiContext; dhlResult = DD_PSI_StartSectionCtl (pSectionCtl, prefList); if ( dhlResult == DHL_OK ) { *returnPSIControl = (void *)pSectionCtl; } else { DD_PSI_StopSectionCtl( pSectionCtl ); DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_MonitorPSIPid : PSI_StartSectionCtl has returned error(0x%x)\r\n" , dhlResult); dhlResult = DHL_FAIL_CORE_DRIVER; } GOOUT1: DD_PSI_UnlockSectionCtl( pSectionCtl ); GOOUT2: if( dhlResult != DHL_OK ) DD_PSI_ReleaseSectionCtl( pSectionCtl ); #if DONOT_USE_LOCK_SECTCTRLARRAY DD_PSI_UnlockSectCtlArray( pPsiInfra ); #endif return dhlResult; } /*it is added to support Big Size SI.*/ DHL_RESULT DD_PSI_MonitorPSIPidBig( void *pPsiInfo, DS_U16 pid, PSIMode psiMode, PSIUpdateMode updateMode, PSIMask_t *prefList, DS_U16 maxData, DS_U16 maxSections, PSIEventProc_f eventProc, DS_U32 userParam, void **returnPSIControl ) { DHL_RESULT dhlResult = DHL_OK; PSI_INFRA_CTL_t *pPsiInfra = NULL; PSI_SECTION_CTL_t * pSectionCtl = NULL; PSIContext_t *pPsiContext = NULL; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the MonitorPSIPidBig.\r\n"); #endif *returnPSIControl = NULL; pPsiInfra = (PSI_INFRA_CTL_t *)pPsiInfo; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "pPsiInfra = 0x%x. pid = %d , entries.value = 0x%x \r\n" , pPsiInfra ,pid , prefList->entries[0].value); #endif #if 0 bExist = DD_PSI_ExistSectionCtl( pPsiInfra, pid, prefList ); if( bExist == _TRUE_ ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_MonitorPSIPid : it's already exist filter. so, reject your request. \r\n"); dhlResult = DHL_FAIL_NOT_AVAILABLE; goto GOOUT; } #endif #if DONOT_USE_LOCK_SECTCTRLARRAY dhlResult = DD_PSI_LockSectCtlArray( pPsiInfra , OS_WAIT_FOREVER /*infinite*/ ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockSectCtlArray... : timeout.\r\n"); return DHL_FAIL_CORE_DRIVER; } #endif /*ATI section control unitÀ» ÇÒ´ç ¹Þ´Â´Ù.*/ dhlResult = DD_PSI_GetSectionCtlBig( pPsiInfra , pid , prefList , &pSectionCtl ); if( dhlResult != DHL_OK || pSectionCtl == NULL ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_MonitorPSIPidBig : PSI_GetSectionCtlBig has returned NULL.\r\n"); goto GOOUT2; } dhlResult = DD_PSI_LockSectionCtl( pSectionCtl , OS_WAIT_FOREVER ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "PSI_MonitorPSIPidBig : error. DD_PSI_LockSectionCtl timeout.\r\n"); goto GOOUT1; } /*second, allocate current psi context for gathering mpeg sections.*/ /*±âÁ¸¿¡ registerÇϰí releaseÇÏÁö ¾ÊÀº context°¡ ÀÖÀ¸¸é ¸ÕÀú releaseÇÑ´Ù.*/ if( pSectionCtl->pContext ) { DD_PSI_ReleasePSICtx( pSectionCtl->pContext); pSectionCtl->pContext = NULL; } /*»õ·Î ¹Þ±â¸¦ ½Ãµµ ÇÑ´Ù.*/ dhlResult = DD_PSI_RegisterPSICtx( (void *)pSectionCtl, pid, psiMode, updateMode, prefList, maxData, maxSections, eventProc, userParam , cbStopSectionCtl, (DS_U32)(void *)(pSectionCtl->pParent), _FALSE_, (void **)&pPsiContext ); if( dhlResult != DHL_OK || pPsiContext == NULL ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_MonitorPSIPidBig : DD_PSI_RegisterPSICtx return erorr(0x%x)\r\n" , dhlResult ); dhlResult = DHL_FAIL_OUT_OF_RESOURCE; DD_PSI_ReleaseSectionCtl(pSectionCtl); goto GOOUT1; } pSectionCtl->pContext = pPsiContext; dhlResult = DD_PSI_StartSectionCtl (pSectionCtl, prefList); if ( dhlResult == DHL_OK ) { *returnPSIControl = (void *)pSectionCtl; } else { DD_PSI_StopSectionCtl( pSectionCtl ); DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_MonitorPSIPidBig : PSI_StartSectionCtl has returned error(0x%x)\r\n" , dhlResult); dhlResult = DHL_FAIL_CORE_DRIVER; } GOOUT1: DD_PSI_UnlockSectionCtl( pSectionCtl ); GOOUT2: if ( dhlResult != DHL_OK ) { DD_PSI_ReleaseSectionCtl( pSectionCtl ); } #if DONOT_USE_LOCK_SECTCTRLARRAY DD_PSI_UnlockSectCtlArray( pPsiInfra ); #endif return dhlResult; } DHL_RESULT DD_PSI_CancelPSIPid( DHL_PSI_HANDLE hPsiHandle, /*PSI_SECTION_CTL_t **/ void * pSectionCtl ) { DHL_RESULT dhlResult = DHL_OK; PSI_INFRA_CTL_t *pPsiInfra = NULL; PSI_SECTION_CTL_t *pSectCtl = NULL; PSIContext_t *psiCtl; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_CancelPSIPid.\r\n"); #endif if(!hPsiHandle || !pSectionCtl) return DHL_FAIL_NULL_POINTER; pSectCtl = (PSI_SECTION_CTL_t *)pSectionCtl; pPsiInfra = (PSI_INFRA_CTL_t *)hPsiHandle; psiCtl = (PSIContext_t *)pSectCtl->pContext; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_CancelPSIPid : hPsiHandle = 0x%x , pSectionCtl = 0x%x\r\n" ,hPsiHandle , pSectCtl ); #endif #if DONOT_USE_LOCK_SECTCTRLARRAY dhlResult = DD_PSI_LockSectCtlArray( pPsiInfra , OS_WAIT_FOREVER /*infinite*/ ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_LockSectCtlArray... : timeout.\r\n"); return DHL_FAIL_CORE_DRIVER; } #endif dhlResult = DD_PSI_LockSectionCtl(pSectCtl , OS_WAIT_FOREVER /*infinite*/ ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_CancelPSIPid : timeout.\r\n"); return dhlResult; } dhlResult = DD_PSI_StopSectionCtl( pSectCtl ); if ( dhlResult != DHL_OK ) { #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_CancelPSIPid : DD_PSI_StopSectionCtl returned error(0x%x)\r\n" , dhlResult ); #endif dhlResult = DHL_FAIL_CORE_DRIVER; } #if 0 // ÀÏ´Ü »ç¿ëÇÏÁö ¸»°í, leakage°¡ °è¼ÓÇØ¼­ »ý±â¸é »ç¿ëÇÏÀÚ. // // descriptor array°¡ ÇØÁ¦µÇÁö ¾Ê¾ÒÀ¸¸é, cancelÇÒ¶§ ÇØÁ¦ÇÏÀÚ. (hwatk/20060830) // if (psiCtl->curDataArray) { DD_PSI_FreePSIData(psiCtl->curDataArray); psiCtl->curDataArray = NULL; } if (psiCtl->nextDataArray) { DD_PSI_FreePSIData(psiCtl->nextDataArray); psiCtl->nextDataArray = NULL; } #endif DD_PSI_UnlockSectionCtl(pSectCtl); DD_PSI_ReleaseSectionCtl(pSectionCtl); #if DONOT_USE_LOCK_SECTCTRLARRAY DD_PSI_UnlockSectCtlArray( pPsiInfra ); #endif return dhlResult; } DHL_RESULT DD_PSI_ReadPSIData( DHL_TBL_HANDLE hTblHandle , PSIDataArray_t **returnPsi ) { PSIContext_t *psi = NULL; PSI_SECTION_CTL_t * pSectionCtl = (PSI_SECTION_CTL_t *)hTblHandle; DHL_RESULT dhlResult = DHL_OK; //DS_BOOL bExist = _FALSE_; #if DEBUG DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "in the DD_PSI_ReadPSIData. tblHandle = 0x%x \r\n" ,hTblHandle ); #endif if(!pSectionCtl) return DHL_FAIL_NULL_POINTER; dhlResult = DD_PSI_LockSectionCtl(pSectionCtl , OS_WAIT_FOREVER /*infinite*/ ); if( dhlResult != DHL_OK ) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "DD_PSI_ReadPSIData : timeout.\r\n"); return dhlResult; } psi = pSectionCtl->pContext; if(psi) dhlResult = DD_PSI_ReadPSIArray(psi , returnPsi); else dhlResult = DHL_FAIL_NULL_POINTER; //GOOUT: DD_PSI_UnlockSectionCtl( pSectionCtl ); return dhlResult; } void DD_PSI_FreePSIData(PSIDataArray_t *psiData ) { if(psiData) DD_PSI_FreePSIArray(psiData); } #if 0 ___Local_Functions____________() #endif void hdmx_dbg(int dbg) { g_Demux_Debug = dbg; } void hdmx_temp_dbg(int dbg) { g_Temp_Debug = dbg; } void dumpLeakSize(void) { DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "\n\n\nMemory leakage by PSI monitor\n\n\n"); DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "nCount = %d\n", g_TotalLeakCnt); DHL_DbgPrintf( gddPsiDbgLvl, DDDBG_PSI, "nSize = %d\n", g_TotalLeakSize); } void hdmx_stat(void) { printf("4k:%d, 1k:%d\n", g_FilterCount_4Kb, g_FilterCount_1Kb); }