专利名称:数字电视epg信息的自动清理、增加记录和查找获取方法
技术领域:
本发明属于数字电视机技术领域,更明确地说涉及数字电视EPG信息的自动清理、增加记录和查找获取方法的设计。
背景技术:
数字电视接收终端产品中,电子节目指南(Electronic Program Guide)EPG是与消费者关系非常密切的一项功能。通过电子节目指南,消费者可以了解各频道节目未来的播放情况、进行节目预约、阅读剧情简介、获取数字传媒的各种信息等等。
传统的EPG信息的自动删除、增加记录和查找获取方法没有自动维护功能,不能防止数据溢出,工作不够稳定。同时,其信息存储和检索速度较慢,调用接口也较麻烦,不利于移植推广。
发明内容
本发明地目的,就在于克服上述缺点和不足,提供一种完整、简单、易维护的数字电视EPG信息的自动清理、增加记录和查找获取方法。它具有自动维护功能,可以防止数据溢出,工作十分稳定。同时,其信息存储和检索速度快,调用接口简单。而且具有良好的可移植性,除数字电视机外,还可推广到其它接收设备中。
为了达到上述目的,本发明包括自动清理、增加EPG信息记录、增加EPG当前/下一个信息记录和查找获取四部分。其中自动清理部分包括以下步骤
①确定内存中所有节目共用的EPG信息的记录空间和最大记录条数,以保持EPG信息中所有信息的时间差不超过内存中保留EPG信息的时间,设定清理EPG信息的时间周期为1天,防止长时间工作时溢出;
②当EPG记录总数>0时,检索出当前最新记录的时间;
③计算出门限时间,亦即最新记录的时间减EPG信息保留的时间(缺省为7天);
④删除超出门限时间的记录;
⑤更新EPG信息记录总数并重新整理信息记录。
本发明的所有频道共享一块内存,作为电子节目指南的信息存储区。但该内存的电子节目指南信息存储区可以有不同的划分,因此其最大记录数量是可调的。
增加EPG信息记录部分包括以下步骤
①调整记录起始时间时区;
②获取EPG信息记录插入点,包括以下分步骤
(1)检测EPG信息记录总数,当它=0时,即进入下一步骤;
(2)当它不等于0时,检测EPG存储区是否已满,当EPG存储区已满时,即进入下一步骤;
(3)当EPG存储区不满时,根据service-id和event-id进行检索,如果检索到已有该记录,即进入下一步骤;
(4)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将EPG信息记录总数加1;
③判断记录插入点索引的数值,当记录插入点索引<0时,不增加新的EPG信息记录;
④当记录插入点索引≥0时,将当前记录拷贝到EPG信息数组中。
增加当前/下一个信息记录部分包括以下步骤
①获取当前/下一个信息记录插入点,包括以下分步骤
(1)检测当前/下一个信息记录总数,当它=0时,即进入下一步骤;
(2)当它不等于0时,检测当前/下一个存储区是否已满,当EPG存储区已满时,即进入下一步骤;
(3)当当前/下一个存储区不满时,根据service-id和evemt-id进行检索,如果检索到已有该记录,即进入下一步骤;
(4)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将当前/下一个信息记录总数加1;
②判断记录插入点索引的数值,当记录插入点索引<0时,不增加新的当前/下一个信息记录;
③当记录插入点索引≥0时,将当前记录拷贝到当前/下一个信息数组中。
查找获取部分包括以下步骤
①判断输入参数是否有效,当输入参数无效时,直接返回;
②当输入参数有效时,查找第一项匹配的EPG信息记录和总共匹配的记录数量;
③比较待查询记录索引和匹配的记录数量,当待查询记录索引≥匹配的记录数量时无获取,当待查询记录索引<匹配的记录数量时,获取一条EPG信息。
本发明查找获取一条EPG信息或者存储一条EPG信息直接采用折半查找法。定位及查找速度快。它只有4个关键性接口函数,其中两个用于数据注入、两个用于数据获取。
本发明的任务就是这样完成的。
本发明提供了一种完整、简单、易维护的数字电视EPG信息的自动清理、增加记录和查找获取方法。它具有自动维护功能,可设定信息保留时间,可每天进行一次垃圾清理,以防止数据溢出,能确保长时间工作稳定。同时,其信息存储和检索速度快,调用接口简单。它还具有良好的可移植性,除数字电视机外,还可推广到其它接收设备中。
图1为本发明自动清理的流程图。
图2为图1中清理过期EPG信息的流程图。
图3为增加EPG信息记录的流程图。
图4为图3中获取EPG信息记录插入点的流程图。
图5为增加Now/Next信息记录的流程图。
图6为图5中获取Now/Next信息记录插入点的流程图。
图7为获取一条EPG信息的流程图。
具体实施例方式
实施例1。一种数字电视EPG信息的自动清理、增加记录和查找获取方法,包括自动清理、增加EPG信息记录、增加EPG当前/下一个信息记录和查找获取四部分。如图1所示,其中自动清理部分包括以下步骤
①确定内存中所有节目共用的EPG信息的记录空间和最大记录条数,以保持EPG信息中所有信息的时间差不超过内存中保留EPG信息的时间,设定保留EPG信息的时间为延迟1天,防止长时间工作时溢出;
②当EPG记录总数>0时,检索出当前最新记录的时间;
③计算出门限时间,亦即最新记录的时间减保留EPG信息的时间;
④删除超出门限时间的记录;
⑤更新EPG信息记录总数并重新整理信息记录。
其源代码为
//保持EPG信息中的所有信息时间差不超过DaysToKeep,以防止长时间工作时溢出BOOL EPG::EPGList_GabageRemove(void){int i=0,J=0;int temp_Year;UCHAR8 temp_Month,temp_Day;long LatestTime,FirstTime,TempTime;int GabageCount=0;if(Weekly_EPG_Info_Number<=0) return TRUE; temp_Year=Weekly_EPG_Info
.start_time.Year; temp_Month=Weekly_EPG_Info
.start_time.Month; temp_Day=Weekly_EPG_Info
.start_time.Day; LatestTime=(temp_Year<<16)|(temp_Month<<8)|temp_Day; FirstTime=LatestTime; //找出最近的时间 for(i=0;i<Weekly_EPG_Info_Number;i++) { temp_Year=Weekly_EPG_Info[i].start_time.Year; temp_Month=Weekly_EPG_Info[i].start_time.Month; temp_Day=Weekly_EPG_Info[i].start_time.Day; TempTime=(temp_Year<<16)(temp_Month<<8)|temp_Day; if(LatestTime<TempTime) { LatestTime=TempTime;<!-- SIPO <DP n="4"> --><dp n="d4"/> } } temp_Day=LatestTime&0x000000ff; temp_Month=(LatestTime&0x0000ff00)>>8; temp_Year=(LatestTime&0xffff0000)>>16; //计算门限时间,以DaysToKeep为限 if(temp_Day>DaysToKeep) temp_Day=temp_Day-DaysToKeep; else if((temp_Month==2)‖(temp_Month==4)‖(temp_Month==6) ‖(temp_Month==8)‖(temp_Month==9)‖(temp_Month==11) ‖(temp_Month==1)) { if(temp_Month-1==0) { temp_Month=12; temp_Year--; } else temp_Month--; temp_Day=31+temp_Day-DaysToKeep; } else if((temp_Month==5)‖(temp_Month==7)‖(temp_Month==10)‖(temp_Month==12)) { temp_Month--; temp_Day=30+temp_Day-DaysToKeep; } else if(temp_Month==3) { if((temp_Year%400)==0)‖(((temp_Year%4)==0)&&((temp_Year%100)!=0))) {<!-- SIPO <DP n="5"> --><dp n="d5"/> temp_Month--; temp_Day=29+temp_Day-DaysToKeep; } else { temp_Month--; temp_Day=28+temp_Day-DaysToKeep; } } printf(″Gate Time is%d,%d,%d\n″,temp_Year,temp_Month,temp_Day); //删除超出时间限制的信息 FirstTime=(temp_Year<<16)|(temp_Month<<8)|temp_Day; for(i=0;i<Weekly_EPG_Info_Number;i++) { temp_Year=Weekly_EPG_Info[i].start_time.Year; temp_Month=Weekly_EPG_Info[i].start_time.Month; temp_Day=Weekly_EPG_Info[i].start_time.Day; TempTime=(temp_Year<<16)|(temp_Month<<8)|temp_Day; if(FirstTime>Temp Time) { memset((void*)&Weekly_EPG_Info[i],0,sizeof(Weekly_EPG_INFO_STRUCT)); GabageCount++; } } if(GabageCount==0) return TRUE; //重新整理EPG信息记录 int HoleIndex=0,DefragmentIndex; int k=Weekly_EPG_Info_Number; while(k)<!-- SIPO <DP n="6"> --><dp n="d6"/> { for(i=HoleIndex;i<Weekly_EPG_Info_Number;i++) { if(Weekly_EPG_Info[i].service_id==0) { HoleIndex=i; break; } } for(j=HoleIndex;j<Weekly_EPG_Info_Number;j++) { if(Weekly_EPG_Info[j].service_id|=0) { DefragmentIndex=j; break; } } memcpy((void*)&Weekly_EPG_Info[HoleIndex], (void*)&Weekly_EPG_Info[DefragmentIndex], sizeof(Weekly_EPG_INFO_STRUCT)); memset((void*)&Weekly_EPG_Info[DefragmentIndex],0,sizeof(Weekly_EPG_INFO_STRUCT)); HoleIndex++; k--; if(HoleIndex>=DefragmentIndex) break; } Weekly_EPG_Info_Number=Weekly_EPG_Info_number-GabageCount; return TRUE;}
如图3~图4所示,增加EPG信息记录部分包括以下步骤
①调整记录起始时间时区;
②获取EPG信息记录插入点,包括以下分步骤
(1)检测EPG信息记录总数,当它=0时,即进入下一步骤;
(2)当它不等于0时,检测EPG存储区是否已满,当EPG存储区已满时,
即进入下一步骤;
③当EPG存储区不满时,根据service-id和evemt-id进行检索
(1)如果检索到已有该记录,即进入下一步骤;
(2)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将EPG信息记录总数加1;
④判断记录插入点索引的数值,当记录插入点索引<0时,不增加新的EPG信息记录;
⑤当记录插入点索引≥0时,将当前记录拷贝到EPG信息数组中。
其源代码为
∥增加一个新的EPG信息BOOL EPG::AddEPGList(tagDVBEIT_EVENT_ENTRY_STRUCT*pEPG){ int IndexofNewInfo;//---------------------------时区调整--------------------------------------------------- if((*pEPG).start_time.Hour<16) { (*pEPG).start_time.Hour=(*pEPG).start_time.Hour+China_TimeZone; } else { (*pEPG).start_time.Hour=(*pEPG).start_time.Hour+China_TimeZone-24; (*pEPG).start_time.Day=(*pEPG).start_time.Day+1; if((*pEPG).start_time.Month==1‖(*pEPG).start_time.Month==3‖(*pEPG).start_time.Month==5 ‖(*pEPG).start_time.Month==7‖(*pEPG).start_time.Month==8‖(*pEPG).start_time.Month==10 ‖(*pEPG).start_time.Month==12) {<!-- SIPO <DP n="8"> --><dp n="d8"/> if((*pEPG).start_time.Day>31) { (*pEPG).start_time.Day=1; (*pEPG).start_time.Month=(*pEPG).start_time.Month+1; if((*pEPG).start_time.Month==13) { (*pEPG).start_time.Month=1; (*pEPG).start_time.Year=(*pEPG).start_time.Year+1; } } } else if((*pEPG).start_time.Month==4‖(*pEPG).start_time.Month==6 ‖(*pEPG).start_time.Month==9‖(*pEPG).start_time.Month==11) { if((*pEPG).start_time.Day>30) { (*pEPG).start_time.Day=1; (*pEPG).start_time.Month=(*pEPG).start_time.Month+1; if((*pEPG).start_time.Month==13) { (*pEPG).start_time.Month=1; (*pEPG).start_time.Year=(*pEPG).start_time.Year+1; } } } else { int OddMonth=0; if(((*pEPG)start_time.Year%400)==0‖ (((*pEPG).start_time.Year%4)==0&&((*pEPG).start_time.Year%100)!=0))<!-- SIPO <DP n="9"> --><dp n="d9"/> OddMonth=1; if((*pEPG).start_time.Day>28+OddMonth) { (*pEPG).start_time.Day=1; (*pEPG).start_time.Month=(*pEPG).start_time.Month+1; if((*pEPG).start_time.Month==13) { (*pEPG).start_time.Month=1; (*pEPG).start_time.Year=(*pEPG).start_time.Year+1; } } } }//------------------------------------获取插入点----------------------------------------- IndexofNewInfo=Get_EPG_ServiceID_Index((*pEPG).service_id,(*pEPG).event_id); if(IndexofNewInfo==-1) {//没有可用插入点 return FALSE; } else {//将新的EPG信息记录拷贝到EPG信息库中 Weekly_EPG_Info[IndexofNewInfo].service_id=(*pEPG).service_id; Weekly_EPG_Info[IndexofNewInfo].duration=(*pEPG).duration; Weekly_EPG_Info[IndexofNewInfo].event_id=(*pEPG).event_id; Weekly_EPG_Info[IndexofNewInfo].start_time.Year=(*pEPG).start_time.Year; Weekly_EPG_Info[IndexofNewInfo].start_time.Month=(*pEPG).start_time.Month; Weekly EPG_Info[IndexofNewInfo].start_time.Day=(*pEPG).start_time.Day; Weekly_EPG_Infp[IndexofNewInfo].start_time.Hour=(*pEPG).start_time.Hour; Weekly_EPG_Info[IndexofNewInfo].start_time.Minute=(*pEPG)start_time.Minute; Weekly_EPG_Info[IndexofNewInfo].start_time.Second=(*pEPG).start_time.Second;<!-- SIPO <DP n="10"> --><dp n="d10"/> Weekly_EPG_Info[IndexofNewInfo].end_time.Year=(*pEPG).end_time.Year; Weekly_EPG_Info[IndexofNewInfo].end_time.Month=(*pEPG).end_time.Month; Weekly_EPG_Info[IndexofNewInfo].end_time.Day=(*pEPG).end_time.Day; Weekly_EPG_Info[IndexofNewInfo].end_time.Hour=(*pEPG).end_time.Hour; Weekly_EPG_Info[IndexofNewInfo].end time.Minute=(*pEPG).end_time.Minute; Weekly_EPG_Info[IndexofNewInfo].end_time.Second=(*pEPG).end_time.Second; Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_length=(*pEPG).short_event_desc.event_name_length; Weekly_EPG_Info[IndexofNewInfo].short_event_desc.text_length=(*pEPG).short_event_desc.text_length; if(Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_length>=30) { Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_length=30; memcpy((char*)Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_str,(char*)(*pEPG).short_event_desc.event_name_str,30); Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_str[29]=′\0′; } else strcpy((char*)Weekly_EPG_Info[IndexofNewInfo].short_event_desc.event_name_str,(char*)(*pEPG).short_event_desc.event_name_str); if(Weekly_EPG_Info[IndexofNewInfo].short_event_desc.text_length>=30) { Weekly_EPG_Info[IndexofNewInfo].short_event_desc.text_length=30; memcpy((char*)Weekly_EPG_Info[IndexofNewInfo].short_event_desc.text_str,(char*)(*pEPG).short_event_desc.text_str,30); Weekly_EPG_Info[IndexofNewInfo].short_event_desc.text_str[29]=′\0′; } else strcpy((char*)Weekly_EPG_Info[IndexofNewInffo].short_event_desc.text_str,(char*)(*pEPG).short_event_desc.text_str);<!-- SIPO <DP n="11"> --><dp n="d11"/> } return TRUE;}//查找指定serviceID和eventID的数组下标,如果没有找到,就分配一个//serviceID和eventID按照升序排列int EPG::Get_EPG_ServiceID_Index(UINT16serviceID,UINT16eventID){ int i; BOOL foundIt; int IndexFound; if(Weekly_EPG_Info_Number==0) { Weekly_EPG_Info_Number++; return 0; } if(Weekly_EPG_Info_Number>=Max_Weekly_EPG_Info_Number) { printf(″Now EPG storage full!\n″); return-1; } //检查是否存在该serviceID和eventID,如果存在,直接返回索引 foundIt=QuickFind(serviceID,eventID,TRUE,&IndexFound);//printf(″Index is%d,Found result is%d\n″,IndexFound,foundIt); if(foundIt) return IndexFound; else //如果不存在eventID,分配一个新的 { for(i=Weekly_EPG_Info_Number-1;i>=IndexFound;i--) memcpy((void*)&Weekly_EPG_Info[i+1],(void*)&Weekly_EPG_Info[i],<!-- SIPO <DP n="12"> --><dp n="d12"/>sizeof(Weekly_EPG_INFO_STRUCT)); i++; memset((void*)&Weekly_EPG_Info[i],0,sizeof(Weekly_EPG_INFO_STRUCT)); Weekly_EPG_Info_Number++; return IndexFound; }return IndexFound;}
如图5~图6所示,增加当前/下一个信息记录部分包括以下步骤
①获取当前/下一个信息记录插入点,包括以下分步骤
(1)检测当前/下一个信息记录总数,当它=0时,返回0;
(2)当它不等于0时,检测当前/下一个存储区是否已满,当EPG存储区已满时,返回-1;
(3)当当前/下一个存储区不满时,根据service-id和evemt-id进行检索,如果检索到已有该记录,即返回该记录的索引;
(4)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将当前/下一个信息记录总数加1,返回该记录的索引;
②判断记录插入点索引的数值
(1)当记录插入点索引<0时,不增加新的当前/下一个信息记录;
(2)当记录插入点索引≥0时,将当前记录拷贝到当前/下一个信息数组中。
增加EPG信息记录、增加EPG当前/下一个信息记录部分的源代码如下
//增加一个新的当前/下一个event信息BOOL EPG::AddNowNextInfo(tagDVBEIT_EVENT_ENTRY_STRUCT*pShortEvent){int IndexofNewInfo;//----------------获取插入点-------------------------------------------------------------------------- IndexofNewInfo=Get_NowNext_ServieeID_Index((*pShortEvent).service_id,(*pShortEvent).NextFlag); if(IndexofNewInfo==-1)<!-- SIPO <DP n="13"> --><dp n="d13"/> { printf(″EPG Storage Full,Error\n″); return FALSE; } else { Now_Next_Info[IndexofNewInfo].NextFlag=(*pShortEvent).NextFlag; Now_Next_Info[IndexofNewInfo].service_id=(*pShortEvent).service_id; Now_Next_Info[IndexofNewInfo].duration=(*pShortEvent).duration; Now_Next_Info[IndexofNewInfo].event_id=(*pShortEvent).event_id; Now_Next_Info[IndexofNewInfo].start_time.Year=(*pShortEvent).start_time.Year; Now_Next_Info[IndexofNewInfo].start_time.Month=(*pShortEvent).start_time.Month; Now_Next_Info[IndexofNewInfo].start_timeDay=(*pShortEvent).start_time.Day; Now_Next_Info[IndexofNewInfo].start_time.Hour=(*pShortEvent).start_time.Hour; Now_Next_Info[IndexofNewInfo].start_time.Minute=(*pShortEvent).start_time.Minute; Now_Next_Info[IndexofNewInfo].start_time.Second=(*pShortEvent).start_time.Second; Now_Next_Info[IndexofNewInfo].end_time.Year=(*pShortEvent).end_time.Year; Now_Next_Info[IndexofNewInfo].end_time.Month=(*pShortEvent).end_time.Month; Now_Next_Info[IndexofNewInfo].end_time.Day=(*pShortEvent).end_time.Day; Now_Next_Info[IndexofNewInfo].end_time.Hour=(*pShortEvent).end_time.Hour; Now Next_Info[IndexofNewInfo].end_time.Minute=(*pShortEvent).end_time.Minute; Now_Next_Info[IndexofNewInfo].end_time.Second=(*pShortEvent).end_time.Second; Now_Next_Info[IndexofNewInfo].short_event_desc.event_name_length=(*pShortEvent).short_event_desc.event_name_length; Now_Next_Info[IndexofNewInfo].short_event_desc.text_length=(*pShortEvent).short_event_desc.text_length; if(Now_Next_Info[IndexofNewInfo].short_evgnt_desc.event_name_length>=30) { Now_Next_Info[IndexofNewInfo].short_event_desc.event_name_length=30; memcpy((char*)Now_Next_Info[IndexofNewInfo].short_event_desc.event_name_str,(char*)(*pShortEvent).short_event_desc.event_name_str,30);<!-- SIPO <DP n="14"> --><dp n="d14"/> Now_Next_Info[IndexofNewInfo].short_event_desc.event_name_str[29]=′\0′; } else strcpy((char*)Now_Next_Info[IndexofNewInfo].short_event_desc.event_name_str,(char*)(*pShortEvent).short_event_desc.event_name_str); } return TRUE;}//查找指定serviceID的数组下标,如果没有找到,就分配一个//serviceID按照升序排列int EPG::Get_NowNext_ServiceID_Index(UINT16serviceID,BOOL NextFlag){ int i; BOOL foundIt; int IndexFound; if(Now_Next_Info_Numbef==0) { Now_Next_Info_Number++; return 0; }if(Now_Next_Info_Number>=Max_Now_Next_Info_Number) { printf(″Now EPG storage full!\n″); returt-1; } //检查是否存在该serviceID和eventID,如果存在,直接返回索引 foundIt=QuickFind(serviceID,(int)NextFlag,FALSE,&IndexFound); if(foundIt) return IndexFound; else<!-- SIPO <DP n="15"> --><dp n="d15"/> //如果不存在eventID,分配一个新的 { for(i=Now_Next_Info_Number-1;i>=IndexFound;i--) memcpy((void*)&Now_Next_Info[i+1],(void*)&Now_Next_Info[i],sizeof(Now_Next_INFO_STRUCT)); i++; memset((void*)&Now_Next_Info[i],0,sizeof(Now_Next_INFO_STRUCT)); Now_Next_Info_Number++; return IndexFound; } return IndexFound;}
如图7所示,EPG信息记录查找获取部分包括以下步骤
①判断输入参数是否有效,当输入参数无效时,无获取;
②当输入参数有效时,查找第一项匹配的EPG信息记录和总共匹配的记录数量;
③比较待查询记录索引和匹配的记录数量,当待查询记录索引≥匹配的记录数量时无获取,当待查询记录索引<匹配的记录数量时,获取一条EPG信息。
其源代码如下
//输入serviceID和日期以及当天第几条EPG,返回指向该EPG记录的指针,没有则为空//注意IndexOfRecords取值从0开始 Weekly_EPG_INFO_STRUCT*EPG::Get_EPG_Info_InOneDay(UINT16 serviceID,UCHAR8 Date,int IndexOfRecords) { int RecordsFound=0; int firstIndex; if(Date>31‖Date<=0‖IndexOfRecords<0) return NULL; firstIndex=QuickLocateMultiEPG(serviceID,Date,&RecordsFound);<!-- SIPO <DP n="16"> --><dp n="d16"/> if(IndexOfRecords>=RecordsFound) { printf(″No More EPG Records for This Day!\n″); return NULL; } else { return&(Weekly_EPG_Info[firstIndex+IndexOfRecords]); }}//注意,此处假设EPG信息制作时,指定的节目EVENT_ID连续,即使不连续,<br/>//中间也不会插入其他节目的eventID。如果此假设不成立,则应修改本函数<br/>int EPG::QuickLocateMultiEPG(UINT16ServiceID,UCHAR8Date,int*MatchedNumber)<br/>{ int left=0; int right=0; int mid; long tempID; tempID=(ServiceID<<16)|Date; int firstIndex=0,lastIndex=0; right=Weekly_EPG_Info_Number-1; if(right<0) { *MatchedNumber=0; return 0; } mid=(right+left)/2;//定位第一个匹配纪录 while(left<=right) {<!-- SIPO <DP n="17"> --><dp n="d17"/> mid=(right+left)/2; if(tempID<=((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].start_time.Day)) right=mid-1; else left=mid+1; } if(tempID==((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].start_time.Day)) { firstIndex=mid; } else if(tempID==((Weekly_EPG_Info[mid+1].service_id<<16)|Weekly_EPG_Info[mid+1].start_time.Day)) { firstIndex=mid+1; } else { *MatchedNumber=0; return 0; }//定位最后一个匹配纪录 left=0; right=Weekly_EPG_Info_Number-1; mid=(right+left)/2; while(left<=right) { mid=(right+left)/2; if(tempID<((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].start_ime.Day)) right=mid-1; else left=mid+1;<!-- SIPO <DP n="18"> --><dp n="d18"/> } if(tempID==((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].start_time.Day)) { lastIndex=mid; } else if(tempID==((Weekly_EPG_Info[mid-1].service_id<<16)|Weekly_EPG_Info[mid-1].start_time.Day)) { lastIndex=mid-1; } *MatchedNumber=lastIndex-firstIndex+1; return firstIndex; }
查找获取一条当前/下一个信息直接采用折半查找法。查找获取及折半查找的源代码如下
//获取一条当前或者下一个event信息的指针//输入service ID,Current状态。//NextFlag=FALSE,表示获取该serviceID的当前节目信息//NextFlag=TRUE,表示获取该serviceID的下一个节目信息Now_Next_INFO_STRUCT*EPG::GetNowNextInfo(UINT16 serviceID,BOOL NextFlag){ int left=0,right=0,mid=0; long tempID=(serviceID<<16)|(int)NextFlag; right=Now_Next_Info_Number-1; if(right<0) { return NULL; } mid=(right+left)/2; while(left<=right) {<!-- SIPO <DP n="19"> --><dp n="d19"/> mid=(right+left)/2; if(tempID<(Now_Next_Info[mid].service_id<<16|(int)(Now_Next_Info[mid].NextFlag))) { right=mid-1; } else if(tempID>(Now_Next_Info[mid]service_id<<16|(int)(Now_Next_Info[mid].NextFlag))) { left=mid+1; } else if(tempID==(Now_Next_Info[mid].service_id<<16|(int)(Now_Next_Info[mid].NextFlag))) { return&Now_Next_Info[mid]; } } if(tempID==(Now_Next_Info[mid].service_id<<16|(int)(Now_Next_Info[mid].NextFlag))) { return&Now_Next_Info[mid]; } return NULL;}//折半查找//FindInEPG时,serviceID和eventID联合作为关键字//FindInEPG为假时,认为是在nownext信息中搜索,此时eventID被NextFlag替代BOOL EPG::QuickFind(UINT16 ServiceID,UINT16 eventID,BOOL FindInEPG,int*IndexFound){ int left=0; int right=0; int mid; UINT32tempID;<!-- SIPO <DP n="20"> --><dp n="d20"/> tempID=(ServiceID<<16)|eventID; if(FindInEPG) { right=Weekly_EPG_Info_Number-1; if(right<0) { *IndexFound=0; return FALSE; } mid=(right+left)/2; while(left<=right) { mid=(right+left)/2; if(tempID<((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].event_id)) right=mid-1; else if(tempID>((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].event_id)) left=mid+1; else if(tempID==((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].event_id)) { *IndexFound=mid; return TRUE; } } if(tempID<((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].event_id)) { *IndexFound=mid; return FALSE; }<!-- SIPO <DP n="21"> --><dp n="d21"/> else if(tempID==((Weekly_EPG_Info[mid].service_id<<16)|Weekly_EPG_Info[mid].event_id)) { *IndexFound=mid; return TRUE; } else { *IndexFound=mid+1; return FALSE; } } else//find in NowNextInfo { //注意此时eventID已经被NextFlag替代 right=Now_Next_Info_Number-1; left=0; if(right<0) { *IndexFound=0; return FALSE; } mid=(right+ieft)/2;|(int)Now_Next_Info[1].NextFlag)); while(left<=right) { mid=(right+left)/2; if(tempID<((Now_Next_Next_Info[mid].service_id<<16)|(int)Now_Next_Info[mid]NextFlag)) right=mid-1; else if(tempID>((Now_Next_Info[mid].service_id<<16)|(int)Now_Next_Info[mid]NextFlag))<!-- SIPO <DP n="22"> --><dp n="d22"/> left=mid+1; else if(tempID==((Now_Next_Info[mid].service_id <<16)|(int)Now_Next_Info[mid].NextFlag)) { *IndexFound=mid; return TRUE; } } if(tempID<((Now_Next_Info[mid].serviee_id<<16)|(int)Now_Next_Info[mid].NextFlag)) { *IndexFound=mid; return FALSE; } else if(tempID==((Now_Next_Infi[mid].service_id<<16)|(int)Now_Next_Info[mid].NextFlag)) { *IndexFound=mid; return TRUE; } else { *IndexFound=mid+1; return FALSE; } }}void CleanEPG(void*pvParam){ while(1)<!-- SIPO <DP n="23"> --><dp n="d23"/> { //每天清理一次EPG数据 Delay(1000*3600*24); EPG_DVBC.EPGList_GabageRemove(); } return;}EPG.H#ifndef EPG_h#define EPG_h#define max_events_per_program 7*24#define NEXT TRUE#define NOW FALSEtypedef struct SHORT_EVENT_DESC_STRUCT{ /*for short_event_descriptor()*/ UCHAR8 event_name_length; UCHAR8 event_name_str[30];//15个汉字 UCHAR8 text_length; UCHAR8 text_str[30];//15个汉字};typedef struct EXT_EVENT_DESC_STRUCT{ /*for extended_event_descriptor()*/ UCHAR8 ISO_639_language_code[4]; int item_description_length[MAX_NUM_OF_ITEMS]; UCHAR8 item_description_char[MAX_NUM_OF_ITEMS][30]; int item_length[MAX_NUM_OF_ITEMS]; UCHAR8 item_char[MAX_NUM_OF_ITEMS][30];<!-- SIPO <DP n="24"> --><dp n="d24"/> UCHAR8 text_length; UCHAR8 text_char[128]; }; struct Now_Next_INFO_STRUCT { UINT16 service_id; UINT16 event_id; DVBTIME start_time; DVBTIME end_time; UINT32 duration; BOOLNextFlag; SHORT_EVENT_DESC_STRUCT short_event_desc; };struct Weekly_EPG_INFO_STRUCT { UINT16 service_id; UINT16 event_id; DVBTIME start_time; DVBTIME end_time; UINT32 duration; SHORT_EVENT_DESC_STRUCT short_event_dese; };struct Ext_EPG_INFO_STRUCT { UINT16 service_id; UINT16 event_id; DVBTIME start_time; DVBTIME end_time; UINT32 duration;<!-- SIPO <DP n="25"> --><dp n="d25"/>EXT_EVENT_DESC_STRUCT ext_event_desc;};void CleanEPG(void*pvParam);class EPG{publicCORE_TASK_ID TaskID_CleanEPG;EPG(); ~EPG(); BOOL Init(void); BOOL AddNowNewtInfo(tagDVBEIT_EVENT_ENTRY_STRUCT*pShortEvent); BOOL AddEPGList(tagDVBEIT_EVENT_ENTRY_STRUCT*pEPG); BOOL ADDExtEPGList(tagDVBEIT_EVENT_ENTRY_STRUCT*pExtEPG); BOOL EPGList_GabageRemove(void); Now_Next_INFO_STRUCT*GetNowNextInfo(UINT16 serviceID,BOOL Current); Weekly_EPG_INFO_STRUCT*Get_EPG_Info_InOneDay(UINT16 serviceID,UCHAR8 Date,intIndexOfRecords); int Get_Now_Next_Inft_Number(void); int Get_Weekly_EPG_Info_Number(void); void outputNowNextInfo(void); void outputEPGListInfo(void); void PrintEPGofOneDay(UINT16 ServiceID,UCHAR8 Day); private int Max_Now_Next_Info_Number; int Now_Next_Info_Number; CORE_SEM_ID EPG_LOCK1; CORE_SEM_ID NowNext_LOCK; int Max_Weekly_EPG_Info_Number; int Weekly_EPG_Info_Number; int China_TimeZone; int Max_Ext_EPG_Info_Number;<!-- SIPO <DP n="26"> --><dp n="d26"/> int Ext_EPG_Info_Number; int DaysToKeep;//保留EPG的天数 Now_Next_INFO_STRUCT*Now_Next_Info; Weekly_EPG_INFO_STRUCT*Weekly_EPG_Info; Ext_EPG_INFO_STRUCT*Ext_EPG_Info; BOOL QuickFind(UINT16 ServiceID,UINT16 eventID,BOOL FindInEPG,int*IndexFound); int QuickLoeateMultiEPG(UINT16 ServiceID,UCHAR8 Date,int*MatchedNumber); int Get_NowNext_ServiceID_Index(UINT16 serviceID,BOOL NextFlag); int Get_EPG_ServiceID_Index(UINT16 servieeID,UINT16 eventID); };#endif
实施例1具有自动维护功能,可设定信息保留时间,可每天进行一次垃圾清理,以防止数据溢出,能确保长时间工作稳定。同时,其信息存储和检索速度快,调用接口简单。它还具有良好的可移植性,除数字电视机外,还可推广到其它接收设备中。
权利要求
1.一种数字电视EPG信息的自动清理、增加记录和查找获取方法,其特征在于它包括自动清理、增加EPG信息记录、增加EPG当前/下一个信息记录和查找获取四部分,其中自动清理包括以下步骤
①确定内存中所有节目共用的EPG信息的记录空间和最大记录条数,以保持EPG信息中所有信息的时间差不超过内存中保留EPG信息的时间,设定保留EPG信息的时间,防止长时间工作时溢出;
②当EPG记录总数>0时,检索出当前最新记录的时间;
③计算出门限时间,亦即最新记录的时间减EPG信息保留的时间;
④删除超出门限时间的记录;
⑤更新EPG信息记录总数并重新整理信息记录。
2.按照权利要求1所述的数字电视EPG信息的自动清理、增加记录和查找获取方法,其特征在于增加EPG信息记录部分包括以下步骤
①调整记录起始时间时区;
②获取EPG信息记录插入点,包括以下分步骤
(1)检测EPG信息记录总数,当它=0时,即进入下一步骤;
(2)当它不等于0时,检测EPG存储区是否已满,当EPG存储区已满时,即进入下一步骤;
(3)当EPG存储区不满时,根据service-id和evemt-id进行检索,如果检索到已有该记录,即进入下一步骤;
(4)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将EPG信息记录总数加1;
③判断记录插入点索引的数值,当记录插入点索引<0时,不增加新的EPG信息记录;
④当记录插入点索引≥0时,将当前记录拷贝到EPG信息数组中。
3.按照权利要求2所述的数字电视EPG信息的自动清理、增加记录和查找获取方法,其特征在于增加当前/下一个信息记录部分包括以下步骤
①获取当前/下一个信息记录插入点,包括以下分步骤
(1)检测当前/下一个信息记录总数,当它=0时,即进入下一步骤;
(2)当它不等于0时,检测当前/下一个存储区是否已满,当EPG存储区已满时,即进入下一步骤;
(3)当当前/下一个存储区不满时,根据service-id和evemt-id进行检索,如果检索到已有该记录,即进入下一步骤;
(4)如果没有检索到已有该记录,则将插入点之后的记录后移、将插入点的记录清零、将当前/下一个信息记录总数加1;
②判断记录插入点索引的数值,当记录插入点索引<0时,不增加新的当前/下一个信息记录;
③当记录插入点索引≥0时,将当前记录拷贝到当前/下一个信息数组中。
4.按照权利要求3所述的数字电视EPG信息的自动清理、增加记录和查找获取方法,其特征在于查找获取部分包括以下步骤
①判断输入参数是否有效,当输入参数无效时,无获取;
②当输入参数有效时,查找第一项匹配的EPG信息记录和总共匹配的记录数量;
③比较待查询记录索引和匹配的记录数量,当待查询记录索引≥匹配的记录数量时无获取,当待查询记录索引<匹配的记录数量时,获取一条EPG信息。
5.按照权利要求3所述的数字电视EPG信息的自动清理、增加记录和查找获取方法,其特征在于查找获取一条EPG信息直接采用折半查找法。
全文摘要
一种数字电视EPG信息的自动清理、增加记录和查找获取方法。它包括自动清理、增加EPG信息记录、增加EPG当前/下一个信息记录和查找获取四部分。自动清理包括确定内存中共用的EPG信息的记录空间和最大记录条数,设定保留EPG信息的时间,防止长时间工作时溢出;当EPG记录总数>0时,检索出当前最新记录的时间;计算出门限时间,亦即最新记录的时间减保留EPG信息的时间;删除超出门限时间的记录;更新EPG信息记录总数并重新整理信息记录等步骤。它自动清理维护,可防止数据溢出,工作十分稳定。其信息存储和检索速度快,调用接口简单。而且具有良好的可移植性,除数字电视机外,还可推广到其它接收设备中。
文档编号H04N7/08GK1758746SQ20051004478
公开日2006年4月12日 申请日期2005年9月19日 优先权日2005年9月19日
发明者邓泽学 申请人:海信集团有限公司, 青岛海信电器股份有限公司