/******************************************************************** DMW_EpgInterface.c EPG Middleware baseline implementation Copyright 2004 Digital STREAM Technology, Inc. All Rights Reserved $Id: DMW_EpgInterface.c v1.00 2004/04 cafrii Exp $ ********************************************************************/ /*_____ I N C L U D E __________________________________________*/ #include "DMW_Platform.h" #include "DLIB_BitOp.h" #include "DLIB_PSI_Utils.h" #include "DMW_CodeConv.h" #include "DMW_ChannelAPI.h" #include "DMW_EpgInterface.h" //#include //#include DHL_MODULE("$epi", 0); /*------------------------------------------------------- Configurations.. -------------------------------------------------------*/ #define DMW_EPG_TESTCODE 1 /* 1À̸é TestXX ÇÔ¼öµéÀ» ºôµå¿¡ Æ÷ÇÔ.. */ /* #define USE_OLD_2_PASS_METHOD 0 */ #define USE_EIT_FIRST_MODE_DEFAULT 0 /* 1À̸é Epg Update¸¦ ½ÃÀÛÇÒ ¶§ ±âº»ÀûÀ¸·Î Eit first ¸ðµå·Î ½ÃÀÛÇÑ´Ù. Eit¸¦ »¡¸® ¹ÞÀ» ¼ö ÀÖ´Â ÀåÁ¡ÀÌ ÀÖ´Â ¹Ý¸é PSIP ÀÌ ¿ÏÀüÇÏÁö ¸øÇÏ´Â °æ¿ì Ett¸¦ ¾Æ¿¹ ¸ø¹ÞÀ» ¼öµµ ÀÖ´Ù.. */ int g_PrintEventInfo = 1; /* GetEvent·Î event Á¤º¸¸¦ °¡Á®¿Â ´ÙÀ½¿¡ Äֿܼ¡ ¸ðµÎ Ãâ·ÂÇØÁØ´Ù. */ #define IGNORE_RRT_REGION 1 //±âÁ¸ rrt regionÀ¸·Î 5¸¸ ó¸®ÇßÀ¸³ª, ¾Ë·ÁÁø region 1,2¸¦ Á¦¿ÜÇÑ ³ª¸ÓÁö¸¦ //´Ù ó¸®Çϵµ·Ï º¯°æÇÔ. /*-------------------------------------------------------*/ #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) /*--------------------------------------------------------------------*/ #if COMMENT ____desc_parsing____(){} #endif STATUS DMW_GetPsipDescriptor(UINT8 *descriptors, UINT16 len, UINT8 tag, UINT16 instance, UINT8 **descriptor) { UINT8 *p; UINT16 count; UINT8 descriptor_length; STATUS status; /* search for descriptor of type 'tag' */ count = 0; status = statusNotFound; p = descriptors; while (p < descriptors + len) { if (*p == tag) { if (count == instance) { /* check for length error */ descriptor_length = p[1]; if ((p + descriptor_length + 2) <= (descriptors + len)) { if (descriptor) *descriptor = p; status = statusOK; } else status = statusPSIPError; break; /* break 'while' */ } else { count++; } } descriptor_length = p[1]; /* p[0] is tag, p[1] is length of this tag desc.. */ p += (descriptor_length + 2); /* desc length + (2 bytes: tag, length itself) */ } return status; } /* Content Advisory descriptor¸¦ »õ·Î¿î format¿¡ ¸Â°Ô parse.. ±âÁ¸¿¡´Â ContentAdvisoryDescriptor¸¦ parsingÇÑ ´ÙÀ½¿¡ À̸¦ ´Ù½Ã DMW_RatingÀ¸·Î º¯È¯ÇÏ¿´À¸³ª, ÀÌÁ¦´Â Á÷Á¢ descriptorÁ¤º¸¿¡¼­ DMW_RatingÀ¸·Î º¯È¯ ÃßÃâÇÑ´Ù. Áߺ¹µÈ regionÀÌ ¿©·¯°³ Á¸ÀçÇÒ °æ¿ì¶óµµ ¿¡·¯·Î ó¸®ÇÏÁö ¾Ê´Â´Ù. caller´Â ÀÌ·± °æ¿ì¿¡ ´ëÇØ¼­ ³ª¸§´ë·ÎÀÇ policy¸¦ °¡Áö°í ÀÖ¾î¾ß ÇÑ´Ù. */ STATUS DMW_ParseRatingDescriptor(UINT8 *descriptors, int descriptor_length, DMW_Rating5 *ri) { UINT8 *p; bitBuffer_t tBits, *bits = &tBits; INT32 count, i,k; STATUS status; if (descriptors == NULL || descriptor_length <= 0) return statusInvalidArgument; /* search ca descriptor */ status = DMW_GetPsipDescriptor(descriptors, descriptor_length, content_advisory_tag, 0, &p); if (status) return status; /* not found error */ if (p == NULL || p[0] != content_advisory_tag) return statusInvalidArgument; if (ri == NULL) return statusInvalidArgument; bitBufferInitialize(bits,p+2,p[1]); bitBufferSkipBits(bits,2); ri->region_count = bitBufferGetBits(bits,6); if (ri->region_count > MAX_RATING_RGNS_NUM) { dprint(0, "!! region count overflow %d (max %d)\n", ri->region_count, MAX_RATING_RGNS_NUM); ri->region_count = MAX_RATING_RGNS_NUM; } /* °­Á¦·Î Å©±â¸¦ ÁÙ¿´À¸´Ï, raw descriptor ³¡ºÎºÐ¿¡ parsingÀÌ ¾ÈµÈ µ¥ÀÌÅͰ¡ ³²¾ÆÀÖ°Ô µÉ ¼öµµ ÀÖÀ½. */ for (i=0; iregion_count; i++) { DMW_RatingRegion *rr = &ri->region[i]; rr->region_id = bitBufferGetBits(bits,8); rr->num_dimensions = bitBufferGetBits(bits,8); count = rr->num_dimensions; if (rr->num_dimensions > MAX_RATING_DIMS_NUM) { dprint(0, "!! dims count overflow %d (max %d)\n", rr->num_dimensions, MAX_RATING_DIMS_NUM); rr->num_dimensions = MAX_RATING_DIMS_NUM; } for (k=0; knum_dimensions; k++) { rr->dimension[k].index = bitBufferGetBits(bits,8); bitBufferSkipBits(bits,4); rr->dimension[k].value = bitBufferGetBits(bits,4); } /* truncate µÈ ¿µ¿ªÀº skipÀ» ÇØÁà¾ß ÇÔ. */ for ( ; kn_subchannel; i++) { if (chInfo->subchannel[i].source_id == source_id) { return &chInfo->subchannel[i]; } } return NULL; } #if COMMENT ____Test____(){} #endif typedef struct { int rf; int region; int n_dim; int dim[5], val[5]; } EpgFakeRatingInfo; /* Å×½ºÆ®¸¦ À§ÇÑ ¸ñÀûÀ¸·Î.. cafrii 060616 µ¿ÀÏ À̸§ÀÇ Äڵ尡 App¿¡ º¹»çµÇ¾î »ç¿ëÁßÀ̾ À̸§ º¯°æ.. */ EpgFakeRatingInfo g_EpgFakeRatingInfo; void DMW_EPG_SetFakeRatingData(int rf, int region, int d1, int d2, int d3, int d4, int d5) { int n_dim; if (rf <= 0) { /* disable fake rating feature */ g_EpgFakeRatingInfo.rf = 0; return; } g_EpgFakeRatingInfo.rf = rf; g_EpgFakeRatingInfo.region = region; /* dn °ª¿¡ -1À» ÁöÁ¤ÇÏ¸é ±× ÀÌÈÄÀÇ argument´Â ¸ðµÎ ¹«½ÃÇÑ´Ù. */ n_dim = 0; if (d1 < 0) goto label_exit; g_EpgFakeRatingInfo.dim[n_dim] = (d1>>8)&0xff; g_EpgFakeRatingInfo.val[n_dim] = (d1&0xff); n_dim++; if (d2 < 0) goto label_exit; g_EpgFakeRatingInfo.dim[n_dim] = (d2>>8)&0xff; g_EpgFakeRatingInfo.val[n_dim] = (d2&0xff); n_dim++; if (d3 < 0) goto label_exit; g_EpgFakeRatingInfo.dim[n_dim] = (d3>>8)&0xff; g_EpgFakeRatingInfo.val[n_dim] = (d3&0xff); n_dim++; if (d4 < 0) goto label_exit; g_EpgFakeRatingInfo.dim[n_dim] = (d4>>8)&0xff; g_EpgFakeRatingInfo.val[n_dim] = (d4&0xff); n_dim++; if (d5 < 0) goto label_exit; g_EpgFakeRatingInfo.dim[n_dim] = (d5>>8)&0xff; g_EpgFakeRatingInfo.val[n_dim] = (d5&0xff); n_dim++; label_exit: g_EpgFakeRatingInfo.n_dim = n_dim; } /* return TRUE if faking is success. */ BOOL DoFakeRatingData(int rf, DMW_Rating5 *pRating) { /* fake rating ±â´É */ int k; if (g_EpgFakeRatingInfo.rf && g_EpgFakeRatingInfo.rf == rf && g_EpgFakeRatingInfo.n_dim > 0) { dprint(0, "!! %s: simulate Fake Rating information\n", __FUNCTION__); pRating->region_count = 1; pRating->region[0].region_id = g_EpgFakeRatingInfo.region; pRating->region[0].num_dimensions = g_EpgFakeRatingInfo.n_dim; dprint(0, "fake: region %d, %d dims\n", g_EpgFakeRatingInfo.region, g_EpgFakeRatingInfo.n_dim); for (k=0; kregion[0].dimension[k].index = g_EpgFakeRatingInfo.dim[k]; pRating->region[0].dimension[k].value = g_EpgFakeRatingInfo.val[k]; dprint(0, "fake: [%d] dim idx %d, val %d\n", k, g_EpgFakeRatingInfo.dim[k], g_EpgFakeRatingInfo.val[k]); } return TRUE; } return FALSE; } #if COMMENT ____API____(){} #endif STATUS DMW_EPG_Init() { dprint(1, "DMW_EPG_Init()\n"); /* g_fnPrevHook = DMW_CDB_RegisterUcmDeleteHook(DMW_EPG_UcmDeleteHook); */ /* UCM DB¿ÍÀÇ ¸µÅ©°¡ ¾ø±â ¶§¹®¿¡ UCM delete¿¡ ´ëÇØ¼­ hookingÀ» ÇÒ Çʿ䰡 ¾ø´Ù. °ü·ÃµÈ UCM DB°¡ Áö¿öÁö´õ¶óµµ EPG DB´Â °è¼Ó Á¸ÀçÇÒ ¼ö ÀÖ°í, (³ªÁß¿¡ DRF Æ©´×À» ÇÏ°Ô µÇ¸é Àç »ç¿ëµÉ ¼ö ÀÖÀ½) ÇÊ¿äÇÏ´Ù¸é DeleteAll À» ÀÌ¿ëÇØ¼­ EPG¸¦ Áö¿ï ¼ö ÀÖ´Ù. */ return Dmc_EpgInit(); } /*-------------------------------------------------------------------- Control API */ /* cafrii 060320 change prototype (add source_id) */ STATUS DMW_EPG_UpdateCurrentRf(int rf, int source_id, EpgUpdateCallbackFn func) { /* source_id°¡ non-zeroÀ̸é ÇØ´ç source_id¸¦ ¿ì¼±Çؼ­ ¹ÞÀ½. source_id°¡ 0À̸é preferred source_id °¡ ¾øÀ½. ¸ðµç subchannelÀ» °ñ°í·ç ¼ö½Å */ tDHL_TSD tsd; UINT32 flag; /* ÁöÁ¤ÇÑ rf Àüü¸¦ update ½ÃÀÛÇÑ´Ù. */ dprint(1, "DMW_EPG_UpdateCurrentRf(rf %d, callback 0x%x)\n", rf, func); /* ¾î´À TSD unitÀ» »ç¿ëÇÒ °ÍÀÎÁö ÁöÁ¤ÇÑ´Ù. */ tsd = DHL_DMX_GetTsd(); /* cafrii 041019 change, allow all possible tsd's input */ #if USE_EIT_FIRST_MODE_DEFAULT flag = epgScanFlag_EitFirst; #else flag = 0; #endif return Dmc_EpgUpdateStart(rf, tsd, (DmcEpgEventProc) func, source_id, flag); } STATUS DMW_EPG_UpdateCurrentChannel(int iUCMId, EpgUpdateCallbackFn func) { /* ƯÁ¤ source_id ¸¦ prefer ÇØ¼­ udpate¸¦ ½ÃÀÛÇÑ´Ù. */ tDHL_TSD tsd; int idx; int rf, source_id = 0; UINT32 flag; dprint(1, "DMW_EPG_UpdateCurrentChannel(uid %d)\n", iUCMId); tsd = DHL_DMX_GetTsd(); /* cafrii 041019 change, allow all possible tsd's input */ /* Uid·Î ºÎÅÍ RF °ªÀ» ¾Ë¾Æ³½´Ù.. */ DMW_MSC_LockUcm(); idx = DMW_MSC_Uid2Index(iUCMId); if (idx >= 0) { rf = g_UCM[idx].RF; source_id = g_UCM[idx].source_id; } else { rf = -1; } DMW_MSC_UnlockUcm(); if (rf < 0) return statusNotFound; #if USE_EIT_FIRST_MODE_DEFAULT flag = epgScanFlag_EitFirst; #else flag = 0; #endif return Dmc_EpgUpdateStart(rf, tsd, (DmcEpgEventProc) func, source_id, flag); } STATUS DMW_EPG_CancelUpdate() { dprint(1, "DMW_EPG_CancelUpdate()\n"); return Dmc_EpgUpdateCancel(); } STATUS DMW_EPG_DeleteAll() { dprint(1, "DMW_EPG_DeleteAll()\n"); return Dmc_EpgDeleteAll(); } #if COMMENT ____API____(){} #endif /*-------------------------------------------------------------------- Query API */ static void FreeEpgEventItem(DMW_EpgEvent *pEvent) { if ((pEvent->titleTextLength) > 0 && (pEvent->titleText)) { DHL_OS_Free((void**)&pEvent->titleText); pEvent->titleTextLength = 0; } if ((pEvent->eventETMLength > 0) && (pEvent->eventETM)) { DHL_OS_Free((void**)&pEvent->eventETM); pEvent->eventETMLength = 0; } if (pEvent->caption) { FreeMpegDescriptor(pEvent->caption); pEvent->caption = NULL; } } void DMW_EPG_FreeEpgEvent(DMW_EpgEvent *pEvent) { if (pEvent == NULL) return; dprint(1, "DMW_EPG_FreeEpgEvent\n"); FreeEpgEventItem(pEvent); DHL_OS_Free((void**)&pEvent); } void DMW_EPG_FreeEpgEvents(DMW_EpgEvent *pEvents, int iCount) { int i; if (pEvents == NULL) return; dprint(1, "DMW_EPG_FreeEpgEvents(%d)\n", iCount); for (i=0; iid; UINT16 source_id = subchInfo->source_id; ettSectionPtr_t ett; /* ½ÃÀÛÇϱâ Àü¿¡ ¸ÕÀú resetÇÑ´Ù. flag¸¦ ÀÌ¿ëÇÏ¿© incrementalÇÏ°Ô Á¤º¸¸¦ ä¿ö°¡´Â ¹æ½ÄÀº »ç¿ëÇÒ ¼ö ¾øÀ½. */ memset(p, 0, sizeof(DMW_EpgEvent)); /*---------- General Info --------------*/ p->programId = event->event_id; p->programLength = event->length_in_seconds; p->startTime = event->start_time; /*---------- Rating Info --------------*/ if (flag & GET_EVENT_RATING) { if (DoFakeRatingData(rf, &p->rating)) { /* fake rrt data loading success. */ } else { status = DMW_ParseRatingDescriptor(event->descriptors, event->descriptor_length, &p->rating); if (status) { p->rating.region_count = 0; /* dprint(0, "[RRT] no rating info from eit\n"); */ } } } /*---------- Caption Info --------------*/ if (flag & GET_EVENT_CAPTION) { status = DMW_ParseCaptionDescriptor(event->descriptors, event->descriptor_length, &p->caption); if (status) { if (status != statusNotFound) dprint(0, "!! err in GetCaptionDesc:ParsingCaDesc.. %d\n", status); p->caption = NULL; } } /*---------- Title Info --------------*/ if (flag & GET_EVENT_TITLE) { if (event->title_length > 0) { p->titleText = DHL_OS_Malloc(event->title_length+1); if (p->titleText) { p->titleTextLength = event->title_length; memcpy(p->titleText, event->title, event->title_length); } else { dprint(0, "!! out of memory for titletext len %d of event[%d], evid 0x%x\n", event->title_length, iEit, event->event_id); p->titleTextLength = 0; } } else { dprint(0, "!! event title length %d\n", event->title_length); /* cafrii 060321 bugfix %n->%d */ p->titleText = NULL; p->titleTextLength = 0; } } /*---------- Text Info -------------- etmÀ» ãÀ¸·Á¸é ett list¸¦ µÚÁ®¾ß ÇÑ´Ù.. */ /* cafrii 070730 bugfix, GET_EVENT_TITLE->GET_EVENT_TEXT */ if (flag & GET_EVENT_TEXT) { UINT32 etm_id; etm_id = MakeEventETMID(source_id, event->event_id); /* cafrii 041028, MakeETMID -> MakeEventETMID */ /* ¸ðµç ett array¸¦ ´Ù µÚÁ®°¡¸ç, etm_id ¿¡ ÇØ´çµÇ´Â ett·ÎºÎÅÍ etmÀ» °¡Á®¿Í¼­ º¹»çÇÑ´Ù.. --> iEit-1, iEit, iEit+1 ÀÌ·¸°Ô ¼¼°³¸¸ ºñ±³ÇÏ¸é µÉ °Í °°´Ù. EitÀÇ À§Ä¡¿Í ±×¸® ¸Ö¸® ¶³¾îÁ® ÀÖÁö ¾ÊÀ» °ÍÀ̹ǷÎ. */ /* for (i=0; i<128; i++) // <-- inefficient!! */ for (i= max(0, iEit-1); i<= min(127, iEit+1); i++) /* cafrii 041223 change */ { if (subchInfo->n_ett[i] == 0 || subchInfo->etts[i] == NULL) continue; for (k=0; kn_ett[i]; k++) { if (subchInfo->etts[i][k] == NULL) continue; if (subchInfo->etts[i][k]->ETM_id == etm_id) { ett = subchInfo->etts[i][k]; if (ett->extended_text_message_length > 0) { p->eventETM = DHL_OS_Malloc(ett->extended_text_message_length+1); if (p->eventETM == NULL) { dprint(0, "!! out of memory for etm len %d of ett[%d][%d]\n", ett->extended_text_message_length, i, k); p->eventETMLength = 0; } else { p->eventETMLength = ett->extended_text_message_length; memcpy(p->eventETM, ett->extended_text_message, p->eventETMLength); } } else { /* etm length °¡ À߸øµÇ¾ú´Ù.. ¹«½Ã.. */ dprint(0, "!! ett[%d][%d] etm len %d\n", i, k, ett->extended_text_message_length); p->eventETM = NULL; p->eventETMLength = 0; } goto label_end_etm; /* go out of this loop!! */ } } } label_end_etm: ; /* cafrii 070327 add to remove compiler warning */ } } /* DMW_EPG_GetEventsByRF ÁöÁ¤ÇÑ uid ä³Î¿¡ µî·ÏµÈ EPG evnet Á¤º¸µé Áß¿¡¼­ ½ÃÀ۽ð£, duration ¿¡ ÇØ´çµÇ´Â event µéÀÇ list (array) ¸¦ µ¹·ÁÁØ´Ù.. ÇÊ¿äÇÑ ¸Þ¸ð¸®´Â ³»ºÎÀûÀ¸·Î ÇÒ´çÀ» ÇÑ´Ù. (DHL_OS_Malloc) ÀúÀåµÈ °¹¼ö´Â iEventCounts ·Î ¸®ÅÏ.. ½Ã°£ ´ÜÀ§´Â ¸ðµÎ GPS ÀÌ´Ù.. »ç¿ë ÈÄ¿¡ caller´Â ¸Þ¸ð¸®¸¦ ÇØÁ¦ ÇØ¾ß ÇÑ´Ù. */ STATUS DMW_EPG_GetEventsByRF(int rf, int source_id, UINT32 nStartTime, UINT32 nDuration, DMW_EpgEventPtr *aFoundEvents, int *piEventCounts, UINT32 flag) { /* todo ÀÏ´Ü ¸î°³ÀÇ Eit event °¡ ÇØ´çµÇ´ÂÁö °è»êÀ» ÇÑ ´ÙÀ½¿¡ ¸Þ¸ð¸®¸¦ ÇÒ´çÇϰí, ´Ù½Ã Eit/Ett Çϳª¾¿ Parsing ÇØ¼­ DMW_EpgEvent¸¦ ¸¸µé¾î¾ß ÇÑ´Ù. ÀÌ·¸°Ô Çϸé memory fragmentation °¡´É¼ºÀ» ´õ ÁÙÀÏ ¼ö ÀÖ´Ù.. ½Ã°£Àº ´õ°É¸². */ #define SAFE_EXIT(val) returnStatus=(val); goto label_exit; /* cafrii 060616 bugfix, status -> returnStatus */ int i, k; int iEit, iEvent; STATUS status; /* temporary. */ STATUS returnStatus = statusOK; DmcChannelInfo *chInfo = NULL; DmcSubChannelInfo *subchInfo = NULL; DMW_EpgEvent *EventList; DMW_EpgEvent *p; /* temporary.. */ int iEventCount; int sz_event_list; int maxEvent; if (flag == 0) flag = GET_EVENT_ALL; maxEvent = (flag & 0xffff); /* ÃÖ´ë 65535°³ ±îÁö¸¸ °¡´É. */ /* cafrii 060620 add */ /* »ç¿ëÀÚ°¡ ½Ç¼ö·Î max °ªÀ» ÁöÁ¤ÇÏÁö ¾ÊÀº °æ¿ì µðÆúÆ® °ª ÁöÁ¤. */ if (maxEvent == 0) maxEvent = DEFAULT_MAX_EVENT_NUMBER; dprint(1, "DMW_EPG_GetEventsByRF: rf %d, source_id %d, max %d, flag 0x%x\n", rf, source_id, maxEvent, flag); if (rf < 0) return statusNotFound; if (maxEvent <= 0) return statusInvalidArgument; /* rf, source_id ¸¦ »ç¿ëÇÏ¿© event list¸¦ ¾ò¾î³½´Ù. rf >= 0 À̾î¾ß ÇÑ´Ù. */ Dmc_EpgLockCoreDB(TRUE); chInfo = Dmc_GetChannelInfo(g_EpgDB, rf); if (chInfo == NULL) { dprint(2, "!! rf %d chInfo not found.. maybe epg is not ready..\n", rf); /* cafrii 041208, change debug level */ SAFE_EXIT(statusNotFound); } for (i=0; in_subchannel; i++) { if (chInfo->subchannel[i].source_id == source_id) { subchInfo = &chInfo->subchannel[i]; break; } } if (!subchInfo) { dprint(1, "!! subchInfo source_id %d not found..\n", source_id); SAFE_EXIT(statusNotFound); } /* test.. */ dprint(3, " sizeof DMW_EpgEvent: %d\n", sizeof(DMW_EpgEvent)); if(flag&GET_EVENT_STATIC_MEM) { //aFoundEvents´Â À¯È¿ÇÑ static memoryÀÇ ÁÖ¼ÒÀÓ sz_event_list=maxEvent; EventList=*aFoundEvents; } else { sz_event_list = 8; dprint(3, " pre-alloc %d event list space..\n", sz_event_list); EventList = DHL_OS_Malloc(sz_event_list * sizeof(DMW_EpgEvent)); if (EventList == NULL) { dprint(0, "!! out of memory for Eventlist\n"); SAFE_EXIT(statusOutOfMemory); } } if((flag&GET_EVENT_STATIC_MEM)==0) memset(EventList, 0, sz_event_list * sizeof(DMW_EpgEvent)); iEventCount = 0; for (iEit=0; iEit<128; iEit++) { eitPtr_t eit; ettSectionPtr_t ett; eitEventPtr_t event; /* eitPtr_t */ UINT32 max_start_time, min_end_time; UINT32 min_start_time; int num_event; if (iEventCount >= maxEvent) /* ÀÌ¹Ì full ÀÌ¸é ±×³É ÁßÁö.. */ break; eit = subchInfo->eits[iEit]; if (eit == NULL) continue; if (eit->source_id != source_id) { dprint(0, "!! eit[%d] source id %d mismatch to subch source id %d\n", iEit, eit->source_id, source_id); continue; } num_event = eit->numEvents; if (eit->event == NULL || num_event <= 0) { /* dprint(3, " eit[%d] event %x, n_event %d\n", iEit, eit->event, num_event); */ continue; } if (num_event <= 0) continue; /* cafrii 041223, add efficient search/stop code ÀÌ eit³»¿¡ °¡Àå ºü¸¥ event°¡ ¿øÇÏ´Â time range¿¡¼­ ÇÑÂü ¹þ¾î³ª ÀÖ´Ù¸é search¸¦ Áß´ÜÇÑ´Ù. */ min_start_time = 0xFFFFFFFF; for (k=0; kevent[k].start_time < min_start_time) min_start_time = eit->event[k].start_time; } if (nStartTime + nDuration-1 + 3*3600 < min_start_time) { /* ÀÌ EIT ¿¡ ÀÖ´Â ¸ðµç À̺¥Æ®µéÀÌ ¿øÇÏ´Â ½Ã°£ ±¸°£ º¸´Ù 3½Ã°£ ÀÌÈÄ¿¡ À§Ä¡ÇÑ´Ù.. ÀÌ ¸»Àº ÀÌ EIT ÀÌÈķδ ´õÀÌ»ó EIT °Ë»öÀ» ÇÒ Çʿ䰡 ¾ø´Ù´Â ÀǹÌ.. */ dprint(2, " search stop at eit[%d]..\n", iEit); continue; } for (iEvent=0; iEventevent[iEvent]; /* check overlap: (nStartTime, nDuration) and (event->start_time, event->length_in_seconds) */ max_start_time = max(nStartTime, event->start_time); min_end_time = min(nStartTime+nDuration-1, event->start_time+event->length_in_seconds-1); if (max_start_time > min_end_time) /* ¿µ¿ª¿¡ ¼ÓÇÏÁö ¾ÊÀ½.. */ continue; /* ÇϳªÀÇ event°¡ ¿©·¯ Eit °æ°è¿¡ °ÉÃÄ ÀÖ´Â °æ¿ì¿¡ µÎ¹ø Áߺ¹ ¼öÁýµÇÁö ¾Êµµ·Ï °Ë»ç°¡ ÇÊ¿äÇÏ´Ù.. */ for (i=0; ievent_id) /* this is already registerred.. */ break; } if (i < iEventCount) { dprint(2, " event id %d (%x) is already searched\n", event->event_id, event->event_id); continue; /* ´ÙÀ½ event ÁøÇà.. */ } else if (iEventCount >= maxEvent) { dprint(0, "!! num event is beyond limit %d\n", maxEvent); /* continue; */ /* Áö¿ø °¡´ÉÇÑ °¹¼ö¸¦ ³Ñ¾î¼¹À½.. */ goto label_end_loop; } /*------------------*/ if (iEventCount >= sz_event_list) { /* reallocation.. */ dprint(3, " ++ realloc %d event list space..\n", sz_event_list*2); p = DHL_OS_Malloc(sz_event_list * 2 * sizeof(DMW_EpgEvent)); if (p == NULL) { dprint(0, "!! out of memory for Eventlist\n"); /* Áö±Ý±îÁö ¸¸µé¾î³õÀº ¸®¼Ò½º°¡ ¸¹À¸¹Ç·Î ÀÌ »óÅ¿¡¼­ ´ë·« ¸¶¹«¸®Çؼ­ ¸®ÅÏÇÑ´Ù.. */ for (i=0; ievent_id, p); /*---------- General Info --------------*/ p->programId = event->event_id; p->programLength = event->length_in_seconds; p->startTime = event->start_time; /*---------- Rating Info --------------*/ if (flag & GET_EVENT_RATING) { if (DoFakeRatingData(rf, &p->rating)) { /* fake rrt data loading success. */ } else { status = DMW_ParseRatingDescriptor(event->descriptors, event->descriptor_length, &p->rating); if (status) { p->rating.region_count = 0; /* dprint(0, "[RRT] no rating info from eit\n"); */ } } } /*---------- Caption Info --------------*/ if (flag & GET_EVENT_CAPTION) { status = DMW_ParseCaptionDescriptor(event->descriptors, event->descriptor_length, &p->caption); if (status) { if (status != statusNotFound) dprint(0, "!! err in GetCaptionDesc:ParsingCaDesc.. %d\n", status); p->caption = NULL; } } /*---------- Title Info --------------*/ if (flag & GET_EVENT_TITLE) { if (event->title_length > 0) { if((flag&GET_EVENT_STATIC_MEM)==0) p->titleText = DHL_OS_Malloc(event->title_length+1); if (p->titleText) { p->titleTextLength = event->title_length; memcpy(p->titleText, event->title, event->title_length); } else { dprint(0, "!! out of memory for titletext len %d of event[%d][%d]\n", event->title_length, iEit, iEvent); p->titleTextLength = 0; } } else { dprint(0, "!! event title length %d\n", event->title_length); /* cafrii 060321 bugfix %n->%d */ p->titleText = NULL; p->titleTextLength = 0; } } /*---------- Text Info -------------- etmÀ» ãÀ¸·Á¸é ett list¸¦ µÚÁ®¾ß ÇÑ´Ù.. */ /* cafrii 070730 bugfix, GET_EVENT_TITLE->GET_EVENT_TEXT */ if (flag & GET_EVENT_TEXT) { UINT32 etm_id; etm_id = MakeEventETMID(source_id, event->event_id); /* cafrii 041028, MakeETMID -> MakeEventETMID */ /* ¸ðµç ett array¸¦ ´Ù µÚÁ®°¡¸ç, etm_id ¿¡ ÇØ´çµÇ´Â ett·ÎºÎÅÍ etmÀ» °¡Á®¿Í¼­ º¹»çÇÑ´Ù.. --> iEit-1, iEit, iEit+1 ÀÌ·¸°Ô ¼¼°³¸¸ ºñ±³ÇÏ¸é µÉ °Í °°´Ù. EitÀÇ À§Ä¡¿Í ±×¸® ¸Ö¸® ¶³¾îÁ® ÀÖÁö ¾ÊÀ» °ÍÀ̹ǷÎ. */ /* for (i=0; i<128; i++) // <-- inefficient!! */ for (i= max(0, iEit-1); i<= min(127, iEit+1); i++) /* cafrii 041223 change */ { if (subchInfo->n_ett[i] == 0 || subchInfo->etts[i] == NULL) continue; for (k=0; kn_ett[i]; k++) { if (subchInfo->etts[i][k] == NULL) continue; if (subchInfo->etts[i][k]->ETM_id == etm_id) { ett = subchInfo->etts[i][k]; if (ett->extended_text_message_length > 0) { if((flag&GET_EVENT_STATIC_MEM)==0) p->eventETM = DHL_OS_Malloc(ett->extended_text_message_length+1); if (p->eventETM == NULL) { dprint(0, "!! out of memory for etm len %d of ett[%d][%d]\n", ett->extended_text_message_length, i, k); p->eventETMLength = 0; } else { p->eventETMLength = ett->extended_text_message_length; memcpy(p->eventETM, ett->extended_text_message, p->eventETMLength); } } else { /* etm length °¡ À߸øµÇ¾ú´Ù.. ¹«½Ã.. */ dprint(0, "!! ett[%d][%d] etm len %d\n", i, k, ett->extended_text_message_length); p->eventETM = NULL; p->eventETMLength = 0; } goto label_end_etm; /* go out of this loop!! */ } } } label_end_etm: ; /* cafrii 070327 add to remove compiler warning */ } iEventCount++; if (iEventCount >= maxEvent) { dprint(3, " max event limit %d reached\n", maxEvent); goto label_end_loop; } } /* for iEvent */ } /* for iEit */ label_end_loop: dprint(1, "Total %d events copied.. 0x%x\n", iEventCount, EventList); if (1) /* cafrii 061106 add sorting... */ { int n_change = 0; DMW_EpgEvent tmpEvent; for (i=0; i EventList[k].startTime) { tmpEvent = EventList[i]; EventList[i] = EventList[k]; EventList[k] = tmpEvent; n_change++; } } } if (n_change > 0) dprint(2, " sorting.. %d changes\n", n_change); } if (g_PrintEventInfo) { for (i=0; iprogramId, p->startTime, p->programLength/60, p->programLength%60, p->titleTextLength, p->eventETMLength); if (p->titleTextLength && dprintable(3)) Dmc_PrintMultipleString(p->titleText, p->titleTextLength, 10, 0); /* indent 10 */ if (p->eventETMLength && dprintable(3)) Dmc_PrintMultipleString(p->eventETM, p->eventETMLength, 10, 0); /* indent 10 */ } } if (aFoundEvents && piEventCounts) { /* BK modified (05.08.02), memory leakage */ if(iEventCount>0){ if((flag&GET_EVENT_STATIC_MEM)==0) *aFoundEvents = EventList; *piEventCounts = iEventCount; } else{ /*iEventCount==0À¸·Î ³»·Á ¿À´Â °æ¿ì°¡ ¹ß»ýÇÔ, ÀÌ °æ¿ì caller¿¡¼­´Â ÇØÁ¦ÇÏÁö ¾Ê´Â´Ù. EventList freeÇϰí caller¿¡°Ô ³Ñ±âÁö ¾Ê´Â´Ù. */ if((flag&GET_EVENT_STATIC_MEM)==0) { DHL_OS_Printf("BKDBG] iEventCount=%d, free event list\n",iEventCount); DHL_OS_Free((void**)&EventList); *aFoundEvents = NULL; *piEventCounts = 0; } returnStatus = statusNotFound; /* cafrii 050808 add */ } } else { dprint(0, "!! null argument! free 0x%x\n", EventList); DMW_EPG_FreeEpgEvents(EventList, iEventCount); EventList = NULL; iEventCount = 0; } label_exit: Dmc_EpgLockCoreDB(FALSE); return returnStatus; } STATUS DMW_EPG_GetEventsInRange(int iUCMId, UINT32 nStartTime, UINT32 nDuration, DMW_EpgEventPtr *aFoundEvents, int *piEventCounts, UINT32 flag) { int idx; int rf, source_id = 0; dprint(1, "DMW_EPG_GetEventsInRange uid %d\n", iUCMId); /* Uid·Î ºÎÅÍ RF °ªÀ» ¾Ë¾Æ³½´Ù.. */ DMW_MSC_LockUcm(); idx = DMW_MSC_Uid2Index(iUCMId); if (idx >= 0) { rf = g_UCM[idx].RF; source_id = g_UCM[idx].source_id; } else { rf = -1; } DMW_MSC_UnlockUcm(); if (rf < 0) return statusNotFound; return DMW_EPG_GetEventsByRF(rf, source_id, nStartTime, nDuration, aFoundEvents, piEventCounts, flag); } STATUS DMW_EPG_GetEventInTime(int iUCMId, UINT32 nTime, DMW_EpgEventPtr *pFoundEvent, UINT32 flag) { int idx; int rf, source_id = 0; dprint(1, "DMW_EPG_GetEventsInTime uid %d\n", iUCMId); /* Uid·Î ºÎÅÍ RF °ªÀ» ¾Ë¾Æ³½´Ù.. */ DMW_MSC_LockUcm(); idx = DMW_MSC_Uid2Index(iUCMId); if (idx >= 0) { rf = g_UCM[idx].RF; source_id = g_UCM[idx].source_id; } else { rf = -1; } DMW_MSC_UnlockUcm(); if (rf < 0) return statusNotFound; return DMW_EPG_GetEventInTimeByRf(rf, source_id, nTime, pFoundEvent, flag); } STATUS DMW_EPG_GetEventInTimeByRf(int rf, int source_id, UINT32 nTime, DMW_EpgEventPtr *pFoundEvent, UINT32 flag) { int i, nEventCount; STATUS status; dprint(1, "DMW_EPG_GetEventsInTimeByRf (rf %d, sid %d)\n", rf, source_id); flag = (flag & ~0xffff) | 1; /* max event °¹¼ö¸¦ 1·Î ÇÑ´Ù. ÇѰ³¸¸ ÇÊ¿äÇϱ⠶§¹®. */ status = DMW_EPG_GetEventsByRF(rf, source_id, nTime, 1, pFoundEvent, &nEventCount, flag); /* nDuration : 1 seconds nEventToFetch : 1 ¿©·¯°³ÀÇ event°¡ ½Ã°£»óÀ¸·Î °ãÃÆÀ» ¶§¿¡µµ ´Ü 1°³¸¸ °¡Á®¿Â´Ù.. */ if (status) return status; if (nEventCount > 1) { /* ÇѰ³¸¸ °¡Á®¿À±æ ¹Ù·¨´Âµ¥, 2°³ ÀÌ»ó Get µÇ¾ú´Ù¸é Çϳª¸¸ ³öµÎ°í ´Ù Áö¿î´Ù.. */ dprint(0, "!!!! too many events %d.. delete all without 1\n", nEventCount); for(i=1; i= 0) { rf = g_UCM[idx].RF; source_id = g_UCM[idx].source_id; } else { rf = -1; } DMW_MSC_UnlockUcm(); if (rf < 0) return statusNotFound; return DMW_EPG_GetEventInTimeByRf(rf, source_id, evid, pFoundEvent, flag); } /* DMW_EPG_GetEventByEvidAndRf: API Epg DB¿¡¼­ ƯÁ¤ ÇÁ·Î±×·¥ Á¤º¸¸¦ ã´Â´Ù. @rf, @source_id´Â Á¤º¸¸¦ ãÀ¸·Á°í Çϴ ä³Î(¼­ºêä³Î) id ÀÌ´Ù. @evid´Â ã°íÀÚ ÇÏ´Â ÇÁ·Î±×·¥ÀÇ event_id ÀÌ´Ù. ÇÁ·Î±×·¥À» ã¾Æ¼­ ³»ºÎ¿¡¼­ DMW_EpgEvent* ¹öÆÛ¸¦ µ¿Àû ÇÒ´çÇϰí, @ppReturnEvent¸¦ ÅëÇØ¼­ ¸®ÅÏÇÑ´Ù. »ç¿ë ÈÄ DMW_EPG_FreeEpgEvent()¸¦ ÀÌ¿ëÇÏ¿© free ÇØ¾ß ÇÑ´Ù. @flag¸¦ »ç¿ëÇÏ¿© ¾î¶°ÇÑ À̺¥Æ® Á¤º¸¸¦ ãÀ» °ÍÀÎÁö ÁöÁ¤ÇÑ´Ù. flag Çü½ÄÀº DMW_EPG_GetEventsByRF()ÀÇ °æ¿ì¿Í ºñ½ÁÇÏÁö¸¸ maxEvent Á¤º¸´Â »ç¿ëµÇÁö ¾Ê´Â´Ù. ÀÌ ÇÔ¼ö´Â Ç×»ó ÇϳªÀÇ event¸¸ ã´Â´Ù. @flag·Î ¾Æ¹«°Íµµ ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é (0À» ÁöÁ¤Çϸé) ¾ÆÁÖ ±âº»ÀûÀÎ Á¤º¸¸¸À» ¸®ÅÏÇϹǷΠ´ëºÎºÐ GET_EVENT_TITLE¿Í °°Àº Ç÷¡±×¸¦ ÁöÁ¤ÇØ¾ß ÇÑ´Ù. ¸®Åϰª: ãÀ¸¸é statusOK, ¸øÃ£À¸¸é statusNotFound. */ STATUS DMW_EPG_GetEventByEvidAndRf(int rf, int source_id, UINT16 evid, DMW_EpgEventPtr *ppReturnEvent, UINT32 flag) { #define SAFE_EXIT(val) returnStatus=(val); goto label_exit; int iEit, iEvent; STATUS returnStatus = statusNotFound; DmcChannelInfo *chInfo = NULL; DmcSubChannelInfo *subchInfo = NULL; DMW_EpgEvent *pEvent = NULL; dprint(1, "%s: rf %d, source_id %d, flag 0x%x\n", __FUNCTION__, rf, source_id, flag); if (rf < 0) return statusNotFound; Dmc_EpgLockCoreDB(TRUE); if (!(chInfo = SRCH_ChInfo(rf))) { dprint(2, "!! rf %d chInfo not found.. maybe epg is not ready..\n", rf); SAFE_EXIT(statusNotFound); } if (!(subchInfo = SRCH_SubchInfo(chInfo, source_id))) { dprint(1, "!! subchInfo source_id %d not found..\n", source_id); SAFE_EXIT(statusNotFound); } pEvent = DHL_OS_Malloc(sizeof(DMW_EpgEvent)); if (pEvent == NULL) { dprint(0, "!! out of memory for Event\n"); SAFE_EXIT(statusOutOfMemory); } memset(pEvent, 0, sizeof(DMW_EpgEvent)); /* ¸ðµç eit, ¸ðµç event ¿¡¼­ evid¸¦ °¡Áø event Á¤º¸¸¦ ã´Â´Ù. */ for (iEit=0; iEit<128; iEit++) { eitPtr_t eit = subchInfo->eits[iEit]; if (eit == NULL) continue; /* it is not error. not received yet. */ if (eit->source_id != source_id) continue; /* something wrong. */ for (iEvent=0; eit->event && iEventnumEvents; iEvent++) { if (eit->event[iEvent].event_id != evid) continue; /* this is not what we want to find. */ /* now, we found the event! */ MakeEpgEvent(chInfo, subchInfo, iEit, &eit->event[iEvent], flag, pEvent); returnStatus = statusOK; goto label_exit; } } label_exit: Dmc_EpgLockCoreDB(FALSE); if (returnStatus != statusOK) { /* event not found. don't return event pointer. */ DHL_OS_Free((void**)&pEvent); } else { *ppReturnEvent = pEvent; } return returnStatus; } /* cafrii 060814 add */ void DMW_EPG_GetScanStatus(int uid, DmcEpgStatus *pStat) { /* ÇØ´ç subchannelÀÌ complete »óÅÂÀÎÁö ¾Æ´ÑÁö.. ÇØ´ç subchannelÀÇ ÃÑ °Ë»ö ´©Àû ½Ã°£ÀÌ ¸îÃÊÀÎÁö.. */ int rf, source_id = 0; int idx; DmcEpgStatus stat; memset(&stat, 0, sizeof(stat)); /* Uid·Î ºÎÅÍ RF °ªÀ» ¾Ë¾Æ³½´Ù.. */ DMW_MSC_LockUcm(); idx = DMW_MSC_Uid2Index(uid); if (idx >= 0) { rf = g_UCM[idx].RF; source_id = g_UCM[idx].source_id; } else { rf = -1; } DMW_MSC_UnlockUcm(); if (rf < 0) stat.cStatus = EPG_STATUS_NOT_FOUND; else { dprint(2, "DMW_EPG_GetEventsInTimeByRf (uid %d, rf %d, sid %d)\n", uid, rf, source_id); Dmc_EpgCheckScanStatus(rf, source_id, &stat); } if (pStat) *pStat = stat; } #if COMMENT ____API2____(){} #endif /* ÇØ´ç ½Ã°£ÀÇ À̺¥Æ®¿¡¼­ Caption descrioptor Á¤º¸¸¦ ÃßÃâÇÑ´Ù. ÇöÀç CC screen ratio¸¦ ¾Ë¾Æ³»±â À§Çؼ­ »ç¿ëÇÑ´Ù. Banner OSD¿¡¼­ CC icon Ç¥½Ã¿ëÀ¸·Î´Â CC MWÀÇ query¸¦ ÀÌ¿ëÇÏ´Â°Ô ³´´Ù. */ STATUS DMW_EPG_GetCaptionDescriptor(int iUCMId, UINT32 nTime, captionServiceDescriptorPtr_t *pccdesc) { STATUS status = statusOK; int i; int rf, source_id = 0; int iEit, iEvent; captionServiceDescriptor_t *cc_descriptor = NULL; DmcChannelInfo *chInfo = NULL; DmcSubChannelInfo *subchInfo = NULL; if (pccdesc == NULL) return statusInvalidArgument; /* Uid·Î ºÎÅÍ RF °ªÀ» ¾Ë¾Æ³½´Ù.. */ if (1) { int idx; DMW_MSC_LockUcm(); idx = DMW_MSC_Uid2Index(iUCMId); if (idx >= 0) { rf = g_UCM[idx].RF; source_id = g_UCM[idx].source_id; } else { rf = -1; } DMW_MSC_UnlockUcm(); } /* Core DB¸¦ °Ë»öÇÑ´Ù. */ *pccdesc = NULL; Dmc_EpgLockCoreDB(TRUE); chInfo = Dmc_GetChannelInfo(g_EpgDB, rf); if (chInfo == NULL) { dprint(2, "!! rf %d chInfo not found.. maybe epg is not ready..\n", rf); Dmc_EpgLockCoreDB(FALSE); return statusNotFound; } for (i=0; in_subchannel; i++) { if (chInfo->subchannel[i].source_id == source_id) { subchInfo = &chInfo->subchannel[i]; break; } } if (!subchInfo) { dprint(1, "!! subchInfo source_id %d not found..\n", source_id); Dmc_EpgLockCoreDB(FALSE); return statusNotFound; } for (iEit=0; iEit<=1; iEit++) /* Eit-0, Eit-1 ¸¸ °Ë»ç.. */ { eitPtr_t eit; /* temporary shortcut value */ eitEventPtr_t event; eit = subchInfo->eits[iEit]; if (eit == NULL) continue; if (eit->source_id != source_id) { dprint(0, "!! eit[%d] source id %d mismatch to subch source id %d\n", iEit, eit->source_id, source_id); continue; } if (eit->event == NULL || eit->numEvents <= 0) { continue; } for (iEvent=0; iEventnumEvents; iEvent++) { event = &eit->event[iEvent]; if (nTime < event->start_time || event->start_time + event->length_in_seconds-1 < nTime) continue; status = DMW_ParseCaptionDescriptor(event->descriptors, event->descriptor_length, &cc_descriptor); if (status) { if (status != statusNotFound) dprint(0, "!! err in GetCaptionDesc:ParsingCaDesc.. %d\n", status); cc_descriptor = NULL; } *pccdesc = cc_descriptor; /* if (cc_descriptor) break; */ break; /* cafrii 060308 fix °á°ú¿¡ »ó°ü¾øÀÌ ¹Ù·Î ºüÁ® ³ª°£´Ù. µÑ ÀÌ»óÀÇ event°¡ ÁßøµÇ´Â °æ¿ì´Â °í·Á ¾ÈÇÑ´Ù. */ } if (cc_descriptor) break; } Dmc_EpgLockCoreDB(FALSE); if (cc_descriptor == NULL) { /* Event°¡ ¾ø°Å³ª, Rating Info°¡ event³»¿¡ ¾ø´Â °æ¿ì.. */ dprint(3, " no event or no rating info..\n"); return statusNotFound; } return status; } STATUS DMW_EPG_GetCaptionDescriptorInPMT(captionServiceDescriptorPtr_t *pCC_Service) { DHL_RESULT err; STATUS status = statusNotFound; UINT8 *pDescriptor = 0; ProgramAVInfo *av = Dmc_LockAVMutex(); *pCC_Service = NULL; if (av->pmt) { /* PMT¿¡¼­ descriptorsÁ¤º¸°¡ ÀÖÀ» °æ¿ì¸¸... */ if (av->pmt->descriptors != NULL && av->pmt->descriptor_length > 0) { status = DMW_GetPsipDescriptor(av->pmt->descriptors, av->pmt->descriptor_length, caption_service_tag, 0, /* ù¹øÂ° instance¸¸ ã´Â´Ù. */ &pDescriptor); } if (!status) { err = ParseCaptionServiceDescriptor(pDescriptor, pCC_Service); if (!err) status = statusOK; else status = statusOutOfMemory; } } Dmc_UnlockAVMutex(); return status; } /* ÇöÀçÀÇ Rating Á¤º¸¸¦ queryÇÑ´Ù. rating block üũ¸¦ À§Çؼ­ »ç¿ëµÈ´Ù. */ STATUS DMW_EPG_GetRatingInfo(int iUCMId, UINT32 nTime, DMW_Rating5 *pRating) { int idx; int rf, source_id = 0; DMW_MSC_LockUcm(); idx = DMW_MSC_Uid2Index(iUCMId); if (idx >= 0) { rf = g_UCM[idx].RF; source_id = g_UCM[idx].source_id; } else { rf = -1; } DMW_MSC_UnlockUcm(); return DMW_EPG_GetRatingInfoByRF(rf, source_id, nTime, pRating); } /* cafrii 060605 add */ STATUS DMW_EPG_GetRatingInfoByRF(int rf, UINT16 source_id, UINT32 nTime, DMW_Rating5 *pRating) { int i, j; STATUS status = statusOK; DmcChannelInfo *chInfo = NULL; DmcSubChannelInfo *subchInfo = NULL; dprint(1, "%s: rf %d, sid %d, time %x\n", __FUNCTION__, rf, source_id, nTime); if (pRating == NULL) return statusInvalidArgument; pRating->region_count = 0; /* cafrii 060609 add */ /* fake rating ±â´É */ if (DoFakeRatingData(rf, pRating)) return statusOK; Dmc_EpgLockCoreDB(TRUE); chInfo = Dmc_GetChannelInfo(g_EpgDB, rf); if (chInfo == NULL) { dprint(0, "!! rf %d chInfo not found.. maybe epg is not ready..\n", rf); status = statusNotFound; goto label_exit; } for (i=0; in_subchannel; i++) { if (chInfo->subchannel[i].source_id == source_id) { subchInfo = &chInfo->subchannel[i]; break; } } if (!subchInfo) { dprint(0, "!! subchInfo source_id %d not found..\n", source_id); } for(i=0; i<=1 && subchInfo; i++) /* eit 0, 1 °Ë»ç */ { eitPtr_t eit; /* temporary shortcut value */ eitEventPtr_t event; eit = subchInfo->eits[i]; if (eit == NULL) continue; if (eit->source_id != source_id) { dprint(0, "!! eit[%d] source id %d mismatch to subch source id %d\n", i, (int)eit->source_id, source_id); continue; } if (eit->event == NULL || eit->numEvents <= 0) continue; for (j=0; jnumEvents; j++) { event = &eit->event[j]; if (nTime < event->start_time || event->start_time + event->length_in_seconds-1 < nTime) continue; /* cafrii 060609 add more check */ if (event->descriptor_length > 0) { status = DMW_ParseRatingDescriptor(event->descriptors, event->descriptor_length, pRating); if (status) { pRating->region_count = 0; /* dprint(0, "[RRT] no rating info from eit\n"); */ } else status = statusOK; } /* event¸¦ Çϳª¶óµµ ó¸®ÇßÀ¸¸é ±× ´ÙÀ½ event¸¦ º¸Áö ¾Êµµ·Ï ÇÑ´Ù. event°¡ °ãÄ¡´Â °ÍÀ» Çã¿ëÇÏÁö ¾Ê´Â´Ù. */ goto label_exit; } } status = statusNotFound; /* cafrii 060609 bugfix? */ label_exit: Dmc_EpgLockCoreDB(FALSE); return status; } STATUS DMW_EPG_GetRatingInfoInPMT(DMW_Rating5 *pRating) { STATUS status = statusNotFound; ProgramAVInfo *av; av = Dmc_LockAVMutex(); if (av->pmt) { status = DMW_ParseRatingDescriptor(av->pmt->descriptors, av->pmt->descriptor_length, pRating); if (status) pRating->region_count = 0; } Dmc_UnlockAVMutex(); return status; } BOOL DMW_EPG_IsValidRating766Info(DMW_Rating766 *pr766) { DMW_Rating766 r766 = *pr766; if (r766.type == RATING766_US_Entire_Audience || r766.type == RATING766_US_Children || r766.type == RATING766_US_MPAA || r766.type == RATING766_CANADA_English || r766.type == RATING766_CANADA_French) { return TRUE; } return FALSE; } /* General rating informationÀ» EIA 766 typeÀÇ rating informationÀ¸·Î º¯È¯ÇÑ´Ù. rating regionÀº 1, 2 ±×¸®°í Ưº°ÇÑ °æ¿ì 4 ±îÁö Æ÷ÇÔÇÑ´Ù. */ void DMW_EPG_ConvertToRating766Info(DMW_RatingRegion *pRegion, DMW_Rating766 *pR766) { int nRatingTV = 0, nRatingTVY = 0, nRatingMPAA = 0; int D=0, L=0, S=0, V=0, FV=0; int nRatingCaEng = -1, nRatingCaFre = -1; /* Canadian RatingÀº 0°ªÀÌ valid ÇϹǷΠÁÖÀÇ.. */ int i, region, count=0; DMW_Rating766 r766[RRT1_MAX_DIM]; /* = (DMW_Rating766 *)OS_Malloc(sizeof(DMW_Rating766)*5); */ if (pR766 == NULL) return; if (pRegion == NULL) { /* Missing rating üũ */ /* memset(pR766, 0, sizeof(DMW_Rating766)); */ for(i=0;iregion_id; if (0 && region==0x04) /* region 4 test -> Ȥ½Ã region 4µµ ¾²ÀÏ ¼ö ÀÖÀ¸¹Ç·Î ¸·À½*/ region = 0x01; if (region == 0x01) goto label_region_1; if (region == 0x02) goto label_region_2; /* region1,2ÀÌ ¾Æ´Ï¸é.. */ goto label_end; /* for(i=0;i=(mn)&&(val)<=(mx) ? (val) : 0) #define ADJMAX(val, mx) ((val)<=(mx) ? (val) : 0) label_region_1: /* 1. µ¿ÀÏÇÑ dimensionÀÌ ¿©·¯°³ µé¾îÀÖ´Â °æ¿ì -> dim 0, 5, 7 Àº óÀ½¿¡ ³ª¿Â °ÍÀ» ¿ì¼±. ³ª¸ÓÁö DLS..µîÀº ³ªÁß°É·Î overwrite 2. dim 0, 5, 7ÀÌ ¿©·¯°³ Æ÷ÇԵǾî ÀÖ´Â °æ¿ì -> ³»ºÎ¿¡¼­ Á¤ÇÑ ¿ì¼± ¼øÀ§´ë·Î.. */ for (i=0; inum_dimensions; i++) { if (pRegion->dimension[i].index == 0 && nRatingTV == 0) { nRatingTV = ADJRANGE(pRegion->dimension[i].value, 1, 5); } else if (pRegion->dimension[i].index == 5 && nRatingTVY == 0) { nRatingTVY = ADJRANGE(pRegion->dimension[i].value, 1, 2); } else if (pRegion->dimension[i].index == 7 && nRatingMPAA == 0) { nRatingMPAA = ADJRANGE(pRegion->dimension[i].value, 1, 8); } /* DLSV µîÀº º¹¼ö°³ Á¸ÀçÇÒ °æ¿ì ÃÖÈÄÀÇ °ªÀÌ Ã¤ÅõÊ. */ else if (pRegion->dimension[i].index == 1) D = pRegion->dimension[i].value ? 1 : 0; else if (pRegion->dimension[i].index == 2) L = pRegion->dimension[i].value ? 1 : 0; else if (pRegion->dimension[i].index == 3) S = pRegion->dimension[i].value ? 1 : 0; else if (pRegion->dimension[i].index == 4) V = pRegion->dimension[i].value ? 1 : 0; else if (pRegion->dimension[i].index == 6) FV = pRegion->dimension[i].value ? 1 : 0; } /* À§¿¡¼­ ¹Ì¸® ÃʱâÈ­.. */ /* memset(r766,0,sizeof(DMW_Rating766)*RRT1_MAX_DIM); */ /* validity check.. some combination is not allowed */ if (nRatingTV) { r766[count].type = RATING766_US_Entire_Audience; r766[count].value = nRatingTV; if (nRatingTV != 1) { /* TV-NoneÀº ¾î¶°ÇÑ DLSVµµ Çã¿ëÇÏÁö ¾ÊÀ½ */ r766[count].D = nRatingTV != 5 ? D : 0; /* TV-MA´Â D¸¦ Çã¿ëÇÏÁö ¾ÊÀ½ */ r766[count].L = L; r766[count].S = S; r766[count].V = V; } count++; } if (nRatingTVY) { r766[count].type = RATING766_US_Children; r766[count].value = nRatingTVY; r766[count].FV = nRatingTVY == 2 ? FV : 0; /* FV´Â TV-Y7¿¡¼­¸¸ Çã¿ë */ count++; } if (nRatingMPAA) { r766[count].type = RATING766_US_MPAA; r766[count].value = nRatingMPAA; count++; } goto label_end; label_region_2: /* iskang 080623. 1°³¸¸ °Ë»çÇÏ´ø °ÍÀº dim¼ö¸¸Å­ ÇÑ´Ù. */ /* cafrii 081217 bugfix!! dimensionÀÌ 3°³ ÀÌ»óÀÎ °æ¿ì r766 buf overflow ¹ß»ý!! loop ¸ÕÀú µ¹¸é¼­ üũ ÇÑ ÈÄ r766 write ÇÔ. ¸Ç óÀ½ ¹ß°ßµÇ´Â °ªµé·Î nRatingCaEng, nRatingCaFre ÀúÀå. */ for (i=0; inum_dimensions; i++) { if (pRegion->dimension[i].index == 0 && nRatingCaEng == -1) { nRatingCaEng = ADJMAX(pRegion->dimension[i].value, 6); } else if (pRegion->dimension[i].index == 1 && nRatingCaFre == -1) { nRatingCaFre = ADJMAX(pRegion->dimension[i].value, 5); } } if (nRatingCaEng >= 0) { r766[count].type = RATING766_CANADA_English; r766[count].value = nRatingCaEng; count++; } if (nRatingCaFre >= 0) { r766[count].type = RATING766_CANADA_French; r766[count].value = nRatingCaFre; count++; } goto label_end; #undef ADJRANGE #undef ADJMAX label_end: memcpy(pR766, r766, sizeof(DMW_Rating766)*RRT1_MAX_DIM); } char *DMW_EPG_Rating766String(DMW_Rating766 *pInfo, char *buf) { /* argument 'buf'´Â ÃæºÐÇÑ °ø°£À» °¡Áö°í ÀÖ¾î¾ß ÇÑ´Ù°í °¡Á¤ÇÏÀÚ. ÃÖ´ë ±æÀÌ´Â "TV-PG (DLSV)" "TV-PG-D-L-S-V" "TV-PG (D,L,S,V)" */ static char _buf[30]; /* internal static buffer */ if (buf == NULL) buf = _buf; if (pInfo->type == RATING766_US_Children) { strcpy(buf, (pInfo->value == 1) ? "TV-Y" : (pInfo->value == 2) ? "TV-Y7" : "TV-Y?"); strcat(buf, pInfo->value==2 && pInfo->FV ? "-FV" : ""); } else if (pInfo->type == RATING766_US_Entire_Audience) { strcpy(buf, (pInfo->value == 1) ? "TV-None" : (pInfo->value == 2) ? "TV-G" : (pInfo->value == 3) ? "TV-PG" : (pInfo->value == 4) ? "TV-14" : (pInfo->value == 5) ? "TV-MA" : "TV-?"); #if 0 /* °ýÈ£¸¦ »ç¿ëÇϴ ǥ±â¹ý, "TV-PG (DLSV)" */ if (pInfo->D||pInfo->L||pInfo->S||pInfo->V) { strcat(buf, " ("); if (pInfo->D) strcat(buf, "D"); if (pInfo->L) strcat(buf, "L"); if (pInfo->S) strcat(buf, "S"); if (pInfo->V) strcat(buf, "V"); strcat(buf, ")"); } #elif 0 /* °ýÈ£¿Í coma »ç¿ëÇϴ ǥ±â¹ý, "TV-PG (D,L,S,V)" cafrii 060801, remove parenthasis to shrink string length --> "TV-PG D,L,S,V" */ if (pInfo->D||pInfo->L||pInfo->S||pInfo->V) { BOOL comma = 0; strcat(buf, " "); /* strcat(buf, " ("); */ if (pInfo->D) strcat(buf, comma ? ",D" : "D"), comma=1; if (pInfo->L) strcat(buf, comma ? ",L" : "L"), comma=1; if (pInfo->S) strcat(buf, comma ? ",S" : "S"), comma=1; if (pInfo->V) strcat(buf, comma ? ",V" : "V"), comma=1; /* strcat(buf, ")"); */ } #elif 1 /* dash¸¦ »ç¿ëÇϴ ǥ±â¹ý. "TV-PG-D-L-S-V" */ if (pInfo->D||pInfo->L||pInfo->S||pInfo->V) { strcat(buf, pInfo->D ? "-D" : ""); strcat(buf, pInfo->L ? "-L" : ""); strcat(buf, pInfo->S ? "-S" : ""); strcat(buf, pInfo->V ? "-V" : ""); } #else /* any other format? */ #endif } else if (pInfo->type == RATING766_US_MPAA) { strcpy(buf, (pInfo->value == 1) ? "MPAA-N/A" : (pInfo->value == 2) ? "MPAA-G" : (pInfo->value == 3) ? "MPAA-PG" : (pInfo->value == 4) ? "MPAA-PG-13" : (pInfo->value == 5) ? "MPAA-R" : (pInfo->value == 6) ? "MPAA-NC-17" : (pInfo->value == 7) ? "MPAA-X" : (pInfo->value == 8) ? "MPAA-NR" : "MPAA ?"); } else if (pInfo->type == RATING766_CANADA_English) { strcpy(buf, (pInfo->value == 0) ? "E" : (pInfo->value == 1) ? "C" : (pInfo->value == 2) ? "C8+" : (pInfo->value == 3) ? "G" : (pInfo->value == 4) ? "PG" : (pInfo->value == 5) ? "14+" : (pInfo->value == 6) ? "18+" : "CA Eng ?"); } else if (pInfo->type == RATING766_CANADA_French) { strcpy(buf, (pInfo->value == 0) ? "E" : (pInfo->value == 1) ? "G" : (pInfo->value == 2) ? "8 ans+" : (pInfo->value == 3) ? "13 ans+" : (pInfo->value == 4) ? "16 ans+" : (pInfo->value == 5) ? "18 ans+" : "CA Fre ?"); } else { /* RATING766_NONE */ strcpy(buf, "None"); /* ÀÌ·±°Ô ³ª¿À¸é ¾ÈµÈ´Ù. */ } return buf; } /*---------------------------------- DMW_EPG_CheckRatingBlockByRRT RRT ±âÁØÀ¸·Î pRating Á¤º¸ÀÇ block ¿©ºÎ¸¦ üũÇÑ´Ù. param: IN: pRating OUT: pbNoRating, return value TRUE : blocked */ BOOL DMW_EPG_CheckRatingBlockByRRT(DMW_Rating5 *pRating, BOOL *pbNoRating) { /* ÁÖÀÇ: RRT°¡ º¯°æµÇ´Â ¼ø°£ µîÀÇ Æ¯¼öÇÑ °æ¿ì¿¡´Â Rating°ú RRT°¡ ¼­·Î ÀÏÄ¡ÇÏÁö ¾ÊÀ» °æ¿ì°¡ ÀÖ´Ù. index Á¶°Ç üũ¸¦ È®½ÇÈ÷ ÇØ¾ß ÇÑ´Ù. ¿¹: °¢ ä³Îº°·Î ´Ù¸¥ RRT versionÀÌ Àü¼ÛµÇ°í ÀÖ´Â °æ¿ì, ä³ÎÀ» º¯°æÇÒ ¶§.. */ int iRegion, iDim; BOOL bNoRating = TRUE; /* RatingÀÇ °¢ °ªµéÀÌ RRTÀÇ ¾î¶°ÇÑ Á¶°Ç¿¡µµ °É¸®Áö ¾ÊÀ¸¸é No RatingÀÌ µÈ´Ù. Çϳª¶óµµ Á¶°Ç¿¡ ¸Â´Â°Ô ÀÖÀ¸¸é (block ¿©ºÎ¿¡ °ü°è¾øÀÌ) No RatingÀÌ ¾Æ´Ï´Ù. */ BOOL bBlock = FALSE; int index, value, k; rrtSectionPtr_t pRrt; Dmc_EpgLockRrtDB(TRUE, TRUE); /* cafrii 060719 CoreDB->RrtDB */ pRrt = Dmc_EpgGetCurrentRrt(); if (pRrt == NULL) { /* RRT°¡ ¾ÆÁ÷ ¾ø´Â °æ¿ì¸¦ No RatingÀ¸·Î º¼ °ÍÀÎÁö¿¡ ´ëÇØ¼­´Â À̰ßÀÌ ÀÖÀ» ¼ö ÀÖÀ½. ±×·¯³ª Region 5ÀÇ ratingÀº RRT ¾øÀÌ´Â ¾Æ¹«·± Àǹ̰¡ ¾ø´Â °ÍÀ̹ǷΠRatingÀÌ ¾ø´Â °Å³ª ´Ù¸¦ ¹Ù ¾ø´Ù. */ goto label_exit; } /* region 5¸¸ °Ë»ç. Â÷ ÈÄ¿¡´Â regionÀÌ ´õ Ãß°¡µÉ Áö´Â ¸ð¸£°ÚÀ¸³ª.. ÇöÀç´Â 5. region 5°¡ ¿©·¯°³ ÀÖ´Â °æ¿ì óÀ½ À§Ä¡ÇÏ´Â region 5¸¸ ó¸®ÇÔ. ±× ÀÌÈÄÀÇ region 5´Â ¹«½Ã. */ /* cafrii 060719 change region 5°¡ ¿©·¯°³·Î ³ª´©¾îÁ® Á¸ÀçÇÒ ¼ö ÀÖÀ¸¹Ç·Î ¸ðµç region 5¸¦ ´Ù °Ë»çÇØ¾ß ÇÑ´Ù. */ #if 0 /* search region 5 */ for (iRegion=0; iRegionregion_count; iRegion++) { if (pRating->region[iRegion].region_id == 5) break; } if (iRegion >= pRating->region_count) { dprint(3, "check rating: region 5 not found in rating info\n"); goto label_exit; } #endif for (iRegion=0; iRegionregion_count; iRegion++) { #if IGNORE_RRT_REGION==0 if (pRating->region[iRegion].region_id != 5) continue; #else if (pRating->region[iRegion].region_id == 1 || pRating->region[iRegion].region_id == 2) continue; #endif for (iDim=0; iDimregion[iRegion].num_dimensions; iDim++) { /* Rating Á¤º¸·ÎºÎÅÍ rating dimension°ú value¸¦ °¡Á®¿Â´Ù. */ index = pRating->region[iRegion].dimension[iDim].index; value = pRating->region[iRegion].dimension[iDim].value; /* RRTÀÇ dimension & value¸¦ Âü°íÇÏ¿© block ¿©ºÎ¸¦ ¾Ë¾Æ³½´Ù. */ if (pRrt->dimensions_defined <= index) { dprint(0, "[RRT] !! Warning : Invalid Dimension idx %d (should be 0 ~ %d)\n", index, 0, pRrt->dimensions_defined-1); continue; } if (pRrt->dimension[index].first_value_empty) value--; if (value < 0) { dprint(0, "[RRT] !! value 0 used in empty first dimension\n"); continue; } /* ¾Æ·¡ °æ¿ì´Â value°¡ ÃÖ´ë°ªÀ» ¹þ¾î³­ À߸øµÈ °æ¿ìÀÌÁö¸¸, grad schedule¿¡ µû¶ó ÃÖ¼Ò ´ëÀÀÀº ÇÑ´Ù. */ if (pRrt->dimension[index].values_defined <= value) { /* graduate schedule°ú ÇÏÀ§ value °ª¿¡ µû¶ó block ÇØ¾ß ÇÒ ¼öµµ ÀÖÀ½. */ for (k=0; kdimension[index].values_defined; k++) { if (pRrt->dimension[index].value[k].block_on) { bBlock = TRUE; break; } } if (bBlock) { dprint(0, "[RRT] Notice: undefined value %d, but blocked\n", value); break; } else { dprint(0, "[RRT] !! Warning : Invalid value %d\n", value); continue; } } bNoRating = FALSE; /* Á¦´ë·Î µÈ rrt entry¸¦ ¹ß°ßÇßÀ¸¹Ç·Î Àû¾îµµ missing ratingÀº ¾Æ´Ï´Ù. block ¿©ºÎ¿Í´Â »ó°ü ¾øÀ½. */ if (pRrt->dimension[index].value[value].block_on) { bBlock = TRUE; break; } } } label_exit: Dmc_EpgLockRrtDB(FALSE, TRUE); /* cafrii 060719 CoreDB->RrtDB */ if (bBlock) /* in case for undefined value block */ bNoRating = FALSE; if (pbNoRating) *pbNoRating = bNoRating; return bBlock; } #if 0 /* sorting library todo.. string compositionÀ» ÇÒ ¶§ sortingÀ» ÇØ¾ß ÇÏ´ÂÁö´Â °­Á¦ »çÇ×Àº ¾øÀ¸³ª ±âÁ¸ Äڵ忡¼­ Çß´ø ÀûÀÌ ÀÖÀ¸¹Ç·Î ½Ã°£ µÉ¶§ Á¤¸®ÇÏÀÚ. */ static int QMakeNum(UINT32 numStr) { UINT16 *temp=(UINT16 *)&numStr; return *temp *100000 + *(temp+1); } static void QSwap(UINT32 *a, UINT32 *b) { UINT32 temp; if(a==b) return; temp=*a; *a=*b; *b=temp; } static void BSort(UINT32 *str, UINT16 numItem) { int i, j; if(numItem <= 1) return; for(i=0; i QMakeNum(str[j+1])) QSwap(&str[j], &str[j+1]); } } } #endif /* #define RATING_MSG_SEPARATOR '-' */ UINT16 RATING_MSG_SEPARATOR = '-'; UINT16 RATING_MSG_SEPARATOR_COMMA = ','; /* Dynamic RRT »óÈ£ ÂüÁ¶¿¡ ÀÇÇÑ ÇöÀç ÇÁ·Î±×·¥ÀÇ Rating stringÀ» °¡Á®¿Â´Ù. ¸¸¾à ÇØ´ç regionÀÇ Á¤º¸·ÎºÎÅÍ ÀûÀýÇÑ stringÀ» ¾òÁö ¸øÇϸé FALSE¸¦ ¸®ÅÏÇÑ´Ù. */ STATUS DMW_EPG_GetRatingStringByRRT(DMW_Rating5 *pRating, UINT16 *str, int nBufSize) { int iRegion, len; int index, value; int iDim; STATUS status = statusOK; #define MAX_TEXT 32 /* °¢ dimensionº° ±ÛÀÚ´Â ÃÖ´ë 32 */ UINT16 cTemp[MAX_TEXT+1]; rrtSectionPtr_t rrt; if (pRating == NULL || str == NULL) return statusInvalidArgument; str[0] = 0; Dmc_EpgLockRrtDB(TRUE, TRUE); /* cafrii 060719 CoreDB->RrtDB */ rrt = Dmc_EpgGetCurrentRrt(); if (rrt == NULL) { dprint(1, "!! %s: no rrt yet\n", __FUNCTION__); status = statusError; goto label_exit; } #if 0 /* ¿¹Àü ¹æ½Ä.. »ç¿ë ±ÝÁö.. */ /* search region 5 */ iRegion = -1; for (i=0; iregion_count; i++) { if (pRating->region[i].region_id == 5) { iRegion = i; break; } } if (iRegion < 0) { dprint(2, " region 5 not found\n"); status = statusNotFound; goto label_exit; } #endif status = statusNotFound; /* cafrii 060719 change region 5°¡ ¿©·¯°³·Î ³ª´©¾îÁ® Á¸ÀçÇÒ ¼ö ÀÖÀ¸¹Ç·Î ¸ðµç region 5¸¦ ´Ù °Ë»çÇØ¾ß ÇÑ´Ù. */ for (iRegion=0; iRegionregion_count; iRegion++) { #if IGNORE_RRT_REGION==0 if (pRating->region[iRegion].region_id != 5) continue; #else if (pRating->region[iRegion].region_id == 1 || pRating->region[iRegion].region_id == 2) continue; #endif /* BSort((UINT32 *)pRating->region[region].dims, pRating->region[region].dimsNum); */ /* ¸ðµç dimensionÀÇ À̸§À» decodingÇÏ¿© ¿¬°á½ÃŲ´Ù. */ for (iDim=0; iDimregion[iRegion].num_dimensions; iDim++) { index = pRating->region[iRegion].dimension[iDim].index; value = pRating->region[iRegion].dimension[iDim].value; if (rrt->dimensions_defined <= index) { dprint(3, "[RRT] !! Warning : Invalid Dimension idx %d (should be 0 ~ %d)\n", index, 0, rrt->dimensions_defined-1); continue; } if (rrt->dimension[index].first_value_empty) value--; if (value < 0) { /* dprint(3, "[RRT] !! value 0 used in empty first dimension\n"); */ continue; } if (rrt->dimension[index].values_defined <= value) { /* dprint(3, "[RRT] !! invalid value \n"); */ continue; } len = DLIB_PSI_DecodeMultipleStringStructure( rrt->dimension[index].value[value].abbrev_rating_value_length, rrt->dimension[index].value[value].abbrev_rating_value, "eng", MAX_TEXT, cTemp); if (len <= 0) len = DLIB_PSI_DecodeMultipleStringStructure( rrt->dimension[index].value[value].abbrev_rating_value_length, rrt->dimension[index].value[value].abbrev_rating_value, "kor", MAX_TEXT, cTemp); if (len <= 0) { /* dprint(0, "!! decode MSS return null\n"); */ } else if (len + UniStrLen(str) >= nBufSize) { dprint(0, "!! warning: rating string buf overflow.\n"); } else { status = statusOK; if (len >= MAX_TEXT) cTemp[MAX_TEXT-1] = 0; else cTemp[len] = 0; if (str[0] == 0) UniStrCopy(str, cTemp); else { len = UniStrLen(str); str[len] = (UINT16) RATING_MSG_SEPARATOR_COMMA; UniStrCopy(str+len+1, cTemp); } } } } label_exit: Dmc_EpgLockRrtDB(FALSE, TRUE); /* cafrii 060719 CoreDB->RrtDB */ return status; } #if COMMENT ____API3____(){} #endif /* ÀÌ API3 ±×·ìÀÇ ÇÔ¼öµéÀº DMW_EpgUtils.c ¿¡¼­ °¡Á®¿Â °ÍµéÀÓ. EpgUtils ÀϺΠÇÔ¼öµéÀº DLIB_PSI_Utils.c ·Î À̵¿µÇ¾úÀ½ */ void DMW_EPG_FreeMLInfo(DMW_AudioElementPtr aLingualInfos) { if (aLingualInfos) DHL_OS_Free((void**)&aLingualInfos); } /* PMT·ÎºÎÅÍ DMW_AudioElement Á¤º¸¸¦ ¾ò´Â´Ù. language Á¤º¸°¡ ¾ø´Â °æ¿ì¿¡µµ AudioElement¸¦ ÀúÀåÇÑ´Ù. Áï Àüü audio °¹¼ö¸¦ ¾Ë¼ö ÀÖ´Ù. */ STATUS DMW_EPG_GetMLInfoInPMT(MPEG_PMT *pmt, DMW_AudioElementPtr *aLingualInfos, int *iLingualCount) { int i, j; STATUS status = statusOK; DHL_RESULT dhr; DMW_AudioElementPtr pAudioElements = NULL; int nAudioStreamPMT; /* PMT¿¡ µî·ÏµÈ Àüü audio stream °¹¼ö */ int iAudioCount = 0; /* Áߺ¹µÇÁö ¾ÊÀº PID¸¦ °¡Áø audio stream °¹¼ö */ UINT32 languageCode; int serviceType; BOOLEAN bSameAudioExist = FALSE; if (pmt == NULL) { status = statusNotFound; goto label_end; } /* PMT¿¡¼­ audio stream ÀÇ °¹¼ö¸¦ count. */ nAudioStreamPMT = 0; for (i=0; inumStreams; i++) { switch (pmt->streams[i].stream_type) { case StreamType_AC3Audio: case StreamType_MPEG1Audio: case StreamType_MPEG2Audio: case StreamType_AACAudioADTS: case StreamType_AACAudioLATM: nAudioStreamPMT++; break; default: break; } } if (nAudioStreamPMT == 0) { status = statusNotFound; goto label_end; } /* ¸Þ¸ð¸®¸¦ ÇÒ´çÇÑ´Ù. */ pAudioElements = DHL_OS_Malloc(sizeof(DMW_AudioElement) * nAudioStreamPMT); if (pAudioElements == NULL) { dprint(0, "!! %s: Out of memory for AudioElement\n", __FUNCTION__); status = statusOutOfMemory; goto label_end; } memset(pAudioElements, 0, sizeof(DMW_AudioElement) * nAudioStreamPMT); for (i=0; inumStreams; i++) { switch (pmt->streams[i].stream_type) { case StreamType_AC3Audio: case StreamType_MPEG1Audio: case StreamType_MPEG2Audio: case StreamType_AACAudioADTS: case StreamType_AACAudioLATM: break; default: continue; break; } /* ÀÌ¹Ì °°Àº PIDÀÇ Audio°¡ gatherµÈ °æ¿ì´Â ¹«½Ã. */ bSameAudioExist = FALSE; for (j=0; jstreams[i].elementary_PID) { bSameAudioExist = TRUE; break; } } if (bSameAudioExist) continue; dhr = DLIB_PSI_GetLanguageCodeFromDescriptors( pmt->streams[i].descriptors, pmt->streams[i].descriptor_length, 0, &languageCode, &serviceType); /* cafrii 060220 fix audio °¹¼ö Á¤º¸¸¦ ¾ò´Â ¸ñÀûµµ ÀÖÀ¸¹Ç·Î ML Á¤º¸°¡ ¾ø´õ¶óµµ audio count´Â Ãß°¡ÇØÁØ´Ù. */ if (dhr != DHL_OK) { languageCode = 0; serviceType = 0; } pAudioElements[iAudioCount].elementaryPid = pmt->streams[i].elementary_PID; pAudioElements[iAudioCount].ISO639_LanguageCode = languageCode; pAudioElements[iAudioCount].serviceType = serviceType; pAudioElements[iAudioCount].audioType = eDHL_AUDIO_TYPE_AC3; switch (pmt->streams[i].stream_type) { case StreamType_AC3Audio: break; case StreamType_MPEG1Audio: pAudioElements[iAudioCount].audioType = eDHL_AUDIO_TYPE_MPEG_1; break; case StreamType_MPEG2Audio: pAudioElements[iAudioCount].audioType = eDHL_AUDIO_TYPE_MPEG_2; break; case StreamType_AACAudioADTS: pAudioElements[iAudioCount].audioType = eDHL_AUDIO_TYPE_AAC_ADTS; break; case StreamType_AACAudioLATM: pAudioElements[iAudioCount].audioType = eDHL_AUDIO_TYPE_AAC_LATM; break; default: continue; break; } iAudioCount++; } /* iAudioCount¿Í nAudioStreamPMTÀº ´Ù¸¦ ¼ö ÀÖÀ½. audio pid°¡ Áߺ¹µÈ °æ¿ì iAudioCount´Â ´õ ÀûÀº °ªÀ» °¡Áø´Ù. */ if (iAudioCount <= 0) { dprint(0, "!! audio count cannot be 0!\n"); *iLingualCount = 0; *aLingualInfos = NULL; DHL_OS_Free((void**)&pAudioElements); /* cafrii 060607 add for bugfix.. memory leak */ status = statusNotFound; } else { *iLingualCount = iAudioCount; *aLingualInfos = pAudioElements; status = statusOK; } label_end: return status; } /* cafrii 061114 add */ #if SUPPORT_MPEG_AUDIO #define StreamTypeToAudioType(t) ( \ (t) == StreamType_AC3Audio ? eDHL_AUDIO_TYPE_AC3: \ (t) == StreamType_MPEG2Audio ? eDHL_AUDIO_TYPE_MPEG_2 : eDHL_AUDIO_TYPE_UNKNOWN ) #else #define StreamTypeToAudioType(t) ( \ (t) == StreamType_AC3Audio ? eDHL_AUDIO_TYPE_AC3 : eDHL_AUDIO_TYPE_UNKNOWN ) #endif /* VCTÀÇ Service Location Descriptor Á¤º¸¸¦ ÀÌ¿ëÇÏ¿© audio language Á¤º¸¸¦ ¾ò¾î¿Â´Ù. ³»ºÎ¿¡¼­ ¸Þ¸ð¸® ÇÒ´çÀ» Çϱ⠶§¹®¿¡ »ç¿ë ÈÄ¿¡ FreeMLInfo ÇØ¾ß ÇÔ. */ STATUS DMW_EPG_GetMLInfoInVctDescriptors(UINT8 *descriptors, int descriptor_length, DMW_AudioElementPtr *aMLInfo, int *piCount) { int i, k, err; int count; /* Áߺ¹µÇÁö ¾Ê´Â ¼ø¼öÇÑ audio °¹¼ö */ DMW_AudioElementPtr mlInfo; int mlCount; tDHL_AudioCodingType audioType; UINT8 *desc; serviceLocationDescriptorPtr_t sld = NULL; /* service_location_tag : 0xA1 */ err = GetMpegDescriptor(descriptors, descriptor_length, 0xA1, 0, &desc); if (err) { return statusNotFound; } err = ParseServiceLocationDescriptor(desc, &sld); if (err) { sld = NULL; return (STATUS)err; /* ÁÖ·Î ¸Þ¸ð¸® °ü·Ã ¿¡·¯.. */ } /* count audio stream number */ mlCount = 0; for (i=0; inumber_elements; i++) { /* cafrii 061114 add support multiple audio format */ if (StreamTypeToAudioType(sld->element[i].stream_type) != eDHL_AUDIO_TYPE_UNKNOWN) mlCount++; } if (mlCount == 0) { FreeMpegDescriptor(sld); return statusNotFound; } mlInfo = (DMW_AudioElement *) DHL_OS_Malloc(mlCount * sizeof(DMW_AudioElement)); if (mlInfo == NULL) { FreeMpegDescriptor(sld); return statusOutOfMemory; } memset(mlInfo, 0, mlCount * sizeof(DMW_AudioElement)); for (i=0, count=0; inumber_elements; i++) { #if DEVELOPMENT_BUILD /* cafrii 080303 avoid using assert */ DHL_ASSERT(count < mlCount, "error"); #else /* cafrii 080305 fix again ¿¹Àü¿¡´Â ÀÌ À§Ä¡°¡ count++ ±¸¹® ¾Æ·¡¿¡ ÀÖ¾ú´Ù°¡ Äڵ带 À§·Î ¿Å±ä °ÍÀ̹ǷΠ>= °¡ ¸ÂÀ½. */ if (count >= mlCount) { dprint(0, "%s: ml count %d exceed to expected %d\n", __FUNCTION__, count, mlCount); break; } #endif /* cafrii 061114 add support multiple audio format */ audioType = StreamTypeToAudioType(sld->element[i].stream_type); if (audioType == eDHL_AUDIO_TYPE_UNKNOWN) continue; /* Áö¿øÇÏÁö ¾Ê´Â streamÀº °Ç³Ê¶Ü. */ /* ±âÁ¸¿¡ Áߺ¹µÇ´Â pid ÀÖ´ÂÁö È®ÀÎ.. */ for (k=0; kelement[i].elementary_PID) break; } if (k < count) /* Áߺ¹ ¹ß°ß. skip.. */ continue; mlInfo[count].elementaryPid = sld->element[i].elementary_PID; mlInfo[count].ISO639_LanguageCode = sld->element[i].ISO639_language_code; mlInfo[count].serviceType = 0; mlInfo[count].audioType = audioType; /* AudioType_AC3; */ count++; } FreeMpegDescriptor(sld); if (aMLInfo) *aMLInfo = mlInfo; if (piCount) *piCount = count; /* mlCount¿Í ´Ù¸¦ ¼ö ÀÖÀ½. pid Áߺ¹ÀÇ °æ¿ì.. */ return statusOK; } STATUS DMW_EPG_GetMLInfoInVct(xvctChannelPtr_t vctch, DMW_AudioElementPtr *aMLInfo, int *piCount) { if (vctch == NULL) return statusInvalidArgument; return DMW_EPG_GetMLInfoInVctDescriptors(vctch->descriptors, vctch->descriptor_length, aMLInfo, piCount); } #if COMMENT _____DebugSymbol____(){} #endif #if DMW_REGISTER_DEBUG_SYMBOL static DHL_SymbolTable _EpgIntfSymbolLink[] = { DHL_FNC_SYM_ENTRY(DMW_EPG_DeleteAll), DHL_FNC_SYM_ENTRY(DMW_EPG_SetFakeRatingData), DHL_VAR_SYM_ENTRY(g_PrintEventInfo), //DHL_VAR_SYM_ENTRY(g_Trace_EpgIntf), DHL_VAR_SYM_ENTRY(RATING_MSG_SEPARATOR), }; #endif void DMW_EPG_RegisterEpgIntfSymbols() { #if DMW_REGISTER_DEBUG_SYMBOL DHL_DBG_RegisterSymbols(_EpgIntfSymbolLink, DHL_NUMSYMBOLS(_EpgIntfSymbolLink)); #endif } #if COMMENT _____Test_____(){} #endif #if DMW_EPG_TESTCODE #include "DMW_SysTime.h" void TestEpgGetEvents(int rf, int source_id) { int err, st; UINT32 utc, gps; DMW_GetUTCTime(NULL, &utc); gps = DMW_ConvertUTC2GPS(NULL, utc); err = DMW_EPG_GetEventsByRF(rf, source_id, gps, 72000, NULL, NULL, 1000); DHL_OS_Printf("************* GetEvents err %d ***************\n", err); st = Dmc_EpgCheckScanStatus(rf, source_id, NULL); DHL_OS_Printf("************ EpgStatus : %s *************\n", EpgStatusString(st)); } int g_StopTestEpgIntfOverload = 0; void TestEpgIntfOverload(int rf, int source_id) { int err; while (g_StopTestEpgIntfOverload == 0) { DHL_OS_Printf("************* start epg update ***************\n"); err = Dmc_EpgUpdateStart(rf, Dmc_GetCurrentTsd(), NULL, 0, 0); DHL_OS_Printf("************* err in update start %d ***************\n", err); DHL_OS_Delay(rand()%10 * 1000); TestEpgGetEvents(rf, source_id); DHL_OS_Delay(rand()%10 * 1000); } } /* Å×½ºÆ® ¹æ¹ý: epg_list¸¦ ¼öÇàÇÏ¿© ÇØ´ç ä³Î epg Àüü ¸®½ºÆ®¸¦ º¸°í, ett°¡ Æ÷ÇÔµÈ Æ¯Á¤ event¸¦ ¼±Åà ÈÄ ±× event id¸¦ ÁöÁ¤ÇÑ´Ù. title, text°¡ Á¦´ë·Î Ãâ·ÂµÇ´ÂÁö È®ÀÎÇÑ´Ù. */ void TestEpgFindEventByEvid(int rf, int source_id, UINT16 evid) { STATUS status; UINT32 tick1, tick2; /* for performance checking */ UINT32 flag = GET_EVENT_TITLE | GET_EVENT_TEXT; DMW_EpgEvent *pEvent = NULL; char buf1[64]; DHL_OS_Printf("== searching evid %x event in rf %d/$%d channel..\n", evid, rf, source_id); tick1 = DHL_OS_GetMsCount(); status = DMW_EPG_GetEventByEvidAndRf(rf, source_id, evid, &pEvent, flag); tick2 = DHL_OS_GetMsCount(); if (status) { DHL_OS_Printf("!! event not found.\n"); return; } DHL_OS_Printf("== event found in %d ms\n", (tick2-tick1)*1000/1000); DHL_OS_Printf(" start time: gps %x, %s\n", pEvent->startTime, GpsTimeString2(pEvent->startTime, buf1, 2)); DHL_OS_Printf(" duration: %d sec\n", pEvent->programLength); DHL_OS_Printf(" title:\n"); Dmc_PrintMultipleString(pEvent->titleText, pEvent->titleTextLength, 6, 0); DHL_OS_Printf(" text:\n"); Dmc_PrintMultipleString(pEvent->eventETM, pEvent->eventETMLength, 6, 0); DMW_EPG_FreeEpgEvent(pEvent); } #endif /* DMW_EPG_TESTCODE */ /******************************************************************** $Log: DMW_EpgInterface.c,v $ 1.29 2005/2/3 remove unused header include change some debug level 1.28 2005/1/6 DMW_EPG_TESTCODE ¸¦ 0À¸·Î.. TestEpgGetEvents ¿¡¼­ Standard API »ç¿ë ¾ÈÇÔ 1.27 2004/12/23 EventÀÇ È¿À²ÀûÀÎ °Ë»öÀ» À§ÇÑ Á¶°Ç½Ä Ãß°¡.. descriptor parser ¸î°³ public API ·Î º¯°æ 1.26 2004/12/22 DMW_EpgEvent ±¸Á¶Ã¼¿¡¼­ ¾È¾²´Â ÇÊµå »èÁ¦ 1.25 2004/12/09 DMW_EPG2_GetRating ÃÖÀûÈ­ 1.24 2004/12/08 DMW_EPG2_GetEvents ¿¡¼­ debug level ¼öÁ¤ 1°÷ 1.23 2004/11/30 DMW_EPG2_GetRating prototype changed 1.22 2004/11/01 eit first mode¸¦ µðÆúÆ®·Î ÇÏÁö ¾ÊÀ½. 1.21 2004/10/28 MakeETMID¸¦ event/channel ¿ë ±¸ºÐ 1.2 2004/10/19 tsd argument is added in CoreAPI 1.1 2004/7/28 add statusOK in GetEventsInTime 1.0 2004/07/15 first design *********************************************************************/