/**************************************************** DMW_ChannelDemux.c Demux related PSI/PSIP table reception functions. Copyright 2003 Digital STREAM Technology, Inc. All Rights Reserved $Id: ChannelDemux.c,v 1.23 2004 cafrii Exp $ *****************************************************/ #include "DMW_Platform.h" #include "DHL_OSAL.h" #include "DHL_DBG.h" //#include "DHL_PsiAPI.h" #include "DLIB_PSI.h" #include "DLIB_PSIP.h" #include "DLIB_PSIP_Monitor.h" #include "DLIB_PSIP_Parser.h" #include "DLIB_PSI_Monitor.h" #include "DLIB_PSI_Parser.h" //#include "DHL_Memchain.h" // for memChain feature.. #include "DLIB_BitOp.h" #include "DMW_Config.h" #include "DMW_Status.h" #include "DMW_DebugUtil.h" #include "DMW_ChannelDemux.h" #include "DMW_Dummy.h" //#include DHL_MODULE("$dmx", 0); //------------------------------------------------------- // Configurations.. #define TEST_CHANNEL_DEMUX 1 // include test code of channel demux #define PSIP_WAIT_IN_TICK (1000/20) // 1/20 ÃÊ À̸é, 60 tick/sec system¿¡¼­´Â ¾à 3 Á¤µµ µÇ´Â °ªÀÌ´Ù. int gMaxTableMonitorsAtOneTime = 24; // // ÀÌ °ªÀº ¹Ýµå½Ã Hardware RestrictionÀ» °í·ÁÇÑ »óÅ¿¡¼­ °áÁ¤µÇ¾î¾ß ÇÑ´Ù. // ZoranÀº 40°³ÀÇ Demux object°¡ »ç¿ë °¡´ÉÇÏ´Ù. (°¢°¢ ´Ù¸¥ PID) // ÀÌ Áß¿¡¼­ Video/Audio, PAT, PMT, MGT, STT, EAS µîÀÇ ¸ð´ÏÅÍ ¿ëµµ·Î »ç¿ëµÇ°í ÀÖÀ» ¼ö ÀÖ´Â °ÍÀ» Á¦¿ÜÇϸé // ´ë·« 32°³ Á¤µµ¸¸ µ¿½Ã monitor°¡ °¡´ÉÇÒ °ÍÀÌ´Ù. // // Beetle 640ÀÇ °æ¿ì¿¡´Â ÃÖ´ë µ¿½Ã¿¡ 32°³ ¹Û¿¡ »ç¿ëÇÒ ¼ö ¾ø´Ù. // µû¶ó¼­ µ¿½Ã ¸ð´ÏÅÍ´Â ¾ÈÀüÇÏ°Ô 24°³ Á¤µµ¸¸ »ç¿ëÇϵµ·Ï Çϰí, // ÇöÀç (2005/5/11) ¼º´É»óÀÇ ¾à°£ÀÇ ¹®Á¦°¡ ÀÖ´Ù. //--------------------------------------------------------------------------- #if COMMENT ________(){} #endif void byteBufInit(byteBufPtr_t bt, UINT8 *buffer, UINT32 bufSize) { /* Initialize */ bt->buffer = buffer; // buffer°¡ NULLÀ̸é simulation mode ·Î¼­, buffer Å©±â estimation¿¡ »ç¿ëµÊ. bt->bufSize = bufSize; bt->offset = 0; bt->overrunError = 0; return; } void byteBufSetBytesBuf(byteBufPtr_t bt, UINT8 *buf, UINT16 nBytes) { if (nBytes == 0) return; // check overrun if (bt->offset + nBytes > bt->bufSize) { bt->overrunError = TRUE; DHL_OS_Printf("!! byteBufSetX overrun, offset %d, bytesize %d\n", bt->offset, (int)nBytes); return; } if (bt->buffer) { memcpy(bt->buffer + bt->offset, buf, nBytes); } bt->offset += nBytes; } void byteBufSetBytes(byteBufPtr_t bt, UINT32 data, UINT8 nBytes) { // nBytes should be 1, 2, 4 if (nBytes == 0 || nBytes > 4) { DHL_OS_Printf("!! byteBufSet invalid bytesize %d\n", (int)nBytes); return; } // check overrun if (bt->offset + nBytes > bt->bufSize) { bt->overrunError = TRUE; DHL_OS_Printf("!! byteBufSet overrun, offset %d, bytesize %d\n", bt->offset, (int)nBytes); return; } if (bt->buffer) { if (nBytes == 1) *(bt->buffer + bt->offset) = data&0xff; else if (nBytes == 2) { *(bt->buffer + bt->offset) = (data>>8 )&0xff; *(bt->buffer + bt->offset + 1) = (data )&0xff; } else if (nBytes == 3) { *(bt->buffer + bt->offset) = (data>>16)&0xff; *(bt->buffer + bt->offset + 1) = (data>>8 )&0xff; *(bt->buffer + bt->offset + 2) = (data )&0xff; } else { *(bt->buffer + bt->offset) = (data>>24)&0xff; *(bt->buffer + bt->offset + 1) = (data>>16)&0xff; *(bt->buffer + bt->offset + 2) = (data>>8 )&0xff; *(bt->buffer + bt->offset + 3) = (data )&0xff; } } bt->offset += nBytes; } STATUS byteBufGetBytesBuf(byteBufPtr_t bt, UINT8 *buf, UINT16 nBytes) { if (bt->offset + nBytes > bt->bufSize) { bt->overrunError = TRUE; DHL_OS_Printf("!! byteBufGetX overrun, offset %d, bytesize %d\n", bt->offset, (int)nBytes); return statusOverflow; } if (nBytes) memcpy(buf, bt->buffer+bt->offset, nBytes); bt->offset += nBytes; return statusOK; } UINT32 byteBufGetBytes(byteBufPtr_t bt, UINT8 nBytes) { UINT32 value; UINT8 data[4] = {0, }; // bytesize should be 1, 2, 4 if (nBytes == 0 || nBytes > 4) { DHL_OS_Printf("!! byteBuf invalid bytesize %d\n", (int)nBytes); return 0; } if (byteBufGetBytesBuf(bt, data, nBytes)) return 0; // error if (nBytes == 1) value = data[0]; else if (nBytes == 2) value = data[0]<<8U | data[1]; else if (nBytes == 3) value = data[0]<<16UL | data[1]<<8UL | data[2]; else value = data[0]<<24UL | data[1]<<16UL | data[2]<<8UL | data[3]; return value; } void byteBufSkipBytes(byteBufPtr_t bt, UINT8 numberOfBytes) { // check overrun if (bt->offset + numberOfBytes > bt->bufSize) { bt->overrunError = TRUE; DHL_OS_Printf("!! byteBuf overrun, offset %d, last skip %d\n", bt->offset, (int)numberOfBytes); return; } bt->offset += numberOfBytes; } UINT32 byteBufGetOffset(byteBufPtr_t bt) { return bt->offset; } BOOL byteBufCheckError(byteBufPtr_t bt) { return (bt->overrunError); } #if COMMENT __________(){} #endif // cafrii 070322 change // // ¸ðµç getXX ·ùÀÇ ÇÔ¼ö¸¦ ÇϳªÀÇ event data procÀ¸·Î ÅëÀÏ.. // ´õÀÌ»ó driver/halÀÇ proc data¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù. typedef struct PSIMultiEventProcData_t { tDHL_PSI_DataArray *desc; DHL_RESULT err; DHL_OS_SEMA_ID sema4; UINT32 id; // cafrii 040331 add this for debugging // ¿©·¯°³ÀÇ PSI monitor¸¦ µ¿½Ã¿¡ ½ÃÀÛÇÏ´Â °æ¿ì, ¹ß»ýµÈ PSI Event°¡ ¾î´À monitor·ÎºÎÅÍ // ¿Â °ÍÀÎÁö¸¦ ¾Ë¾Æ³»´Âµ¥ µµ¿òÀ̵ȴÙ. // event procedure¿¡¼­´Â id ÀÇ ¼ö½Å flag¸¦ set ½ÃÅ´À¸·Î½á event°¡ ¹ß»ýÇß´Ù´Â »ç½ÇÀ» // // Å뺸ÇÑ´Ù. (¹°·Ð sema4¸¦ ÀÌ¿ëÇØ¼­µµ event°¡ Àü´ÞµÈ´Ù.) } PSIMultiEventProcData; // LSB 8 bit´Â PSI arrayÀÇ indexÀÌ´Ù. #define PME_SEND 0x800 // event °¡ SEND µÇ¾úÀ½ #define PME_CNFM 0x400 // event °¡ ¼ö½Å ¹× Confirm µÇ¾úÀ½ #define PME_MASK 0xf00 #define PME_EV_SEND_BADPKT 0x010000 #define PME_EV_SEND_SCRAMBLE 0x020000 #define PME_EV_CNFM_BADPKT 0x100000 #define PME_EV_CNFM_SCRAMBLE 0x200000 #define PME_EV_MASK 0xff0000 #define PMT_FLAG_SINGLE 0x1000000 // Single ModeÀÎ °æ¿ì void _Dmc_MultiEventProc(tDHL_PSI_Event event, tDHL_PSI_ControlHandle psiCtl, UINT32 userParam) { PSIMultiEventProcData *procData = (PSIMultiEventProcData *)userParam; tDHL_PSI_DataArray *desc; DHL_RESULT err; switch (event) { case ePSIEVENT_DATARECEIVED: err = DHL_PSI_ReadPSIData(psiCtl, &desc); if (err) { dprint(0, "++++ !! DHL_PSI_ReadPSIData returned %s\n",ErrorString(err)); } else { procData->desc = desc; //dprint(3, "++++ data for table %d received, psiCtl %x\n", procData->id, psiCtl); // id is just for debugging.. //if (procData->id & PME_SEND) // dprint(0, "!!!! event already sent!! id: 0x%x\n", procData->id); procData->id |= PME_SEND; // indicating that this table is received.. } procData->err = err; dprint(3, "eventproc: event %d received. give sem %x..\n", event, procData->sema4); DHL_OS_GiveSemaphore(procData->sema4); break; case ePSIEVENT_SCRAMBLEDERROR: if (!(procData->id & PME_EV_SEND_SCRAMBLE)) { procData->id |= PME_EV_SEND_SCRAMBLE; procData->err = DHL_FAIL_SCRAMBLED; dprint(0, "++++ psiScrambledErr [%d] --> send evt\n", (procData->id & 0xff)); DHL_OS_GiveSemaphore(procData->sema4); } else dprint(0, "++++ psiScrambledErr [%d]\n", (procData->id & 0xff)); break; case ePSIEVENT_DUP3PACKET: case ePSIEVENT_LOSTPACKET: case ePSIEVENT_DISCONTINUITY: case ePSIEVENT_SYNCERR: case ePSIEVENT_CRCERROR: if (!(procData->id & PME_EV_SEND_BADPKT)) { procData->id |= PME_EV_SEND_BADPKT; dprint(0, "++++ %s [%d] --> send evt\n", DHL_PSIEventString(event), (procData->id & 0xff)); if ((procData->id & PMT_FLAG_SINGLE) == 0) // single RX °¡ ¾Æ´Ñ °æ¿ì¿¡¸¸ event Àü´Þ. DHL_OS_GiveSemaphore(procData->sema4); } else dprint(0, "++++ %s [%d]\n", DHL_PSIEventString(event), (procData->id & 0xff)); break; default: dprint(0, "++++ %s [%d]\n", DHL_PSIEventString(event), (procData->id & 0xff)); break; } } STATUS Dmc_GetPAT(tDHL_TSD tsd, MPEG_PAT **returnPat, int timeOut, BOOL (*ckfn)()) { PSIMultiEventProcData procData; tDHL_PSI_ControlHandle returnPSICtl = (tDHL_PSI_ControlHandle)0; DHL_RESULT err; STATUS status = statusOK; int semErr; UINT32 tickStart; #if 0 if (dmc_TaskID != Dmc_GetCurrentTaskID()) { dprint(2, "!! Dmc_GetPAT() should be called only in DmcTask.\n"); return statusInvalidState; } #endif if (returnPat == NULL) return statusInvalidArgument; memset(&procData, 0, sizeof(procData)); procData.desc = NULL; procData.err = DHL_OK; procData.id = (UINT32)-1; // id·Î Single Mode or Multiple Mode ±¸ºÐ procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcPAT",OS_SEM_PRIO,0); if (!procData.sema4) { return statusOutOfMemory; } if ((err = MonitorPAT(tsd, TRUE, FALSE, // current, not eager ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &returnPSICtl))) { status = statusOutOfResource; goto done; } tickStart = DHL_OS_GetMsCount(); while (1) { semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK); if (semErr == DHL_OK) break; if (ckfn && ckfn()) { status = statusCancelled; goto done2; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { status = statusTimeout; goto done2; } } if (procData.err) { // noDataError, ScrambledError status = statusPSIPError; goto done2; } err = ParsePAT(procData.desc, returnPat); if (IsError(err)) { // noDataError, badFormatError, outOfCPUMemoryError; status = statusPSIPError; *returnPat = NULL; } done2: if (returnPSICtl) DHL_PSI_StopMonitor(returnPSICtl); if (procData.desc) DHL_PSI_FreePSIData(procData.desc); done: if (procData.sema4) DHL_OS_DeleteSemaphore(procData.sema4); return status; } STATUS Dmc_GetPMT(tDHL_TSD tsd, UINT16 pid, UINT16 program_number, MPEG_PMT **returnPmt, int timeOut, BOOL (*ckfn)()) { // GetPMTÀÇ º¯Çü. PSIMultiEventProcData procData; tDHL_PSI_ControlHandle returnPSICtl = (tDHL_PSI_ControlHandle)0; DHL_RESULT err; STATUS status = statusOK; int semErr; UINT32 tickStart; #if 0 if (dmc_TaskID != Dmc_GetCurrentTaskID()) { dprint(2, "!! Dmc_GetPMT() should be called only in DmcTask.\n"); return statusInvalidState; } #endif if (returnPmt == NULL) return statusInvalidArgument; if (pid <= 0 || pid >= 0x1FFF) { // cafrii 050315 add return statusInvalidArgument; } memset(&procData, 0, sizeof(procData)); procData.desc = NULL; procData.err = DHL_OK; procData.id = (UINT32)-1; procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcPMT",OS_SEM_PRIO,0); if (!procData.sema4) { return statusOutOfMemory; } if ((err = MonitorPMT(tsd, pid, program_number, TRUE, // current ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &returnPSICtl))) { status = statusOutOfResource; goto done; } tickStart = DHL_OS_GetMsCount(); while (1) { semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK); if (semErr == DHL_OK) break; if (ckfn && ckfn()) { status = statusCancelled; goto done2; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { status = statusTimeout; goto done2; } } if (procData.err) { status = statusPSIPError; goto done2; } err = ParsePMT(procData.desc, returnPmt); if (IsError(err)) { status = statusPSIPError; *returnPmt = NULL; } done2: if (returnPSICtl) DHL_PSI_StopMonitor(returnPSICtl); if (procData.desc) DHL_PSI_FreePSIData(procData.desc); done: DHL_OS_DeleteSemaphore(procData.sema4); return status; } STATUS Dmc_GetMgtSection(tDHL_TSD tsd, mgtSectionPtr_t *mgtSectPtr, int timeOut, BOOL (*ckfn)()) { PSIMultiEventProcData procData; tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0; int semErr; DHL_RESULT err; STATUS status = statusOK; UINT32 tickStart; #if 0 if (dmc_TaskID != Dmc_GetCurrentTaskID()) { dprint(2, "!! Dmc_GetMgtSection() should be called only in DmcTask.\n"); return statusInvalidState; } #endif if (mgtSectPtr == NULL) return statusInvalidArgument; memset(&procData, 0, sizeof(procData)); procData.desc = NULL; procData.err = DHL_OK; procData.id = (UINT32)-1; procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcMgt",OS_SEM_PRIO,0); if (!procData.sema4) { return statusOutOfMemory; } err = MonitorMgt(tsd, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl); if (err) { status = statusOutOfResource; goto GetSectionExit; } tickStart = DHL_OS_GetMsCount(); while (1) { semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK); if (semErr == DHL_OK) break; if (ckfn && ckfn()) { status = statusCancelled; goto CancelPsiMonitor; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { status = statusTimeout; goto CancelPsiMonitor; } } if ((err = procData.err)) { status = statusPSIPError; goto CancelPsiMonitor; } err = ParseMgtSection(procData.desc->sectPtr[0], mgtSectPtr); if (IsError(err)) { status = statusPSIPError; *mgtSectPtr = NULL; } CancelPsiMonitor: if (psiCtl) DHL_PSI_StopMonitor(psiCtl); if (procData.desc) DHL_PSI_FreePSIData(procData.desc); GetSectionExit: DHL_OS_DeleteSemaphore(procData.sema4); return status; } STATUS Dmc_GetSttSection(tDHL_TSD tsd, sttSectionPtr_t *sttSectPtr, int timeOut, BOOL (*ckfn)()) { PSIMultiEventProcData procData; tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0; int semErr; DHL_RESULT err; STATUS status = statusOK; UINT32 tickStart; #if 0 if (dmc_TaskID != Dmc_GetCurrentTaskID()) { dprint(2, "!! Dmc_GetSttSection() should be called only in DmcTask.\n"); return statusInvalidState; } #endif if (sttSectPtr == NULL) return statusInvalidArgument; memset(&procData, 0, sizeof(procData)); procData.desc = NULL; procData.err = DHL_OK; procData.id = (UINT32)-1; procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcStt",OS_SEM_PRIO,0); if (!procData.sema4) { return statusOutOfMemory; } err = MonitorStt(tsd, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl); if (err) { status = statusOutOfResource; goto GetSectionExit; } tickStart = DHL_OS_GetMsCount(); while (1) { semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK); if (semErr == DHL_OK) break; if (ckfn && ckfn()) { status = statusCancelled; goto CancelPsiMonitor; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { status = statusTimeout; goto CancelPsiMonitor; } } if (procData.err) { status = statusPSIPError; goto CancelPsiMonitor; } err = ParseSttSection(procData.desc->sectPtr[0], sttSectPtr); if (IsError(err)) { status = statusPSIPError; *sttSectPtr = NULL; } CancelPsiMonitor: if (psiCtl) DHL_PSI_StopMonitor(psiCtl); if (procData.desc) DHL_PSI_FreePSIData(procData.desc); GetSectionExit: DHL_OS_DeleteSemaphore(procData.sema4); return status; } STATUS Dmc_GetTvct(tDHL_TSD tsd, tvctPtr_t *tvctPtr, int timeOut, BOOL (*ckfn)()) { PSIMultiEventProcData procData; tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0; int semErr; DHL_RESULT err; STATUS status = statusOK; UINT32 tickStart; #if 0 if (dmc_TaskID != Dmc_GetCurrentTaskID()) { dprint(2, "!! Dmc_GetTvct() should be called only in DmcTask.\n"); return statusInvalidState; } #endif if (tvctPtr == NULL) return statusInvalidArgument; memset(&procData, 0, sizeof(procData)); procData.desc = NULL; procData.err = DHL_OK; procData.id = (UINT32)-1; procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcTvct",OS_SEM_PRIO,0); if (!procData.sema4) { return statusOutOfMemory; } dprint(3, "created sem %x\n", procData.sema4); err = MonitorTvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl); if (err) { status = statusOutOfResource; goto GetSectionExit; } tickStart = DHL_OS_GetMsCount(); while (1) { semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK); if (semErr == DHL_OK) break; if (ckfn && ckfn()) { status = statusCancelled; goto CancelPsiMonitor; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { status = statusTimeout; goto CancelPsiMonitor; } } if (procData.err) { status = statusPSIPError; goto CancelPsiMonitor; } err = ParseTvct(procData.desc->sectPtr, tvctPtr); if (IsError(err)) { status = statusPSIPError; *tvctPtr = NULL; } CancelPsiMonitor: if (psiCtl) DHL_PSI_StopMonitor(psiCtl); if (procData.desc) DHL_PSI_FreePSIData(procData.desc); GetSectionExit: DHL_OS_DeleteSemaphore(procData.sema4); return status; } STATUS Dmc_GetCvct(tDHL_TSD tsd, cvctPtr_t *cvctPtr, int timeOut, BOOL (*ckfn)()) { PSIMultiEventProcData procData; tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0; int semErr; DHL_RESULT err; STATUS status = statusOK; UINT32 tickStart; #if 0 if (dmc_TaskID != Dmc_GetCurrentTaskID()) { dprint(2, "!! Dmc_GetCvct() should be called only in DmcTask.\n"); return statusInvalidState; } #endif if (cvctPtr == NULL) return statusInvalidArgument; memset(&procData, 0, sizeof(procData)); procData.desc = NULL; procData.err = DHL_OK; procData.id = (UINT32)-1; procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcCvct",OS_SEM_PRIO,0); if (!procData.sema4) { return statusOutOfMemory; } err = MonitorCvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl); if (err) { status = statusOutOfResource; goto GetSectionExit; } tickStart = DHL_OS_GetMsCount(); while (1) { semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK); if (semErr == DHL_OK) break; if (ckfn && ckfn()) { status = statusCancelled; goto CancelPsiMonitor; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { status = statusTimeout; goto CancelPsiMonitor; } } if (procData.err) { status = statusPSIPError; goto CancelPsiMonitor; } err = ParseCvct(procData.desc->sectPtr, cvctPtr); if (IsError(err)) { status = statusPSIPError; *cvctPtr = NULL; } CancelPsiMonitor: if (psiCtl) DHL_PSI_StopMonitor(psiCtl); if (procData.desc) DHL_PSI_FreePSIData(procData.desc); GetSectionExit: DHL_OS_DeleteSemaphore(procData.sema4); return status; } STATUS Dmc_GetEit(tDHL_TSD tsd, UINT16 PID, UINT16 source_id, eitPtr_t *eitPtr, int timeOut, BOOL (*ckfn)()) { PSIMultiEventProcData procData; tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0; int semErr; DHL_RESULT err; STATUS status = statusOK; UINT32 tickStart; #if 0 if (dmc_TaskID != Dmc_GetCurrentTaskID()) { dprint(2, "!! Dmc_GetEit() should be called only in DmcTask.\n"); return statusInvalidState; } #endif if (eitPtr == NULL) return statusInvalidArgument; if (PID <= 0 || PID >= 0x1FFF) { // cafrii 050315 add return statusInvalidArgument; } memset(&procData, 0, sizeof(procData)); procData.desc = NULL; procData.err = DHL_OK; procData.id = (UINT32)-1; procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcEit",OS_SEM_PRIO,0); if (!procData.sema4) { return statusOutOfMemory; } err = MonitorEit(tsd, PID, source_id, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl); if (err) { status = statusOutOfResource; goto GetSectionExit; } tickStart = DHL_OS_GetMsCount(); while (1) { semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK); if (semErr == DHL_OK) break; if (ckfn && ckfn()) { status = statusCancelled; goto CancelPsiMonitor; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { status = statusTimeout; goto CancelPsiMonitor; } } if (procData.err) { status = statusPSIPError; goto CancelPsiMonitor; } err = ParseEit(procData.desc->sectPtr, eitPtr); if (IsError(err)) { status = statusPSIPError; *eitPtr = NULL; } CancelPsiMonitor: if (psiCtl) DHL_PSI_StopMonitor(psiCtl); if (procData.desc) DHL_PSI_FreePSIData(procData.desc); GetSectionExit: DHL_OS_DeleteSemaphore(procData.sema4); return status; } STATUS Dmc_GetEttSection(tDHL_TSD tsd, UINT16 PID, UINT32 ETM_id, ettSectionPtr_t *ettSectPtr, int timeOut, BOOL (*ckfn)()) { PSIMultiEventProcData procData; tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0; int semErr; DHL_RESULT err; STATUS status = statusOK; UINT32 tickStart; #if 0 if (dmc_TaskID != Dmc_GetCurrentTaskID()) { dprint(2, "!! Dmc_GetEttSection() should be called only in DmcTask.\n"); return statusInvalidState; } #endif if (ettSectPtr == NULL) return statusInvalidArgument; if (PID <= 0 || PID >= 0x1FFF) { // cafrii 050315 add return statusInvalidArgument; } memset(&procData, 0, sizeof(procData)); procData.desc = NULL; procData.err = DHL_OK; procData.id = (UINT32)-1; procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcEtt",OS_SEM_PRIO,0); if (!procData.sema4) { return statusOutOfMemory; } err = MonitorEtt(tsd, PID, ETM_id, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl); if (err) { status = statusOutOfResource; goto GetSectionExit; } tickStart = DHL_OS_GetMsCount(); while (1) { semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK); if (semErr == DHL_OK) break; if (ckfn && ckfn()) { status = statusCancelled; goto CancelPsiMonitor; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { status = statusTimeout; goto CancelPsiMonitor; } } if (procData.err) { status = statusPSIPError; goto CancelPsiMonitor; } err = ParseEttSection(procData.desc->sectPtr[0], ettSectPtr); if (IsError(err)) { status = statusPSIPError; *ettSectPtr = NULL; } CancelPsiMonitor: if (psiCtl) DHL_PSI_StopMonitor(psiCtl); if (procData.desc) DHL_PSI_FreePSIData(procData.desc); GetSectionExit: DHL_OS_DeleteSemaphore(procData.sema4); return status; } STATUS Dmc_GetRrtSection(tDHL_TSD tsd, UINT8 region, rrtSectionPtr_t *rrtSectPtr, int timeOut, BOOL (*ckfn)()) { PSIMultiEventProcData procData; tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0; int semErr; DHL_RESULT err; STATUS status = statusOK; UINT32 tickStart; #if 0 if (dmc_TaskID != Dmc_GetCurrentTaskID()) { dprint(2, "!! Dmc_GetRrtSection() should be called only in DmcTask.\n"); return statusInvalidState; } #endif if (rrtSectPtr == NULL) return statusInvalidArgument; memset(&procData, 0, sizeof(procData)); procData.desc = NULL; procData.err = DHL_OK; procData.id = (UINT32)-1; procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcRrt",OS_SEM_PRIO,0); if (!procData.sema4) { return statusOutOfMemory; } err = MonitorRrt(tsd, region, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl); if (err) { status = statusOutOfResource; goto GetSectionExit; } tickStart = DHL_OS_GetMsCount(); while (1) { semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK); if (semErr == DHL_OK) break; if (ckfn && ckfn()) { status = statusCancelled; goto CancelPsiMonitor; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { status = statusTimeout; goto CancelPsiMonitor; } } if (procData.err) { status = statusPSIPError; goto CancelPsiMonitor; } err = ParseRrtSection(procData.desc->sectPtr[0], rrtSectPtr); if (IsError(err)) { status = statusPSIPError; *rrtSectPtr = NULL; } CancelPsiMonitor: if (psiCtl) DHL_PSI_StopMonitor(psiCtl); if (procData.desc) DHL_PSI_FreePSIData(procData.desc); GetSectionExit: DHL_OS_DeleteSemaphore(procData.sema4); return status; } void Dmc_FreeAtscTable(void *tablePtrPtr) { // ÀÚµ¿ÀûÀ¸·Î Null setting±îÁö ÇÏ´Â Free API.. // // ex: Dmc_FreeAtscTable(&mgt); // if (tablePtrPtr == NULL || *(void **)tablePtrPtr == NULL) return; // cafrii 040420 FreeAtscTable(*(void **)tablePtrPtr); *(void **)tablePtrPtr = NULL; } // DHL_RESULT MonitorRrt (tDHL_TSD tsd, UINT8 region, tDHL_PSI_Update updateMode, tDHL_PSI_EventProc eventProc, // UINT32 userParam, tDHL_PSI_ControlHandle *psiCtl) // ƯÁ¤ regionÀ» ÁöÁ¤ÇÏÁö ¾Ê°í ¸ðµç RRT¸¦ ´Ù monitorÇÏ´Â ÇÔ¼ö·Î¼­ // ¿©·¯ regionÀÇ rrt¸¦ ´Ù ÇÔ²² ¼ö½ÅÇÒ ¶§ »ç¿ëÇÔ. // STATUS Dmc_MonitorRrt(tDHL_TSD tsd, tDHL_PSI_Update updateMode, tDHL_PSI_EventProc eventProc, UINT32 userParam, tDHL_PSI_ControlHandle *psiCtl) { tDHL_PSI_Filter *pref; // Set up the Table ID filter, table id 0xCA if (DHL_PSI_AllocFilterWithTid(&pref, tid_rating_region_table, TRUE)) { return statusOutOfResource; } // Set up PID Filter if (DHL_PSI_StartMonitor(tsd, PSIP_BASE_PID, ePSIMODE_SECTION, // RRT´Â ÇѰ³ÀÇ sectionÀ¸·Î¸¸ ±¸¼ºµÈ´Ù. updateMode, pref, 4096, 1, eventProc, userParam, psiCtl)) { DHL_OS_Free((void**)&pref); return statusOutOfResource; } return statusOK; } // cafrii 060306 add #undef MEM_LIMIT #define MEM_LIMIT 0x00004000 // 16K #undef checkMemoryError #define checkMemoryError(p) if (p == NULL) {status = statusOutOfMemory; goto ParseExit;} STATUS Dmc_RestoreRrt(UINT8 *buffer, rrtSectionPtr_t *rrtSectionPtr) { rrtSectionPtr_t rrt = NULL; memChainSetup_t memSetup = {MEM_LIMIT,NULL,NULL}; memId_t memId = NULL; bitBuffer_t tBits, *bits = &tBits; INT32 i,j,k; INT32 count_i,count_j,count_k; INT32 section_length; DHL_RESULT err; STATUS status = statusOK; #if 0 // cafrii 080303 avoid using assert DHL_ASSERT((buffer != NULL), "Dmc_RestoreRrt():bad parameter"); #else if (buffer == NULL) return statusInvalidArgument; #endif if (buffer[0] != tid_rating_region_table) { dprint(0, "!! RRT: invalid marker 0x%x\n", buffer[0]); status = statusInvalidArgument; goto ParseExit; } section_length = ((buffer[1] & 0x0F) << 8) | buffer[2]; /* initialize the bitBuffer */ bitBufferInitialize(bits, buffer+3, section_length); /* create the memChain */ err = memChainCreate(&memId,&memSetup); if (err) { status = statusOutOfMemory; goto ParseExit; } /* allocate memory for rrtSection */ rrt = (rrtSectionPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(rrtSection_t)+sizeof(memId_t))) + 1); checkMemoryError(rrt); /* parse section */ rrt->rating_region = (rating_region_k) bitBufferGetBits(bits,8); rrt->version_number = bitBufferGetBits(bits,8); count_i = rrt->rating_region_name_length = bitBufferGetBits(bits,8); rrt->rating_region_name = (UINT8 *)memChainAlloc(memId, count_i*sizeof(UINT8)); checkMemoryError(rrt->rating_region_name); for (i=0; irating_region_name[i] = bitBufferGetBits(bits,8); } count_i = rrt->dimensions_defined = bitBufferGetBits(bits,8); // max 255 rrt->dimension = (rrtDimensionPtr_t)memChainAlloc(memId,count_i*sizeof(rrtDimension_t)); checkMemoryError(rrt->dimension); for (i=0; idimension[i]; count_j = dim->dimension_name_length = bitBufferGetBits(bits,8); dim->dimension_name = (UINT8 *)memChainAlloc(memId, count_j*sizeof(UINT8)); checkMemoryError(dim->dimension_name); for (j=0; jdimension_name[j] = bitBufferGetBits(bits,8); } dim->graduated_scale = bitBufferGetBits(bits,1); dim->first_value_empty = bitBufferGetBits(bits,1); bitBufferSkipBits(bits,2); /* reserved */ count_j = dim->values_defined = bitBufferGetBits(bits,4); // max 15 dim->value = (rrtValuePtr_t)memChainAlloc(memId,count_j*sizeof(rrtValue_t)); checkMemoryError(dim->value); for (j=0; jvalue[j]; value->block_on = bitBufferGetBits(bits,1); bitBufferSkipBits(bits,7); /* reserved */ count_k = value->abbrev_rating_value_length = bitBufferGetBits(bits,8); value->abbrev_rating_value = (UINT8 *)memChainAlloc(memId, count_k*sizeof(UINT8)); checkMemoryError(value->abbrev_rating_value); for (k=0; kabbrev_rating_value[k] = bitBufferGetBits(bits,8); } count_k = value->rating_value_length = bitBufferGetBits(bits,8); value->rating_value = (UINT8 *)memChainAlloc(memId, count_k*sizeof(UINT8)); checkMemoryError(value->rating_value); for (k=0; krating_value[k] = bitBufferGetBits(bits,8); } } } /* parsing complete */ *(((memId_t *)rrt)-1) = memId; memId = NULL; /* so memChain not deleted */ ParseExit: if (memId) { /* delete the cvctSection memory */ memChainDestroy(memId); } if (bitBufferCheckError(bits)) dprint(0, "!! RestoreRRT bitbuffer overrun, bufsize %d, bit offset %d\n", bits->bufSize, bits->bitOffset); *rrtSectionPtr = rrt; return (status); } int Dmc_FlattenRrt(UINT8 *buffer, int bufsize, rrtSectionPtr_t rrt) { int i, k; byteBuf_t bt0, *bt = &bt0; UINT16 length; UINT8 data; if (rrt == NULL) return 0; if (buffer) byteBufInit(bt, buffer, bufsize); else byteBufInit(bt, NULL, 0xFFFF); byteBufSet1Byte(bt, 0); // marker´Â ¸Ç ¸¶Áö¸·¿¡.. byteBufSet2Byte(bt, 0); // section_length byteBufSet1Byte(bt, rrt->rating_region); byteBufSet1Byte(bt, rrt->version_number); byteBufSet1Byte(bt, rrt->rating_region_name_length); byteBufSetBytesBuf(bt, rrt->rating_region_name, rrt->rating_region_name_length); byteBufSet1Byte(bt, rrt->dimensions_defined); for (i=0; idimensions_defined; i++) { rrtDimensionPtr_t dim = &rrt->dimension[i]; byteBufSet1Byte(bt, dim->dimension_name_length); byteBufSetBytesBuf(bt, dim->dimension_name, dim->dimension_name_length); data = (dim->graduated_scale ? 0x80 : 0) | (dim->first_value_empty ? 0x40 : 0) | (dim->values_defined & 0x0f); byteBufSet1Byte(bt, data); for (k=0; kvalues_defined; k++) { rrtValuePtr_t value = &dim->value[k]; byteBufSet1Byte(bt, value->block_on ? 0x80 : 0); byteBufSet1Byte(bt, value->abbrev_rating_value_length); byteBufSetBytesBuf(bt, value->abbrev_rating_value, value->abbrev_rating_value_length); byteBufSet1Byte(bt, value->rating_value_length); byteBufSetBytesBuf(bt, value->rating_value, value->rating_value_length); } } length = byteBufGetOffset(bt); if (buffer) { byteBufInit(bt, buffer, bufsize); byteBufSet1Byte(bt, tid_rating_region_table); // marker byteBufSet2Byte(bt, length); // section_length } return (int)length; } //------------------------------------------------------------------------- #if 0 ___________() #endif #if 0 ___________() #endif STATUS Dmc_GetVctAndPat(tDHL_TSD tsd, tvctPtr_t *tvctPtr, cvctPtr_t *cvctPtr, MPEG_PAT **patPtr, int timeOut, BOOL (*ckfn)(UINT32)) { PSIMultiEventProcData *aProcData; tDHL_PSI_ControlHandle *aPsiCtl; DHL_OS_SEMA_ID sema4; int i, nReceivedTable; UINT32 tickStart; //BOOL bDownloadCancelled = FALSE; DHL_RESULT err; STATUS status = statusOK; int timeoutOrg = timeOut; // caller's original timeout int timeoutAdd = timeoutOrg/2; // additional time in case of bad signal. dprint(1, "Dmc_GetVctAndPat()\n"); if (tvctPtr == NULL && cvctPtr == NULL && patPtr == NULL) { return statusInvalidArgument; } aPsiCtl = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(3 * sizeof(tDHL_PSI_ControlHandle)); if (aPsiCtl == NULL) { dprint(0, "!! out of memory for PsiCtls..\n"); return statusOutOfMemory; } memset (aPsiCtl, 0, 3 * sizeof(tDHL_PSI_ControlHandle)); aProcData = (PSIMultiEventProcData *) DHL_OS_Malloc(3 * sizeof(PSIMultiEventProcData)); if (aProcData == NULL) { dprint(0, "!! out of memory for ProcData..\n"); DHL_OS_Free((void**)&aPsiCtl); return statusOutOfMemory; } memset (aProcData, 0, 3 * sizeof(PSIMultiEventProcData)); // semaphoreÀº Çϳª¸¸ ¸¸µé¾î¼­ ¸ðµç ProcData¿¡ ¶È°°ÀÌ ³Ö¾îÁÖÀÚ. sema4 = DHL_OS_CreateCountingSemaphore("GetVctPat", OS_SEM_FIFO, 0); if (!sema4) { DHL_OS_Free((void**)&aPsiCtl); DHL_OS_Free((void**)&aProcData); return statusOutOfMemory; } // Event report¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ÁغñÇÑ´Ù. for (i=0; i<3; i++) { aProcData[i].err = DHL_OK; // it will be initialized at EventProc.. aProcData[i].sema4 = sema4; // it will be used in EventProc to notify Data arrival aProcData[i].id = i; // id for just debugging.. } // Psi Monitor¸¦ ½ÃÀÛÇÑ´Ù. ¼ö½ÅÇϰíÀÚ ÇÏ´Â Table °¹¼ö¸¸Å­ PsiCtlÀ» »ý¼º ÇØ¾ß ÇÑ´Ù. err = MonitorTvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[0], &aPsiCtl[0]); if (err) { dprint(0, "\t !! MonitorTvct err %d %s\n", err, ErrorString((DHL_RESULT)err)); status = statusOutOfResource; goto CancelPsiMonitor; } err = MonitorCvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[1], &aPsiCtl[1]); if (err) { dprint(0, "\t !! MonitorCvct err %d %s\n", err, ErrorString((DHL_RESULT)err)); status = statusOutOfResource; goto CancelPsiMonitor; } if ((err = MonitorPAT(tsd, TRUE /* current */, FALSE /* not eager */, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[2], &aPsiCtl[2]))) { dprint(0, "\t !! MonitorPAT err %d %s\n", err, ErrorString((DHL_RESULT)err)); status = statusOutOfResource; goto CancelPsiMonitor; } tickStart = DHL_OS_GetMsCount(); nReceivedTable = 0; while (1) { // ÃÑ nEit °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù. // err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK); if (err == DHL_OK) { int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000; // unit: 0.01 sec //nReceivedTable++; // cafrii 070117 change policy!! // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù. // if ((aProcData[0].id & PME_MASK) == PME_SEND) { // TVCT nReceivedTable++; // cafrii 070117 change policy!! aProcData[0].id |= PME_CNFM; // ¿¡·¯¿¡ »ó°ü¾øÀÌ download flag¸¦ set. if (aProcData[0].err == DHL_OK) { if (tvctPtr) { err = ParseTvct(aProcData[0].desc->sectPtr, tvctPtr); if (IsError(err)) *tvctPtr = NULL; // cafrii 050315 add } dprint(2, "\t TVCT received (err %d) %d.%02d sec -> %x\n", aProcData[0].err, elapsedTime/100, elapsedTime%100, tvctPtr); DHL_PSI_FreePSIData(aProcData[0].desc); } } else if ((aProcData[1].id & PME_MASK) == PME_SEND) { // CVCT nReceivedTable++; // cafrii 070117 change policy!! aProcData[1].id |= PME_CNFM; if (aProcData[1].err == DHL_OK) { if (cvctPtr) { err = ParseCvct(aProcData[1].desc->sectPtr, cvctPtr); if (IsError(err)) *cvctPtr = NULL; // cafrii 050315 add } dprint(2, "\t CVCT received (err %d) %d.%02d sec -> %x\n", aProcData[1].err, elapsedTime/100, elapsedTime%100, cvctPtr); DHL_PSI_FreePSIData(aProcData[1].desc); } } else if ((aProcData[2].id & PME_MASK) == PME_SEND) { // PAT nReceivedTable++; // cafrii 070117 change policy!! aProcData[2].id |= PME_CNFM; if (aProcData[2].err == DHL_OK) { if (patPtr) { err = ParsePAT(aProcData[2].desc, patPtr); if (IsError(err)) *patPtr = NULL; // cafrii 050315 add } dprint(2, "\t PAT received (err %d) %d.%02d sec -> %x\n", aProcData[2].err, elapsedTime/100, elapsedTime%100, patPtr); DHL_PSI_FreePSIData(aProcData[2].desc); } } // cafrii 070117 add else { for (i=0; i<3; i++) { // TVCT, CVCT, PAT¿¡ ´ëÇØ¼­ bad packet ó¸®. if ((aProcData[i].id & PME_EV_SEND_BADPKT) && (aProcData[i].id & PME_EV_CNFM_BADPKT) == 0) { aProcData[i].id |= PME_EV_CNFM_BADPKT; if (timeOut < timeoutOrg + timeoutAdd) { timeOut = timeoutOrg + timeoutAdd; dprint(2, "\t timeout increased by badpkt\n"); } } } } } // ·çÇÁ Á¾·á Á¶°Ç.. tvct/cvct µÑ Áß¿¡ Çϳª¶û, pat°¡ ¼ö½ÅµÇ¸é Á¾·á.. // ¸¸¾à ÇÔ¼ö ÀÎÀÚ·Î NULLÀ» ÁöÁ¤Çß´Ù¸é ¼ö½ÅÀÇ Àǻ簡 ¾ø´Â °ÍÀ̹ǷΠ±× tableÀº üũÇÏÁö ¾Ê´Â´Ù. // if (patPtr && (aProcData[2].id & PME_CNFM) == 0) { // pat should be downloaded, but not yet.. // patPtrÀ» non-Null·Î ÁöÁ¤Çϸé PAT´Â ²À ¹Þ¾Æ¾ß ÇÑ´Ù. ´õ ±â´Ù¸®ÀÚ.. } else { // pat´Â ¼ö½ÅÀÌ µÇ¾ú°Å³ª ¼ö½ÅÇÒ Çʿ䰡 ¾ø´Â °æ¿ì.. ÀÌÁ¦ vctµéÀ» üũÇÑ´Ù. // if ((aProcData[0].id & PME_CNFM) || (aProcData[1].id & PME_CNFM)) { // VCT µÑ Áß Çϳª°¡ ¼ö½ÅµÇ¾úÀ¸¹Ç·Î OK.. // ÁÖÀÇ! pat´Â ¼ö½ÅÀÌ ¾ÈµÇ¾úÀ» ¼öµµ ÀÖ´Ù.. ±×·± °æ¿ì¶ó¸é patPtrÀÌ NULLÀÎ °æ¿ìÀÌ´Ù. dprint(2, "xVCT and PAT, %d tables received OK\n", nReceivedTable); break; } // vct µÑ´Ù ¾ÆÁ÷ ¼ö½ÅÀÌ ¾ÈµÈ °æ¿ì.. // ±×·¯³ª ¸¸¾à caller°¡ tvctPtr, cvctPtrÀ» NULL·Î ÁöÁ¤ÇÑ °æ¿ì¶ó¸é ¹ÞÀ» Àǻ簡 ¾ø´Â // °ÍÀ̹ǷΠ´õ ±â´Ù¸± Çʿ䰡 ¾ø´Ù. if (cvctPtr == NULL && tvctPtr == NULL) { dprint(2, "VCT no need to download.. OK\n"); break; } } if (ckfn && ckfn(0)) { // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù. dprint(2, "!! download cancelled\n"); status = statusCancelled; break; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { // ¿©·¯°³ÀÇ tableÀ» ¹Þ°í ÀÖÀ¸¹Ç·Î °³°³ tableÀÇ timeoutÀº ¹«ÀÇ¹Ì //status = statusTimeout; dprint(2, "!! timeout (%ds) err, only %d/%d tables received..\n", timeOut/1000, nReceivedTable, 3); break; } } // while CancelPsiMonitor: for (i=0; i<3; i++) { if (aPsiCtl[i]) DHL_PSI_StopMonitor(aPsiCtl[i]); } if (aPsiCtl) DHL_OS_Free((void**)&aPsiCtl); if (aProcData) DHL_OS_Free((void**)&aProcData); if (sema4) DHL_OS_DeleteSemaphore(sema4); // // caller´Â °¢ table pointerµéÀ» °Ë»çÇØ¼­ ¿¡·¯ À¯¹«¸¦ Ã¼Å©ÇØ¾ß ÇÑ´Ù. // ÀϺΠtableµé¿¡¼­ timeout error°¡ ¹ß»ýÇß´õ¶óµµ, ¸î°³¸¸ ¹ÞÀ¸¸é °è¼Ó ÁøÇàÇÒ ¼ö´Â ÀÖ´Ù. // (¿¹: VCT°¡ ¾ø¾îµµ PAT·Î ÁøÇà °¡´É) // return status; } // // Tvct¿Í Cvct µÑ Áß Çϳª ¸ÕÀú ¿À´Â °ÍÀ» ¹Þ¾Æ¼­ Xvct·Î ¸®ÅÏÇÏ´Â ÇÔ¼ö // STATUS Dmc_GetXvct(tDHL_TSD tsd, xvctPtr_t *xvctPtr, int timeOut, BOOL (*ckfn)(UINT32)) { PSIMultiEventProcData *aProcData; tDHL_PSI_ControlHandle *aPsiCtl; DHL_OS_SEMA_ID sema4; int i, nReceivedTable; UINT32 tickStart; DHL_RESULT err; STATUS status = statusOK; tvctPtr_t tvct = NULL; cvctPtr_t cvct = NULL; dprint(1, "Dmc_GetXvct()\n"); if (xvctPtr == NULL) { return statusInvalidArgument; } aPsiCtl = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(2 * sizeof(tDHL_PSI_ControlHandle)); if (aPsiCtl == NULL) { dprint(0, "!! out of memory for PsiCtls..\n"); return statusOutOfMemory; } memset (aPsiCtl, 0, 2 * sizeof(tDHL_PSI_ControlHandle)); aProcData = (PSIMultiEventProcData *) DHL_OS_Malloc(2 * sizeof(PSIMultiEventProcData)); if (aProcData == NULL) { dprint(0, "!! out of memory for ProcData..\n"); DHL_OS_Free((void**)&aPsiCtl); return statusOutOfMemory; } memset (aProcData, 0, 2 * sizeof(PSIMultiEventProcData)); // semaphoreÀº Çϳª¸¸ ¸¸µé¾î¼­ ¸ðµç ProcData¿¡ ¶È°°ÀÌ ³Ö¾îÁÖÀÚ. sema4 = DHL_OS_CreateCountingSemaphore("GetXVct", OS_SEM_FIFO, 0); if (!sema4) { DHL_OS_Free((void**)&aPsiCtl); DHL_OS_Free((void**)&aProcData); return statusOutOfMemory; } // Event report¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ÁغñÇÑ´Ù. for (i=0; i<2; i++) { aProcData[i].err = DHL_OK; // it will be initialized at EventProc.. aProcData[i].sema4 = sema4; // it will be used in EventProc to notify Data arrival aProcData[i].id = i; // id for just debugging.. } // Psi Monitor¸¦ ½ÃÀÛÇÑ´Ù. ¼ö½ÅÇϰíÀÚ ÇÏ´Â Table °¹¼ö¸¸Å­ PsiCtlÀ» »ý¼º ÇØ¾ß ÇÑ´Ù. err = MonitorTvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[0], &aPsiCtl[0]); if (err) { dprint(0, "\t !! MonitorTvct err %d %s\n", err, ErrorString(err)); status = statusOutOfResource; goto CancelPsiMonitor; } err = MonitorCvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[1], &aPsiCtl[1]); if (err) { dprint(0, "\t !! MonitorCvct err %d %s\n", err, ErrorString(err)); status = statusOutOfResource; goto CancelPsiMonitor; } tickStart = DHL_OS_GetMsCount(); nReceivedTable = 0; while (1) { // ÃÑ 2 °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù. // err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK); if (err == DHL_OK) { int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000; // unit: 0.01 sec //nReceivedTable++; // cafrii 070117 change policy!! // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù. // if ((aProcData[0].id & PME_MASK) == PME_SEND) { // TVCT nReceivedTable++; // cafrii 070117 change policy!! aProcData[0].id |= PME_CNFM; // ¿¡·¯¿¡ »ó°ü¾øÀÌ download flag¸¦ set. if (aProcData[0].err == DHL_OK) { err = ParseTvct(aProcData[0].desc->sectPtr, &tvct); if (IsError(err)) { tvct = NULL; // cafrii 050315 add status = statusPSIPError; } dprint(2, "\t TVCT received (err %d) %d.%02d sec -> %x\n", aProcData[0].err, elapsedTime/100, elapsedTime%100, tvct); DHL_PSI_FreePSIData(aProcData[0].desc); } else status = statusPSIPError; } else if ((aProcData[1].id & PME_MASK) == PME_SEND) { // CVCT nReceivedTable++; // cafrii 070117 change policy!! aProcData[1].id |= PME_CNFM; if (aProcData[1].err == DHL_OK) { err = ParseCvct(aProcData[1].desc->sectPtr, &cvct); if (IsError(err)) { cvct = NULL; // cafrii 050315 add status = statusPSIPError; } dprint(2, "\t CVCT received (err %d) %d.%02d sec -> %x\n", aProcData[1].err, elapsedTime/100, elapsedTime%100, cvct); DHL_PSI_FreePSIData(aProcData[1].desc); } else status = statusPSIPError; } } // ·çÇÁ Á¾·á Á¶°Ç.. tvct/cvct µÑ Áß¿¡ Çϳª°¡ ¼ö½ÅµÇ¸é Á¾·á.. // ¸¸¾à ÇÔ¼ö ÀÎÀÚ·Î NULLÀ» ÁöÁ¤Çß´Ù¸é ¼ö½ÅÀÇ Àǻ簡 ¾ø´Â °ÍÀ̹ǷΠ±× tableÀº üũÇÏÁö ¾Ê´Â´Ù. // // µÎ tableÀÌ µ¿½Ã¿¡ ¼ö½ÅµÉ °æ¿ì CVCT¿¡ ¿ì¼±±ÇÀ» ÁÖ±â À§ÇØ ¼ø¼­ º¯°æ // if (aProcData[1].id & PME_CNFM) { // CVCT ¼ö½Å dprint(2, "CVCT received OK, total %d\n", nReceivedTable); if (cvct) { status = Dmc_TranslateCvct(cvct, xvctPtr); if (status) *xvctPtr = NULL; } else *xvctPtr = NULL; break; // ´õÀÌ»ó üũÇÏÁö ¾Ê°í ¿©±â¼­ loop-out } if (aProcData[0].id & PME_CNFM) { // TVCT ¼ö½Å dprint(2, "TVCT received OK, total %d\n", nReceivedTable); if (tvct) { status = Dmc_TranslateTvct(tvct, xvctPtr); if (status) *xvctPtr = NULL; } else *xvctPtr = NULL; break; } if (ckfn && ckfn(0)) { // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù. dprint(2, "!! download cancelled\n"); status = statusCancelled; break; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { // TVCT/CVCT µÑ Áß¿¡ Çϳª´Â ²À ¹Þ¾ÆÁ®¾ß ÇÑ´Ù. status = statusTimeout; dprint(2, "!! timeout (%ds) err, only %d/%d tables received..\n", timeOut/1000, nReceivedTable, 2); break; } } // while CancelPsiMonitor: for (i=0; i<2; i++) { if (aPsiCtl[i]) DHL_PSI_StopMonitor(aPsiCtl[i]); } DHL_OS_Free((void**)&aPsiCtl); DHL_OS_Free((void**)&aProcData); if (sema4) DHL_OS_DeleteSemaphore(sema4); Dmc_FreeAtscTable(&tvct); Dmc_FreeAtscTable(&cvct); // cafrii 050713 add if (*xvctPtr == NULL && status == statusOK) status = statusPSIPError; // Ưº°ÇÑ ÀÌÀ¯µµ ¾ø´Âµ¥ vct¸¦ ¸ø¹ÞÀº °æ¿ì?? return status; } #if 0 ___________() #endif //------------------------------------ // MainChannelTable °ü·Ã ±â´É // // MainChannelTable À̶õ TVCT, CVCT, PAT, PMTµéÀ» ¸»ÇÏ´Â °ÍÀ¸·Î // Autoscan °úÁ¤¿¡¼­ ÀÌ Å×À̺íÀ» ÇѲ¨¹ø¿¡ ¼ö½ÅÇÏ´Â ±â´ÉÀ» ¼öÇàÇÑ´Ù. // // cafrii 041129 add // void Dmc_FreeMainChannelTables(DmcMainTables *tbls) { int i; if (tbls == NULL) return; Dmc_FreeAtscTable(&tbls->tvct); Dmc_FreeAtscTable(&tbls->cvct); Dmc_FreeAtscTable(&tbls->pat); for (i=0; tbls->pmtList && inum_programs; i++) { Dmc_FreeAtscTable(&tbls->pmtList[i]); } DHL_OS_Free((void**)&tbls->pmtList); } #define MCTID_TVCT 0 #define MCTID_CVCT 1 #define MCTID_PAT 2 STATUS Dmc_GetMainChannelTables(tDHL_TSD tsd, DmcMainTables *tbls, int timeOut, BOOL (*ckfn)(UINT32)) { PSIMultiEventProcData *aProcData; tDHL_PSI_ControlHandle *aPsiCtl; PSIMultiEventProcData *aProcDataPmt = NULL; tDHL_PSI_ControlHandle *aPsiCtlPmt = NULL; DHL_OS_SEMA_ID sema4; DHL_RESULT err; STATUS status = statusOK; int i, k, nReceivedTable; UINT32 tickStart; int elapsedTime; BOOL bPsiCompleted; int nMonitors = 0; // cafrii 060119 add int idxPmt = 0; // cafrii 060726 add, pmt ¸ð´ÏÅÍ index UINT16 pid; int timeoutOrg = timeOut; int timeoutAdd = timeOut/2; // additional time in case of bad signal BOOL bNewMonitorStarted = FALSE; // cafrii 070117 add BOOL bProcessed; dprint(1, "Dmc_GetMainChannelTables()\n"); if (tbls == NULL) { return statusInvalidArgument; } memset(tbls, 0, sizeof(DmcMainTables)); aPsiCtl = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(3 * sizeof(tDHL_PSI_ControlHandle)); if (aPsiCtl == NULL) { dprint(0, "!! out of memory for PsiCtls..\n"); return statusOutOfMemory; } memset (aPsiCtl, 0, 3 * sizeof(tDHL_PSI_ControlHandle)); aProcData = (PSIMultiEventProcData *) DHL_OS_Malloc(3 * sizeof(PSIMultiEventProcData)); if (aProcData == NULL) { dprint(0, "!! out of memory for ProcData..\n"); DHL_OS_Free((void**)&aPsiCtl); return statusOutOfMemory; } memset (aProcData, 0, 3 * sizeof(PSIMultiEventProcData)); // semaphoreÀº Çϳª¸¸ ¸¸µé¾î¼­ ¸ðµç ProcData¿¡ ¶È°°ÀÌ ³Ö¾îÁÖÀÚ. sema4 = DHL_OS_CreateCountingSemaphore("GetMainTbls", OS_SEM_FIFO, 0); if (!sema4) { DHL_OS_Free((void**)&aPsiCtl); DHL_OS_Free((void**)&aProcData); return statusOutOfMemory; } // Event report¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ÁغñÇÑ´Ù. for (i=0; i<3; i++) { aProcData[i].err = DHL_OK; // it will be initialized at EventProc.. aProcData[i].sema4 = sema4; // it will be used in EventProc to notify Data arrival aProcData[i].id = i; // id for just debugging.. } // Psi Monitor¸¦ ½ÃÀÛÇÑ´Ù. ¼ö½ÅÇϰíÀÚ ÇÏ´Â Table °¹¼ö¸¸Å­ PsiCtlÀ» »ý¼º ÇØ¾ß ÇÑ´Ù. // // ------- TVCT ---------- // id : 0 err = MonitorTvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[MCTID_TVCT], &aPsiCtl[MCTID_TVCT]); if (err) { dprint(0, "\t !! MonitorTvct err %d %s\n", err, ErrorString((DHL_RESULT)err)); status = statusOutOfResource; goto CancelPsiMonitor; } nMonitors++; // ------- CVCT ---------- // id : 1 err = MonitorCvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[MCTID_CVCT], &aPsiCtl[MCTID_CVCT]); if (err) { dprint(0, "\t !! MonitorCvct err %d %s\n", err, ErrorString((DHL_RESULT)err)); status = statusOutOfResource; goto CancelPsiMonitor; } nMonitors++; // ------- PAT ---------- // id : 2 if ((err = MonitorPAT(tsd, TRUE /* current */, FALSE /* not eager */, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[MCTID_PAT], &aPsiCtl[MCTID_PAT]))) { dprint(0, "\t !! MonitorPAT err %d %s\n", err, ErrorString((DHL_RESULT)err)); status = statusOutOfResource; goto CancelPsiMonitor; } nMonitors++; // ------- PMT ---------- // id 3 ~ 3+pat->numPrograms-1 // // ÇöÀç´Â ÁøÇà ºÒ°¡.. PMT PID¸¦ ¾Ë¾Æ¾ß Çϱ⠶§¹®.. tickStart = DHL_OS_GetMsCount(); nReceivedTable = 0; while (1) { // ÃÑ 3 ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù. // err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK); if (err) goto label_check; elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000; // unit: 0.01 sec bProcessed = FALSE; // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù. // if ((aProcData[MCTID_TVCT].id & PME_MASK) == PME_SEND) //---------- TVCT { nReceivedTable++; aProcData[MCTID_TVCT].id |= PME_CNFM; // ¿¡·¯¿¡ »ó°ü¾øÀÌ download flag¸¦ set. if (aProcData[MCTID_TVCT].err == DHL_OK) { err = ParseTvct(aProcData[MCTID_TVCT].desc->sectPtr, &tbls->tvct); if (IsError(err)) { tbls->tvct = NULL; // cafrii 050315 add status = statusPSIPError; } dprint(2, "\t TVCT received (err %d) %d.%02d sec -> %x\n", aProcData[MCTID_TVCT].err, elapsedTime/100, elapsedTime%100, tbls->tvct); DHL_PSI_FreePSIData(aProcData[MCTID_TVCT].desc); bProcessed = TRUE; // cafrii 081021 add. if we free monitor asap, performance will improved. DHL_PSI_StopMonitor(aPsiCtl[MCTID_TVCT]); aPsiCtl[MCTID_TVCT] = 0; nMonitors--; } else dprint(0, "!! TVCT received err\n"); } else if ((aProcData[MCTID_CVCT].id & PME_MASK) == PME_SEND) //--------- CVCT { nReceivedTable++; aProcData[MCTID_CVCT].id |= PME_CNFM; if (aProcData[MCTID_CVCT].err == DHL_OK) { err = ParseCvct(aProcData[MCTID_CVCT].desc->sectPtr, &tbls->cvct); if (IsError(err)) { tbls->cvct = NULL; // cafrii 050315 add status = statusPSIPError; } dprint(2, "\t CVCT received (err %d) %d.%02d sec -> %x\n", aProcData[0].err, elapsedTime/100, elapsedTime%100, tbls->cvct); DHL_PSI_FreePSIData(aProcData[MCTID_CVCT].desc); bProcessed = TRUE; // cafrii 081021 add. if we free monitor asap, performance will improved. DHL_PSI_StopMonitor(aPsiCtl[MCTID_CVCT]); aPsiCtl[MCTID_CVCT] = 0; nMonitors--; } else dprint(0, "!! CVCT received err\n"); } else if ((aProcData[MCTID_PAT].id & PME_MASK) == PME_SEND) //---------- PAT { nReceivedTable++; aProcData[MCTID_PAT].id |= PME_CNFM; if (aProcData[MCTID_PAT].err == DHL_OK) { err = ParsePAT(aProcData[MCTID_PAT].desc, &tbls->pat); if (IsError(err)) { tbls->pat = NULL; // cafrii 050315 add status = statusPSIPError; } dprint(2, "\t PAT received (err %d) %d.%02d sec -> %x\n", aProcData[MCTID_PAT].err, elapsedTime/100, elapsedTime%100, tbls->pat); DHL_PSI_FreePSIData(aProcData[MCTID_PAT].desc); if (tbls->pat) { tbls->num_programs = tbls->pat->numPrograms; dprint(2, "\t num programs in PAT : %d\n", tbls->num_programs); if (dprintable(3)) PrintPAT(tbls->pat); // cafrii 050707 add } bProcessed = TRUE; // cafrii 081021 add. if we free monitor asap, performance will improved. DHL_PSI_StopMonitor(aPsiCtl[MCTID_PAT]); aPsiCtl[MCTID_PAT] = 0; nMonitors--; } else dprint(0, "!! PAT received err\n"); // PAT¸¦ ´Ù¿î·Îµå ¹ÞÀº ±× ¼ø°£¿¡¸¸ Çѹø PMT ¸ð´ÏÅ͸¦ ½ÃÀÛÇÑ´Ù. // ¸ð´ÏÅÍ ±¸µ¿ Áß¿¡ ¿¡·¯°¡ ¹ß»ýÇÒ °æ¿ì retry¸¦ ÇÏÁö ¾Ê´Â´Ù. // if (tbls->num_programs > 0) { // »õ·Ó°Ô PMT ¸ð´ÏÅ͸¦ ½ÃÀÛÇÑ´Ù.. bNewMonitorStarted = FALSE; aPsiCtlPmt = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(tbls->num_programs * sizeof(tDHL_PSI_ControlHandle)); if (aPsiCtlPmt == NULL) { dprint(0, "!! out of memory for aPsiCtlPmt..\n"); goto label_check; } memset (aPsiCtlPmt, 0, tbls->num_programs * sizeof(tDHL_PSI_ControlHandle)); aProcDataPmt = (PSIMultiEventProcData *) DHL_OS_Malloc(tbls->num_programs * sizeof(PSIMultiEventProcData)); if (aProcDataPmt == NULL) { dprint(0, "!! out of memory for aProcDataPmt..\n"); DHL_OS_Free((void**)&aPsiCtlPmt); goto label_check; } memset (aProcDataPmt, 0, tbls->num_programs * sizeof(PSIMultiEventProcData)); tbls->pmtList = (MPEG_PMT **) DHL_OS_Malloc(tbls->num_programs * sizeof(MPEG_PMT *)); if (tbls->pmtList == NULL) { dprint(0, "!! out of memory for pmtList..\n"); DHL_OS_Free((void**)&aPsiCtlPmt); DHL_OS_Free((void**)&aProcDataPmt); goto label_check; } memset (tbls->pmtList, 0, tbls->num_programs * sizeof(MPEG_PMT *)); for (idxPmt=0; idxPmtnum_programs; idxPmt++) { pid = tbls->pat->programs[idxPmt].program_map_PID; if (pid <= 0 || pid >= 0x1FFF) { // cafrii 050315 add dprint(0, "!! pmt[%d] pid 0x%x invalid\n", idxPmt, pid); continue; } // cafrii 060119 add if (nMonitors >= gMaxTableMonitorsAtOneTime) { dprint(2, "\t max %d tables monitored.\n", nMonitors); break; } aProcDataPmt[idxPmt].err = DHL_OK; aProcDataPmt[idxPmt].sema4 = sema4; aProcDataPmt[idxPmt].id = 0x10 + idxPmt; // PMTÀÇ id´Â 0x10 + pmt index ÀÌ´Ù. if ((err = MonitorPMT(tsd, pid, tbls->pat->programs[idxPmt].program_number, TRUE /* current */, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcDataPmt[idxPmt], &aPsiCtlPmt[idxPmt]))) { // cafrii 081007 add if (err == DHL_FAIL_OUT_OF_RESOURCE || err == DHL_FAIL_OUT_OF_MEMORY) { dprint(2, "\t stop monitor pmt, at idx %d\n", idxPmt); break; } else dprint(0, "\t !! MonitorPMT[%d] err %d %s\n", idxPmt, err, ErrorString((DHL_RESULT)err)); } else { bNewMonitorStarted = TRUE; nMonitors++; dprint(2, "\t MonitorPMT[%d] pn %d, pid %d success (%d monitors total)\n", idxPmt, tbls->pat->programs[idxPmt].program_number, tbls->pat->programs[idxPmt].program_map_PID, nMonitors); } } // pat°¡ ¼ö½ÅµÇ´Â ½Ã°£ µ¿¾È pmtµéÀº timeout¿¡¼­ ¼ÕÇØ¸¦ ºÃ±â ¶§¹®¿¡ // ´Ù½Ã timeoutÀ» Á¶Á¤ÇÑ´Ù. ÇöÀç ½ÃÁ¡À¸·ÎºÎÅÍ ´Ù½Ã timeoutÀ» ¿¬Àå.. // if (bNewMonitorStarted) { timeOut = DHL_OS_GetMsCount() + timeoutOrg - tickStart; dprint(2, "\t timeout adjusted to %u tick by pat rx\n", timeOut); } } } // Ç×»ó ÀÌ blockÀÌ ½ÇÇà µÉ ¼ö ÀÖµµ·Ï ÇÔ. //else if (aProcDataPmt) //---------- PMT if (aProcDataPmt) { // PAT °¡ ¼ö½ÅÀÌ ÀÌ¹Ì µÇ¾î¼­ Pmt list °¡ ¸¸µé¾îÁ® ÀÖ´Â °æ¿ì¿¡¸¸ üũ °¡´É.. // for (k=0; knum_programs; k++) { if ((aProcDataPmt[k].id & PME_MASK) != PME_SEND) continue; nReceivedTable++; aProcDataPmt[k].id |= PME_CNFM; dprint(3, "\t PMT[%d] received\n", k); if (aProcDataPmt[k].err == DHL_OK) { err = ParsePMT(aProcDataPmt[k].desc, &tbls->pmtList[k]); if (IsError(err)) { tbls->pmtList[k] = NULL; // cafrii 050315 add status = statusPSIPError; } dprint(2, "\t PMT[%d] received (err %d) %d.%02d sec -> %x\n", k, aProcDataPmt[k].err, elapsedTime/100, elapsedTime%100, tbls->pmtList[k]); if (dprintable(3)) PrintPMT(tbls->pmtList[k]); // cafrii 050707 add dprint(3, "\t free PSI data 0x%x\n", aProcDataPmt[k].desc); DHL_PSI_FreePSIData(aProcDataPmt[k].desc); } else dprint(0, "!! PMT[%d] received err\n", k); bProcessed = TRUE; // cafrii 060726 add dynamic delete and re-monitor // pmtÇϳª°¡ ¹Þ¾ÆÁö¸é ³²Àº psifilter·Î ´Ù½Ã pmt ¸ð´ÏÅÍ ½ÃÀÛ. // #if DEVELOPMENT_BUILD // cafrii 080303 avoid using assert DHL_ASSERT(aPsiCtlPmt[k], "null pmtpsictl?"); #else if (aPsiCtlPmt[k] == (tDHL_PSI_ControlHandle)0) dprint(0, "%s: null pmtpsictl[%d]?\n", __FUNCTION__, k); #endif DHL_PSI_StopMonitor(aPsiCtlPmt[k]); aPsiCtlPmt[k] = (tDHL_PSI_ControlHandle)0; nMonitors--; } // cafrii 081021 // ¼³·É pmt processed °¡ ¾ÈµÈ °æ¿ì¶óµµ (bProcessed FALSE), // tvct µîÀÌ ¼ö½Å ¿Ï·á µÇ¾î slotÀÌ available ÇÒ ¼öµµ ÀÖÀ¸¹Ç·Î Ç×»ó üũÇÑ´Ù. // bNewMonitorStarted = FALSE; for (; bProcessed && idxPmtnum_programs; idxPmt++) { pid = tbls->pat->programs[idxPmt].program_map_PID; if (pid <= 0 || pid >= 0x1FFF) { dprint(0, "!! pmt[%d] pid 0x%x invalid\n", idxPmt, pid); continue; } aProcDataPmt[idxPmt].err = DHL_OK; aProcDataPmt[idxPmt].sema4 = sema4; aProcDataPmt[idxPmt].id = 0x10 + idxPmt; // PMTÀÇ id´Â 0x10 + pmt index ÀÌ´Ù. if ((err = MonitorPMT(tsd, pid, tbls->pat->programs[idxPmt].program_number, TRUE /* current */, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcDataPmt[idxPmt], &aPsiCtlPmt[idxPmt]))) { // cafrii 081007 add if (err == DHL_FAIL_OUT_OF_RESOURCE || err == DHL_FAIL_OUT_OF_MEMORY) { dprint(2, "\t full. stop monitor pmt, at idx %d\n", idxPmt); break; } else dprint(0, "\t !! MonitorPMT[%d] err %d %s\n", idxPmt, err, ErrorString((DHL_RESULT)err)); } else { bNewMonitorStarted = TRUE; nMonitors++; dprint(2, "\t MonitorPMT[%d] pn %d, pid %d success (%d monitors total)\n", idxPmt, tbls->pat->programs[idxPmt].program_number, tbls->pat->programs[idxPmt].program_map_PID, nMonitors); // cafrii 081021, // pat, tvct ¿ë slotÀÌ available ÇØ Á³À» ¼ö ÀÖÀ½. ³ª°¡Áö ¸»°í °è¼Ó ÁøÇà. //idxPmt++; //break; } } if (bNewMonitorStarted) { timeOut = DHL_OS_GetMsCount() + timeoutOrg - tickStart; dprint(2, "\t timeout adjusted to %u tick\n", timeOut); } } else { // cafrii 070117 add for (i=0; i<3; i++) { // TVCT, CVCT, PAT¿¡ ´ëÇØ¼­¸¸ bad packet 󸮸¦ ÇÏ¸é µÈ´Ù. if ((aProcData[i].id & PME_EV_SEND_BADPKT) && (aProcData[i].id & PME_EV_CNFM_BADPKT) == 0) { aProcData[i].id |= PME_EV_CNFM_BADPKT; if (timeOut < timeoutOrg + timeoutAdd) { timeOut = timeoutOrg + timeoutAdd; dprint(2, "\t timeout increased by badpkt [%d]\n", i); } } } //dprint(0, "!! semaphore taken, but no filter matched??\n"); } // cafrii 041129 add comment // // ¸ðµÎ OneShotÀ¸·Î Monitor¸¦ ÇßÁö¸¸, °æ¿ì¿¡ µû¶ó¼­ event°¡ µÎ¹ø ºÒ¸± ¼öµµ ÀÖ´Ù. // Áï semaphore ´Â ÁöÁ¤µÈ Ƚ¼ö ÀÌ»óÀ¸·Î take/give µÉ ¼ö ÀÖ´Ù. // ±×·¡¼­ ÀÌ¹Ì Ã³¸®µÈ data ÀÎÁö ¸ÕÀú üũ¸¦ ÇØ º¸´Â ½À°üÀ» µéÀÌ´Â°Ô ÁÁ´Ù. label_check: //--------------------- Á¾·á Á¶°Ç üũ ------------------------- // bPsiCompleted = FALSE; if (aProcData[MCTID_PAT].id & PME_CNFM) { // PAT ¼ö½Å ¿Ï·á. if (aProcDataPmt == NULL) { // PAT´Â ¼ö½ÅÀÌ µÇ¾ú´Âµ¥, PMT list °¡ NULL À̶ó¸é pat ¶Ç´Â system ¿¡ ¿¡·¯°¡ ¹ß»ýÇØ¼­ // PMT¸¦ ´õ ÀÌ»ó ¼ö½ÅÇÒ ¼ö ¾ø´Â »óÅÂÀÓÀ» ¸»ÇÑ´Ù. // bPsiCompleted = TRUE; // ¿¡·¯°¡ ¹ß»ýÇßÀ¸¹Ç·Î.. ÁøÇà ºÒ°¡. completed.. dprint(3, " pat is completed and pmt cannot be downloaded\n"); } else { bPsiCompleted = TRUE; for (k=0; knum_programs; k++) { if (aPsiCtlPmt[k] && (aProcDataPmt[k].id & PME_CNFM) == 0) { // // PMT ¼ö½ÅÀ» À§ÇÑ PsiCtlÀº ½ÃÀ۵Ǿú´Âµ¥, ¾ÆÁ÷ confirme ¾ÈµÈ pmt.. // bPsiCompleted = FALSE; // Çϳª¶óµµ ¼ö½ÅÀÌ ¾ÈµÈ°ÍÀÌ ÀÖÀ¸¸é FALSE.. break; } } if (bPsiCompleted) { dprint(3, " pat and all pmt completed..\n"); } } } // ·çÇÁ Á¾·á Á¶°Ç.. tvct/cvct µÑ Áß¿¡ Çϳª¶û, psi°¡ ¼ö½Å(¶Ç´Â ¿¡·¯)µÇ¸é Á¾·á.. // if (bPsiCompleted && ((aProcData[MCTID_TVCT].id & PME_CNFM) || (aProcData[MCTID_CVCT].id & PME_CNFM))) { // VCT µÑ Áß Çϳª°¡ ¼ö½ÅµÇ¾úÀ¸¹Ç·Î OK.. // ÁÖÀÇ! pat´Â ¼ö½ÅÀÌ ¾ÈµÇ¾úÀ» ¼öµµ ÀÖ´Ù.. ±×·± °æ¿ì¶ó¸é patPtrÀÌ NULLÀÎ °æ¿ìÀÌ´Ù. dprint(2, "xVCT and PAT, %d tables received OK\n", nReceivedTable); break; } //--------------------- Ãë¼Ò Á¶°Ç üũ ------------------------- if (ckfn && ckfn(0)) { // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù. dprint(2, "!! download cancelled\n"); status = statusCancelled; break; } //--------------------- ŸÀÓ ¾Æ¿ô üũ ------------------------- if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { //status = statusTimeout; // ¿©·¯°³ÀÇ tableÀ» ¹Þ°í Àֱ⠶§¹®¿¡ °³°³ tableÀÇ timeoutÀº ¹«ÀǹÌ.. dprint(2, "!! timeout (%ds) err, only %d/%d tables received..\n", timeOut/1000, nReceivedTable, 3 + tbls->num_programs); break; } } // while CancelPsiMonitor: for (i=0; i<3; i++) { if (aPsiCtl[i]) { //dprint(3, " cancel psictl[%d]\n", i); DHL_PSI_StopMonitor(aPsiCtl[i]); nMonitors--; } } DHL_OS_Free((void**)&aPsiCtl); DHL_OS_Free((void**)&aProcData); for (i=0; aPsiCtlPmt && inum_programs; i++) { if (aPsiCtlPmt[i]) { //dprint(3, " cancel pmt psictl[%d]\n", i); DHL_PSI_StopMonitor(aPsiCtlPmt[i]); nMonitors--; } } if (nMonitors != 0) dprint(0, "!! final monitors number not zero, %d\n", nMonitors); if (aPsiCtlPmt) DHL_OS_Free((void**)&aPsiCtlPmt); if (aProcDataPmt) DHL_OS_Free((void**)&aProcDataPmt); if (sema4) DHL_OS_DeleteSemaphore(sema4); // cafrii 081210 add if (tbls->pmtList == NULL && (tbls->pat || tbls->num_programs)) { // valid pat while pmtList is null. // to avoid confusion, delete pat as if pat not received. dprint(0, "!! valid pat while null pmtlist. delete pat!\n"); if (tbls->pat) FreePAT(tbls->pat); tbls->pat = NULL; tbls->num_programs = 0; } return status; } #if 0 ___________() #endif STATUS Dmc_GetMultipleEITsEx(tDHL_TSD tsd, int nEit, UINT16 *aPID, UINT16 *aSourceID, eitPtr_t **aEitPtrPtr, int timeOut, BOOL (*chkfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL)) { // source_id´Â µ¿ÀÏÇϰí (°°Àº ÇÁ·Î±×·Ò) PID¸¸ ´Ù¸¥ (EIT-0, EIT-1, EIT-2, ...)À» µ¿½Ã ¼ö½ÅÇÒ ¼öµµ ÀÖ°í, // PID°¡ µ¿ÀÏÇϰí source_id°¡ ´Ù¸¥ (EIT-0 of multiple program)À» µ¿½Ã ¼ö½ÅÇÒ ¼öµµ ÀÖ´Ù. // Áï aEitPtr[0]ÀÌ EIT-0, aEitPtr[1]ÀÌ EIT-1À» ÀǹÌÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. ÁÖÀÇ¿ä¸Á.. // ¿äûÇÑ EIT¸¦ ¸ðµÎ ¹ÞÀ¸¸é success¸¦ ¸®ÅÏÇÑ´Ù. // Çϳª¶óµµ failÀÌ ³ª¸é (timeoutÀÌ µÇ¾ú°Ç, scramble error°¡ µÇ¾ú°Ç °£¿¡..) statusError¸¦ ¸®ÅÏÇÑ´Ù. // ÇöÀç ±¸Á¶»ó °¢°¢ÀÇ EIT¿¡ ´ëÇØ¼­ ¸®ÅϰªÀ» ÁÙ ¼ö°¡ ¾ø´Ù. // // aPID[x] °¡ 0À̸é request¸¦ ÇÏÁö ¾Ê´Â´Ù. // Áï nEit °¹¼ö¸¸Å­ÀÇ request°¡ µÇÁö ¾ÊÀ» ¼öµµ ÀÖ´Ù. // PSIMultiEventProcData *aProcData; tDHL_PSI_ControlHandle *aPsiCtl; DHL_OS_SEMA_ID sema4; int i, nReceivedEit, nGoodEit, nEitMonitor; UINT32 tickStart; BOOL bDownloadCancelled = FALSE; DHL_RESULT err = DHL_OK; // cafrii 060420 add default value, // in some case, CancelPsiMonitor reached without initializing this variable. STATUS returnStatus = statusOK; nGoodEit = nReceivedEit = 0; // cafrii 041105 move to here dprint(1, "Dmc_GetMultipleEitsEx(%d eit, timeout %d sec)\n", nEit, timeOut/1000); if (nEit <= 0 || aPID == NULL || aSourceID == NULL || aEitPtrPtr == NULL) { dprint(0, "!! Invalid Arguments, nEit %d, aPid %x, aSrcId %x, aEitPP %x\n", nEit, aPID, aSourceID, aEitPtrPtr); return statusInvalidArgument; } aPsiCtl = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(nEit * sizeof(tDHL_PSI_ControlHandle)); if (aPsiCtl == NULL) { dprint(0, "!! out of memory for PsiCtls..\n"); return statusOutOfMemory; } memset (aPsiCtl, 0, nEit * sizeof(tDHL_PSI_ControlHandle)); aProcData = (PSIMultiEventProcData *) DHL_OS_Malloc(nEit * sizeof(PSIMultiEventProcData)); if (aProcData == NULL) { dprint(0, "!! out of memory for ProcData..\n"); DHL_OS_Free((void**)&aPsiCtl); return statusOutOfMemory; } memset (aProcData, 0, nEit * sizeof(PSIMultiEventProcData)); // semaphoreÀº Çϳª¸¸ ¸¸µé¾î¼­ ¸ðµç ProcData¿¡ ¶È°°ÀÌ ³Ö¾îÁÖÀÚ. sema4 = DHL_OS_CreateCountingSemaphore("GetEITs", OS_SEM_FIFO, 0); if (!sema4) { DHL_OS_Free((void**)&aPsiCtl); DHL_OS_Free((void**)&aProcData); return statusOutOfMemory; } // Event report¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ÁغñÇÑ´Ù. for (i=0; i= 0x1FFF) { // cafrii 050315 add dprint(0, "!! Eit[%d] pid 0x%x invalid\n", i, aPID[i]); continue; } err = MonitorEit(tsd, aPID[i], aSourceID[i], ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[i], &aPsiCtl[i]); if (err) { dprint(0, "!! %d-th Eit monitor (pid %d, source %d) failed! err %d %s\n", i, aPID[i], aSourceID[i], err, ErrorString((DHL_RESULT)err)); //goto CancelPsiMonitor; // Áß°£¿¡ Monitor¿¡ ¼º°øÇÑ PsiCtlÀÌ ÀÖÀ» °ÍÀ̹ǷΠ±×³É ÇÔ¼ö ExitÇÏ¸é ¾ÈµÈ´Ù. if (!returnStatus) returnStatus = statusOutOfResource; // cafrii 070321 add comment // °£È¤ PSIPÀÌ À߸ø ¸¸µé¾îÁ®¼­ PES PID¿Í PSI PID¸¦ °ãÃļ­ ¸¸µé¾î ³õ´Â °æ¿ì°¡ ÀÖ¾ú´Ù. // ÀÌ ¿¡·¯ÀÇ °æ¿ì´Â skipÇÏ°í ´ÙÀ½ Monitor¸¦ ÁøÇàÇÑ´Ù. // if (err != DHL_FAIL_BUSY) // ÀÌ ¿¡·¯°¡ ³¯ °æ¿ì¿¡´Â ±×³É ´ÙÀ½ ¸ð´ÏÅÍ °è¼Ó ÁøÇà.. break; } else { nEitMonitor++; } } if (nEitMonitor == 0) goto CancelPsiMonitor; dprint(2, " %d monitor requested..\n", nEitMonitor); tickStart = DHL_OS_GetMsCount(); while (1) { // ÃÑ nEit °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù. // err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK); if (err == DHL_OK) { int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000; // unit: 0.01 sec //nReceivedEit++; // cafrii 070117 change policy!! // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù. for (i=0; isectPtr, aEitPtrPtr[i]); if (IsError(err)) // cafrii 050315 change { // Multiple EIT ¼ö½ÅÀÇ °æ¿ì °¢°¢ÀÇ EIT¿¡ ´ëÇØ ¿¡·¯ ¸®ÅÏÀ» ÇÒ ¼ö ¾ø´Ù. // ¿ÀÁ÷ EitPtr·Î¸¸ °á°ú¸¦ ¾Ë·ÁÁÙ ¼ö Àִµ¥, Parsing µµÁß¿¡ ¿¡·¯°¡ ³ªµµ EitPtrÀÌ Non-NullÀÏ ¼ö ÀÖ´Ù. // ÀÌ °æ¿ì ¸®ÅϵǴ EitPtrÀº FreeAtscTableµµ ÇØ¼­´Â ¾ÈµÈ´Ù. ¹Ù·Î NULL·Î ¸®¼ÂÇØ¹ö¸®ÀÚ. // dprint(0, "!! err in ParseEit of Eit-%d, err %d, %s\n", i, err, ErrorString((DHL_RESULT)err)); *(aEitPtrPtr[i]) = NULL; if (!returnStatus) returnStatus = statusPSIPError; } else { nGoodEit++; } // unlock eit ptr location if (lockfn) lockfn(FALSE); if (chkfn && chkfn(userparam, (UINT32) aEitPtrPtr[i])) { // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù. dprint(2, "!! download cancelled\n"); bDownloadCancelled = TRUE; break; } break; // Çѹø¿¡ Çϳª¾¿ Ç¥½Ã.. } if (bDownloadCancelled) break; if (i >= nEit) dprint(2, " Eit event received but no related eit!!\n"); else dprint(2, " Eit[%d] received (err %d) total %d, %d.%02d sec\n", i, aProcData[i].err, nReceivedEit, elapsedTime/100, elapsedTime%100); } if (chkfn && chkfn(userparam, 0)) { // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù. dprint(2, "!! download cancelled\n"); bDownloadCancelled = TRUE; break; } if (nReceivedEit >= nEitMonitor) { // ¸ðµç °ÍÀ» ´Ù ¼ö½ÅÇÏ¿´´Ù. dprint(2, "all %d tables are received\n", nReceivedEit); break; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { err = DHL_FAIL_TIMEOUT; // cafrii 060420 add // informs that timeout is occurred. dprint(2, "!! timeout (%ds) err, only %d/%d/%d Eits received..\n", timeOut/1000, nGoodEit, nReceivedEit, nEitMonitor); break; // ÀϺδ ¹Þ¾ÒÀ» °ÍÀ̹ǷΠ¾Æ·¡ Parsing ÀÛ¾÷À» °ÅÃÄ¾ß ÇÑ´Ù. } } CancelPsiMonitor: for (i=0; i0 ? statusTimeout : statusError; // ¼ö½Å ¿Ï·áÇÏÁö ¸øÇß´Ù´Â ÀǹÌÀÇ ¿¡·¯°¡ ¾øÀ½.. // cafrii 070712 bugfix // Eit monitor¸¦ Çϳªµµ ½ÃÀÛµµ ¸øÇÏ°í ¹Ù·Î Á¾·áÇÏ´Â °æ¿ì¶ó¸é timeout °á°ú¸¦ ÁÖ¸é ¾ÈµÈ´Ù. // ¹Ù·Î ´Ù½Ã Àç½Ãµµ¸¦ Çϱ⠶§¹®. } } return statusOK; // requestµÈ ¸ðµç EIT°¡ ¸ðµÎ Non-NULLÀÌ¸é ¼º°øÀ¸·Î ÇÏÀÚ.. } STATUS Dmc_GetMultipleEITs(tDHL_TSD tsd, int nEit, UINT16 *aPID, UINT16 *aSourceID, eitPtr_t *aEitPtr, int timeOut, BOOL (*chkfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL)) { // backward compatibile fnction.. // int i; STATUS status; eitPtr_t **eitPtrPtrArry = DHL_OS_Malloc(nEit * sizeof(eitPtr_t *)); if (eitPtrPtrArry == NULL) return statusOutOfMemory; memset (eitPtrPtrArry, 0, nEit * sizeof(eitPtr_t *)); for (i=0; i= 0x1FFF) { // cafrii 050315 change dprint(0, "!! ett[%d] pid 0x%x invalid..\n", i, aEttPID[i]); continue; } // ett´Â Ç×»ó SectionMode·Î µ¿ÀÛÇϱ⠶§¹®¿¡ (Table Àüü¸¦ ¹Þ´Â°Ô Àǹ̰¡ ¾ø´Ù) PSIMode ÀÎÀÚ°¡ ¾øÀ½. err = MonitorEtt(tsd, aEttPID[i], aETMID[i], ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[i], &aPsiCtl[i]); if (err) { dprint(0, "!! %d-th Ett monitor (pid %d, etm 0x%x) failed! err %d %s\n", i, aEttPID[i], aETMID[i], err, ErrorString((DHL_RESULT)err)); if (!returnStatus) returnStatus = statusOutOfResource; if (err != DHL_FAIL_BUSY) // cafrii 041105 add condition break; } else { //dprint(3, " (%d) monitor pid %x etm %x, psiCtl %x\n", i, aEttPID[i], aETMID[i], aPsiCtl[i]); nEttMonitor++; } } if (nEttMonitor == 0) goto CancelPsiMonitor; dprint(2, " %d monitor requested..\n", nEttMonitor); tickStart = DHL_OS_GetMsCount(); while (1) { // ÃÑ nETT °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù. // err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK); if (err == DHL_OK) { int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000; // unit: 0.01 sec //nReceivedEtt++; // cafrii 070117 change policy!! // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù. for (i=0; isectPtr[0], aEttPtrPtr[i]); if (IsError(err)) // cafrii 050315 change { // Multiple ETT ¼ö½ÅÀÇ °æ¿ì °¢°¢ÀÇ ETT¿¡ ´ëÇØ ¿¡·¯ ¸®ÅÏÀ» ÇÒ ¼ö ¾ø´Ù. // ¿ÀÁ÷ EttSectPtr·Î¸¸ °á°ú¸¦ ¾Ë·ÁÁÙ ¼ö Àִµ¥, Parsing µµÁß¿¡ ¿¡·¯°¡ ³ªµµ EttSectPtrÀÌ Non-NullÀÏ ¼ö ÀÖ´Ù. // ÀÌ °æ¿ì ¸®ÅϵǴ EttSectPtrÀº FreeAtscTableµµ ÇØ¼­´Â ¾ÈµÈ´Ù. ¹Ù·Î NULL·Î ¸®¼ÂÇØ¹ö¸®ÀÚ. // dprint(0, "!! err in ParseEttSection, err %d, %s\n", err, ErrorString((DHL_RESULT)err)); *(aEttPtrPtr[i]) = NULL; if (!returnStatus) returnStatus = statusPSIPError; } else { nGoodEtt++; //dprint(3, " --> ett[%d]: [%x]=%x\n", i, aEttPtrPtr[i], *(aEttPtrPtr[i])); } // unlock eit ptr location if (lockfn) lockfn(FALSE); if (ckfn && ckfn(userparam, (UINT32) aEttPtrPtr[i])) { // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù. dprint(2, "!! download cancelled\n"); bDownloadCancelled = TRUE; break; } break; // Çѹø¿¡ Çϳª¾¿ Ç¥½Ã.. } if (bDownloadCancelled) break; if (i >= nETT) dprint(2, " Ett event received but no related ett!!\n"); else dprint(2, " Ett[%d] received (err %d) total %d, %d.%02d sec\n", i, aProcData[i].err, nReceivedEtt, elapsedTime/100, elapsedTime%100); } if (ckfn && ckfn(userparam, 0)) { // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù. dprint(2, "!! download cancelled\n"); bDownloadCancelled = TRUE; break; } if (nReceivedEtt >= nEttMonitor) { // ¸ðµç °ÍÀ» ´Ù ¼ö½ÅÇÏ¿´´Ù. dprint(2, "all %d etts are received!!\n", nReceivedEtt); break; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { // ÀÌ ÇÔ¼ö¿¡¼­ timeout ¸®ÅϰªÀº ¾øÀ½.. //err = statusTimeout; dprint(2, "!! timeout (%ds) err, only %d/%d/%d Etts received..\n", timeOut/1000, nGoodEtt, nReceivedEtt, nEttMonitor); break; // ÀϺδ ¹Þ¾ÒÀ» °ÍÀ̹ǷΠ¾Æ·¡ Parsing ÀÛ¾÷À» °ÅÃÄ¾ß ÇÑ´Ù. } } CancelPsiMonitor: for (i=0; i0 ? statusTimeout : statusError; // ¼ö½Å ¿Ï·áÇÏÁö ¸øÇß´Ù´Â ÀǹÌÀÇ ¿¡·¯°¡ ¾øÀ½.. // cafrii 070712 bugfix // Ett monitor¸¦ Çϳªµµ ½ÃÀÛµµ ¸øÇÏ°í ¹Ù·Î Á¾·áÇÏ´Â °æ¿ì¶ó¸é timeout °á°ú¸¦ ÁÖ¸é ¾ÈµÈ´Ù. // ¹Ù·Î ´Ù½Ã Àç½Ãµµ¸¦ Çϱ⠶§¹®. } } return statusOK; // requestµÈ ¸ðµç EIT°¡ ¸ðµÎ Non-NULLÀÌ¸é ¼º°øÀ¸·Î ÇÏÀÚ.. } STATUS Dmc_GetMultipleETTs(tDHL_TSD tsd, int nETT, UINT16 *aEttPID, UINT32 *aETMID, ettSectionPtr_t *aEttSectPtr, int timeOut, BOOL (*ckfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL)) { // backward compatibile fnction.. // int i; STATUS status; ettSectionPtr_t **ettPtrPtrArry = DHL_OS_Malloc(nETT * sizeof(ettSectionPtr_t *)); if (ettPtrPtrArry == NULL) return statusOutOfMemory; memset (ettPtrPtrArry, 0, nETT * sizeof(ettSectionPtr_t *)); for (i=0; i= gMaxTableMonitorsAtOneTime) { dprint(2, "\t max %d tables monitored. next idxMon: %d\n", nEitMonitor, idxMon); break; } if (aPID[idxMon] == 0) { // PID¸¦ 0À¸·Î ÁöÁ¤Çϸé skip Ç϶ó´Â ÀÇ¹Ì·Î ÇØ¼®. ¿¡·¯°¡ ¾Æ´Ï´Ù. dprint(3, "\t NULL PID in eit[%d]..\n", idxMon); continue; } if (aPID[idxMon] <= 0 || aPID[idxMon] >= 0x1FFF) { // cafrii 050315 add dprint(0, "!! eit[%d] pid 0x%x invalid\n", idxMon, aPID[idxMon]); continue; } if (aEitPtrPtr[idxMon] == NULL) { dprint(0, "!! output eit ptr NULL.. skip eit[%d]\n", idxMon); continue; } err = MonitorEit(tsd, aPID[idxMon], aSourceID[idxMon], ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[idxMon], &aPsiCtl[idxMon]); if (err) { dprint(0, "!! %d-th Eit monitor (pid %d, source %d) failed! err %d %s\n", idxMon, aPID[idxMon], aSourceID[idxMon], err, ErrorString((DHL_RESULT)err)); if (!returnStatus) returnStatus = statusOutOfResource; // ¿¡·¯°¡ ³ª´Â ÁÖ¿ä ¿øÀÎÀº ½Ã½ºÅÛÀÇ °¡¿ë ¸®¼Ò½º°¡ ºÎÁ·ÇÑ °æ¿ìÀÌ´Ù. // ÃÖ´ë·Î »ç¿ë °¡´ÉÇÑ monitor°¹¼ö¸¦ ÃʰúÇ߱⠶§¹®.. // ÀÌ·± °æ¿ì °è¼Ó monitor ÇØºÃÀÚ µ¿ÀÏÇÑ ¿¡·¯°¡ ¹ß»ýÇÑ´Ù. // ÇöÀç±îÁö ¼º°øÇÑ Monitor¸¸ÀÌ¶óµµ ÁøÇàÇϱâ À§ÇØ ¿©±â¼­ ³ª°£´Ù. if (err != DHL_FAIL_BUSY) // cafrii 041105 add condition { // DHL_FAIL_BUSYÀÇ ¸Þ½ÃÁö´Â ÇØ´ç PID°¡ PES ¸ðµå·Î ÀÌ¹Ì »ç¿ëÁßÀ϶§ ¹ß»ýÇÑ´Ù. // ÀÌ´Â application¿¡¼­ ÀÌÀü ä³ÎÀÇ audio, video¸¦ Á¦´ë·Î stop ÇÏÁö ¾Ê¾Ò°Å³ª, // PSIP generatorÀÇ ¿Àµ¿ÀÛ µîÀÌ ÀÌÀ¯ÀÌ´Ù. (av pid¿Í Eit pid¸¦ °°°Ô »ç¿ë?) // ¹®Á¦°¡ µÇ´Â TableÀ» Á¦¿ÜÇÏ°í °è¼Ó ÁøÇàÇϵµ·Ï ÇÑ´Ù. ´Ù¸¥ tableÀº ±¦ÂúÀ» ¼ö ÀÖÀ¸¹Ç·Î.. // // Âü°í·Î PSI monitor´Â µ¿ÀÏÇÑ ¸ð´ÏÅ͸¦ °è¼Ó °É¾îµµ Àý´ë·Î DHL_FAIL_BUSY´Â ¾È³­´Ù. // ¸ðµÎ µ¶¸³ÀûÀÎ ¸ð´ÏÅÍ·Î °£ÁֵDZ⠶§¹®. // °è¼Ó °É´Ù º¸¸é Prefilter ºÎÁ·, DOB ºÎÁ· µîÀÇ ¸Þ½ÃÁö°¡ ¹ß»ýÇÒ °ÍÀÓ. break; } } else { //dprint(3, " (%d) monitor pid %x source_id %x, psiCtl %x\n", // idxMon, aPID[idxMon], aSourceID[idxMon], aPsiCtl[idxMon]); nEitMonitor++; } } if (nEitMonitor == 0) goto CancelPsiMonitor; dprint(2, " %d monitor requested..\n", nEitMonitor); tickStart = DHL_OS_GetMsCount(); while (1) { // ÃÑ nEit °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù. // err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK); if (err == DHL_OK) { int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000; // unit: 0.01 sec //nReceivedEit++; // cafrii 070117 change policy!! // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù. for (i=0; i parse Eit[%d] to loc 0x%x\n", i, aEitPtrPtr[i]); err = ParseEit(aProcData[i].desc->sectPtr, aEitPtrPtr[i]); if (IsError(err)) // cafrii 050315 change { // Multiple EIT ¼ö½ÅÀÇ °æ¿ì °¢°¢ÀÇ EIT¿¡ ´ëÇØ ¿¡·¯ ¸®ÅÏÀ» ÇÒ ¼ö ¾ø´Ù. // ¿ÀÁ÷ EitPtr·Î¸¸ °á°ú¸¦ ¾Ë·ÁÁÙ ¼ö Àִµ¥, Parsing µµÁß¿¡ ¿¡·¯°¡ ³ªµµ EitPtrÀÌ Non-NullÀÏ ¼ö ÀÖ´Ù. // ÀÌ °æ¿ì ¸®ÅϵǴ EitPtrÀº FreeAtscTableµµ ÇØ¼­´Â ¾ÈµÈ´Ù. ¹Ù·Î NULL·Î ¸®¼ÂÇØ¹ö¸®ÀÚ. // dprint(0, "!! err in ParseEit of Eit-%d, err %d, %s\n", i, err, ErrorString((DHL_RESULT)err)); *(aEitPtrPtr[i]) = NULL; if (!returnStatus) returnStatus = statusPSIPError; } else { nGoodEit++; } // unlock eit ptr location if (lockfn) lockfn(FALSE); // »ç¿ëÀÌ ³¡³­ ¸®¼Ò½º´Â ¹Ù·Î¹Ù·Î ÇØÁ¦ÇÑ´Ù. // DHL_PSI_FreePSIData(aProcData[i].desc); // parsingÀÌ ³¡³µ±â ¶§¹®¿¡ ÀÌ desc µ¥ÀÌÅÍ´Â ºÒÇÊ¿äÇÏ´Ù. aProcData[i].desc = NULL; //dprint(3, "\t\t aProcData[%d] freed\n", i); if (aPsiCtl[i]) { DHL_PSI_StopMonitor(aPsiCtl[i]); //dprint(3, "\t\t aPsiCtl[%d] freed\n", i); } else dprint(0, "!! PsiCtl[%d] NULL but event notified!\n", i); aPsiCtl[i] = (tDHL_PSI_ControlHandle)0; // ÀÌÁ¦ »õ·Î¿î ¸ð´ÏÅ͸¦ ´Ù½Ã ½ÃÀÛÇÑ´Ù. ÇѰ³¸¸ Ãß°¡·Î ½ÃÀÛÇÏ¸é µÈ´Ù. // for (; idxMon= 0x1FFF) { // cafrii 050315 add dprint(0, "!! Eit[%d] pid 0x%x invalid\n", idxMon, aPID[idxMon]); continue; } if (aEitPtrPtr[idxMon] == NULL) { dprint(0, "!! Eit[%d] output ptr NULL\n", idxMon); continue; } err = MonitorEit(tsd, aPID[idxMon], aSourceID[idxMon], ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[idxMon], &aPsiCtl[idxMon]); if (err) { dprint(0, "!! %d-th Eit monitor (pid %d, source %d) failed! err %d %s\n", idxMon, aPID[idxMon], aSourceID[idxMon], err, ErrorString((DHL_RESULT)err)); if (!returnStatus) returnStatus = statusOutOfResource; // À̰÷Àº table ÀÌ Çϳª¾¿ ¹Þ¾ÆÁú¶§¸¶´Ù relay·Î monitor¸¦ °Å´Â °÷Àε¥, // monitor¿¡¼­ ¿¡·¯°¡ ¹ß»ýÇÒ °æ¿ì, À̸¦ ¹æÁöÇÏ´Â ·ÎÁ÷ÀÌ ¾ÆÁ÷ ¾ø´Ù. // º¸Åë Çѹø ¿¡·¯°¡ ³ª¸é °è¼Ó ¿¡·¯°¡ ³¯ °ÍÀÌ´Ù. if (err != DHL_FAIL_BUSY) // cafrii 041105 add condition break; } else { dprint(2, "\t relayed monitor %d-th Eit ok\n", idxMon); nEitMonitor++; idxMon++; } break; // Çϳª¸¸ ¸ð´ÏÅÍ ÇÏ°í ³ª°¡¸é µÈ´Ù. } // Eit[i]¿¡ °üÇÑ ¸ðµç ÀÛ¾÷ÀÌ ³¡³µ´Ù. cancel ¿©ºÎ¸¦ °Ë»çÇÏ°í ´ÙÀ½ Eit·Î ³Ñ¾î°¨.. // if (chkfn && chkfn(userparam, (UINT32) aEitPtrPtr[i])) { // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù. dprint(2, "!! download cancelled\n"); bDownloadCancelled = TRUE; break; } break; // Çѹø¿¡ Çϳª¾¿ Ç¥½Ã.. } // for all Eits.. if (bDownloadCancelled) break; if (i >= nEit) dprint(2, " Eit event received but no related eit!!\n"); else dprint(2, " Eit[%d] received (err %d) total %d, %d.%02d sec\n", i, aProcData[i].err, nReceivedEit, elapsedTime/100, elapsedTime%100); } // end if semaphore taken.. if (chkfn && chkfn(userparam, 0)) { // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù. dprint(2, "!! download cancelled\n"); bDownloadCancelled = TRUE; break; } if (nReceivedEit >= nEitMonitor) { // ¸ðµç °ÍÀ» ´Ù ¼ö½ÅÇÏ¿´´Ù. dprint(2, "all %d tables are received\n", nReceivedEit); break; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { err = DHL_FAIL_TIMEOUT; // cafrii 060420 add // informs that timeout is occurred. dprint(2, "!! timeout (%ds) err, only %d/%d/%d Eits received..\n", timeOut/1000, nGoodEit, nReceivedEit, nEitMonitor); break; // ÀϺδ ¹Þ¾ÒÀ» °ÍÀ̹ǷΠ¾Æ·¡ Parsing ÀÛ¾÷À» °ÅÃÄ¾ß ÇÑ´Ù. } } CancelPsiMonitor: // Á¤»óÀûÀ¸·Î Á¾·áµÇ¾ú´Ù¸é À̰÷¿¡¼­ freeµÇ´Â °ÍÀº Çϳªµµ ¾ø¾î¾ß ÇÑ´Ù. // ±×·¯³ª timeoutÀ̳ª user cancelÀÌ µÇ¾ú´Ù¸é ÇöÀç ÁøÇàÁßÀÎ °ÍµéÀÌ ÀÖÀ» °ÍÀ̹ǷΠÀ̰÷¿¡¼­ »èÁ¦ÇØ¾ß ÇÑ´Ù. // for (i=0; i0 ? statusTimeout : statusError; // ¼ö½Å ¿Ï·áÇÏÁö ¸øÇß´Ù´Â ÀǹÌÀÇ ¿¡·¯°¡ ¾øÀ½.. // cafrii 070712 bugfix // Eit monitor¸¦ Çϳªµµ ½ÃÀÛµµ ¸øÇÏ°í ¹Ù·Î Á¾·áÇÏ´Â °æ¿ì¶ó¸é timeout °á°ú¸¦ ÁÖ¸é ¾ÈµÈ´Ù. // ¹Ù·Î ´Ù½Ã Àç½Ãµµ¸¦ Çϱ⠶§¹®. } } return statusOK; // requestµÈ ¸ðµç EIT°¡ ¸ðµÎ Non-NULLÀÌ¸é ¼º°øÀ¸·Î ÇÏÀÚ.. } STATUS Dmc_GetRelayEITs(tDHL_TSD tsd, int nEit, UINT16 *aPID, UINT16 *aSourceID, eitPtr_t *aEitPtr, int timeOut, BOOL (*chkfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL)) { // backward compatibile fnction.. // int i; STATUS status; eitPtr_t **eitPtrPtrArry = DHL_OS_Malloc(nEit * sizeof(eitPtr_t *)); if (eitPtrPtrArry == NULL) return statusOutOfMemory; memset (eitPtrPtrArry, 0, nEit * sizeof(eitPtr_t *)); for (i=0; i= gMaxTableMonitorsAtOneTime) { dprint(2, "\t maax %d tables monitored. next idxMon: %d\n", nEttMonitor, idxMon); break; } if (aEttPID[idxMon] == 0) { dprint(3, "\t NULL PID in ett[%d]..\n", idxMon); continue; } if (aEttPID[idxMon] <= 0 || aEttPID[idxMon] >= 0x1FFF) { // cafrii 050315 add dprint(0, "!! ett[%d] pid 0x%x invalid\n", idxMon, aEttPID[idxMon]); continue; } if (aEttPtrPtr[idxMon] == NULL) { dprint(0, "!! output ett ptr NULL.. skip ett[%d]\n", idxMon); continue; } // ett´Â Ç×»ó SectionMode·Î µ¿ÀÛÇϱ⠶§¹®¿¡ (Table Àüü¸¦ ¹Þ´Â°Ô Àǹ̰¡ ¾ø´Ù) PSIMode ÀÎÀÚ°¡ ¾øÀ½. err = MonitorEtt(tsd, aEttPID[idxMon], aETMID[idxMon], ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[idxMon], &aPsiCtl[idxMon]); if (err) { dprint(0, "!! %d-th Ett monitor (pid %d, etm 0x%x) failed! err %d %s\n", idxMon, aEttPID[idxMon], aETMID[idxMon], err, ErrorString((DHL_RESULT)err)); if (!returnStatus) returnStatus = statusOutOfResource; if (err != DHL_FAIL_BUSY) // cafrii 041105 add condition break; } else { //dprint(3, " (%d) monitor pid %x etm %x, psiCtl %x\n", // idxMon, aEttPID[idxMon], aETMID[idxMon], aPsiCtl[idxMon]); nEttMonitor++; } } if (nEttMonitor == 0) goto CancelPsiMonitor; dprint(2, " %d monitor requested..\n", nEttMonitor); tickStart = DHL_OS_GetMsCount(); while (1) { // ÃÑ nETT °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù. // err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK); if (err == DHL_OK) { int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000; // unit: 0.01 sec //nReceivedEtt++; // cafrii 070117 change policy!! // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù. for (i=0; isectPtr[0], aEttPtrPtr[i]); if (IsError(err)) // cafrii 050315 change { // Multiple ETT ¼ö½ÅÀÇ °æ¿ì °¢°¢ÀÇ ETT¿¡ ´ëÇØ ¿¡·¯ ¸®ÅÏÀ» ÇÒ ¼ö ¾ø´Ù. // ¿ÀÁ÷ EttSectPtr·Î¸¸ °á°ú¸¦ ¾Ë·ÁÁÙ ¼ö Àִµ¥, Parsing µµÁß¿¡ ¿¡·¯°¡ ³ªµµ EttSectPtrÀÌ Non-NullÀÏ ¼ö ÀÖ´Ù. // ÀÌ °æ¿ì ¸®ÅϵǴ EttSectPtrÀº FreeAtscTableµµ ÇØ¼­´Â ¾ÈµÈ´Ù. ¹Ù·Î NULL·Î ¸®¼ÂÇØ¹ö¸®ÀÚ. // dprint(0, "!! err in ParseEttSection, err %d, %s\n", err, ErrorString((DHL_RESULT)err)); *(aEttPtrPtr[i]) = NULL; if (!returnStatus) returnStatus = statusPSIPError; } else { nGoodEtt++; //dprint(3, " --> ett[%d]: [%x]=%x\n", i, aEttPtrPtr[i], *(aEttPtrPtr[i])); } // unlock eit ptr location if (lockfn) lockfn(FALSE); // »ç¿ëÀÌ ³¡³­ ¸®¼Ò½º´Â ¹Ù·Î¹Ù·Î ÇØÁ¦ÇÑ´Ù. // DHL_PSI_FreePSIData(aProcData[i].desc); // parsingÀÌ ³¡³µ±â ¶§¹®¿¡ ÀÌ desc µ¥ÀÌÅÍ´Â ºÒÇÊ¿äÇÏ´Ù. aProcData[i].desc = NULL; //dprint(3, "\t\t aProcData[%d] freed\n", i); if (aPsiCtl[i]) { DHL_PSI_StopMonitor(aPsiCtl[i]); //dprint(3, "\t\t aPsiCtl[%d] freed\n", i); } else dprint(0, "!! PsiCtl[%d] NULL but event notified!\n", i); aPsiCtl[i] = (tDHL_PSI_ControlHandle)0; // ÀÌÁ¦ »õ·Î¿î ¸ð´ÏÅ͸¦ ´Ù½Ã ½ÃÀÛÇÑ´Ù. ÇѰ³¸¸ Ãß°¡·Î ½ÃÀÛÇÏ¸é µÈ´Ù. // for (; idxMon= 0x1FFF) { // cafrii 050315 add dprint(0, "!! Ett[%d] pid 0x%x invalid\n", idxMon, aEttPID[idxMon]); continue; } if (aEttPtrPtr[idxMon] == NULL) { dprint(0, "!! Ett[%d] output ptr NULL\n", idxMon); continue; } err = MonitorEtt(tsd, aEttPID[idxMon], aETMID[idxMon], ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[idxMon], &aPsiCtl[idxMon]); if (err) { dprint(0, "!! %d-th Ett monitor (pid %d, etm 0x%x) failed! err %d %s\n", idxMon, aEttPID[idxMon], aETMID[idxMon], err, ErrorString((DHL_RESULT)err)); if (!returnStatus) returnStatus = statusOutOfResource; if (err != DHL_FAIL_BUSY) // cafrii 041105 add condition break; } else { dprint(2, "\t relayed monitor %d-th Ett ok\n", idxMon); nEttMonitor++; idxMon++; } break; // Çϳª¸¸ ¸ð´ÏÅÍ ÇÏ°í ³ª°¡¸é µÈ´Ù. } // Ett[i]¿¡ °üÇÑ ¸ðµç ÀÛ¾÷ÀÌ ³¡³µ´Ù. cancel ¿©ºÎ¸¦ °Ë»çÇÏ°í ´ÙÀ½ Eit·Î ³Ñ¾î°¨.. // if (ckfn && ckfn(userparam, (UINT32) aEttPtrPtr[i])) { // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù. dprint(2, "!! download cancelled\n"); bDownloadCancelled = TRUE; break; } break; // Çѹø¿¡ Çϳª¾¿ Ç¥½Ã.. } // for all Etts.. if (bDownloadCancelled) break; if (i >= nETT) dprint(2, " Ett event received but no related ett!!\n"); else dprint(2, " Ett[%d] received (err %d) total %d, %d.%02d sec\n", i, aProcData[i].err, nReceivedEtt, elapsedTime/100, elapsedTime%100); }// end if semaphore taken.. if (ckfn && ckfn(userparam, 0)) { // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù. dprint(2, "!! download cancelled\n"); bDownloadCancelled = TRUE; break; } if (nReceivedEtt >= nEttMonitor) { // ¸ðµç °ÍÀ» ´Ù ¼ö½ÅÇÏ¿´´Ù. dprint(2, "all %d etts are received!!\n", nReceivedEtt); break; } if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) { err = DHL_FAIL_TIMEOUT; // cafrii 060420 add // informs that timeout is occurred. dprint(2, "!! timeout (%ds) err, only %d/%d/%d Etts received..\n", timeOut/1000, nGoodEtt, nReceivedEtt, nEttMonitor); break; // ÀϺδ ¹Þ¾ÒÀ» °ÍÀ̹ǷΠ¾Æ·¡ Parsing ÀÛ¾÷À» °ÅÃÄ¾ß ÇÑ´Ù. } } CancelPsiMonitor: // Á¤»óÀûÀ¸·Î Á¾·áµÇ¾ú´Ù¸é À̰÷¿¡¼­ freeµÇ´Â °ÍÀº Çϳªµµ ¾ø¾î¾ß ÇÑ´Ù. // ±×·¯³ª timeoutÀ̳ª user cancelÀÌ µÇ¾ú´Ù¸é ÇöÀç ÁøÇàÁßÀÎ °ÍµéÀÌ ÀÖÀ» °ÍÀ̹ǷΠÀ̰÷¿¡¼­ »èÁ¦ÇØ¾ß ÇÑ´Ù. // for (i=0; i0 ? statusTimeout : statusError; // ¼ö½Å ¿Ï·áÇÏÁö ¸øÇß´Ù´Â ÀǹÌÀÇ ¿¡·¯°¡ ¾øÀ½.. // cafrii 070712 bugfix // Ett monitor¸¦ Çϳªµµ ½ÃÀÛµµ ¸øÇÏ°í ¹Ù·Î Á¾·áÇÏ´Â °æ¿ì¶ó¸é timeout °á°ú¸¦ ÁÖ¸é ¾ÈµÈ´Ù. // ¹Ù·Î ´Ù½Ã Àç½Ãµµ¸¦ Çϱ⠶§¹®. } } return statusOK; // requestµÈ ¸ðµç EIT°¡ ¸ðµÎ Non-NULLÀÌ¸é ¼º°øÀ¸·Î ÇÏÀÚ.. } STATUS Dmc_GetRelayETTs(tDHL_TSD tsd, int nETT, UINT16 *aEttPID, UINT32 *aETMID, ettSectionPtr_t *aEttSectPtr, int timeOut, BOOL (*ckfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL)) { // backward compatibile fnction.. // int i; STATUS status; ettSectionPtr_t **ettPtrPtrArry = DHL_OS_Malloc(nETT * sizeof(ettSectionPtr_t *)); if (ettPtrPtrArry == NULL) return statusOutOfMemory; memset (ettPtrPtrArry, 0, nETT * sizeof(ettSectionPtr_t *)); for (i=0; itables_defined; i++) // search all tables.. { int index; if (mgt->table[i].table_type >= tt_EIT_min && mgt->table[i].table_type <= tt_EIT_max) { index = (mgt->table[i].table_type - tt_EIT_min); aPID[index] = mgt->table[i].table_type_PID; aSourceID[index] = source_id; DHL_OS_Printf(" [%d] Eit-%d : pid %d\n", nEit, index, aPID[index]); nEit++; } } DHL_OS_Printf("total %d Eits detected..\n", nEit); if (nEit > 0) { err = Dmc_GetRelayEITs(tsd, nEit, aPID, aSourceID, aEit, timeOut, NULL, 0, NULL); if (err) { DHL_OS_Printf("!! err in getting relayed eits..\n"); } else { for (i=0; inumChannels; //for (i=0; inumChannels = numChannels; // allocate space in xvct for channels (*xvctPtr)->channel = (xvctChannelPtr_t)memChainAlloc(memId,numChannels*sizeof(xvctChannel_t)); checkMemoryError((*xvctPtr)->channel); (*xvctPtr)->is_cvct = (vct_type_k)TRUE; // cafrii 041130 move position (*xvctPtr)->transport_stream_id = cvctPtr->transport_stream_id; (*xvctPtr)->version_number = cvctPtr->version_number; // allocate space for descriptors and copy (if any) if (cvctPtr->additional_descriptor_length > 0) { (*xvctPtr)->additional_descriptors = (UINT8 *)memChainAlloc(memId,cvctPtr->additional_descriptor_length*sizeof(UINT8)); if ((*xvctPtr)->additional_descriptors == NULL) { status = statusOutOfMemory; // cafrii 050713 add goto ParseExit; } memcpy((*xvctPtr)->additional_descriptors,cvctPtr->additional_descriptors, (*xvctPtr)->additional_descriptor_length); } for (i=0; ichannel[i]; xvctChannelPtr_t xvctChannel = &(*xvctPtr)->channel[i]; memcpy(xvctChannel->short_name, cvctChannel->short_name, sizeof(UINT16)*7); xvctChannel->major_channel_number = cvctChannel->major_channel_number; xvctChannel->minor_channel_number = cvctChannel->minor_channel_number; xvctChannel->modulation_mode = cvctChannel->modulation_mode; xvctChannel->carrier_frequency = cvctChannel->carrier_frequency; xvctChannel->channel_TSID = cvctChannel->channel_TSID; xvctChannel->program_number = cvctChannel->program_number; xvctChannel->ETM_location = cvctChannel->ETM_location; xvctChannel->access_controlled = cvctChannel->access_controlled; xvctChannel->hidden = cvctChannel->hidden; //xvctChannel->is_cvct = TRUE; // if cvct.. xvctChannel->path_select = cvctChannel->path_select; xvctChannel->out_of_band = cvctChannel->out_of_band; xvctChannel->show_guide = cvctChannel->show_guide; xvctChannel->service_type = cvctChannel->service_type; xvctChannel->source_id = cvctChannel->source_id; // allocate space for descriptors and copy (if any) if (cvctChannel->descriptor_length > 0) { xvctChannel->descriptors = (UINT8 *)memChainAlloc(memId,cvctChannel->descriptor_length*sizeof(UINT8)); if (xvctChannel->descriptors == NULL) { status = statusOutOfMemory; // cafrii 050713 add goto ParseExit; } memcpy(xvctChannel->descriptors, cvctChannel->descriptors, cvctChannel->descriptor_length); xvctChannel->descriptor_length = cvctChannel->descriptor_length; } else { xvctChannel->descriptors = NULL; xvctChannel->descriptor_length = 0; } } // parsing complete *(((memId_t *)(*xvctPtr))-1) = memId; memId = NULL; // so memChain not deleted ParseExit: if (memId) { // delete the xvct memory memChainDestroy(memId); } return status; } /*============================================================================== STATUS Dmc_TranslateTvct (tvctPtr_t tvctPtr, xvctPtr_t *xvctPtr) Translate TVCT into General XVCT structure and return its pointer ==============================================================================*/ STATUS Dmc_TranslateTvct (tvctPtr_t tvctPtr, xvctPtr_t *xvctPtr) { UINT16 numChannels; UINT16 i; memChainSetup_t memSetup = {MEM_LIMIT,NULL,NULL}; memId_t memId = NULL; DHL_RESULT err; STATUS status = statusOK; if (tvctPtr == NULL) return statusInvalidArgument; // create the memChain err = memChainCreate(&memId,&memSetup); if (err) { status = statusOutOfMemory; goto ParseExit; } // allocate memory for tvct *xvctPtr = (xvctPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(xvct_t)+sizeof(memId_t))) + 1); checkMemoryError(*xvctPtr); // Get the total number of channels in all sections numChannels = tvctPtr->numChannels; //for (i=0; inumChannels = numChannels; // allocate space in xvct for channels (*xvctPtr)->channel = (xvctChannelPtr_t)memChainAlloc(memId,numChannels*sizeof(xvctChannel_t)); checkMemoryError((*xvctPtr)->channel); (*xvctPtr)->is_cvct = (vct_type_k)FALSE; // cafrii 041130 move position (*xvctPtr)->transport_stream_id = tvctPtr->transport_stream_id; (*xvctPtr)->version_number = tvctPtr->version_number; // allocate space for descriptors and copy (if any) if (tvctPtr->additional_descriptor_length > 0) { (*xvctPtr)->additional_descriptors = (UINT8 *)memChainAlloc(memId,tvctPtr->additional_descriptor_length*sizeof(UINT8)); if ((*xvctPtr)->additional_descriptors == NULL) { status = statusOutOfMemory; // cafrii 050713 add goto ParseExit; } memcpy((*xvctPtr)->additional_descriptors,tvctPtr->additional_descriptors, (*xvctPtr)->additional_descriptor_length); } for (i=0; ichannel[i]; xvctChannelPtr_t xvctChannel = &(*xvctPtr)->channel[i]; memcpy(xvctChannel->short_name, tvctChannel->short_name, sizeof(UINT16)*7); xvctChannel->major_channel_number = tvctChannel->major_channel_number; xvctChannel->minor_channel_number = tvctChannel->minor_channel_number; xvctChannel->modulation_mode = tvctChannel->modulation_mode; xvctChannel->carrier_frequency = tvctChannel->carrier_frequency; xvctChannel->channel_TSID = tvctChannel->channel_TSID; xvctChannel->program_number = tvctChannel->program_number; xvctChannel->ETM_location = tvctChannel->ETM_location; xvctChannel->access_controlled = tvctChannel->access_controlled; xvctChannel->hidden = tvctChannel->hidden; //xvctChannel->is_cvct = FALSE; // this is tvct.. xvctChannel->path_select = (path_select_k)0; xvctChannel->out_of_band = 0; xvctChannel->show_guide = tvctChannel->show_guide; xvctChannel->service_type = tvctChannel->service_type; xvctChannel->source_id = tvctChannel->source_id; // allocate space for descriptors and copy (if any) if (tvctChannel->descriptor_length > 0) { xvctChannel->descriptors = (UINT8 *)memChainAlloc(memId,tvctChannel->descriptor_length*sizeof(UINT8)); if (xvctChannel->descriptors == NULL) { status = statusOutOfMemory; // cafrii 050713 add goto ParseExit; } memcpy(xvctChannel->descriptors, tvctChannel->descriptors, tvctChannel->descriptor_length); xvctChannel->descriptor_length = tvctChannel->descriptor_length; } else { xvctChannel->descriptors = NULL; xvctChannel->descriptor_length = 0; } } // parsing complete *(((memId_t *)(*xvctPtr))-1) = memId; memId = NULL; // so memChain not deleted ParseExit: if (memId) { // delete the xvct memory memChainDestroy(memId); } return status; } void TestTranslateTvct(tvctPtr_t tvct, int number) { int err, i; xvctPtr_t xvct; if (tvct == NULL) return; if (number == 0) number = 10; for (i=0; iis_cvct ? "CVCT" : "TVCT"); DHL_OS_Printf("transport_stream_id: 0x%04X (%d)\n",(int)xvctPtr->transport_stream_id,(int)xvctPtr->transport_stream_id); DHL_OS_Printf("version_number: %d\n", (int)xvctPtr->version_number); DHL_OS_Printf("numChannels:%d\n", (int)xvctPtr->numChannels); for (i=0; inumChannels; i++) { DHL_OS_Printf("channel[%d]:\n", i); DHL_OS_Printf("\tshort_name: "); for (j=0; (j<7) && (xvctPtr->channel[i].short_name[j] != 0x0000); j++) { if ((xvctPtr->channel[i].short_name[j] >> 8) == 0x00) { DHL_OS_Printf("%c",(int)xvctPtr->channel[i].short_name[j]); } else { DHL_OS_Printf("?"); } } DHL_OS_Printf("\n"); DHL_OS_Printf("\tmajor_channel_number: %d\n", (int)xvctPtr->channel[i].major_channel_number); DHL_OS_Printf("\tminor_channel_number: %d\n", (int)xvctPtr->channel[i].minor_channel_number); DHL_OS_Printf("\tmodulation_mode: 0x%02X ", xvctPtr->channel[i].modulation_mode); switch (xvctPtr->channel[i].modulation_mode) { case 0x00: DHL_OS_Printf("(reserved)\n"); break; case mm_analog: DHL_OS_Printf("(analog)\n"); break; case mm_SCTE_mode_1: DHL_OS_Printf("(mm_SCTE_mode_1)\n"); break; case mm_SCTE_mode_2: DHL_OS_Printf("(mm_SCTE_mode_2)\n"); break; case mm_ATSC_8VSB: DHL_OS_Printf("(ATSC_8VSB)\n"); break; case mm_ATSC_16VSB: DHL_OS_Printf("(ATSC_16VSB)\n"); break; case mm_private_descriptor: DHL_OS_Printf("(Modulation defined in private descriptor)\n"); break; default: DHL_OS_Printf("(User Private)\n"); break; } DHL_OS_Printf("\tcarrier_frequency: %f MHz\n", xvctPtr->channel[i].carrier_frequency/1000000.0); DHL_OS_Printf("\tchannel_TSID: 0x%04X\n", (int)xvctPtr->channel[i].channel_TSID); DHL_OS_Printf("\tprogram_number: 0x%04X\n", (int)xvctPtr->channel[i].program_number); DHL_OS_Printf("\tETM_location: 0x%02X ", xvctPtr->channel[i].ETM_location); switch (xvctPtr->channel[i].ETM_location) { case ETM_none: DHL_OS_Printf("(No ETM)\n"); break; case ETM_in_this_PTC: DHL_OS_Printf("(ETM in PTC carrying this PSIP)\n"); break; case ETM_in_channel_TSID_PTC: DHL_OS_Printf("(ETM in PTC specified by channel_TSID)\n"); break; default: DHL_OS_Printf("(Reserved for future ATSC use)\n"); break; } DHL_OS_Printf("\taccess_controlled: 0x%01X (%s)\n", (int)xvctPtr->channel[i].access_controlled, xvctPtr->channel[i].access_controlled ? "Yes" : "No"); DHL_OS_Printf("\thidden: 0x%01X (%s)\n", (int)xvctPtr->channel[i].hidden,xvctPtr->channel[i].hidden ? "Yes" : "No"); DHL_OS_Printf("\tpath_select: 0x%01X (path %d)\n", xvctPtr->channel[i].path_select,xvctPtr->channel[i].path_select+1); DHL_OS_Printf("\tout_of_band: 0x%01X (%s)\n", (int)xvctPtr->channel[i].out_of_band, xvctPtr->channel[i].out_of_band ? "Yes" : "No"); DHL_OS_Printf("\tshow_guide: 0x%01X (%s)\n", (int)xvctPtr->channel[i].show_guide, xvctPtr->channel[i].show_guide ? "Yes" : "No"); DHL_OS_Printf("\tservice_type: 0x%02X ", xvctPtr->channel[i].service_type); switch (xvctPtr->channel[i].service_type) { case st_analog_television: DHL_OS_Printf("(analog_television)\n"); break; case st_ATSC_digital_television: DHL_OS_Printf("(ATSC_digital_television)\n"); break; case st_ATSC_audio_only: DHL_OS_Printf("(ATSC_audio_only)\n"); break; case st_ATSC_data_broadcast_service: DHL_OS_Printf("(ATSC_data_broadcast_service)\n"); break; default: DHL_OS_Printf("(Reserved)\n"); break; } DHL_OS_Printf("\tsource_id: 0x%04X\n", (int)xvctPtr->channel[i].source_id); DHL_OS_Printf("\tdescriptor_length: %d\n", (int)xvctPtr->channel[i].descriptor_length); for (j=0; jchannel[i].descriptor_length; j++) DHL_OS_Printf("%02x ", (int)(xvctPtr->channel[i].descriptors[j])); if (xvctPtr->channel[i].descriptor_length) DHL_OS_Printf("\n"); } DHL_OS_Printf("additional_descriptor_length: %d\n", (int)xvctPtr->additional_descriptor_length); for (j=0; jadditional_descriptor_length; j++) DHL_OS_Printf("%02x ", (int)(xvctPtr->additional_descriptors[j])); if (xvctPtr->additional_descriptor_length) DHL_OS_Printf("\n"); } #if 0 Dmc_GetEttSection dmc_tsd, 0x1200, 0x3683a, &ett, 5*60*60, 0 Dmc_GetEit dmc_tsd, 0x1001, 3, &eit, 10*60*60, 0 #endif #if COMMENT __________(){} #endif #if TEST_CHANNEL_DEMUX static int gCancelRequestCount; static int gTimeout = 2; void PsiCancel() { gCancelRequestCount = 1; } static BOOL _SimpleCheck(UINT32 param) { if (gCancelRequestCount) { gCancelRequestCount = 0; printf("!!!! cancelled\n"); return TRUE; } return FALSE; } #include "DHL_FE.h" void TestPsi(int id, int param1, int param2, int param3, int param4) { STATUS status; tDHL_TSD tsd = DHL_DMX_GetTsd(); int sec = 1000; if (id == 0) { // Tuner set: TestPsi 0, 1, 81 DHL_RESULT dhlResult; printf("Tune RF, channeltype %d, RF %d\n", param1, param2); // param1 (0:AIR, 1:STD) param2=DHL_FE_ChannelToFrequency(param2, (tDHL_FreqStd)param1); dhlResult = DHL_FE_Start(DEFAULT_TUNER_ID, param2, eDHL_DEMOD_8VSB, NULL); printf("Ch %d start result %d\n", param2, dhlResult); } else if (id == 100) { // Timeout: TestPsi 100 10 printf("\n timeout changed to %d sec\n", param1); gTimeout = param1; } if (id == 1) { // GetPAT: TestPsi 1 MPEG_PAT *pat; gCancelRequestCount = 0; status = Dmc_GetPAT(tsd, &pat, gTimeout*sec, _SimpleCheck); if (!status) { PrintPAT(pat); Dmc_FreeAtscTable(&pat); } else printf("!! status %d %s\n", status, DMW_CDB_ErrString(status)); } else if (id == 2) { // GetPMT: TestPsi 2, 16, 1 MPEG_PMT *pmt; printf("Get PMT of pid %u, #%u..\n", param1, param2); gCancelRequestCount = 0; status = Dmc_GetPMT(tsd, param1, param2, &pmt, gTimeout*sec, _SimpleCheck); if (!status) { PrintPMT(pmt); Dmc_FreeAtscTable(&pmt); } else printf("!! status %d %s\n", status, DMW_CDB_ErrString(status)); } else if (id == 3) { // GetTvct: TestPsi 3 tvctPtr_t tvct; gCancelRequestCount = 0; status = Dmc_GetTvct(tsd, &tvct, gTimeout*sec, _SimpleCheck); if (!status) { PrintTvct(tvct); Dmc_FreeAtscTable(&tvct); } else printf("!! status %d %s\n", status, DMW_CDB_ErrString(status)); } else if (id == 4) { // Xvct: TestPsi 4 xvctPtr_t xvct; gCancelRequestCount = 0; status = Dmc_GetXvct(tsd, &xvct, gTimeout*sec, _SimpleCheck); if (!status) { PrintXvct(xvct); Dmc_FreeAtscTable(&xvct); } else printf("!! status %d %s\n", status, DMW_CDB_ErrString(status)); } else if (id == 10) { // TVCT, CVCT, PAT multi: TestPsi 10 tvctPtr_t tvct = NULL; cvctPtr_t cvct = NULL; MPEG_PAT *pat = NULL; gCancelRequestCount = 0; status = Dmc_GetVctAndPat(tsd, &tvct, &cvct, &pat, gTimeout*sec, _SimpleCheck); if (!status) { if (tvct) PrintTvct(tvct); if (cvct) PrintCvct(cvct); if (pat) PrintPAT(pat); Dmc_FreeAtscTable(&tvct); Dmc_FreeAtscTable(&cvct); Dmc_FreeAtscTable(&pat); } else printf("!! status %d %s\n", status, DMW_CDB_ErrString(status)); } else if (id == 20) { // Main Channel Table multi DmcMainTables tbls; gCancelRequestCount = 0; status = Dmc_GetMainChannelTables(tsd, &tbls, gTimeout*sec, _SimpleCheck); if (!status) { printf(" tvct 0x%x, cvct 0x%x, pat 0x%x, #pmt %d\n", tbls.tvct, tbls.cvct, tbls.pat, tbls.num_programs); Dmc_FreeMainChannelTables(&tbls); } else printf("!! status %d %s\n", status, DMW_CDB_ErrString(status)); } } /* cafrii 070730 add TVCT continuous reception test for prot sarnoff stream analysis */ void _TvctContTestEventProc(tDHL_PSI_Event event, tDHL_PSI_ControlHandle psiCtl, UINT32 userParam) { //PSIMultiEventProcData *procData = (PSIMultiEventProcData *)userParam; tDHL_PSI_DataArray *desc; DHL_RESULT err; tvctPtr_t tvct; switch (event) { case ePSIEVENT_DATARECEIVED: err = DHL_PSI_ReadPSIData(psiCtl, &desc); if (err) { dprint(0, "@@@@ !! DHL_PSI_ReadPSIData returned %s\n",ErrorString(err)); break; } dprint(0, "===== TVCT =====\n"); err = ParseTvct(desc->sectPtr, &tvct); if (err) { dprint(0, "@@@@ !! ParseTvct err %d\n", err); DHL_PSI_FreePSIData(desc); break; } DHL_PSI_FreePSIData(desc); PrintTvct(tvct); Dmc_FreeAtscTable(&tvct); break; default: dprint(0, "@@@@ %s\n", DHL_PSIEventString(event)); break; } } /* test ½ÃÀÛÇϱâ: TvctContTest & test Á¾·á: TvctContTest 1 */ void TvctContTest(BOOL bStop) { DHL_RESULT err; tDHL_TSD tsd = DHL_DMX_GetTsd(); static tDHL_PSI_ControlHandle s_psiCtl; if (bStop) { if (s_psiCtl) { DHL_PSI_StopMonitor(s_psiCtl); s_psiCtl = 0; } else DHL_OS_Printf("!! no psictrl\n"); return; } err = MonitorTvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_CONTINEOUS, _TvctContTestEventProc, (UINT32)0, &s_psiCtl); if (err) { DHL_OS_Printf("!! Monitor err %d\n", err); } } #endif // TEST_CHANNEL_DEMUX #if COMMENT ___________(){} #endif #if DMW_REGISTER_DEBUG_SYMBOL static DHL_SymbolTable ChannelDemuxSymbols[] = { //---- functions //---- variables //DHL_VAR_SYM_ENTRY(g_Trace_DmcDemux), 0, }; #endif // DMW_REGISTER_DEBUG_SYMBOL void Dmc_RegisterChannelDemuxSymbols() { #if DMW_REGISTER_DEBUG_SYMBOL DHL_DBG_RegisterSymbols(ChannelDemuxSymbols, DHL_NUMSYMBOLS(ChannelDemuxSymbols)); #endif } /******************************************************************** $Log: DMW_ChannelDemux.c,v $ 1.45 2005/3/15 ParseXXX È£Ãâ ÈÄ ¸®ÅϰªÀÌ ¿¡·¯À̸é pointer¸¦ NULL·Î ¼³Á¤ PMT, Eit, Ett ¸ð´ÏÅÍ¿¡ pid °ª validity üũ 1.44 2004/11/30 is_cvct À§Ä¡ À̵¿ 1.43 2004/11/29 DmcMainTables ±¸Á¶ Ãß°¡ ¹× MainChannelTable ¼ö½Å ÇÔ¼ö Ãß°¡ 1.42 2004/11/26 Dmc_Translate*vct Ãß°¡ 1.41 2004/11/5 ƯÁ¤ »óȲ¿¡¼­ nGoodEit µî º¯¼öµé ÃʱâÈ­ ¾ÈµÈ ¹®Á¦ ¼öÁ¤ MonitorEit/Ett µî¿¡¼­ ¿¡·¯³¯ °æ¿ì ´ëÀÀ ÄÚµå Ãß°¡ 1.4 2004/10/20 move DMW_DEMUX_DEBUG block to Epg-X module 1.3 2004/7/12 change ckfn prototype, parse tables while MulipleRx add userparam, lock fn in multi-rx function timeOut value now can be negative in all GetXX fn wait tick is unified using PSIP_WAIT_IN_TICK 1.25 2004/7/02 DMW_DEMUX_DEBUG flag added 1.24 2004/6/17 Dmc_GetVctAndPat redesigned 1.23 2004/06/07 SYS_TIME_MODULE_ENABLED, DMW_UNIPRINT_ENABLED add 1.22 2004/04/28 bugfix, debug line update 1.21 2004/04/20 GetMultipleExxEx, Dmc_GetStt/Rrt added 1.2 2004/04/01 add GetMultipleETTs 1.1 2004/03/31 add GetMultipleEITs 1.0 2004/01/?? add Cancellable GetPsi functions *********************************************************************/